From d8414567db62aea12bfb9987ae601ff08d5de2b0 Mon Sep 17 00:00:00 2001 From: Alistair Strachan Date: Tue, 2 Apr 2019 23:59:58 -0700 Subject: [PATCH 0001/1121] ANDROID: cuttlefish_defconfig: Enable CONFIG_FUSE_FS Bug: 120439617 Bug: 129901600 Change-Id: Iff554123147f7761ca639b89612138b82a4a400a Signed-off-by: Alistair Strachan --- arch/arm64/configs/cuttlefish_defconfig | 1 + arch/x86/configs/x86_64_cuttlefish_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig index 0aa3968857c1..ee06eafc68c6 100644 --- a/arch/arm64/configs/cuttlefish_defconfig +++ b/arch/arm64/configs/cuttlefish_defconfig @@ -413,6 +413,7 @@ CONFIG_F2FS_FS_ENCRYPTION=y # CONFIG_DNOTIFY is not set CONFIG_QUOTA=y CONFIG_QFMT_V2=y +CONFIG_FUSE_FS=y CONFIG_OVERLAY_FS=y CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig index b46c7cfeee3c..3af7bfc85a3f 100644 --- a/arch/x86/configs/x86_64_cuttlefish_defconfig +++ b/arch/x86/configs/x86_64_cuttlefish_defconfig @@ -426,6 +426,7 @@ CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set CONFIG_QFMT_V2=y CONFIG_AUTOFS4_FS=y +CONFIG_FUSE_FS=y CONFIG_OVERLAY_FS=y CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y -- GitLab From c87ec45ddc123df7b4bc8a64e50e1d6d29050d9d Mon Sep 17 00:00:00 2001 From: Zhiqiang Tu Date: Tue, 9 Apr 2019 15:56:51 +0800 Subject: [PATCH 0002/1121] virtio_mmio: Change initcall level to arch_initcall Virtio clock depends on virtio mmio. Initcall level is changed to make sure that virtio_mmio is ready before virtio clock probe. Change-Id: I174d1c85e88d0e124dd07bce57c38d2b5318de52 Signed-off-by: Zhiqiang Tu --- drivers/virtio/virtio_mmio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c index 74dc7170fd35..d9fe54f41e71 100644 --- a/drivers/virtio/virtio_mmio.c +++ b/drivers/virtio/virtio_mmio.c @@ -748,7 +748,7 @@ static void __exit virtio_mmio_exit(void) vm_unregister_cmdline_devices(); } -module_init(virtio_mmio_init); +arch_initcall(virtio_mmio_init); module_exit(virtio_mmio_exit); MODULE_AUTHOR("Pawel Moll "); -- GitLab From 7b98aa6fd865d04093d4a018aa1b9c05fa013502 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Tue, 26 Feb 2019 13:17:02 -0700 Subject: [PATCH 0003/1121] ANDROID: cfi: Remove unused variable in ptr_to_check_fn An unused variable will be exposed by a backport of mainline commit 0a5f41767444 ("kbuild: clang: disable unused variable warnings only when constant"). kernel/cfi.c:231:16: warning: unused variable 'check' [-Wunused-variable] unsigned long check; ^ 1 warning generated. Remove it so there is no more warning. Change-Id: I05a4c20d2a54790991dc1c88c48d8258c548a8cd Signed-off-by: Nathan Chancellor --- kernel/cfi.c | 1 - 1 file changed, 1 deletion(-) diff --git a/kernel/cfi.c b/kernel/cfi.c index 3265b55efc22..967b0755c00e 100644 --- a/kernel/cfi.c +++ b/kernel/cfi.c @@ -229,7 +229,6 @@ static inline cfi_check_fn ptr_to_check_fn(const struct cfi_shadow __rcu *s, unsigned long ptr) { int index; - unsigned long check; if (unlikely(!s)) return NULL; /* No shadow available */ -- GitLab From 95196d1bad3fcfbd57ff8e81277c64a1ef40f954 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Tue, 9 Apr 2019 10:46:35 -0700 Subject: [PATCH 0004/1121] ANDROID: Makefile: Add '-fsplit-lto-unit' to cfi-clang-flags After r350949 in clang, linking an CONFIG_CFI_CLANG kernel fails with the following error: aarch64-linux-gnu-ld.gold: fatal error: LLVM gold plugin: linking module flags 'EnableSplitLTOUnit': IDs have conflicting values -fsplit-lto-unit is needed when using -fsanitize-cfi so add the flag if it is supported by the compiler. CONFIG_CFI_CLANG works as expected with a tip of tree LLVM toolchain after this commit. Change-Id: I358ff024204c7abcef57b43a583ae960b89113f7 Link: https://github.com/ClangBuiltLinux/linux/issues/406 Link: https://github.com/llvm/llvm-project/commit/84cecfcb3db7c3275ae2d64c419a752d9f5311d6 Signed-off-by: Nathan Chancellor --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8d3de06a4655..ab98dc91513b 100644 --- a/Makefile +++ b/Makefile @@ -834,7 +834,7 @@ export LDFINAL_vmlinux LDFLAGS_FINAL_vmlinux endif ifdef CONFIG_CFI_CLANG -cfi-clang-flags += -fsanitize=cfi +cfi-clang-flags += -fsanitize=cfi $(call cc-option, -fsplit-lto-unit) DISABLE_CFI_CLANG := -fno-sanitize=cfi ifdef CONFIG_MODULES cfi-clang-flags += -fsanitize-cfi-cross-dso -- GitLab From f289d4cdf0ccc5284db141407b8749afbcfc69be Mon Sep 17 00:00:00 2001 From: Caesar Wang Date: Tue, 23 Aug 2016 11:47:02 +0100 Subject: [PATCH 0005/1121] sched/fair: remove printk while schedule is in progress It will cause deadlock and while(1) if call printk while schedule is in progress. The block state like as below: cpu0(hold the console sem): printk->console_unlock->up_sem->spin_lock(&sem->lock)->wake_up_process(cpu1) ->try_to_wake_up(cpu1)->while(p->on_cpu). cpu1(request console sem): console_lock->down_sem->schedule->idle_banlance->update_cpu_capacity-> printk->console_trylock->spin_lock(&sem->lock). p->on_cpu will be 1 forever, because the task is still running on cpu1, so cpu0 is blocked in while(p->on_cpu), but cpu1 could not get spin_lock(&sem->lock), it is blocked too, it means the task will running on cpu1 forever. Change-Id: I61f5633b5e8dfa4fb6bac801dc1732a5494a0a88 Signed-off-by: Caesar Wang Git-commit: df232437710122fcb4e4a0484a1eded5aec29a6a Git-repo: https://android.googlesource.com/kernel/msm Signed-off-by: Pavankumar Kondeti --- kernel/sched/fair.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 91ea9af6c1c4..df1b2a70b146 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -9240,7 +9240,8 @@ static void update_cpu_capacity(struct sched_domain *sd, int cpu) mcc->cpu = cpu; #ifdef CONFIG_SCHED_DEBUG raw_spin_unlock_irqrestore(&mcc->lock, flags); - pr_info("CPU%d: update max cpu_capacity %lu\n", cpu, capacity); + printk_deferred(KERN_INFO "CPU%d: update max cpu_capacity %lu\n", + cpu, capacity); goto skip_unlock; #endif } -- GitLab From 71eb40b7926e2e43e49bb7615d6dda1fd914e1f0 Mon Sep 17 00:00:00 2001 From: Sandeep Patil Date: Wed, 10 Apr 2019 08:29:22 -0700 Subject: [PATCH 0006/1121] Revert "ANDROID: dm: do_mounts_dm: Update init/do_mounts_dm.c to the latest ChromiumOS version." This reverts commit 834155c54dc917399dbb41a4b3c754b489542dcb. Bug: 129143048 Test: Boot cuttlefish Signed-off-by: Sandeep Patil --- drivers/md/dm.h | 2 + include/linux/device-mapper.h | 7 - init/do_mounts_dm.c | 556 ++++++++++++++++------------------ 3 files changed, 258 insertions(+), 307 deletions(-) diff --git a/drivers/md/dm.h b/drivers/md/dm.h index ab289ce9c3cd..38c84c0a35d4 100644 --- a/drivers/md/dm.h +++ b/drivers/md/dm.h @@ -80,6 +80,8 @@ void dm_set_md_type(struct mapped_device *md, enum dm_queue_mode type); enum dm_queue_mode dm_get_md_type(struct mapped_device *md); struct target_type *dm_get_immutable_target_type(struct mapped_device *md); +int dm_setup_md_queue(struct mapped_device *md, struct dm_table *t); + /* * To check the return value from dm_table_find_target(). */ diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index be0eb0118992..0f5f4915b3ab 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -465,13 +465,6 @@ union map_info *dm_get_rq_mapinfo(struct request *rq); struct queue_limits *dm_get_queue_limits(struct mapped_device *md); -void dm_lock_md_type(struct mapped_device *md); -void dm_unlock_md_type(struct mapped_device *md); -void dm_set_md_type(struct mapped_device *md, unsigned type); -unsigned dm_get_md_type(struct mapped_device *md); -int dm_setup_md_queue(struct mapped_device *md, struct dm_table *t); -unsigned dm_table_get_type(struct dm_table *t); - /* * Geometry functions. */ diff --git a/init/do_mounts_dm.c b/init/do_mounts_dm.c index af84b01ccfbc..a557c5ee00a7 100644 --- a/init/do_mounts_dm.c +++ b/init/do_mounts_dm.c @@ -5,17 +5,13 @@ * * This file is released under the GPL. */ -#include -#include #include #include #include -#include #include "do_mounts.h" +#include "../drivers/md/dm.h" -#define DM_MAX_DEVICES 256 -#define DM_MAX_TARGETS 256 #define DM_MAX_NAME 32 #define DM_MAX_UUID 129 #define DM_NO_UUID "none" @@ -23,47 +19,14 @@ #define DM_MSG_PREFIX "init" /* Separators used for parsing the dm= argument. */ -#define DM_FIELD_SEP " " -#define DM_LINE_SEP "," -#define DM_ANY_SEP DM_FIELD_SEP DM_LINE_SEP +#define DM_FIELD_SEP ' ' +#define DM_LINE_SEP ',' /* * When the device-mapper and any targets are compiled into the kernel - * (not a module), one or more device-mappers may be created and used - * as the root device at boot time with the parameters given with the - * boot line dm=... - * - * Multiple device-mappers can be stacked specifing the number of - * devices. A device can have multiple targets if the the number of - * targets is specified. - * - * TODO(taysom:defect 32847) - * In the future, the field will be mandatory. - * - * ::= [] + - * ::= "," + - * ::= [] - * ::= "," - * ::= "ro" | "rw" - * ::= xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx | "none" - * ::= "verity" | "bootcache" | ... - * - * Example: - * 2 vboot none ro 1, - * 0 1768000 bootcache - * device=aa55b119-2a47-8c45-946a-5ac57765011f+1 - * signature=76e9be054b15884a9fa85973e9cb274c93afadb6 - * cache_start=1768000 max_blocks=100000 size_limit=23 max_trace=20000, - * vroot none ro 1, - * 0 1740800 verity payload=254:0 hashtree=254:0 hashstart=1740800 alg=sha1 - * root_hexdigest=76e9be054b15884a9fa85973e9cb274c93afadb6 - * salt=5b3549d54d6c7a3837b9b81ed72e49463a64c03680c47835bef94d768e5646fe - * - * Notes: - * 1. uuid is a label for the device and we set it to "none". - * 2. The field will be optional initially and assumed to be 1. - * Once all the scripts that set these fields have been set, it will - * be made mandatory. + * (not a module), one target may be created and used as the root device at + * boot time with the parameters given with the boot line dm=... + * The code for that is here. */ struct dm_setup_target { @@ -75,388 +38,381 @@ struct dm_setup_target { struct dm_setup_target *next; }; -struct dm_device { +static struct { int minor; int ro; char name[DM_MAX_NAME]; char uuid[DM_MAX_UUID]; - unsigned long num_targets; + char *targets; struct dm_setup_target *target; int target_count; - struct dm_device *next; -}; - -struct dm_option { - char *start; - char *next; - size_t len; - char delim; -}; - -static struct { - unsigned long num_devices; - char *str; } dm_setup_args __initdata; static __initdata int dm_early_setup; -static int __init get_dm_option(struct dm_option *opt, const char *accept) +static size_t __init get_dm_option(char *str, char **next, char sep) { - char *str = opt->next; - char *endp; + size_t len = 0; + char *endp = NULL; if (!str) return 0; - str = skip_spaces(str); - opt->start = str; - endp = strpbrk(str, accept); + endp = strchr(str, sep); if (!endp) { /* act like strchrnul */ - opt->len = strlen(str); - endp = str + opt->len; + len = strlen(str); + endp = str + len; } else { - opt->len = endp - str; + len = endp - str; } - opt->delim = *endp; + + if (endp == str) + return 0; + + if (!next) + return len; + if (*endp == 0) { /* Don't advance past the nul. */ - opt->next = endp; + *next = endp; } else { - opt->next = endp + 1; + *next = endp + 1; } - return opt->len != 0; + return len; } -static int __init dm_setup_cleanup(struct dm_device *devices) +static int __init dm_setup_args_init(void) { - struct dm_device *dev = devices; - - while (dev) { - struct dm_device *old_dev = dev; - struct dm_setup_target *target = dev->target; - while (target) { - struct dm_setup_target *old_target = target; - kfree(target->type); - kfree(target->params); - target = target->next; - kfree(old_target); - dev->target_count--; - } - BUG_ON(dev->target_count); - dev = dev->next; - kfree(old_dev); + dm_setup_args.minor = 0; + dm_setup_args.ro = 0; + dm_setup_args.target = NULL; + dm_setup_args.target_count = 0; + return 0; +} + +static int __init dm_setup_cleanup(void) +{ + struct dm_setup_target *target = dm_setup_args.target; + struct dm_setup_target *old_target = NULL; + while (target) { + kfree(target->type); + kfree(target->params); + old_target = target; + target = target->next; + kfree(old_target); + dm_setup_args.target_count--; } + BUG_ON(dm_setup_args.target_count); return 0; } -static char * __init dm_parse_device(struct dm_device *dev, char *str) +static char * __init dm_setup_parse_device_args(char *str) { - struct dm_option opt; - size_t len; + char *next = NULL; + size_t len = 0; /* Grab the logical name of the device to be exported to udev */ - opt.next = str; - if (!get_dm_option(&opt, DM_FIELD_SEP)) { + len = get_dm_option(str, &next, DM_FIELD_SEP); + if (!len) { DMERR("failed to parse device name"); goto parse_fail; } - len = min(opt.len + 1, sizeof(dev->name)); - strlcpy(dev->name, opt.start, len); /* includes nul */ + len = min(len + 1, sizeof(dm_setup_args.name)); + strlcpy(dm_setup_args.name, str, len); /* includes nul */ + str = skip_spaces(next); /* Grab the UUID value or "none" */ - if (!get_dm_option(&opt, DM_FIELD_SEP)) { + len = get_dm_option(str, &next, DM_FIELD_SEP); + if (!len) { DMERR("failed to parse device uuid"); goto parse_fail; } - len = min(opt.len + 1, sizeof(dev->uuid)); - strlcpy(dev->uuid, opt.start, len); + len = min(len + 1, sizeof(dm_setup_args.uuid)); + strlcpy(dm_setup_args.uuid, str, len); + str = skip_spaces(next); /* Determine if the table/device will be read only or read-write */ - get_dm_option(&opt, DM_ANY_SEP); - if (!strncmp("ro", opt.start, opt.len)) { - dev->ro = 1; - } else if (!strncmp("rw", opt.start, opt.len)) { - dev->ro = 0; + if (!strncmp("ro,", str, 3)) { + dm_setup_args.ro = 1; + } else if (!strncmp("rw,", str, 3)) { + dm_setup_args.ro = 0; } else { DMERR("failed to parse table mode"); goto parse_fail; } + str = skip_spaces(str + 3); - /* Optional number field */ - /* XXX: The field will be mandatory in the next round */ - if (opt.delim == DM_FIELD_SEP[0]) { - if (!get_dm_option(&opt, DM_LINE_SEP)) - return NULL; - dev->num_targets = simple_strtoul(opt.start, NULL, 10); - } else { - dev->num_targets = 1; - } - if (dev->num_targets > DM_MAX_TARGETS) { - DMERR("too many targets %lu > %d", - dev->num_targets, DM_MAX_TARGETS); - } - return opt.next; + return str; parse_fail: return NULL; } -static char * __init dm_parse_targets(struct dm_device *dev, char *str) +static void __init dm_substitute_devices(char *str, size_t str_len) { - struct dm_option opt; - struct dm_setup_target **target = &dev->target; - unsigned long num_targets = dev->num_targets; - unsigned long i; + char *candidate = str; + char *candidate_end = str; + char old_char; + size_t len = 0; + dev_t dev; + + if (str_len < 3) + return; + + while (str && *str) { + candidate = strchr(str, '/'); + if (!candidate) + break; + + /* Avoid embedded slashes */ + if (candidate != str && *(candidate - 1) != DM_FIELD_SEP) { + str = strchr(candidate, DM_FIELD_SEP); + continue; + } + + len = get_dm_option(candidate, &candidate_end, DM_FIELD_SEP); + str = skip_spaces(candidate_end); + if (len < 3 || len > 37) /* name_to_dev_t max; maj:mix min */ + continue; + + /* Temporarily terminate with a nul */ + if (*candidate_end) + candidate_end--; + old_char = *candidate_end; + *candidate_end = '\0'; + + DMDEBUG("converting candidate device '%s' to dev_t", candidate); + /* Use the boot-time specific device naming */ + dev = name_to_dev_t(candidate); + *candidate_end = old_char; + + DMDEBUG(" -> %u", dev); + /* No suitable replacement found */ + if (!dev) + continue; + + /* Rewrite the /dev/path as a major:minor */ + len = snprintf(candidate, len, "%u:%u", MAJOR(dev), MINOR(dev)); + if (!len) { + DMERR("error substituting device major/minor."); + break; + } + candidate += len; + /* Pad out with spaces (fixing our nul) */ + while (candidate < candidate_end) + *(candidate++) = DM_FIELD_SEP; + } +} + +static int __init dm_setup_parse_targets(char *str) +{ + char *next = NULL; + size_t len = 0; + struct dm_setup_target **target = NULL; /* Targets are defined as per the table format but with a * comma as a newline separator. */ - opt.next = str; - for (i = 0; i < num_targets; i++) { + target = &dm_setup_args.target; + while (str && *str) { *target = kzalloc(sizeof(struct dm_setup_target), GFP_KERNEL); if (!*target) { - DMERR("failed to allocate memory for target %s<%ld>", - dev->name, i); + DMERR("failed to allocate memory for target %d", + dm_setup_args.target_count); goto parse_fail; } - dev->target_count++; + dm_setup_args.target_count++; - if (!get_dm_option(&opt, DM_FIELD_SEP)) { - DMERR("failed to parse starting sector" - " for target %s<%ld>", dev->name, i); + (*target)->begin = simple_strtoull(str, &next, 10); + if (!next || *next != DM_FIELD_SEP) { + DMERR("failed to parse starting sector for target %d", + dm_setup_args.target_count - 1); goto parse_fail; } - (*target)->begin = simple_strtoull(opt.start, NULL, 10); + str = skip_spaces(next + 1); - if (!get_dm_option(&opt, DM_FIELD_SEP)) { - DMERR("failed to parse length for target %s<%ld>", - dev->name, i); + (*target)->length = simple_strtoull(str, &next, 10); + if (!next || *next != DM_FIELD_SEP) { + DMERR("failed to parse length for target %d", + dm_setup_args.target_count - 1); goto parse_fail; } - (*target)->length = simple_strtoull(opt.start, NULL, 10); - - if (get_dm_option(&opt, DM_FIELD_SEP)) - (*target)->type = kstrndup(opt.start, opt.len, - GFP_KERNEL); - if (!((*target)->type)) { - DMERR("failed to parse type for target %s<%ld>", - dev->name, i); + str = skip_spaces(next + 1); + + len = get_dm_option(str, &next, DM_FIELD_SEP); + if (!len || + !((*target)->type = kstrndup(str, len, GFP_KERNEL))) { + DMERR("failed to parse type for target %d", + dm_setup_args.target_count - 1); goto parse_fail; } - if (get_dm_option(&opt, DM_LINE_SEP)) - (*target)->params = kstrndup(opt.start, opt.len, - GFP_KERNEL); - if (!((*target)->params)) { - DMERR("failed to parse params for target %s<%ld>", - dev->name, i); + str = skip_spaces(next); + + len = get_dm_option(str, &next, DM_LINE_SEP); + if (!len || + !((*target)->params = kstrndup(str, len, GFP_KERNEL))) { + DMERR("failed to parse params for target %d", + dm_setup_args.target_count - 1); goto parse_fail; } + str = skip_spaces(next); + + /* Before moving on, walk through the copied target and + * attempt to replace all /dev/xxx with the major:minor number. + * It may not be possible to resolve them traditionally at + * boot-time. */ + dm_substitute_devices((*target)->params, len); + target = &((*target)->next); } - DMDEBUG("parsed %d targets", dev->target_count); + DMDEBUG("parsed %d targets", dm_setup_args.target_count); - return opt.next; + return 0; parse_fail: - return NULL; -} - -static struct dm_device * __init dm_parse_args(void) -{ - struct dm_device *devices = NULL; - struct dm_device **tail = &devices; - struct dm_device *dev; - char *str = dm_setup_args.str; - unsigned long num_devices = dm_setup_args.num_devices; - unsigned long i; - - if (!str) - return NULL; - for (i = 0; i < num_devices; i++) { - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) { - DMERR("failed to allocated memory for dev"); - goto error; - } - *tail = dev; - tail = &dev->next; - /* - * devices are given minor numbers 0 - n-1 - * in the order they are found in the arg - * string. - */ - dev->minor = i; - str = dm_parse_device(dev, str); - if (!str) /* NULL indicates error in parsing, bail */ - goto error; - - str = dm_parse_targets(dev, str); - if (!str) - goto error; - } - return devices; -error: - dm_setup_cleanup(devices); - return NULL; + return 1; } /* * Parse the command-line parameters given our kernel, but do not * actually try to invoke the DM device now; that is handled by - * dm_setup_drives after the low-level disk drivers have initialised. - * dm format is described at the top of the file. - * - * Because dm minor numbers are assigned in assending order starting with 0, - * You can assume the first device is /dev/dm-0, the next device is /dev/dm-1, - * and so forth. + * dm_setup_drive after the low-level disk drivers have initialised. + * dm format is as follows: + * dm="name uuid fmode,[table line 1],[table line 2],..." + * May be used with root=/dev/dm-0 as it always uses the first dm minor. */ + static int __init dm_setup(char *str) { - struct dm_option opt; - unsigned long num_devices; + dm_setup_args_init(); + str = dm_setup_parse_device_args(str); if (!str) { DMDEBUG("str is NULL"); goto parse_fail; } - opt.next = str; - if (!get_dm_option(&opt, DM_FIELD_SEP)) - goto parse_fail; - if (isdigit(opt.start[0])) { /* XXX: Optional number field */ - num_devices = simple_strtoul(opt.start, NULL, 10); - str = opt.next; - } else { - num_devices = 1; - /* Don't advance str */ - } - if (num_devices > DM_MAX_DEVICES) { - DMDEBUG("too many devices %lu > %d", - num_devices, DM_MAX_DEVICES); - } - dm_setup_args.str = str; - dm_setup_args.num_devices = num_devices; - DMINFO("will configure %lu devices", num_devices); + + /* Target parsing is delayed until we have dynamic memory */ + dm_setup_args.targets = str; + + printk(KERN_INFO "dm: will configure '%s' on dm-%d\n", + dm_setup_args.name, dm_setup_args.minor); + dm_early_setup = 1; return 1; parse_fail: - DMWARN("Invalid arguments supplied to dm=."); + printk(KERN_WARNING "dm: Invalid arguments supplied to dm=.\n"); return 0; } -static void __init dm_setup_drives(void) + +static void __init dm_setup_drive(void) { struct mapped_device *md = NULL; struct dm_table *table = NULL; struct dm_setup_target *target; - struct dm_device *dev; - char *uuid; + char *uuid = dm_setup_args.uuid; fmode_t fmode = FMODE_READ; - struct dm_device *devices; - devices = dm_parse_args(); + /* Finish parsing the targets. */ + if (dm_setup_parse_targets(dm_setup_args.targets)) + goto parse_fail; - for (dev = devices; dev; dev = dev->next) { - if (dm_create(dev->minor, &md)) { - DMDEBUG("failed to create the device"); - goto dm_create_fail; - } - DMDEBUG("created device '%s'", dm_device_name(md)); - - /* - * In addition to flagging the table below, the disk must be - * set explicitly ro/rw. - */ - set_disk_ro(dm_disk(md), dev->ro); - - if (!dev->ro) - fmode |= FMODE_WRITE; - if (dm_table_create(&table, fmode, dev->target_count, md)) { - DMDEBUG("failed to create the table"); - goto dm_table_create_fail; - } + if (dm_create(dm_setup_args.minor, &md)) { + DMDEBUG("failed to create the device"); + goto dm_create_fail; + } + DMDEBUG("created device '%s'", dm_device_name(md)); - dm_lock_md_type(md); - - for (target = dev->target; target; target = target->next) { - DMINFO("adding target '%llu %llu %s %s'", - (unsigned long long) target->begin, - (unsigned long long) target->length, - target->type, target->params); - if (dm_table_add_target(table, target->type, - target->begin, - target->length, - target->params)) { - DMDEBUG("failed to add the target" - " to the table"); - goto add_target_fail; - } - } - if (dm_table_complete(table)) { - DMDEBUG("failed to complete the table"); - goto table_complete_fail; - } + /* In addition to flagging the table below, the disk must be + * set explicitly ro/rw. */ + set_disk_ro(dm_disk(md), dm_setup_args.ro); + + if (!dm_setup_args.ro) + fmode |= FMODE_WRITE; + if (dm_table_create(&table, fmode, dm_setup_args.target_count, md)) { + DMDEBUG("failed to create the table"); + goto dm_table_create_fail; + } - /* Suspend the device so that we can bind it to the table. */ - if (dm_suspend(md, 0)) { - DMDEBUG("failed to suspend the device pre-bind"); - goto suspend_fail; + dm_lock_md_type(md); + target = dm_setup_args.target; + while (target) { + DMINFO("adding target '%llu %llu %s %s'", + (unsigned long long) target->begin, + (unsigned long long) target->length, target->type, + target->params); + if (dm_table_add_target(table, target->type, target->begin, + target->length, target->params)) { + DMDEBUG("failed to add the target to the table"); + goto add_target_fail; } + target = target->next; + } - /* Initial table load: acquire type of table. */ - dm_set_md_type(md, dm_table_get_type(table)); + if (dm_table_complete(table)) { + DMDEBUG("failed to complete the table"); + goto table_complete_fail; + } - /* Setup md->queue to reflect md's type. */ + if (dm_get_md_type(md) == DM_TYPE_NONE) { + dm_set_md_type(md, dm_table_get_type(table)); if (dm_setup_md_queue(md, table)) { DMWARN("unable to set up device queue for new table."); goto setup_md_queue_fail; } + } else if (dm_get_md_type(md) != dm_table_get_type(table)) { + DMWARN("can't change device type after initial table load."); + goto setup_md_queue_fail; + } + + /* Suspend the device so that we can bind it to the table. */ + if (dm_suspend(md, 0)) { + DMDEBUG("failed to suspend the device pre-bind"); + goto suspend_fail; + } - /* - * Bind the table to the device. This is the only way - * to associate md->map with the table and set the disk - * capacity directly. - */ - if (dm_swap_table(md, table)) { /* should return NULL. */ - DMDEBUG("failed to bind the device to the table"); - goto table_bind_fail; - } - - /* Finally, resume and the device should be ready. */ - if (dm_resume(md)) { - DMDEBUG("failed to resume the device"); - goto resume_fail; - } - - /* Export the dm device via the ioctl interface */ - if (!strcmp(DM_NO_UUID, dev->uuid)) - uuid = NULL; - if (dm_ioctl_export(md, dev->name, uuid)) { - DMDEBUG("failed to export device with given" - " name and uuid"); - goto export_fail; - } + /* Bind the table to the device. This is the only way to associate + * md->map with the table and set the disk capacity directly. */ + if (dm_swap_table(md, table)) { /* should return NULL. */ + DMDEBUG("failed to bind the device to the table"); + goto table_bind_fail; + } - dm_unlock_md_type(md); + /* Finally, resume and the device should be ready. */ + if (dm_resume(md)) { + DMDEBUG("failed to resume the device"); + goto resume_fail; + } - DMINFO("dm-%d is ready", dev->minor); + /* Export the dm device via the ioctl interface */ + if (!strcmp(DM_NO_UUID, dm_setup_args.uuid)) + uuid = NULL; + if (dm_ioctl_export(md, dm_setup_args.name, uuid)) { + DMDEBUG("failed to export device with given name and uuid"); + goto export_fail; } - dm_setup_cleanup(devices); + printk(KERN_INFO "dm: dm-%d is ready\n", dm_setup_args.minor); + + dm_unlock_md_type(md); + dm_setup_cleanup(); return; export_fail: resume_fail: table_bind_fail: -setup_md_queue_fail: suspend_fail: +setup_md_queue_fail: table_complete_fail: add_target_fail: dm_unlock_md_type(md); dm_table_create_fail: dm_put(md); dm_create_fail: - DMWARN("starting dm-%d (%s) failed", - dev->minor, dev->name); - dm_setup_cleanup(devices); + dm_setup_cleanup(); +parse_fail: + printk(KERN_WARNING "dm: starting dm-%d (%s) failed\n", + dm_setup_args.minor, dm_setup_args.name); } __setup("dm=", dm_setup); @@ -465,6 +421,6 @@ void __init dm_run_setup(void) { if (!dm_early_setup) return; - DMINFO("attempting early device configuration."); - dm_setup_drives(); + printk(KERN_INFO "dm: attempting early device configuration.\n"); + dm_setup_drive(); } -- GitLab From 357c3d313225f9999aa8db335080c02e566f0d17 Mon Sep 17 00:00:00 2001 From: Sandeep Patil Date: Wed, 10 Apr 2019 10:12:12 -0700 Subject: [PATCH 0007/1121] Revert "ANDROID: dm: do_mounts_dm: fix dm_substitute_devices()" This reverts commit 052d02c07cbe70ddbd6da4b001c220d7e597286a. Bug: 129143048 Test: Boot cuttlefish from AOSP Signed-off-by: Sandeep Patil --- init/do_mounts_dm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/init/do_mounts_dm.c b/init/do_mounts_dm.c index a557c5ee00a7..0fe9c5f7d5e9 100644 --- a/init/do_mounts_dm.c +++ b/init/do_mounts_dm.c @@ -176,8 +176,7 @@ static void __init dm_substitute_devices(char *str, size_t str_len) continue; /* Temporarily terminate with a nul */ - if (*candidate_end) - candidate_end--; + candidate_end--; old_char = *candidate_end; *candidate_end = '\0'; -- GitLab From afaef205428b4379d03fa35f1e97126c05e4bf9f Mon Sep 17 00:00:00 2001 From: Sandeep Patil Date: Wed, 10 Apr 2019 10:13:14 -0700 Subject: [PATCH 0008/1121] Revert "ANDROID: dm: do_mounts_dm: Rebase on top of 4.9" This reverts commit 398884b9e1d8208ac8bb89ec8eaa23e84b4cbda9. Bug: 129143048 Test: Boot cuttlefish from AOSP Signed-off-by: Sandeep Patil --- init/do_mounts_dm.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/init/do_mounts_dm.c b/init/do_mounts_dm.c index 0fe9c5f7d5e9..e76c137a4cb6 100644 --- a/init/do_mounts_dm.c +++ b/init/do_mounts_dm.c @@ -10,7 +10,6 @@ #include #include "do_mounts.h" -#include "../drivers/md/dm.h" #define DM_MAX_NAME 32 #define DM_MAX_UUID 129 @@ -334,7 +333,6 @@ static void __init dm_setup_drive(void) goto dm_table_create_fail; } - dm_lock_md_type(md); target = dm_setup_args.target; while (target) { DMINFO("adding target '%llu %llu %s %s'", @@ -354,17 +352,6 @@ static void __init dm_setup_drive(void) goto table_complete_fail; } - if (dm_get_md_type(md) == DM_TYPE_NONE) { - dm_set_md_type(md, dm_table_get_type(table)); - if (dm_setup_md_queue(md, table)) { - DMWARN("unable to set up device queue for new table."); - goto setup_md_queue_fail; - } - } else if (dm_get_md_type(md) != dm_table_get_type(table)) { - DMWARN("can't change device type after initial table load."); - goto setup_md_queue_fail; - } - /* Suspend the device so that we can bind it to the table. */ if (dm_suspend(md, 0)) { DMDEBUG("failed to suspend the device pre-bind"); @@ -393,7 +380,6 @@ static void __init dm_setup_drive(void) } printk(KERN_INFO "dm: dm-%d is ready\n", dm_setup_args.minor); - dm_unlock_md_type(md); dm_setup_cleanup(); return; @@ -401,10 +387,8 @@ static void __init dm_setup_drive(void) resume_fail: table_bind_fail: suspend_fail: -setup_md_queue_fail: table_complete_fail: add_target_fail: - dm_unlock_md_type(md); dm_table_create_fail: dm_put(md); dm_create_fail: -- GitLab From efe836537cf2c9d563674f9439b69d452aab169e Mon Sep 17 00:00:00 2001 From: Sandeep Patil Date: Wed, 10 Apr 2019 17:16:35 -0700 Subject: [PATCH 0009/1121] Revert "CHROMIUM: dm: boot time specification of dm=" This reverts commit 0cc78aab2839588831e7b148596fa7a931f6e256. Bug: 129143048 Test: Boot cuttlefish from AOSP Signed-off-by: Sandeep Patil --- .../admin-guide/kernel-parameters.txt | 3 -- Documentation/device-mapper/boot.txt | 42 ------------------- drivers/md/dm-ioctl.c | 39 ----------------- drivers/md/dm-table.c | 1 - include/linux/device-mapper.h | 6 --- init/Makefile | 1 - init/do_mounts.c | 1 - init/do_mounts.h | 10 ----- 8 files changed, 103 deletions(-) delete mode 100644 Documentation/device-mapper/boot.txt diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 3971554ca0d0..f6a77b9a9d26 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -837,9 +837,6 @@ dis_ucode_ldr [X86] Disable the microcode loader. - dm= [DM] Allows early creation of a device-mapper device. - See Documentation/device-mapper/boot.txt. - dma_debug=off If the kernel is compiled with DMA_API_DEBUG support, this option disables the debugging code at boot. diff --git a/Documentation/device-mapper/boot.txt b/Documentation/device-mapper/boot.txt deleted file mode 100644 index adcaad5e5e32..000000000000 --- a/Documentation/device-mapper/boot.txt +++ /dev/null @@ -1,42 +0,0 @@ -Boot time creation of mapped devices -=================================== - -It is possible to configure a device mapper device to act as the root -device for your system in two ways. - -The first is to build an initial ramdisk which boots to a minimal -userspace which configures the device, then pivot_root(8) in to it. - -For simple device mapper configurations, it is possible to boot directly -using the following kernel command line: - -dm=" ,table line 1,...,table line n" - -name = the name to associate with the device - after boot, udev, if used, will use that name to label - the device node. -uuid = may be 'none' or the UUID desired for the device. -ro = may be "ro" or "rw". If "ro", the device and device table will be - marked read-only. - -Each table line may be as normal when using the dmsetup tool except for -two variations: -1. Any use of commas will be interpreted as a newline -2. Quotation marks cannot be escaped and cannot be used without - terminating the dm= argument. - -Unless renamed by udev, the device node created will be dm-0 as the -first minor number for the device-mapper is used during early creation. - -Example -======= - -- Booting to a linear array made up of user-mode linux block devices: - - dm="lroot none 0, 0 4096 linear 98:16 0, 4096 4096 linear 98:32 0" \ - root=/dev/dm-0 - -Will boot to a rw dm-linear target of 8192 sectors split across two -block devices identified by their major:minor numbers. After boot, udev -will rename this target to /dev/mapper/lroot (depending on the rules). -No uuid was assigned. diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index 787afba77b2e..ca948155191a 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -1986,45 +1986,6 @@ void dm_interface_exit(void) dm_hash_exit(); } - -/** - * dm_ioctl_export - Permanently export a mapped device via the ioctl interface - * @md: Pointer to mapped_device - * @name: Buffer (size DM_NAME_LEN) for name - * @uuid: Buffer (size DM_UUID_LEN) for uuid or NULL if not desired - */ -int dm_ioctl_export(struct mapped_device *md, const char *name, - const char *uuid) -{ - int r = 0; - struct hash_cell *hc; - - if (!md) { - r = -ENXIO; - goto out; - } - - /* The name and uuid can only be set once. */ - mutex_lock(&dm_hash_cells_mutex); - hc = dm_get_mdptr(md); - mutex_unlock(&dm_hash_cells_mutex); - if (hc) { - DMERR("%s: already exported", dm_device_name(md)); - r = -ENXIO; - goto out; - } - - r = dm_hash_insert(name, uuid, md); - if (r) { - DMERR("%s: could not bind to '%s'", dm_device_name(md), name); - goto out; - } - - /* Let udev know we've changed. */ - dm_kobject_uevent(md, KOBJ_CHANGE, dm_get_event_nr(md)); -out: - return r; -} /** * dm_copy_name_and_uuid - Copy mapped device name & uuid into supplied buffers * @md: Pointer to mapped_device diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 6916aa9535da..49d20c910e00 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 0f5f4915b3ab..91a063a1f3b3 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -430,12 +430,6 @@ void dm_put(struct mapped_device *md); void dm_set_mdptr(struct mapped_device *md, void *ptr); void *dm_get_mdptr(struct mapped_device *md); -/* - * Export the device via the ioctl interface (uses mdptr). - */ -int dm_ioctl_export(struct mapped_device *md, const char *name, - const char *uuid); - /* * A device can still be used while suspended, but I/O is deferred. */ diff --git a/init/Makefile b/init/Makefile index 0320e1a0705d..a04f1c18b58c 100644 --- a/init/Makefile +++ b/init/Makefile @@ -18,7 +18,6 @@ mounts-y := do_mounts.o mounts-$(CONFIG_BLK_DEV_RAM) += do_mounts_rd.o mounts-$(CONFIG_BLK_DEV_INITRD) += do_mounts_initrd.o mounts-$(CONFIG_BLK_DEV_MD) += do_mounts_md.o -mounts-$(CONFIG_BLK_DEV_DM) += do_mounts_dm.o # dependencies on generated files need to be listed explicitly $(obj)/version.o: include/generated/compile.h diff --git a/init/do_mounts.c b/init/do_mounts.c index 27826694ea26..7cf4f6dafd5f 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -565,7 +565,6 @@ void __init prepare_namespace(void) wait_for_device_probe(); md_run_setup(); - dm_run_setup(); if (saved_root_name[0]) { root_device_name = saved_root_name; diff --git a/init/do_mounts.h b/init/do_mounts.h index cd201124714b..5b05c8f93f47 100644 --- a/init/do_mounts.h +++ b/init/do_mounts.h @@ -61,13 +61,3 @@ void md_run_setup(void); static inline void md_run_setup(void) {} #endif - -#ifdef CONFIG_BLK_DEV_DM - -void dm_run_setup(void); - -#else - -static inline void dm_run_setup(void) {} - -#endif -- GitLab From f5393c36705010563a97e3a73e28ace83ff515e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Fri, 5 Apr 2019 11:07:58 +0200 Subject: [PATCH 0010/1121] net: sfp: move sfp_register_socket call from sfp_remove to sfp_probe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit c4ba68b8691e4 backported from upstream to 4.14 stable was probably applied wrongly, and instead of calling sfp_register_socket in sfp_probe, the socket registering code was put into sfp_remove. This is obviously wrong. The commit first appeared in 4.14.104. Fix it for the next 4.14 release. Fixes: c4ba68b8691e4 ("net: sfp: do not probe SFP module before we're attached") Cc: stable Cc: Russell King Cc: David S. Miller Cc: Greg Kroah-Hartman Cc: Sasha Levin Signed-off-by: Marek BehĂșn Signed-off-by: Sasha Levin --- drivers/net/phy/sfp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c index a1b68b19d912..5ab725a571a8 100644 --- a/drivers/net/phy/sfp.c +++ b/drivers/net/phy/sfp.c @@ -878,6 +878,10 @@ static int sfp_probe(struct platform_device *pdev) if (poll) mod_delayed_work(system_wq, &sfp->poll, poll_jiffies); + sfp->sfp_bus = sfp_register_socket(sfp->dev, sfp, &sfp_module_ops); + if (!sfp->sfp_bus) + return -ENOMEM; + return 0; } @@ -887,10 +891,6 @@ static int sfp_remove(struct platform_device *pdev) sfp_unregister_socket(sfp->sfp_bus); - sfp->sfp_bus = sfp_register_socket(sfp->dev, sfp, &sfp_module_ops); - if (!sfp->sfp_bus) - return -ENOMEM; - return 0; } -- GitLab From 3363914c6b2bf9370708ef296a004edc84012f24 Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Thu, 30 Nov 2017 07:57:57 -0800 Subject: [PATCH 0011/1121] x86/power: Fix some ordering bugs in __restore_processor_context() [ Upstream commit 5b06bbcfc2c621da3009da8decb7511500c293ed ] __restore_processor_context() had a couple of ordering bugs. It restored GSBASE after calling load_gs_index(), and the latter can call into tracing code. It also tried to restore segment registers before restoring the LDT, which is straight-up wrong. Reorder the code so that we restore GSBASE, then the descriptor tables, then the segments. This fixes two bugs. First, it fixes a regression that broke resume under certain configurations due to irqflag tracing in native_load_gs_index(). Second, it fixes resume when the userspace process that initiated suspect had funny segments. The latter can be reproduced by compiling this: // SPDX-License-Identifier: GPL-2.0 /* * ldt_echo.c - Echo argv[1] while using an LDT segment */ int main(int argc, char **argv) { int ret; size_t len; char *buf; const struct user_desc desc = { .entry_number = 0, .base_addr = 0, .limit = 0xfffff, .seg_32bit = 1, .contents = 0, /* Data, grow-up */ .read_exec_only = 0, .limit_in_pages = 1, .seg_not_present = 0, .useable = 0 }; if (argc != 2) errx(1, "Usage: %s STRING", argv[0]); len = asprintf(&buf, "%s\n", argv[1]); if (len < 0) errx(1, "Out of memory"); ret = syscall(SYS_modify_ldt, 1, &desc, sizeof(desc)); if (ret < -1) errno = -ret; if (ret) err(1, "modify_ldt"); asm volatile ("movw %0, %%es" :: "rm" ((unsigned short)7)); write(1, buf, len); return 0; } and running ldt_echo >/sys/power/mem Without the fix, the latter causes a triple fault on resume. Fixes: ca37e57bbe0c ("x86/entry/64: Add missing irqflags tracing to native_load_gs_index()") Reported-by: Jarkko Nikula Signed-off-by: Andy Lutomirski Signed-off-by: Thomas Gleixner Tested-by: Jarkko Nikula Cc: Peter Zijlstra Cc: Borislav Petkov Cc: Linus Torvalds Link: https://lkml.kernel.org/r/6b31721ea92f51ea839e79bd97ade4a75b1eeea2.1512057304.git.luto@kernel.org Signed-off-by: Ingo Molnar Signed-off-by: Sasha Levin --- arch/x86/power/cpu.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c index 04d5157fe7f8..a51d2dfb57d1 100644 --- a/arch/x86/power/cpu.c +++ b/arch/x86/power/cpu.c @@ -228,8 +228,20 @@ static void notrace __restore_processor_state(struct saved_context *ctxt) load_idt((const struct desc_ptr *)&ctxt->idt_limit); #endif +#ifdef CONFIG_X86_64 /* - * segment registers + * We need GSBASE restored before percpu access can work. + * percpu access can happen in exception handlers or in complicated + * helpers like load_gs_index(). + */ + wrmsrl(MSR_GS_BASE, ctxt->gs_base); +#endif + + fix_processor_context(); + + /* + * Restore segment registers. This happens after restoring the GDT + * and LDT, which happen in fix_processor_context(). */ #ifdef CONFIG_X86_32 loadsegment(es, ctxt->es); @@ -250,13 +262,14 @@ static void notrace __restore_processor_state(struct saved_context *ctxt) load_gs_index(ctxt->gs); asm volatile ("movw %0, %%ss" :: "r" (ctxt->ss)); + /* + * Restore FSBASE and user GSBASE after reloading the respective + * segment selectors. + */ wrmsrl(MSR_FS_BASE, ctxt->fs_base); - wrmsrl(MSR_GS_BASE, ctxt->gs_base); wrmsrl(MSR_KERNEL_GS_BASE, ctxt->gs_kernel_base); #endif - fix_processor_context(); - do_fpu_end(); tsc_verify_tsc_adjust(true); x86_platform.restore_sched_clock_state(); -- GitLab From c4cafb8a3ee0e9e0ca86f36623a5facfa5b93bd8 Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Thu, 14 Dec 2017 13:19:05 -0800 Subject: [PATCH 0012/1121] x86/power/64: Use struct desc_ptr for the IDT in struct saved_context [ Upstream commit 090edbe23ff57940fca7f57d9165ce57a826bd7a ] x86_64's saved_context nonsensically used separate idt_limit and idt_base fields and then cast &idt_limit to struct desc_ptr *. This was correct (with -fno-strict-aliasing), but it's confusing, served no purpose, and required #ifdeffery. Simplify this by using struct desc_ptr directly. No change in functionality. Tested-by: Jarkko Nikula Signed-off-by: Andy Lutomirski Acked-by: Rafael J. Wysocki Acked-by: Thomas Gleixner Cc: Borislav Petkov Cc: Josh Poimboeuf Cc: Linus Torvalds Cc: Pavel Machek Cc: Peter Zijlstra Cc: Rafael J. Wysocki Cc: Zhang Rui Link: http://lkml.kernel.org/r/967909ce38d341b01d45eff53e278e2728a3a93a.1513286253.git.luto@kernel.org Signed-off-by: Ingo Molnar Signed-off-by: Sasha Levin --- arch/x86/include/asm/suspend_64.h | 3 +-- arch/x86/power/cpu.c | 11 +---------- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/arch/x86/include/asm/suspend_64.h b/arch/x86/include/asm/suspend_64.h index 7306e911faee..600e9e0aea51 100644 --- a/arch/x86/include/asm/suspend_64.h +++ b/arch/x86/include/asm/suspend_64.h @@ -30,8 +30,7 @@ struct saved_context { u16 gdt_pad; /* Unused */ struct desc_ptr gdt_desc; u16 idt_pad; - u16 idt_limit; - unsigned long idt_base; + struct desc_ptr idt; u16 ldt; u16 tss; unsigned long tr; diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c index a51d2dfb57d1..cba2e2c3f89e 100644 --- a/arch/x86/power/cpu.c +++ b/arch/x86/power/cpu.c @@ -82,12 +82,8 @@ static void __save_processor_state(struct saved_context *ctxt) /* * descriptor tables */ -#ifdef CONFIG_X86_32 store_idt(&ctxt->idt); -#else -/* CONFIG_X86_64 */ - store_idt((struct desc_ptr *)&ctxt->idt_limit); -#endif + /* * We save it here, but restore it only in the hibernate case. * For ACPI S3 resume, this is loaded via 'early_gdt_desc' in 64-bit @@ -221,12 +217,7 @@ static void notrace __restore_processor_state(struct saved_context *ctxt) * now restore the descriptor tables to their proper values * ltr is done i fix_processor_context(). */ -#ifdef CONFIG_X86_32 load_idt(&ctxt->idt); -#else -/* CONFIG_X86_64 */ - load_idt((const struct desc_ptr *)&ctxt->idt_limit); -#endif #ifdef CONFIG_X86_64 /* -- GitLab From 28c25a93926066500c9be08197b4535cbdb00165 Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Thu, 14 Dec 2017 13:19:06 -0800 Subject: [PATCH 0013/1121] x86/power/32: Move SYSENTER MSR restoration to fix_processor_context() [ Upstream commit 896c80bef4d3b357814a476663158aaf669d0fb3 ] x86_64 restores system call MSRs in fix_processor_context(), and x86_32 restored them along with segment registers. The 64-bit variant makes more sense, so move the 32-bit code to match the 64-bit code. No side effects are expected to runtime behavior. Tested-by: Jarkko Nikula Signed-off-by: Andy Lutomirski Acked-by: Rafael J. Wysocki Acked-by: Thomas Gleixner Cc: Borislav Petkov Cc: Josh Poimboeuf Cc: Linus Torvalds Cc: Pavel Machek Cc: Peter Zijlstra Cc: Rafael J. Wysocki Cc: Zhang Rui Link: http://lkml.kernel.org/r/65158f8d7ee64dd6bbc6c1c83b3b34aaa854e3ae.1513286253.git.luto@kernel.org Signed-off-by: Ingo Molnar Signed-off-by: Sasha Levin --- arch/x86/power/cpu.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c index cba2e2c3f89e..8e1668470b23 100644 --- a/arch/x86/power/cpu.c +++ b/arch/x86/power/cpu.c @@ -176,6 +176,9 @@ static void fix_processor_context(void) write_gdt_entry(desc, GDT_ENTRY_TSS, &tss, DESC_TSS); syscall_init(); /* This sets MSR_*STAR and related */ +#else + if (boot_cpu_has(X86_FEATURE_SEP)) + enable_sep_cpu(); #endif load_TR_desc(); /* This does ltr */ load_mm_ldt(current->active_mm); /* This does lldt */ @@ -239,12 +242,6 @@ static void notrace __restore_processor_state(struct saved_context *ctxt) loadsegment(fs, ctxt->fs); loadsegment(gs, ctxt->gs); loadsegment(ss, ctxt->ss); - - /* - * sysenter MSRs - */ - if (boot_cpu_has(X86_FEATURE_SEP)) - enable_sep_cpu(); #else /* CONFIG_X86_64 */ asm volatile ("movw %0, %%ds" :: "r" (ctxt->ds)); -- GitLab From 9b0cc293ed6cb94e024ede2fea081f216eb5b435 Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Thu, 14 Dec 2017 13:19:07 -0800 Subject: [PATCH 0014/1121] x86/power: Make restore_processor_context() sane [ Upstream commit 7ee18d677989e99635027cee04c878950e0752b9 ] My previous attempt to fix a couple of bugs in __restore_processor_context(): 5b06bbcfc2c6 ("x86/power: Fix some ordering bugs in __restore_processor_context()") ... introduced yet another bug, breaking suspend-resume. Rather than trying to come up with a minimal fix, let's try to clean it up for real. This patch fixes quite a few things: - The old code saved a nonsensical subset of segment registers. The only registers that need to be saved are those that contain userspace state or those that can't be trivially restored without percpu access working. (On x86_32, we can restore percpu access by writing __KERNEL_PERCPU to %fs. On x86_64, it's easier to save and restore the kernel's GSBASE.) With this patch, we restore hardcoded values to the kernel state where applicable and explicitly restore the user state after fixing all the descriptor tables. - We used to use an unholy mix of inline asm and C helpers for segment register access. Let's get rid of the inline asm. This fixes the reported s2ram hangs and make the code all around more logical. Analyzed-by: Linus Torvalds Reported-by: Jarkko Nikula Reported-by: Pavel Machek Tested-by: Jarkko Nikula Tested-by: Pavel Machek Signed-off-by: Andy Lutomirski Acked-by: Rafael J. Wysocki Acked-by: Thomas Gleixner Cc: Borislav Petkov Cc: Josh Poimboeuf Cc: Peter Zijlstra Cc: Rafael J. Wysocki Cc: Zhang Rui Fixes: 5b06bbcfc2c6 ("x86/power: Fix some ordering bugs in __restore_processor_context()") Link: http://lkml.kernel.org/r/398ee68e5c0f766425a7b746becfc810840770ff.1513286253.git.luto@kernel.org Signed-off-by: Ingo Molnar Signed-off-by: Sasha Levin --- arch/x86/include/asm/suspend_32.h | 8 +++- arch/x86/include/asm/suspend_64.h | 16 ++++++- arch/x86/power/cpu.c | 79 ++++++++++++++++--------------- 3 files changed, 62 insertions(+), 41 deletions(-) diff --git a/arch/x86/include/asm/suspend_32.h b/arch/x86/include/asm/suspend_32.h index 982c325dad33..8be6afb58471 100644 --- a/arch/x86/include/asm/suspend_32.h +++ b/arch/x86/include/asm/suspend_32.h @@ -12,7 +12,13 @@ /* image of the saved processor state */ struct saved_context { - u16 es, fs, gs, ss; + /* + * On x86_32, all segment registers, with the possible exception of + * gs, are saved at kernel entry in pt_regs. + */ +#ifdef CONFIG_X86_32_LAZY_GS + u16 gs; +#endif unsigned long cr0, cr2, cr3, cr4; u64 misc_enable; bool misc_enable_saved; diff --git a/arch/x86/include/asm/suspend_64.h b/arch/x86/include/asm/suspend_64.h index 600e9e0aea51..a7af9f53c0cb 100644 --- a/arch/x86/include/asm/suspend_64.h +++ b/arch/x86/include/asm/suspend_64.h @@ -20,8 +20,20 @@ */ struct saved_context { struct pt_regs regs; - u16 ds, es, fs, gs, ss; - unsigned long gs_base, gs_kernel_base, fs_base; + + /* + * User CS and SS are saved in current_pt_regs(). The rest of the + * segment selectors need to be saved and restored here. + */ + u16 ds, es, fs, gs; + + /* + * Usermode FSBASE and GSBASE may not match the fs and gs selectors, + * so we save them separately. We save the kernelmode GSBASE to + * restore percpu access after resume. + */ + unsigned long kernelmode_gs_base, usermode_gs_base, fs_base; + unsigned long cr0, cr2, cr3, cr4, cr8; u64 misc_enable; bool misc_enable_saved; diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c index 8e1668470b23..a7d966964c6f 100644 --- a/arch/x86/power/cpu.c +++ b/arch/x86/power/cpu.c @@ -99,22 +99,18 @@ static void __save_processor_state(struct saved_context *ctxt) /* * segment registers */ -#ifdef CONFIG_X86_32 - savesegment(es, ctxt->es); - savesegment(fs, ctxt->fs); +#ifdef CONFIG_X86_32_LAZY_GS savesegment(gs, ctxt->gs); - savesegment(ss, ctxt->ss); -#else -/* CONFIG_X86_64 */ - asm volatile ("movw %%ds, %0" : "=m" (ctxt->ds)); - asm volatile ("movw %%es, %0" : "=m" (ctxt->es)); - asm volatile ("movw %%fs, %0" : "=m" (ctxt->fs)); - asm volatile ("movw %%gs, %0" : "=m" (ctxt->gs)); - asm volatile ("movw %%ss, %0" : "=m" (ctxt->ss)); +#endif +#ifdef CONFIG_X86_64 + savesegment(gs, ctxt->gs); + savesegment(fs, ctxt->fs); + savesegment(ds, ctxt->ds); + savesegment(es, ctxt->es); rdmsrl(MSR_FS_BASE, ctxt->fs_base); - rdmsrl(MSR_GS_BASE, ctxt->gs_base); - rdmsrl(MSR_KERNEL_GS_BASE, ctxt->gs_kernel_base); + rdmsrl(MSR_GS_BASE, ctxt->kernelmode_gs_base); + rdmsrl(MSR_KERNEL_GS_BASE, ctxt->usermode_gs_base); mtrr_save_fixed_ranges(NULL); rdmsrl(MSR_EFER, ctxt->efer); @@ -191,9 +187,12 @@ static void fix_processor_context(void) } /** - * __restore_processor_state - restore the contents of CPU registers saved - * by __save_processor_state() - * @ctxt - structure to load the registers contents from + * __restore_processor_state - restore the contents of CPU registers saved + * by __save_processor_state() + * @ctxt - structure to load the registers contents from + * + * The asm code that gets us here will have restored a usable GDT, although + * it will be pointing to the wrong alias. */ static void notrace __restore_processor_state(struct saved_context *ctxt) { @@ -216,46 +215,50 @@ static void notrace __restore_processor_state(struct saved_context *ctxt) write_cr2(ctxt->cr2); write_cr0(ctxt->cr0); + /* Restore the IDT. */ + load_idt(&ctxt->idt); + /* - * now restore the descriptor tables to their proper values - * ltr is done i fix_processor_context(). + * Just in case the asm code got us here with the SS, DS, or ES + * out of sync with the GDT, update them. */ - load_idt(&ctxt->idt); + loadsegment(ss, __KERNEL_DS); + loadsegment(ds, __USER_DS); + loadsegment(es, __USER_DS); -#ifdef CONFIG_X86_64 /* - * We need GSBASE restored before percpu access can work. - * percpu access can happen in exception handlers or in complicated - * helpers like load_gs_index(). + * Restore percpu access. Percpu access can happen in exception + * handlers or in complicated helpers like load_gs_index(). */ - wrmsrl(MSR_GS_BASE, ctxt->gs_base); +#ifdef CONFIG_X86_64 + wrmsrl(MSR_GS_BASE, ctxt->kernelmode_gs_base); +#else + loadsegment(fs, __KERNEL_PERCPU); + loadsegment(gs, __KERNEL_STACK_CANARY); #endif + /* Restore the TSS, RO GDT, LDT, and usermode-relevant MSRs. */ fix_processor_context(); /* - * Restore segment registers. This happens after restoring the GDT - * and LDT, which happen in fix_processor_context(). + * Now that we have descriptor tables fully restored and working + * exception handling, restore the usermode segments. */ -#ifdef CONFIG_X86_32 +#ifdef CONFIG_X86_64 + loadsegment(ds, ctxt->es); loadsegment(es, ctxt->es); loadsegment(fs, ctxt->fs); - loadsegment(gs, ctxt->gs); - loadsegment(ss, ctxt->ss); -#else -/* CONFIG_X86_64 */ - asm volatile ("movw %0, %%ds" :: "r" (ctxt->ds)); - asm volatile ("movw %0, %%es" :: "r" (ctxt->es)); - asm volatile ("movw %0, %%fs" :: "r" (ctxt->fs)); load_gs_index(ctxt->gs); - asm volatile ("movw %0, %%ss" :: "r" (ctxt->ss)); /* - * Restore FSBASE and user GSBASE after reloading the respective - * segment selectors. + * Restore FSBASE and GSBASE after restoring the selectors, since + * restoring the selectors clobbers the bases. Keep in mind + * that MSR_KERNEL_GS_BASE is horribly misnamed. */ wrmsrl(MSR_FS_BASE, ctxt->fs_base); - wrmsrl(MSR_KERNEL_GS_BASE, ctxt->gs_kernel_base); + wrmsrl(MSR_KERNEL_GS_BASE, ctxt->usermode_gs_base); +#elif defined(CONFIG_X86_32_LAZY_GS) + loadsegment(gs, ctxt->gs); #endif do_fpu_end(); -- GitLab From 3cb115e638ecc8ff0c626e4a227e297afaacf055 Mon Sep 17 00:00:00 2001 From: Yan Zhao Date: Mon, 8 Apr 2019 01:12:47 -0400 Subject: [PATCH 0015/1121] drm/i915/gvt: do not let pin count of shadow mm go negative [ Upstream commit 663a50ceac75c2208d2ad95365bc8382fd42f44d ] shadow mm's pin count got increased in workload preparation phase, which is after workload scanning. it will get decreased in complete_current_workload() anyway after workload completion. Sometimes, if a workload meets a scanning error, its shadow mm pin count will not get increased but will get decreased in the end. This patch lets shadow mm's pin count not go below 0. Fixes: 2707e4446688 ("drm/i915/gvt: vGPU graphics memory virtualization") Cc: zhenyuw@linux.intel.com Cc: stable@vger.kernel.org #4.14+ Signed-off-by: Yan Zhao Signed-off-by: Zhenyu Wang Signed-off-by: Sasha Levin --- drivers/gpu/drm/i915/gvt/gtt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index dadacbe558ab..1a1f7eb46d1e 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c @@ -1629,7 +1629,7 @@ void intel_vgpu_unpin_mm(struct intel_vgpu_mm *mm) if (WARN_ON(mm->type != INTEL_GVT_MM_PPGTT)) return; - atomic_dec(&mm->pincount); + atomic_dec_if_positive(&mm->pincount); } /** -- GitLab From 7f8e322e448b493cab180fe6c85a1cbe9c0c2aad Mon Sep 17 00:00:00 2001 From: Breno Leitao Date: Mon, 8 Apr 2019 16:32:38 +1000 Subject: [PATCH 0016/1121] powerpc/tm: Limit TM code inside PPC_TRANSACTIONAL_MEM [ Upstream commit 897bc3df8c5aebb54c32d831f917592e873d0559 ] Commit e1c3743e1a20 ("powerpc/tm: Set MSR[TS] just prior to recheckpoint") moved a code block around and this block uses a 'msr' variable outside of the CONFIG_PPC_TRANSACTIONAL_MEM, however the 'msr' variable is declared inside a CONFIG_PPC_TRANSACTIONAL_MEM block, causing a possible error when CONFIG_PPC_TRANSACTION_MEM is not defined. error: 'msr' undeclared (first use in this function) This is not causing a compilation error in the mainline kernel, because 'msr' is being used as an argument of MSR_TM_ACTIVE(), which is defined as the following when CONFIG_PPC_TRANSACTIONAL_MEM is *not* set: #define MSR_TM_ACTIVE(x) 0 This patch just fixes this issue avoiding the 'msr' variable usage outside the CONFIG_PPC_TRANSACTIONAL_MEM block, avoiding trusting in the MSR_TM_ACTIVE() definition. Cc: stable@vger.kernel.org Reported-by: Christoph Biedl Fixes: e1c3743e1a20 ("powerpc/tm: Set MSR[TS] just prior to recheckpoint") Signed-off-by: Breno Leitao Signed-off-by: Michael Ellerman Signed-off-by: Sasha Levin --- arch/powerpc/kernel/signal_64.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index 979b9463e17b..927384d85faf 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -746,12 +746,25 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5, if (restore_tm_sigcontexts(current, &uc->uc_mcontext, &uc_transact->uc_mcontext)) goto badframe; - } - else - /* Fall through, for non-TM restore */ + } else #endif - if (restore_sigcontext(current, NULL, 1, &uc->uc_mcontext)) - goto badframe; + { + /* + * Fall through, for non-TM restore + * + * Unset MSR[TS] on the thread regs since MSR from user + * context does not have MSR active, and recheckpoint was + * not called since restore_tm_sigcontexts() was not called + * also. + * + * If not unsetting it, the code can RFID to userspace with + * MSR[TS] set, but without CPU in the proper state, + * causing a TM bad thing. + */ + current->thread.regs->msr &= ~MSR_TS_MASK; + if (restore_sigcontext(current, NULL, 1, &uc->uc_mcontext)) + goto badframe; + } if (restore_altstack(&uc->uc_stack)) goto badframe; -- GitLab From 1efb2caed0ad8f9dca9a57aa1f9c6517ec38fb61 Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Mon, 11 Feb 2019 11:30:04 -0800 Subject: [PATCH 0017/1121] kbuild: clang: choose GCC_TOOLCHAIN_DIR not on LD commit ad15006cc78459d059af56729c4d9bed7c7fd860 upstream. This causes an issue when trying to build with `make LD=ld.lld` if ld.lld and the rest of your cross tools aren't in the same directory (ex. /usr/local/bin) (as is the case for Android's build system), as the GCC_TOOLCHAIN_DIR then gets set based on `which $(LD)` which will point where LLVM tools are, not GCC/binutils tools are located. Instead, select the GCC_TOOLCHAIN_DIR based on another tool provided by binutils for which LLVM does not provide a substitute for, such as elfedit. Fixes: 785f11aa595b ("kbuild: Add better clang cross build support") Link: https://github.com/ClangBuiltLinux/linux/issues/341 Suggested-by: Nathan Chancellor Reviewed-by: Nathan Chancellor Tested-by: Nathan Chancellor Signed-off-by: Nick Desaulniers Signed-off-by: Masahiro Yamada Signed-off-by: Nathan Chancellor Signed-off-by: Sasha Levin --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index da223c660c9a..85753250984c 100644 --- a/Makefile +++ b/Makefile @@ -480,7 +480,7 @@ endif ifeq ($(cc-name),clang) ifneq ($(CROSS_COMPILE),) CLANG_FLAGS := --target=$(notdir $(CROSS_COMPILE:%-=%)) -GCC_TOOLCHAIN_DIR := $(dir $(shell which $(LD))) +GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE)elfedit)) CLANG_FLAGS += --prefix=$(GCC_TOOLCHAIN_DIR) GCC_TOOLCHAIN := $(realpath $(GCC_TOOLCHAIN_DIR)/..) endif -- GitLab From 3d4b1ffc7edb1f963b0223469b0e8b699a197c1f Mon Sep 17 00:00:00 2001 From: Alistair Strachan Date: Fri, 3 Aug 2018 10:39:31 -0700 Subject: [PATCH 0018/1121] x86: vdso: Use $LD instead of $CC to link commit 379d98ddf41344273d9718556f761420f4dc80b3 upstream. The vdso{32,64}.so can fail to link with CC=clang when clang tries to find a suitable GCC toolchain to link these libraries with. /usr/bin/ld: arch/x86/entry/vdso/vclock_gettime.o: access beyond end of merged section (782) This happens because the host environment leaked into the cross compiler environment due to the way clang searches for suitable GCC toolchains. Clang is a retargetable compiler, and each invocation of it must provide --target= --gcc-toolchain= to allow it to find the correct binutils for cross compilation. These flags had been added to KBUILD_CFLAGS, but the vdso code uses CC and not KBUILD_CFLAGS (for various reasons) which breaks clang's ability to find the correct linker when cross compiling. Most of the time this goes unnoticed because the host linker is new enough to work anyway, or is incompatible and skipped, but this cannot be reliably assumed. This change alters the vdso makefile to just use LD directly, which bypasses clang and thus the searching problem. The makefile will just use ${CROSS_COMPILE}ld instead, which is always what we want. This matches the method used to link vmlinux. This drops references to DISABLE_LTO; this option doesn't seem to be set anywhere, and not knowing what its possible values are, it's not clear how to convert it from CC to LD flag. Signed-off-by: Alistair Strachan Signed-off-by: Thomas Gleixner Acked-by: Andy Lutomirski Cc: "H. Peter Anvin" Cc: Greg Kroah-Hartman Cc: kernel-team@android.com Cc: joel@joelfernandes.org Cc: Andi Kleen Link: https://lkml.kernel.org/r/20180803173931.117515-1-astrachan@google.com Signed-off-by: Nathan Chancellor Signed-off-by: Sasha Levin --- arch/x86/entry/vdso/Makefile | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile index 0a550dc5c525..0defcc939ab4 100644 --- a/arch/x86/entry/vdso/Makefile +++ b/arch/x86/entry/vdso/Makefile @@ -48,10 +48,8 @@ targets += $(vdso_img_sodbg) export CPPFLAGS_vdso.lds += -P -C -VDSO_LDFLAGS_vdso.lds = -m64 -Wl,-soname=linux-vdso.so.1 \ - -Wl,--no-undefined \ - -Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096 \ - $(DISABLE_LTO) +VDSO_LDFLAGS_vdso.lds = -m elf_x86_64 -soname linux-vdso.so.1 --no-undefined \ + -z max-page-size=4096 -z common-page-size=4096 $(obj)/vdso64.so.dbg: $(src)/vdso.lds $(vobjs) FORCE $(call if_changed,vdso) @@ -103,10 +101,8 @@ CFLAGS_REMOVE_vvar.o = -pg # CPPFLAGS_vdsox32.lds = $(CPPFLAGS_vdso.lds) -VDSO_LDFLAGS_vdsox32.lds = -Wl,-m,elf32_x86_64 \ - -Wl,-soname=linux-vdso.so.1 \ - -Wl,-z,max-page-size=4096 \ - -Wl,-z,common-page-size=4096 +VDSO_LDFLAGS_vdsox32.lds = -m elf32_x86_64 -soname linux-vdso.so.1 \ + -z max-page-size=4096 -z common-page-size=4096 # 64-bit objects to re-brand as x32 vobjs64-for-x32 := $(filter-out $(vobjs-nox32),$(vobjs-y)) @@ -134,7 +130,7 @@ $(obj)/vdsox32.so.dbg: $(src)/vdsox32.lds $(vobjx32s) FORCE $(call if_changed,vdso) CPPFLAGS_vdso32.lds = $(CPPFLAGS_vdso.lds) -VDSO_LDFLAGS_vdso32.lds = -m32 -Wl,-m,elf_i386 -Wl,-soname=linux-gate.so.1 +VDSO_LDFLAGS_vdso32.lds = -m elf_i386 -soname linux-gate.so.1 # This makes sure the $(obj) subdirectory exists even though vdso32/ # is not a kbuild sub-make subdirectory. @@ -180,13 +176,13 @@ $(obj)/vdso32.so.dbg: FORCE \ # The DSO images are built using a special linker script. # quiet_cmd_vdso = VDSO $@ - cmd_vdso = $(CC) -nostdlib -o $@ \ + cmd_vdso = $(LD) -nostdlib -o $@ \ $(VDSO_LDFLAGS) $(VDSO_LDFLAGS_$(filter %.lds,$(^F))) \ - -Wl,-T,$(filter %.lds,$^) $(filter %.o,$^) && \ + -T $(filter %.lds,$^) $(filter %.o,$^) && \ sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@' -VDSO_LDFLAGS = -fPIC -shared $(call cc-ldoption, -Wl$(comma)--hash-style=both) \ - $(call cc-ldoption, -Wl$(comma)--build-id) -Wl,-Bsymbolic $(LTO_CFLAGS) +VDSO_LDFLAGS = -shared $(call ld-option, --hash-style=both) \ + $(call ld-option, --build-id) -Bsymbolic GCOV_PROFILE := n # -- GitLab From 625c82068a277db442e9fa08727d1670373203f9 Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Thu, 6 Dec 2018 11:12:31 -0800 Subject: [PATCH 0019/1121] x86/vdso: Drop implicit common-page-size linker flag commit ac3e233d29f7f77f28243af0132057d378d3ea58 upstream. GNU linker's -z common-page-size's default value is based on the target architecture. arch/x86/entry/vdso/Makefile sets it to the architecture default, which is implicit and redundant. Drop it. Fixes: 2aae950b21e4 ("x86_64: Add vDSO for x86-64 with gettimeofday/clock_gettime/getcpu") Reported-by: Dmitry Golovin Reported-by: Bill Wendling Suggested-by: Dmitry Golovin Suggested-by: Rui Ueyama Signed-off-by: Nick Desaulniers Signed-off-by: Borislav Petkov Acked-by: Andy Lutomirski Cc: Andi Kleen Cc: Fangrui Song Cc: "H. Peter Anvin" Cc: Ingo Molnar Cc: Thomas Gleixner Cc: x86-ml Link: https://lkml.kernel.org/r/20181206191231.192355-1-ndesaulniers@google.com Link: https://bugs.llvm.org/show_bug.cgi?id=38774 Link: https://github.com/ClangBuiltLinux/linux/issues/31 Signed-off-by: Nathan Chancellor Signed-off-by: Sasha Levin --- arch/x86/entry/vdso/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile index 0defcc939ab4..839015f1b0de 100644 --- a/arch/x86/entry/vdso/Makefile +++ b/arch/x86/entry/vdso/Makefile @@ -49,7 +49,7 @@ targets += $(vdso_img_sodbg) export CPPFLAGS_vdso.lds += -P -C VDSO_LDFLAGS_vdso.lds = -m elf_x86_64 -soname linux-vdso.so.1 --no-undefined \ - -z max-page-size=4096 -z common-page-size=4096 + -z max-page-size=4096 $(obj)/vdso64.so.dbg: $(src)/vdso.lds $(vobjs) FORCE $(call if_changed,vdso) @@ -102,7 +102,7 @@ CFLAGS_REMOVE_vvar.o = -pg CPPFLAGS_vdsox32.lds = $(CPPFLAGS_vdso.lds) VDSO_LDFLAGS_vdsox32.lds = -m elf32_x86_64 -soname linux-vdso.so.1 \ - -z max-page-size=4096 -z common-page-size=4096 + -z max-page-size=4096 # 64-bit objects to re-brand as x32 vobjs64-for-x32 := $(filter-out $(vobjs-nox32),$(vobjs-y)) -- GitLab From 56dbdae0c48827f8fa8bb23f6a26c8785bc455c8 Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Fri, 5 Apr 2019 18:38:45 -0700 Subject: [PATCH 0020/1121] lib/string.c: implement a basic bcmp [ Upstream commit 5f074f3e192f10c9fade898b9b3b8812e3d83342 ] A recent optimization in Clang (r355672) lowers comparisons of the return value of memcmp against zero to comparisons of the return value of bcmp against zero. This helps some platforms that implement bcmp more efficiently than memcmp. glibc simply aliases bcmp to memcmp, but an optimized implementation is in the works. This results in linkage failures for all targets with Clang due to the undefined symbol. For now, just implement bcmp as a tailcail to memcmp to unbreak the build. This routine can be further optimized in the future. Other ideas discussed: * A weak alias was discussed, but breaks for architectures that define their own implementations of memcmp since aliases to declarations are not permitted (only definitions). Arch-specific memcmp implementations typically declare memcmp in C headers, but implement them in assembly. * -ffreestanding also is used sporadically throughout the kernel. * -fno-builtin-bcmp doesn't work when doing LTO. Link: https://bugs.llvm.org/show_bug.cgi?id=41035 Link: https://code.woboq.org/userspace/glibc/string/memcmp.c.html#bcmp Link: https://github.com/llvm/llvm-project/commit/8e16d73346f8091461319a7dfc4ddd18eedcff13 Link: https://github.com/ClangBuiltLinux/linux/issues/416 Link: http://lkml.kernel.org/r/20190313211335.165605-1-ndesaulniers@google.com Signed-off-by: Nick Desaulniers Reported-by: Nathan Chancellor Reported-by: Adhemerval Zanella Suggested-by: Arnd Bergmann Suggested-by: James Y Knight Suggested-by: Masahiro Yamada Suggested-by: Nathan Chancellor Suggested-by: Rasmus Villemoes Acked-by: Steven Rostedt (VMware) Reviewed-by: Nathan Chancellor Tested-by: Nathan Chancellor Reviewed-by: Masahiro Yamada Reviewed-by: Andy Shevchenko Cc: David Laight Cc: Rasmus Villemoes Cc: Namhyung Kim Cc: Greg Kroah-Hartman Cc: Alexander Shishkin Cc: Dan Williams Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Sasha Levin --- include/linux/string.h | 3 +++ lib/string.c | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/include/linux/string.h b/include/linux/string.h index 96115bf561b4..3d43329c20be 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -142,6 +142,9 @@ extern void * memscan(void *,int,__kernel_size_t); #ifndef __HAVE_ARCH_MEMCMP extern int memcmp(const void *,const void *,__kernel_size_t); #endif +#ifndef __HAVE_ARCH_BCMP +extern int bcmp(const void *,const void *,__kernel_size_t); +#endif #ifndef __HAVE_ARCH_MEMCHR extern void * memchr(const void *,int,__kernel_size_t); #endif diff --git a/lib/string.c b/lib/string.c index 5e8d410a93df..1530643edf00 100644 --- a/lib/string.c +++ b/lib/string.c @@ -865,6 +865,26 @@ __visible int memcmp(const void *cs, const void *ct, size_t count) EXPORT_SYMBOL(memcmp); #endif +#ifndef __HAVE_ARCH_BCMP +/** + * bcmp - returns 0 if and only if the buffers have identical contents. + * @a: pointer to first buffer. + * @b: pointer to second buffer. + * @len: size of buffers. + * + * The sign or magnitude of a non-zero return value has no particular + * meaning, and architectures may implement their own more efficient bcmp(). So + * while this particular implementation is a simple (tail) call to memcmp, do + * not rely on anything but whether the return value is zero or non-zero. + */ +#undef bcmp +int bcmp(const void *a, const void *b, size_t len) +{ + return memcmp(a, b, len); +} +EXPORT_SYMBOL(bcmp); +#endif + #ifndef __HAVE_ARCH_MEMSCAN /** * memscan - Find a character in an area of memory. -- GitLab From 83b4ccf2ae92a6efc55f978568c08cc3b6fc0b10 Mon Sep 17 00:00:00 2001 From: Gilad Ben-Yossef Date: Sun, 7 Jan 2018 12:14:22 +0000 Subject: [PATCH 0021/1121] stating: ccree: revert "staging: ccree: fix leak of import() after init()" commit 293edc27f8bc8a44978e9e95902b07b74f1c7523 upstream This reverts commit c5f39d07860c ("staging: ccree: fix leak of import() after init()") and commit aece09024414 ("staging: ccree: Uninitialized return in ssi_ahash_import()"). This is the wrong solution and ends up relying on uninitialized memory, although it was not obvious to me at the time. Cc: stable@vger.kernel.org Signed-off-by: Gilad Ben-Yossef Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sudip Mukherjee Signed-off-by: Sasha Levin --- drivers/staging/ccree/ssi_hash.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/staging/ccree/ssi_hash.c b/drivers/staging/ccree/ssi_hash.c index e266a70a1b32..13291aeaf350 100644 --- a/drivers/staging/ccree/ssi_hash.c +++ b/drivers/staging/ccree/ssi_hash.c @@ -1781,7 +1781,7 @@ static int ssi_ahash_import(struct ahash_request *req, const void *in) struct device *dev = &ctx->drvdata->plat_dev->dev; struct ahash_req_ctx *state = ahash_request_ctx(req); u32 tmp; - int rc = 0; + int rc; memcpy(&tmp, in, sizeof(u32)); if (tmp != CC_EXPORT_MAGIC) { @@ -1790,12 +1790,9 @@ static int ssi_ahash_import(struct ahash_request *req, const void *in) } in += sizeof(u32); - /* call init() to allocate bufs if the user hasn't */ - if (!state->digest_buff) { - rc = ssi_hash_init(state, ctx); - if (rc) - goto out; - } + rc = ssi_hash_init(state, ctx); + if (rc) + goto out; dma_sync_single_for_cpu(dev, state->digest_buff_dma_addr, ctx->inter_digestsize, DMA_BIDIRECTIONAL); -- GitLab From 8add7054070ab79cb271b336d9660bca0ffcaf85 Mon Sep 17 00:00:00 2001 From: Yueyi Li Date: Mon, 24 Dec 2018 07:40:07 +0000 Subject: [PATCH 0022/1121] arm64: kaslr: Reserve size of ARM64_MEMSTART_ALIGN in linear region [ Upstream commit c8a43c18a97845e7f94ed7d181c11f41964976a2 ] When KASLR is enabled (CONFIG_RANDOMIZE_BASE=y), the top 4K of kernel virtual address space may be mapped to physical addresses despite being reserved for ERR_PTR values. Fix the randomization of the linear region so that we avoid mapping the last page of the virtual address space. Cc: Ard Biesheuvel Signed-off-by: liyueyi [will: rewrote commit message; merged in suggestion from Ard] Signed-off-by: Will Deacon Signed-off-by: Sasha Levin (Microsoft) --- arch/arm64/mm/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index caa295cd5d09..9e6c822d458d 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -447,7 +447,7 @@ void __init arm64_memblock_init(void) * memory spans, randomize the linear region as well. */ if (memstart_offset_seed > 0 && range >= ARM64_MEMSTART_ALIGN) { - range = range / ARM64_MEMSTART_ALIGN + 1; + range /= ARM64_MEMSTART_ALIGN; memstart_addr -= ARM64_MEMSTART_ALIGN * ((range * memstart_offset_seed) >> 16); } -- GitLab From 429977fd9f7153607230a6040ee12510a525e930 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 5 Apr 2019 15:39:26 +0200 Subject: [PATCH 0023/1121] tty: mark Siemens R3964 line discipline as BROKEN commit c7084edc3f6d67750f50d4183134c4fb5712a5c8 upstream. The n_r3964 line discipline driver was written in a different time, when SMP machines were rare, and users were trusted to do the right thing. Since then, the world has moved on but not this code, it has stayed rooted in the past with its lovely hand-crafted list structures and loads of "interesting" race conditions all over the place. After attempting to clean up most of the issues, I just gave up and am now marking the driver as BROKEN so that hopefully someone who has this hardware will show up out of the woodwork (I know you are out there!) and will help with debugging a raft of changes that I had laying around for the code, but was too afraid to commit as odds are they would break things. Many thanks to Jann and Linus for pointing out the initial problems in this codebase, as well as many reviews of my attempts to fix the issues. It was a case of whack-a-mole, and as you can see, the mole won. Reported-by: Jann Horn Signed-off-by: Greg Kroah-Hartman Signed-off-by: Linus Torvalds --- drivers/char/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index c28dca0c613d..88316f86cc95 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -380,7 +380,7 @@ config XILINX_HWICAP config R3964 tristate "Siemens R3964 line discipline" - depends on TTY + depends on TTY && BROKEN ---help--- This driver allows synchronous communication with devices using the Siemens R3964 packet protocol. Unless you are dealing with special -- GitLab From ad2548c9462f1aa41ddb8b7f61afeb418e64cec7 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 21 Jan 2019 17:26:42 +0100 Subject: [PATCH 0024/1121] tty: ldisc: add sysctl to prevent autoloading of ldiscs commit 7c0cca7c847e6e019d67b7d793efbbe3b947d004 upstream. By default, the kernel will automatically load the module of any line dicipline that is asked for. As this sometimes isn't the safest thing to do, provide a sysctl to disable this feature. By default, we set this to 'y' as that is the historical way that Linux has worked, and we do not want to break working systems. But in the future, perhaps this can default to 'n' to prevent this functionality. Signed-off-by: Greg Kroah-Hartman Reviewed-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- drivers/tty/Kconfig | 24 +++++++++++++++++++++ drivers/tty/tty_io.c | 3 +++ drivers/tty/tty_ldisc.c | 47 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+) diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig index b811442c5ce6..9788a25a34f4 100644 --- a/drivers/tty/Kconfig +++ b/drivers/tty/Kconfig @@ -467,4 +467,28 @@ config VCC depends on SUN_LDOMS help Support for Sun logical domain consoles. + +config LDISC_AUTOLOAD + bool "Automatically load TTY Line Disciplines" + default y + help + Historically the kernel has always automatically loaded any + line discipline that is in a kernel module when a user asks + for it to be loaded with the TIOCSETD ioctl, or through other + means. This is not always the best thing to do on systems + where you know you will not be using some of the more + "ancient" line disciplines, so prevent the kernel from doing + this unless the request is coming from a process with the + CAP_SYS_MODULE permissions. + + Say 'Y' here if you trust your userspace users to do the right + thing, or if you have only provided the line disciplines that + you know you will be using, or if you wish to continue to use + the traditional method of on-demand loading of these modules + by any user. + + This functionality can be changed at runtime with the + dev.tty.ldisc_autoload sysctl, this configuration option will + only set the default value of this functionality. + endif # TTY diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 7e351d205393..dba4f53a7fff 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -511,6 +511,8 @@ static const struct file_operations hung_up_tty_fops = { static DEFINE_SPINLOCK(redirect_lock); static struct file *redirect; +extern void tty_sysctl_init(void); + /** * tty_wakeup - request more data * @tty: terminal @@ -3332,6 +3334,7 @@ void console_sysfs_notify(void) */ int __init tty_init(void) { + tty_sysctl_init(); cdev_init(&tty_cdev, &tty_fops); if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) || register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0) diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index ca656ef8de64..01fcdc7ff077 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -155,6 +155,13 @@ static void put_ldops(struct tty_ldisc_ops *ldops) * takes tty_ldiscs_lock to guard against ldisc races */ +#if defined(CONFIG_LDISC_AUTOLOAD) + #define INITIAL_AUTOLOAD_STATE 1 +#else + #define INITIAL_AUTOLOAD_STATE 0 +#endif +static int tty_ldisc_autoload = INITIAL_AUTOLOAD_STATE; + static struct tty_ldisc *tty_ldisc_get(struct tty_struct *tty, int disc) { struct tty_ldisc *ld; @@ -169,6 +176,8 @@ static struct tty_ldisc *tty_ldisc_get(struct tty_struct *tty, int disc) */ ldops = get_ldops(disc); if (IS_ERR(ldops)) { + if (!capable(CAP_SYS_MODULE) && !tty_ldisc_autoload) + return ERR_PTR(-EPERM); request_module("tty-ldisc-%d", disc); ldops = get_ldops(disc); if (IS_ERR(ldops)) @@ -841,3 +850,41 @@ void tty_ldisc_deinit(struct tty_struct *tty) tty_ldisc_put(tty->ldisc); tty->ldisc = NULL; } + +static int zero; +static int one = 1; +static struct ctl_table tty_table[] = { + { + .procname = "ldisc_autoload", + .data = &tty_ldisc_autoload, + .maxlen = sizeof(tty_ldisc_autoload), + .mode = 0644, + .proc_handler = proc_dointvec, + .extra1 = &zero, + .extra2 = &one, + }, + { } +}; + +static struct ctl_table tty_dir_table[] = { + { + .procname = "tty", + .mode = 0555, + .child = tty_table, + }, + { } +}; + +static struct ctl_table tty_root_table[] = { + { + .procname = "dev", + .mode = 0555, + .child = tty_dir_table, + }, + { } +}; + +void tty_sysctl_init(void) +{ + register_sysctl_table(tty_root_table); +} -- GitLab From 58ffe3e3248f90dc9ae30ccda9defae0dddd16f7 Mon Sep 17 00:00:00 2001 From: Junwei Hu Date: Tue, 2 Apr 2019 19:38:04 +0800 Subject: [PATCH 0025/1121] ipv6: Fix dangling pointer when ipv6 fragment [ Upstream commit ef0efcd3bd3fd0589732b67fb586ffd3c8705806 ] At the beginning of ip6_fragment func, the prevhdr pointer is obtained in the ip6_find_1stfragopt func. However, all the pointers pointing into skb header may change when calling skb_checksum_help func with skb->ip_summed = CHECKSUM_PARTIAL condition. The prevhdr pointe will be dangling if it is not reloaded after calling __skb_linearize func in skb_checksum_help func. Here, I add a variable, nexthdr_offset, to evaluate the offset, which does not changes even after calling __skb_linearize func. Fixes: 405c92f7a541 ("ipv6: add defensive check for CHECKSUM_PARTIAL skbs in ip_fragment") Signed-off-by: Junwei Hu Reported-by: Wenhao Zhang Reported-by: syzbot+e8ce541d095e486074fc@syzkaller.appspotmail.com Reviewed-by: Zhiqiang Liu Acked-by: Martin KaFai Lau Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/ipv6/ip6_output.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 7ca8264cbdf9..2af849ba33c9 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -611,7 +611,7 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, inet6_sk(skb->sk) : NULL; struct ipv6hdr *tmp_hdr; struct frag_hdr *fh; - unsigned int mtu, hlen, left, len; + unsigned int mtu, hlen, left, len, nexthdr_offset; int hroom, troom; __be32 frag_id; int ptr, offset = 0, err = 0; @@ -622,6 +622,7 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, goto fail; hlen = err; nexthdr = *prevhdr; + nexthdr_offset = prevhdr - skb_network_header(skb); mtu = ip6_skb_dst_mtu(skb); @@ -656,6 +657,7 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, (err = skb_checksum_help(skb))) goto fail; + prevhdr = skb_network_header(skb) + nexthdr_offset; hroom = LL_RESERVED_SPACE(rt->dst.dev); if (skb_has_frag_list(skb)) { unsigned int first_len = skb_pagelen(skb); -- GitLab From b74c2990d061b3928eea19ba19e89209bb7f2152 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 4 Apr 2019 16:37:53 +0200 Subject: [PATCH 0026/1121] ipv6: sit: reset ip header pointer in ipip6_rcv [ Upstream commit bb9bd814ebf04f579be466ba61fc922625508807 ] ipip6 tunnels run iptunnel_pull_header on received skbs. This can determine the following use-after-free accessing iph pointer since the packet will be 'uncloned' running pskb_expand_head if it is a cloned gso skb (e.g if the packet has been sent though a veth device) [ 706.369655] BUG: KASAN: use-after-free in ipip6_rcv+0x1678/0x16e0 [sit] [ 706.449056] Read of size 1 at addr ffffe01b6bd855f5 by task ksoftirqd/1/= [ 706.669494] Hardware name: HPE ProLiant m400 Server/ProLiant m400 Server, BIOS U02 08/19/2016 [ 706.771839] Call trace: [ 706.801159] dump_backtrace+0x0/0x2f8 [ 706.845079] show_stack+0x24/0x30 [ 706.884833] dump_stack+0xe0/0x11c [ 706.925629] print_address_description+0x68/0x260 [ 706.982070] kasan_report+0x178/0x340 [ 707.025995] __asan_report_load1_noabort+0x30/0x40 [ 707.083481] ipip6_rcv+0x1678/0x16e0 [sit] [ 707.132623] tunnel64_rcv+0xd4/0x200 [tunnel4] [ 707.185940] ip_local_deliver_finish+0x3b8/0x988 [ 707.241338] ip_local_deliver+0x144/0x470 [ 707.289436] ip_rcv_finish+0x43c/0x14b0 [ 707.335447] ip_rcv+0x628/0x1138 [ 707.374151] __netif_receive_skb_core+0x1670/0x2600 [ 707.432680] __netif_receive_skb+0x28/0x190 [ 707.482859] process_backlog+0x1d0/0x610 [ 707.529913] net_rx_action+0x37c/0xf68 [ 707.574882] __do_softirq+0x288/0x1018 [ 707.619852] run_ksoftirqd+0x70/0xa8 [ 707.662734] smpboot_thread_fn+0x3a4/0x9e8 [ 707.711875] kthread+0x2c8/0x350 [ 707.750583] ret_from_fork+0x10/0x18 [ 707.811302] Allocated by task 16982: [ 707.854182] kasan_kmalloc.part.1+0x40/0x108 [ 707.905405] kasan_kmalloc+0xb4/0xc8 [ 707.948291] kasan_slab_alloc+0x14/0x20 [ 707.994309] __kmalloc_node_track_caller+0x158/0x5e0 [ 708.053902] __kmalloc_reserve.isra.8+0x54/0xe0 [ 708.108280] __alloc_skb+0xd8/0x400 [ 708.150139] sk_stream_alloc_skb+0xa4/0x638 [ 708.200346] tcp_sendmsg_locked+0x818/0x2b90 [ 708.251581] tcp_sendmsg+0x40/0x60 [ 708.292376] inet_sendmsg+0xf0/0x520 [ 708.335259] sock_sendmsg+0xac/0xf8 [ 708.377096] sock_write_iter+0x1c0/0x2c0 [ 708.424154] new_sync_write+0x358/0x4a8 [ 708.470162] __vfs_write+0xc4/0xf8 [ 708.510950] vfs_write+0x12c/0x3d0 [ 708.551739] ksys_write+0xcc/0x178 [ 708.592533] __arm64_sys_write+0x70/0xa0 [ 708.639593] el0_svc_handler+0x13c/0x298 [ 708.686646] el0_svc+0x8/0xc [ 708.739019] Freed by task 17: [ 708.774597] __kasan_slab_free+0x114/0x228 [ 708.823736] kasan_slab_free+0x10/0x18 [ 708.868703] kfree+0x100/0x3d8 [ 708.905320] skb_free_head+0x7c/0x98 [ 708.948204] skb_release_data+0x320/0x490 [ 708.996301] pskb_expand_head+0x60c/0x970 [ 709.044399] __iptunnel_pull_header+0x3b8/0x5d0 [ 709.098770] ipip6_rcv+0x41c/0x16e0 [sit] [ 709.146873] tunnel64_rcv+0xd4/0x200 [tunnel4] [ 709.200195] ip_local_deliver_finish+0x3b8/0x988 [ 709.255596] ip_local_deliver+0x144/0x470 [ 709.303692] ip_rcv_finish+0x43c/0x14b0 [ 709.349705] ip_rcv+0x628/0x1138 [ 709.388413] __netif_receive_skb_core+0x1670/0x2600 [ 709.446943] __netif_receive_skb+0x28/0x190 [ 709.497120] process_backlog+0x1d0/0x610 [ 709.544169] net_rx_action+0x37c/0xf68 [ 709.589131] __do_softirq+0x288/0x1018 [ 709.651938] The buggy address belongs to the object at ffffe01b6bd85580 which belongs to the cache kmalloc-1024 of size 1024 [ 709.804356] The buggy address is located 117 bytes inside of 1024-byte region [ffffe01b6bd85580, ffffe01b6bd85980) [ 709.946340] The buggy address belongs to the page: [ 710.003824] page:ffff7ff806daf600 count:1 mapcount:0 mapping:ffffe01c4001f600 index:0x0 [ 710.099914] flags: 0xfffff8000000100(slab) [ 710.149059] raw: 0fffff8000000100 dead000000000100 dead000000000200 ffffe01c4001f600 [ 710.242011] raw: 0000000000000000 0000000000380038 00000001ffffffff 0000000000000000 [ 710.334966] page dumped because: kasan: bad access detected Fix it resetting iph pointer after iptunnel_pull_header Fixes: a09a4c8dd1ec ("tunnels: Remove encapsulation offloads on decap") Tested-by: Jianlin Shi Signed-off-by: Lorenzo Bianconi Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/ipv6/sit.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index e23190725244..f7d080d1cf8e 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -661,6 +661,10 @@ static int ipip6_rcv(struct sk_buff *skb) !net_eq(tunnel->net, dev_net(tunnel->dev)))) goto out; + /* skb can be uncloned in iptunnel_pull_header, so + * old iph is no longer valid + */ + iph = (const struct iphdr *)skb_mac_header(skb); err = IP_ECN_decapsulate(iph, skb); if (unlikely(err)) { if (log_ecn_error) -- GitLab From 393c8b4c6790c21d7f639c47436b13e975eee7b1 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 29 Mar 2019 12:19:46 +0100 Subject: [PATCH 0027/1121] kcm: switch order of device registration to fix a crash [ Upstream commit 3c446e6f96997f2a95bf0037ef463802162d2323 ] When kcm is loaded while many processes try to create a KCM socket, a crash occurs: BUG: unable to handle kernel NULL pointer dereference at 000000000000000e IP: mutex_lock+0x27/0x40 kernel/locking/mutex.c:240 PGD 8000000016ef2067 P4D 8000000016ef2067 PUD 3d6e9067 PMD 0 Oops: 0002 [#1] SMP KASAN PTI CPU: 0 PID: 7005 Comm: syz-executor.5 Not tainted 4.12.14-396-default #1 SLE15-SP1 (unreleased) RIP: 0010:mutex_lock+0x27/0x40 kernel/locking/mutex.c:240 RSP: 0018:ffff88000d487a00 EFLAGS: 00010246 RAX: 0000000000000000 RBX: 000000000000000e RCX: 1ffff100082b0719 ... CR2: 000000000000000e CR3: 000000004b1bc003 CR4: 0000000000060ef0 Call Trace: kcm_create+0x600/0xbf0 [kcm] __sock_create+0x324/0x750 net/socket.c:1272 ... This is due to race between sock_create and unfinished register_pernet_device. kcm_create tries to do "net_generic(net, kcm_net_id)". but kcm_net_id is not initialized yet. So switch the order of the two to close the race. This can be reproduced with mutiple processes doing socket(PF_KCM, ...) and one process doing module removal. Fixes: ab7ac4eb9832 ("kcm: Kernel Connection Multiplexor module") Reviewed-by: Michal Kubecek Signed-off-by: Jiri Slaby Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/kcm/kcmsock.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c index 9bf997404918..7b4f3f865861 100644 --- a/net/kcm/kcmsock.c +++ b/net/kcm/kcmsock.c @@ -2059,14 +2059,14 @@ static int __init kcm_init(void) if (err) goto fail; - err = sock_register(&kcm_family_ops); - if (err) - goto sock_register_fail; - err = register_pernet_device(&kcm_net_ops); if (err) goto net_ops_fail; + err = sock_register(&kcm_family_ops); + if (err) + goto sock_register_fail; + err = kcm_proc_init(); if (err) goto proc_init_fail; @@ -2074,12 +2074,12 @@ static int __init kcm_init(void) return 0; proc_init_fail: - unregister_pernet_device(&kcm_net_ops); - -net_ops_fail: sock_unregister(PF_KCM); sock_register_fail: + unregister_pernet_device(&kcm_net_ops); + +net_ops_fail: proto_unregister(&kcm_proto); fail: @@ -2095,8 +2095,8 @@ static int __init kcm_init(void) static void __exit kcm_exit(void) { kcm_proc_exit(); - unregister_pernet_device(&kcm_net_ops); sock_unregister(PF_KCM); + unregister_pernet_device(&kcm_net_ops); proto_unregister(&kcm_proto); destroy_workqueue(kcm_wq); -- GitLab From 23bfd229819139b6a9635e6efb9d2fa0309b3de2 Mon Sep 17 00:00:00 2001 From: Steffen Klassert Date: Tue, 2 Apr 2019 08:16:03 +0200 Subject: [PATCH 0028/1121] net-gro: Fix GRO flush when receiving a GSO packet. [ Upstream commit 0ab03f353d3613ea49d1f924faf98559003670a8 ] Currently we may merge incorrectly a received GSO packet or a packet with frag_list into a packet sitting in the gro_hash list. skb_segment() may crash case because the assumptions on the skb layout are not met. The correct behaviour would be to flush the packet in the gro_hash list and send the received GSO packet directly afterwards. Commit d61d072e87c8e ("net-gro: avoid reorders") sets NAPI_GRO_CB(skb)->flush in this case, but this is not checked before merging. This patch makes sure to check this flag and to not merge in that case. Fixes: d61d072e87c8e ("net-gro: avoid reorders") Signed-off-by: Steffen Klassert Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/core/skbuff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 1b39aef5cf82..2b3b0307dd89 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -3808,7 +3808,7 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb) struct sk_buff *lp, *p = *head; unsigned int delta_truesize; - if (unlikely(p->len + len >= 65536)) + if (unlikely(p->len + len >= 65536 || NAPI_GRO_CB(skb)->flush)) return -E2BIG; lp = NAPI_GRO_CB(p)->last; -- GitLab From 96d8f6246ca2c7cfbb67ca8bb83f0bb81731b520 Mon Sep 17 00:00:00 2001 From: Artemy Kovalyov Date: Tue, 19 Mar 2019 11:24:38 +0200 Subject: [PATCH 0029/1121] net/mlx5: Decrease default mr cache size [ Upstream commit e8b26b2135dedc0284490bfeac06dfc4418d0105 ] Delete initialization of high order entries in mr cache to decrease initial memory footprint. When required, the administrator can populate the entries with memory keys via the /sys interface. This approach is very helpful to significantly reduce the per HW function memory footprint in virtualization environments such as SRIOV. Fixes: 9603b61de1ee ("mlx5: Move pci device handling from mlx5_ib to mlx5_core") Signed-off-by: Artemy Kovalyov Signed-off-by: Moni Shoua Signed-off-by: Leon Romanovsky Reported-by: Shalom Toledo Acked-by: Or Gerlitz Signed-off-by: Saeed Mahameed Signed-off-by: Greg Kroah-Hartman --- .../net/ethernet/mellanox/mlx5/core/main.c | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index 558fc6a05e2a..826d1a4600f3 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -155,26 +155,6 @@ static struct mlx5_profile profile[] = { .size = 8, .limit = 4 }, - .mr_cache[16] = { - .size = 8, - .limit = 4 - }, - .mr_cache[17] = { - .size = 8, - .limit = 4 - }, - .mr_cache[18] = { - .size = 8, - .limit = 4 - }, - .mr_cache[19] = { - .size = 4, - .limit = 2 - }, - .mr_cache[20] = { - .size = 4, - .limit = 2 - }, }, }; -- GitLab From c8a88799e632045399af886a1b1a5205e5d49897 Mon Sep 17 00:00:00 2001 From: Mao Wenan Date: Thu, 28 Mar 2019 17:10:56 +0800 Subject: [PATCH 0030/1121] net: rds: force to destroy connection if t_sock is NULL in rds_tcp_kill_sock(). [ Upstream commit cb66ddd156203daefb8d71158036b27b0e2caf63 ] When it is to cleanup net namespace, rds_tcp_exit_net() will call rds_tcp_kill_sock(), if t_sock is NULL, it will not call rds_conn_destroy(), rds_conn_path_destroy() and rds_tcp_conn_free() to free connection, and the worker cp_conn_w is not stopped, afterwards the net is freed in net_drop_ns(); While cp_conn_w rds_connect_worker() will call rds_tcp_conn_path_connect() and reference 'net' which has already been freed. In rds_tcp_conn_path_connect(), rds_tcp_set_callbacks() will set t_sock = sock before sock->ops->connect, but if connect() is failed, it will call rds_tcp_restore_callbacks() and set t_sock = NULL, if connect is always failed, rds_connect_worker() will try to reconnect all the time, so rds_tcp_kill_sock() will never to cancel worker cp_conn_w and free the connections. Therefore, the condition !tc->t_sock is not needed if it is going to do cleanup_net->rds_tcp_exit_net->rds_tcp_kill_sock, because tc->t_sock is always NULL, and there is on other path to cancel cp_conn_w and free connection. So this patch is to fix this. rds_tcp_kill_sock(): ... if (net != c_net || !tc->t_sock) ... Acked-by: Santosh Shilimkar ================================================================== BUG: KASAN: use-after-free in inet_create+0xbcc/0xd28 net/ipv4/af_inet.c:340 Read of size 4 at addr ffff8003496a4684 by task kworker/u8:4/3721 CPU: 3 PID: 3721 Comm: kworker/u8:4 Not tainted 5.1.0 #11 Hardware name: linux,dummy-virt (DT) Workqueue: krdsd rds_connect_worker Call trace: dump_backtrace+0x0/0x3c0 arch/arm64/kernel/time.c:53 show_stack+0x28/0x38 arch/arm64/kernel/traps.c:152 __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x120/0x188 lib/dump_stack.c:113 print_address_description+0x68/0x278 mm/kasan/report.c:253 kasan_report_error mm/kasan/report.c:351 [inline] kasan_report+0x21c/0x348 mm/kasan/report.c:409 __asan_report_load4_noabort+0x30/0x40 mm/kasan/report.c:429 inet_create+0xbcc/0xd28 net/ipv4/af_inet.c:340 __sock_create+0x4f8/0x770 net/socket.c:1276 sock_create_kern+0x50/0x68 net/socket.c:1322 rds_tcp_conn_path_connect+0x2b4/0x690 net/rds/tcp_connect.c:114 rds_connect_worker+0x108/0x1d0 net/rds/threads.c:175 process_one_work+0x6e8/0x1700 kernel/workqueue.c:2153 worker_thread+0x3b0/0xdd0 kernel/workqueue.c:2296 kthread+0x2f0/0x378 kernel/kthread.c:255 ret_from_fork+0x10/0x18 arch/arm64/kernel/entry.S:1117 Allocated by task 687: save_stack mm/kasan/kasan.c:448 [inline] set_track mm/kasan/kasan.c:460 [inline] kasan_kmalloc+0xd4/0x180 mm/kasan/kasan.c:553 kasan_slab_alloc+0x14/0x20 mm/kasan/kasan.c:490 slab_post_alloc_hook mm/slab.h:444 [inline] slab_alloc_node mm/slub.c:2705 [inline] slab_alloc mm/slub.c:2713 [inline] kmem_cache_alloc+0x14c/0x388 mm/slub.c:2718 kmem_cache_zalloc include/linux/slab.h:697 [inline] net_alloc net/core/net_namespace.c:384 [inline] copy_net_ns+0xc4/0x2d0 net/core/net_namespace.c:424 create_new_namespaces+0x300/0x658 kernel/nsproxy.c:107 unshare_nsproxy_namespaces+0xa0/0x198 kernel/nsproxy.c:206 ksys_unshare+0x340/0x628 kernel/fork.c:2577 __do_sys_unshare kernel/fork.c:2645 [inline] __se_sys_unshare kernel/fork.c:2643 [inline] __arm64_sys_unshare+0x38/0x58 kernel/fork.c:2643 __invoke_syscall arch/arm64/kernel/syscall.c:35 [inline] invoke_syscall arch/arm64/kernel/syscall.c:47 [inline] el0_svc_common+0x168/0x390 arch/arm64/kernel/syscall.c:83 el0_svc_handler+0x60/0xd0 arch/arm64/kernel/syscall.c:129 el0_svc+0x8/0xc arch/arm64/kernel/entry.S:960 Freed by task 264: save_stack mm/kasan/kasan.c:448 [inline] set_track mm/kasan/kasan.c:460 [inline] __kasan_slab_free+0x114/0x220 mm/kasan/kasan.c:521 kasan_slab_free+0x10/0x18 mm/kasan/kasan.c:528 slab_free_hook mm/slub.c:1370 [inline] slab_free_freelist_hook mm/slub.c:1397 [inline] slab_free mm/slub.c:2952 [inline] kmem_cache_free+0xb8/0x3a8 mm/slub.c:2968 net_free net/core/net_namespace.c:400 [inline] net_drop_ns.part.6+0x78/0x90 net/core/net_namespace.c:407 net_drop_ns net/core/net_namespace.c:406 [inline] cleanup_net+0x53c/0x6d8 net/core/net_namespace.c:569 process_one_work+0x6e8/0x1700 kernel/workqueue.c:2153 worker_thread+0x3b0/0xdd0 kernel/workqueue.c:2296 kthread+0x2f0/0x378 kernel/kthread.c:255 ret_from_fork+0x10/0x18 arch/arm64/kernel/entry.S:1117 The buggy address belongs to the object at ffff8003496a3f80 which belongs to the cache net_namespace of size 7872 The buggy address is located 1796 bytes inside of 7872-byte region [ffff8003496a3f80, ffff8003496a5e40) The buggy address belongs to the page: page:ffff7e000d25a800 count:1 mapcount:0 mapping:ffff80036ce4b000 index:0x0 compound_mapcount: 0 flags: 0xffffe0000008100(slab|head) raw: 0ffffe0000008100 dead000000000100 dead000000000200 ffff80036ce4b000 raw: 0000000000000000 0000000080040004 00000001ffffffff 0000000000000000 page dumped because: kasan: bad access detected Memory state around the buggy address: ffff8003496a4580: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff8003496a4600: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb >ffff8003496a4680: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ^ ffff8003496a4700: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff8003496a4780: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ================================================================== Fixes: 467fa15356ac("RDS-TCP: Support multiple RDS-TCP listen endpoints, one per netns.") Reported-by: Hulk Robot Signed-off-by: Mao Wenan Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/rds/tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/rds/tcp.c b/net/rds/tcp.c index 2a08bf75d008..82e9ffecd90e 100644 --- a/net/rds/tcp.c +++ b/net/rds/tcp.c @@ -530,7 +530,7 @@ static void rds_tcp_kill_sock(struct net *net) list_for_each_entry_safe(tc, _tc, &rds_tcp_conn_list, t_tcp_node) { struct net *c_net = read_pnet(&tc->t_cpath->cp_conn->c_net); - if (net != c_net || !tc->t_sock) + if (net != c_net) continue; if (!list_has_conn(&tmp_list, tc->t_cpath->cp_conn)) { list_move_tail(&tc->t_tcp_node, &tmp_list); -- GitLab From a54dc7b6972eee8dfc73a36d40b4bdb138deed96 Mon Sep 17 00:00:00 2001 From: Nicolas Dichtel Date: Thu, 28 Mar 2019 10:35:06 +0100 Subject: [PATCH 0031/1121] net/sched: fix ->get helper of the matchall cls [ Upstream commit 0db6f8befc32c68bb13d7ffbb2e563c79e913e13 ] It returned always NULL, thus it was never possible to get the filter. Example: $ ip link add foo type dummy $ ip link add bar type dummy $ tc qdisc add dev foo clsact $ tc filter add dev foo protocol all pref 1 ingress handle 1234 \ matchall action mirred ingress mirror dev bar Before the patch: $ tc filter get dev foo protocol all pref 1 ingress handle 1234 matchall Error: Specified filter handle not found. We have an error talking to the kernel After: $ tc filter get dev foo protocol all pref 1 ingress handle 1234 matchall filter ingress protocol all pref 1 matchall chain 0 handle 0x4d2 not_in_hw action order 1: mirred (Ingress Mirror to device bar) pipe index 1 ref 1 bind 1 CC: Yotam Gigi CC: Jiri Pirko Fixes: fd62d9f5c575 ("net/sched: matchall: Fix configuration race") Signed-off-by: Nicolas Dichtel Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/sched/cls_matchall.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/sched/cls_matchall.c b/net/sched/cls_matchall.c index 6499aecfbfc4..d8fd152779c8 100644 --- a/net/sched/cls_matchall.c +++ b/net/sched/cls_matchall.c @@ -125,6 +125,11 @@ static void mall_destroy(struct tcf_proto *tp) static void *mall_get(struct tcf_proto *tp, u32 handle) { + struct cls_mall_head *head = rtnl_dereference(tp->root); + + if (head && head->handle == handle) + return head; + return NULL; } -- GitLab From 94ef6b9842bd6b16b0e38c8aec15da2171f8104f Mon Sep 17 00:00:00 2001 From: Andrea Righi Date: Thu, 28 Mar 2019 07:36:00 +0100 Subject: [PATCH 0032/1121] openvswitch: fix flow actions reallocation [ Upstream commit f28cd2af22a0c134e4aa1c64a70f70d815d473fb ] The flow action buffer can be resized if it's not big enough to contain all the requested flow actions. However, this resize doesn't take into account the new requested size, the buffer is only increased by a factor of 2x. This might be not enough to contain the new data, causing a buffer overflow, for example: [ 42.044472] ============================================================================= [ 42.045608] BUG kmalloc-96 (Not tainted): Redzone overwritten [ 42.046415] ----------------------------------------------------------------------------- [ 42.047715] Disabling lock debugging due to kernel taint [ 42.047716] INFO: 0x8bf2c4a5-0x720c0928. First byte 0x0 instead of 0xcc [ 42.048677] INFO: Slab 0xbc6d2040 objects=29 used=18 fp=0xdc07dec4 flags=0x2808101 [ 42.049743] INFO: Object 0xd53a3464 @offset=2528 fp=0xccdcdebb [ 42.050747] Redzone 76f1b237: cc cc cc cc cc cc cc cc ........ [ 42.051839] Object d53a3464: 6b 6b 6b 6b 6b 6b 6b 6b 0c 00 00 00 6c 00 00 00 kkkkkkkk....l... [ 42.053015] Object f49a30cc: 6c 00 0c 00 00 00 00 00 00 00 00 03 78 a3 15 f6 l...........x... [ 42.054203] Object acfe4220: 20 00 02 00 ff ff ff ff 00 00 00 00 00 00 00 00 ............... [ 42.055370] Object 21024e91: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ [ 42.056541] Object 070e04c3: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ [ 42.057797] Object 948a777a: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ [ 42.059061] Redzone 8bf2c4a5: 00 00 00 00 .... [ 42.060189] Padding a681b46e: 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZ Fix by making sure the new buffer is properly resized to contain all the requested data. BugLink: https://bugs.launchpad.net/bugs/1813244 Signed-off-by: Andrea Righi Acked-by: Pravin B Shelar Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/openvswitch/flow_netlink.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c index e687b89dafe6..f5deae2ccb79 100644 --- a/net/openvswitch/flow_netlink.c +++ b/net/openvswitch/flow_netlink.c @@ -1967,14 +1967,14 @@ static struct nlattr *reserve_sfa_size(struct sw_flow_actions **sfa, struct sw_flow_actions *acts; int new_acts_size; - int req_size = NLA_ALIGN(attr_len); + size_t req_size = NLA_ALIGN(attr_len); int next_offset = offsetof(struct sw_flow_actions, actions) + (*sfa)->actions_len; if (req_size <= (ksize(*sfa) - next_offset)) goto out; - new_acts_size = ksize(*sfa) * 2; + new_acts_size = max(next_offset + req_size, ksize(*sfa) * 2); if (new_acts_size > MAX_ACTIONS_BUFSIZE) { if ((MAX_ACTIONS_BUFSIZE - next_offset) < req_size) { -- GitLab From be7e16e566f4216b703cb838679024a117a8e059 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Wed, 27 Mar 2019 15:26:01 +0100 Subject: [PATCH 0033/1121] qmi_wwan: add Olicard 600 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 6289d0facd9ebce4cc83e5da39e15643ee998dc5 ] This is a Qualcomm based device with a QMI function on interface 4. It is mode switched from 2020:2030 using a standard eject message. T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 6 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=2020 ProdID=2031 Rev= 2.32 S: Manufacturer=Mobile Connect S: Product=Mobile Connect S: SerialNumber=0123456789ABCDEF C:* #Ifs= 6 Cfg#= 1 Atr=80 MxPwr=500mA I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=(none) E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=(none) E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=(none) E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) E: Ad=89(I) Atr=03(Int.) MxPS= 8 Ivl=32ms E: Ad=88(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 5 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=(none) E: Ad=8a(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=125us Signed-off-by: BjĂžrn Mork Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/usb/qmi_wwan.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 65e47cc52d14..01abe8eea753 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -1188,6 +1188,7 @@ static const struct usb_device_id products[] = { {QMI_FIXED_INTF(0x19d2, 0x2002, 4)}, /* ZTE (Vodafone) K3765-Z */ {QMI_FIXED_INTF(0x2001, 0x7e19, 4)}, /* D-Link DWM-221 B1 */ {QMI_FIXED_INTF(0x2001, 0x7e35, 4)}, /* D-Link DWM-222 */ + {QMI_FIXED_INTF(0x2020, 0x2031, 4)}, /* Olicard 600 */ {QMI_FIXED_INTF(0x2020, 0x2033, 4)}, /* BroadMobi BM806U */ {QMI_FIXED_INTF(0x0f3d, 0x68a2, 8)}, /* Sierra Wireless MC7700 */ {QMI_FIXED_INTF(0x114f, 0x68a2, 8)}, /* Sierra Wireless MC7750 */ -- GitLab From a7bc830b76341b612a664b6649440937f7595190 Mon Sep 17 00:00:00 2001 From: Xin Long Date: Sun, 31 Mar 2019 16:58:15 +0800 Subject: [PATCH 0034/1121] sctp: initialize _pad of sockaddr_in before copying to user memory [ Upstream commit 09279e615c81ce55e04835970601ae286e3facbe ] Syzbot report a kernel-infoleak: BUG: KMSAN: kernel-infoleak in _copy_to_user+0x16b/0x1f0 lib/usercopy.c:32 Call Trace: _copy_to_user+0x16b/0x1f0 lib/usercopy.c:32 copy_to_user include/linux/uaccess.h:174 [inline] sctp_getsockopt_peer_addrs net/sctp/socket.c:5911 [inline] sctp_getsockopt+0x1668e/0x17f70 net/sctp/socket.c:7562 ... Uninit was stored to memory at: sctp_transport_init net/sctp/transport.c:61 [inline] sctp_transport_new+0x16d/0x9a0 net/sctp/transport.c:115 sctp_assoc_add_peer+0x532/0x1f70 net/sctp/associola.c:637 sctp_process_param net/sctp/sm_make_chunk.c:2548 [inline] sctp_process_init+0x1a1b/0x3ed0 net/sctp/sm_make_chunk.c:2361 ... Bytes 8-15 of 16 are uninitialized It was caused by that th _pad field (the 8-15 bytes) of a v4 addr (saved in struct sockaddr_in) wasn't initialized, but directly copied to user memory in sctp_getsockopt_peer_addrs(). So fix it by calling memset(addr->v4.sin_zero, 0, 8) to initialize _pad of sockaddr_in before copying it to user memory in sctp_v4_addr_to_user(), as sctp_v6_addr_to_user() does. Reported-by: syzbot+86b5c7c236a22616a72f@syzkaller.appspotmail.com Signed-off-by: Xin Long Tested-by: Alexander Potapenko Acked-by: Neil Horman Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/sctp/protocol.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index cbb04d66f564..a7529aca2ac8 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -605,6 +605,7 @@ static struct sock *sctp_v4_create_accept_sk(struct sock *sk, static int sctp_v4_addr_to_user(struct sctp_sock *sp, union sctp_addr *addr) { /* No address mapping for V4 sockets */ + memset(addr->v4.sin_zero, 0, sizeof(addr->v4.sin_zero)); return sizeof(struct sockaddr_in); } -- GitLab From 2ff8616e56d41bffef7408c896d58097e0669fc8 Mon Sep 17 00:00:00 2001 From: Koen De Schepper Date: Thu, 4 Apr 2019 12:24:02 +0000 Subject: [PATCH 0035/1121] tcp: Ensure DCTCP reacts to losses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit aecfde23108b8e637d9f5c5e523b24fb97035dc3 ] RFC8257 §3.5 explicitly states that "A DCTCP sender MUST react to loss episodes in the same way as conventional TCP". Currently, Linux DCTCP performs no cwnd reduction when losses are encountered. Optionally, the dctcp_clamp_alpha_on_loss resets alpha to its maximal value if a RTO happens. This behavior is sub-optimal for at least two reasons: i) it ignores losses triggering fast retransmissions; and ii) it causes unnecessary large cwnd reduction in the future if the loss was isolated as it resets the historical term of DCTCP's alpha EWMA to its maximal value (i.e., denoting a total congestion). The second reason has an especially noticeable effect when using DCTCP in high BDP environments, where alpha normally stays at low values. This patch replace the clamping of alpha by setting ssthresh to half of cwnd for both fast retransmissions and RTOs, at most once per RTT. Consequently, the dctcp_clamp_alpha_on_loss module parameter has been removed. The table below shows experimental results where we measured the drop probability of a PIE AQM (not applying ECN marks) at a bottleneck in the presence of a single TCP flow with either the alpha-clamping option enabled or the cwnd halving proposed by this patch. Results using reno or cubic are given for comparison. | Link | RTT | Drop TCP CC | speed | base+AQM | probability ==================|=========|==========|============ CUBIC | 40Mbps | 7+20ms | 0.21% RENO | | | 0.19% DCTCP-CLAMP-ALPHA | | | 25.80% DCTCP-HALVE-CWND | | | 0.22% ------------------|---------|----------|------------ CUBIC | 100Mbps | 7+20ms | 0.03% RENO | | | 0.02% DCTCP-CLAMP-ALPHA | | | 23.30% DCTCP-HALVE-CWND | | | 0.04% ------------------|---------|----------|------------ CUBIC | 800Mbps | 1+1ms | 0.04% RENO | | | 0.05% DCTCP-CLAMP-ALPHA | | | 18.70% DCTCP-HALVE-CWND | | | 0.06% We see that, without halving its cwnd for all source of losses, DCTCP drives the AQM to large drop probabilities in order to keep the queue length under control (i.e., it repeatedly faces RTOs). Instead, if DCTCP reacts to all source of losses, it can then be controlled by the AQM using similar drop levels than cubic or reno. Signed-off-by: Koen De Schepper Signed-off-by: Olivier Tilmans Cc: Bob Briscoe Cc: Lawrence Brakmo Cc: Florian Westphal Cc: Daniel Borkmann Cc: Yuchung Cheng Cc: Neal Cardwell Cc: Eric Dumazet Cc: Andrew Shewmaker Cc: Glenn Judd Acked-by: Florian Westphal Acked-by: Neal Cardwell Acked-by: Daniel Borkmann Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/ipv4/tcp_dctcp.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/net/ipv4/tcp_dctcp.c b/net/ipv4/tcp_dctcp.c index 8b637f9f23a2..f0de9fb92f0d 100644 --- a/net/ipv4/tcp_dctcp.c +++ b/net/ipv4/tcp_dctcp.c @@ -66,11 +66,6 @@ static unsigned int dctcp_alpha_on_init __read_mostly = DCTCP_MAX_ALPHA; module_param(dctcp_alpha_on_init, uint, 0644); MODULE_PARM_DESC(dctcp_alpha_on_init, "parameter for initial alpha value"); -static unsigned int dctcp_clamp_alpha_on_loss __read_mostly; -module_param(dctcp_clamp_alpha_on_loss, uint, 0644); -MODULE_PARM_DESC(dctcp_clamp_alpha_on_loss, - "parameter for clamping alpha on loss"); - static struct tcp_congestion_ops dctcp_reno; static void dctcp_reset(const struct tcp_sock *tp, struct dctcp *ca) @@ -211,21 +206,23 @@ static void dctcp_update_alpha(struct sock *sk, u32 flags) } } -static void dctcp_state(struct sock *sk, u8 new_state) +static void dctcp_react_to_loss(struct sock *sk) { - if (dctcp_clamp_alpha_on_loss && new_state == TCP_CA_Loss) { - struct dctcp *ca = inet_csk_ca(sk); + struct dctcp *ca = inet_csk_ca(sk); + struct tcp_sock *tp = tcp_sk(sk); - /* If this extension is enabled, we clamp dctcp_alpha to - * max on packet loss; the motivation is that dctcp_alpha - * is an indicator to the extend of congestion and packet - * loss is an indicator of extreme congestion; setting - * this in practice turned out to be beneficial, and - * effectively assumes total congestion which reduces the - * window by half. - */ - ca->dctcp_alpha = DCTCP_MAX_ALPHA; - } + ca->loss_cwnd = tp->snd_cwnd; + tp->snd_ssthresh = max(tp->snd_cwnd >> 1U, 2U); +} + +static void dctcp_state(struct sock *sk, u8 new_state) +{ + if (new_state == TCP_CA_Recovery && + new_state != inet_csk(sk)->icsk_ca_state) + dctcp_react_to_loss(sk); + /* We handle RTO in dctcp_cwnd_event to ensure that we perform only + * one loss-adjustment per RTT. + */ } static void dctcp_cwnd_event(struct sock *sk, enum tcp_ca_event ev) @@ -237,6 +234,9 @@ static void dctcp_cwnd_event(struct sock *sk, enum tcp_ca_event ev) case CA_EVENT_ECN_NO_CE: dctcp_ce_state_1_to_0(sk); break; + case CA_EVENT_LOSS: + dctcp_react_to_loss(sk); + break; default: /* Don't care for the rest. */ break; -- GitLab From 16b7142372d82cb93099e050559967517b84ac6a Mon Sep 17 00:00:00 2001 From: Stephen Suryaputra Date: Mon, 1 Apr 2019 09:17:32 -0400 Subject: [PATCH 0036/1121] vrf: check accept_source_route on the original netdevice [ Upstream commit 8c83f2df9c6578ea4c5b940d8238ad8a41b87e9e ] Configuration check to accept source route IP options should be made on the incoming netdevice when the skb->dev is an l3mdev master. The route lookup for the source route next hop also needs the incoming netdev. v2->v3: - Simplify by passing the original netdevice down the stack (per David Ahern). Signed-off-by: Stephen Suryaputra Reviewed-by: David Ahern Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- include/net/ip.h | 2 +- net/ipv4/ip_input.c | 7 +++---- net/ipv4/ip_options.c | 4 ++-- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/include/net/ip.h b/include/net/ip.h index 80575db4e304..b8ebee43941f 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -603,7 +603,7 @@ int ip_options_get_from_user(struct net *net, struct ip_options_rcu **optp, unsigned char __user *data, int optlen); void ip_options_undo(struct ip_options *opt); void ip_forward_options(struct sk_buff *skb); -int ip_options_rcv_srr(struct sk_buff *skb); +int ip_options_rcv_srr(struct sk_buff *skb, struct net_device *dev); /* * Functions provided by ip_sockglue.c diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 1b160378ea9c..6fc45d3a1f8a 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -259,11 +259,10 @@ int ip_local_deliver(struct sk_buff *skb) ip_local_deliver_finish); } -static inline bool ip_rcv_options(struct sk_buff *skb) +static inline bool ip_rcv_options(struct sk_buff *skb, struct net_device *dev) { struct ip_options *opt; const struct iphdr *iph; - struct net_device *dev = skb->dev; /* It looks as overkill, because not all IP options require packet mangling. @@ -299,7 +298,7 @@ static inline bool ip_rcv_options(struct sk_buff *skb) } } - if (ip_options_rcv_srr(skb)) + if (ip_options_rcv_srr(skb, dev)) goto drop; } @@ -362,7 +361,7 @@ static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb) } #endif - if (iph->ihl > 5 && ip_rcv_options(skb)) + if (iph->ihl > 5 && ip_rcv_options(skb, dev)) goto drop; rt = skb_rtable(skb); diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c index 32a35043c9f5..3db31bb9df50 100644 --- a/net/ipv4/ip_options.c +++ b/net/ipv4/ip_options.c @@ -612,7 +612,7 @@ void ip_forward_options(struct sk_buff *skb) } } -int ip_options_rcv_srr(struct sk_buff *skb) +int ip_options_rcv_srr(struct sk_buff *skb, struct net_device *dev) { struct ip_options *opt = &(IPCB(skb)->opt); int srrspace, srrptr; @@ -647,7 +647,7 @@ int ip_options_rcv_srr(struct sk_buff *skb) orefdst = skb->_skb_refdst; skb_dst_set(skb, NULL); - err = ip_route_input(skb, nexthop, iph->saddr, iph->tos, skb->dev); + err = ip_route_input(skb, nexthop, iph->saddr, iph->tos, dev); rt2 = skb_rtable(skb); if (err || (rt2->rt_type != RTN_UNICAST && rt2->rt_type != RTN_LOCAL)) { skb_dst_drop(skb); -- GitLab From 7143c8997ae84bbed8d8698fd317d537b5c3e23d Mon Sep 17 00:00:00 2001 From: Gavi Teitz Date: Mon, 11 Mar 2019 11:56:34 +0200 Subject: [PATCH 0037/1121] net/mlx5e: Fix error handling when refreshing TIRs [ Upstream commit bc87a0036826a37b43489b029af8143bd07c6cca ] Previously, a false positive would be caught if the TIRs list is empty, since the err value was initialized to -ENOMEM, and was only updated if a TIR is refreshed. This is resolved by initializing the err value to zero. Fixes: b676f653896a ("net/mlx5e: Refactor refresh TIRs") Signed-off-by: Gavi Teitz Reviewed-by: Roi Dayan Signed-off-by: Saeed Mahameed Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/mellanox/mlx5/core/en_common.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_common.c b/drivers/net/ethernet/mellanox/mlx5/core/en_common.c index ece3fb147e3e..c0bec2f5e0c9 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_common.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_common.c @@ -140,15 +140,17 @@ int mlx5e_refresh_tirs(struct mlx5e_priv *priv, bool enable_uc_lb) { struct mlx5_core_dev *mdev = priv->mdev; struct mlx5e_tir *tir; - int err = -ENOMEM; + int err = 0; u32 tirn = 0; int inlen; void *in; inlen = MLX5_ST_SZ_BYTES(modify_tir_in); in = kvzalloc(inlen, GFP_KERNEL); - if (!in) + if (!in) { + err = -ENOMEM; goto out; + } if (enable_uc_lb) MLX5_SET(modify_tir_in, in, ctx.self_lb_block, -- GitLab From b5ba76a58b09c09ed7efc97de18f93d28c04ee4e Mon Sep 17 00:00:00 2001 From: Yuval Avnery Date: Mon, 11 Mar 2019 06:18:24 +0200 Subject: [PATCH 0038/1121] net/mlx5e: Add a lock on tir list [ Upstream commit 80a2a9026b24c6bd34b8d58256973e22270bedec ] Refresh tirs is looping over a global list of tirs while netdevs are adding and removing tirs from that list. That is why a lock is required. Fixes: 724b2aa15126 ("net/mlx5e: TIRs management refactoring") Signed-off-by: Yuval Avnery Signed-off-by: Saeed Mahameed Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/mellanox/mlx5/core/en_common.c | 7 +++++++ include/linux/mlx5/driver.h | 2 ++ 2 files changed, 9 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_common.c b/drivers/net/ethernet/mellanox/mlx5/core/en_common.c index c0bec2f5e0c9..36ae0b2519d2 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_common.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_common.c @@ -45,7 +45,9 @@ int mlx5e_create_tir(struct mlx5_core_dev *mdev, if (err) return err; + mutex_lock(&mdev->mlx5e_res.td.list_lock); list_add(&tir->list, &mdev->mlx5e_res.td.tirs_list); + mutex_unlock(&mdev->mlx5e_res.td.list_lock); return 0; } @@ -53,8 +55,10 @@ int mlx5e_create_tir(struct mlx5_core_dev *mdev, void mlx5e_destroy_tir(struct mlx5_core_dev *mdev, struct mlx5e_tir *tir) { + mutex_lock(&mdev->mlx5e_res.td.list_lock); mlx5_core_destroy_tir(mdev, tir->tirn); list_del(&tir->list); + mutex_unlock(&mdev->mlx5e_res.td.list_lock); } static int mlx5e_create_mkey(struct mlx5_core_dev *mdev, u32 pdn, @@ -114,6 +118,7 @@ int mlx5e_create_mdev_resources(struct mlx5_core_dev *mdev) } INIT_LIST_HEAD(&mdev->mlx5e_res.td.tirs_list); + mutex_init(&mdev->mlx5e_res.td.list_lock); return 0; @@ -158,6 +163,7 @@ int mlx5e_refresh_tirs(struct mlx5e_priv *priv, bool enable_uc_lb) MLX5_SET(modify_tir_in, in, bitmask.self_lb_en, 1); + mutex_lock(&mdev->mlx5e_res.td.list_lock); list_for_each_entry(tir, &mdev->mlx5e_res.td.tirs_list, list) { tirn = tir->tirn; err = mlx5_core_modify_tir(mdev, tirn, in, inlen); @@ -169,6 +175,7 @@ int mlx5e_refresh_tirs(struct mlx5e_priv *priv, bool enable_uc_lb) kvfree(in); if (err) netdev_err(priv->netdev, "refresh tir(0x%x) failed, %d\n", tirn, err); + mutex_unlock(&mdev->mlx5e_res.td.list_lock); return err; } diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h index 88f0c530fe9c..32d445315128 100644 --- a/include/linux/mlx5/driver.h +++ b/include/linux/mlx5/driver.h @@ -743,6 +743,8 @@ struct mlx5_pagefault { }; struct mlx5_td { + /* protects tirs list changes while tirs refresh */ + struct mutex list_lock; struct list_head tirs_list; u32 tdn; }; -- GitLab From e26c79d2af6e94077beefdfcfbeb3037ac8a9dea Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Wed, 27 Mar 2019 11:38:38 -0700 Subject: [PATCH 0039/1121] nfp: validate the return code from dev_queue_xmit() [ Upstream commit c8ba5b91a04e3e2643e48501c114108802f21cda ] dev_queue_xmit() may return error codes as well as netdev_tx_t, and it always consumes the skb. Make sure we always return a correct netdev_tx_t value. Fixes: eadfa4c3be99 ("nfp: add stats and xmit helpers for representors") Signed-off-by: Jakub Kicinski Reviewed-by: John Hurley Reviewed-by: Simon Horman Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/netronome/nfp/nfp_net_repr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c index 9a7655560629..1910ca21a1bc 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c @@ -200,7 +200,7 @@ static netdev_tx_t nfp_repr_xmit(struct sk_buff *skb, struct net_device *netdev) ret = dev_queue_xmit(skb); nfp_repr_inc_tx_stats(netdev, len, ret); - return ret; + return NETDEV_TX_OK; } static int nfp_repr_stop(struct net_device *netdev) -- GitLab From 46281ee85b651b0df686001651b965d17b8e2c67 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 8 Apr 2019 17:39:54 -0400 Subject: [PATCH 0040/1121] bnxt_en: Improve RX consumer index validity check. [ Upstream commit a1b0e4e684e9c300b9e759b46cb7a0147e61ddff ] There is logic to check that the RX/TPA consumer index is the expected index to work around a hardware problem. However, the potentially bad consumer index is first used to index into an array to reference an entry. This can potentially crash if the bad consumer index is beyond legal range. Improve the logic to use the consumer index for dereferencing after the validity check and log an error message. Fixes: fa7e28127a5a ("bnxt_en: Add workaround to detect bad opaque in rx completion (part 2)") Signed-off-by: Michael Chan Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 15ad247955f7..1e5498431618 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -1076,6 +1076,8 @@ static void bnxt_tpa_start(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, tpa_info = &rxr->rx_tpa[agg_id]; if (unlikely(cons != rxr->rx_next_cons)) { + netdev_warn(bp->dev, "TPA cons %x != expected cons %x\n", + cons, rxr->rx_next_cons); bnxt_sched_reset(bp, rxr); return; } @@ -1528,15 +1530,17 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_napi *bnapi, u32 *raw_cons, } cons = rxcmp->rx_cmp_opaque; - rx_buf = &rxr->rx_buf_ring[cons]; - data = rx_buf->data; - data_ptr = rx_buf->data_ptr; if (unlikely(cons != rxr->rx_next_cons)) { int rc1 = bnxt_discard_rx(bp, bnapi, raw_cons, rxcmp); + netdev_warn(bp->dev, "RX cons %x != expected cons %x\n", + cons, rxr->rx_next_cons); bnxt_sched_reset(bp, rxr); return rc1; } + rx_buf = &rxr->rx_buf_ring[cons]; + data = rx_buf->data; + data_ptr = rx_buf->data_ptr; prefetch(data_ptr); misc = le32_to_cpu(rxcmp->rx_cmp_misc_v1); -- GitLab From 5df47bb622e1b7cb3e99c7df15a4e1676a6af2c1 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 8 Apr 2019 17:39:55 -0400 Subject: [PATCH 0041/1121] bnxt_en: Reset device on RX buffer errors. [ Upstream commit 8e44e96c6c8e8fb80b84a2ca11798a8554f710f2 ] If the RX completion indicates RX buffers errors, the RX ring will be disabled by firmware and no packets will be received on that ring from that point on. Recover by resetting the device. Fixes: c0c050c58d84 ("bnxt_en: New Broadcom ethernet driver.") Signed-off-by: Michael Chan Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 1e5498431618..446577a1a6a5 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -1557,11 +1557,17 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_napi *bnapi, u32 *raw_cons, rx_buf->data = NULL; if (rxcmp1->rx_cmp_cfa_code_errors_v2 & RX_CMP_L2_ERRORS) { + u32 rx_err = le32_to_cpu(rxcmp1->rx_cmp_cfa_code_errors_v2); + bnxt_reuse_rx_data(rxr, cons, data); if (agg_bufs) bnxt_reuse_rx_agg_bufs(bnapi, cp_cons, agg_bufs); rc = -EIO; + if (rx_err & RX_CMPL_ERRORS_BUFFER_ERROR_MASK) { + netdev_warn(bp->dev, "RX buffer error %x\n", rx_err); + bnxt_sched_reset(bp, rxr); + } goto next_rx; } -- GitLab From 0349ad0656a3ea2e6ecb55da946a7000f6abdba5 Mon Sep 17 00:00:00 2001 From: Davide Caratti Date: Thu, 4 Apr 2019 12:31:35 +0200 Subject: [PATCH 0042/1121] net/sched: act_sample: fix divide by zero in the traffic path [ Upstream commit fae2708174ae95d98d19f194e03d6e8f688ae195 ] the control path of 'sample' action does not validate the value of 'rate' provided by the user, but then it uses it as divisor in the traffic path. Validate it in tcf_sample_init(), and return -EINVAL with a proper extack message in case that value is zero, to fix a splat with the script below: # tc f a dev test0 egress matchall action sample rate 0 group 1 index 2 # tc -s a s action sample total acts 1 action order 0: sample rate 1/0 group 1 pipe index 2 ref 1 bind 1 installed 19 sec used 19 sec Action statistics: Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) backlog 0b 0p requeues 0 # ping 192.0.2.1 -I test0 -c1 -q divide error: 0000 [#1] SMP PTI CPU: 1 PID: 6192 Comm: ping Not tainted 5.1.0-rc2.diag2+ #591 Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011 RIP: 0010:tcf_sample_act+0x9e/0x1e0 [act_sample] Code: 6a f1 85 c0 74 0d 80 3d 83 1a 00 00 00 0f 84 9c 00 00 00 4d 85 e4 0f 84 85 00 00 00 e8 9b d7 9c f1 44 8b 8b e0 00 00 00 31 d2 <41> f7 f1 85 d2 75 70 f6 85 83 00 00 00 10 48 8b 45 10 8b 88 08 01 RSP: 0018:ffffae320190ba30 EFLAGS: 00010246 RAX: 00000000b0677d21 RBX: ffff8af1ed9ec000 RCX: 0000000059a9fe49 RDX: 0000000000000000 RSI: 000000000c7e33b7 RDI: ffff8af23daa0af0 RBP: ffff8af1ee11b200 R08: 0000000074fcaf7e R09: 0000000000000000 R10: 0000000000000050 R11: ffffffffb3088680 R12: ffff8af232307f80 R13: 0000000000000003 R14: ffff8af1ed9ec000 R15: 0000000000000000 FS: 00007fe9c6d2f740(0000) GS:ffff8af23da80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007fff6772f000 CR3: 00000000746a2004 CR4: 00000000001606e0 Call Trace: tcf_action_exec+0x7c/0x1c0 tcf_classify+0x57/0x160 __dev_queue_xmit+0x3dc/0xd10 ip_finish_output2+0x257/0x6d0 ip_output+0x75/0x280 ip_send_skb+0x15/0x40 raw_sendmsg+0xae3/0x1410 sock_sendmsg+0x36/0x40 __sys_sendto+0x10e/0x140 __x64_sys_sendto+0x24/0x30 do_syscall_64+0x60/0x210 entry_SYSCALL_64_after_hwframe+0x49/0xbe [...] Kernel panic - not syncing: Fatal exception in interrupt Add a TDC selftest to document that 'rate' is now being validated. Reported-by: Matteo Croce Fixes: 5c5670fae430 ("net/sched: Introduce sample tc action") Signed-off-by: Davide Caratti Acked-by: Yotam Gigi Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/sched/act_sample.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/net/sched/act_sample.c b/net/sched/act_sample.c index a859b55d7899..64fd1e9818a6 100644 --- a/net/sched/act_sample.c +++ b/net/sched/act_sample.c @@ -45,6 +45,7 @@ static int tcf_sample_init(struct net *net, struct nlattr *nla, struct tc_sample *parm; struct tcf_sample *s; bool exists = false; + u32 rate; int ret; if (!nla) @@ -73,10 +74,17 @@ static int tcf_sample_init(struct net *net, struct nlattr *nla, if (!ovr) return -EEXIST; } - s = to_sample(*a); + rate = nla_get_u32(tb[TCA_SAMPLE_RATE]); + if (!rate) { + tcf_idr_release(*a, bind); + return -EINVAL; + } + + s = to_sample(*a); s->tcf_action = parm->action; s->rate = nla_get_u32(tb[TCA_SAMPLE_RATE]); + s->rate = rate; s->psample_group_num = nla_get_u32(tb[TCA_SAMPLE_PSAMPLE_GROUP]); psample_group = psample_group_get(net, s->psample_group_num); if (!psample_group) { -- GitLab From adbb8bdd392db14dc80ad1ac29f8f1d37ab57a62 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 27 Mar 2019 08:21:30 -0700 Subject: [PATCH 0043/1121] netns: provide pure entropy for net_hash_mix() [ Upstream commit 355b98553789b646ed97ad801a619ff898471b92 ] net_hash_mix() currently uses kernel address of a struct net, and is used in many places that could be used to reveal this address to a patient attacker, thus defeating KASLR, for the typical case (initial net namespace, &init_net is not dynamically allocated) I believe the original implementation tried to avoid spending too many cycles in this function, but security comes first. Also provide entropy regardless of CONFIG_NET_NS. Fixes: 0b4419162aa6 ("netns: introduce the net_hash_mix "salt" for hashes") Signed-off-by: Eric Dumazet Reported-by: Amit Klein Reported-by: Benny Pinkas Cc: Pavel Emelyanov Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- include/net/net_namespace.h | 1 + include/net/netns/hash.h | 15 ++------------- net/core/net_namespace.c | 1 + 3 files changed, 4 insertions(+), 13 deletions(-) diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index f4bf75fac349..d96c9d9cca96 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -56,6 +56,7 @@ struct net { */ spinlock_t rules_mod_lock; + u32 hash_mix; atomic64_t cookie_gen; struct list_head list; /* list of network namespaces */ diff --git a/include/net/netns/hash.h b/include/net/netns/hash.h index 24c78183a4c2..d9b665151f3d 100644 --- a/include/net/netns/hash.h +++ b/include/net/netns/hash.h @@ -2,21 +2,10 @@ #ifndef __NET_NS_HASH_H__ #define __NET_NS_HASH_H__ -#include - -struct net; +#include static inline u32 net_hash_mix(const struct net *net) { -#ifdef CONFIG_NET_NS - /* - * shift this right to eliminate bits, that are - * always zeroed - */ - - return (u32)(((unsigned long)net) >> L1_CACHE_SHIFT); -#else - return 0; -#endif + return net->hash_mix; } #endif diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 0dd6359e5924..60b88718b1d4 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -285,6 +285,7 @@ static __net_init int setup_net(struct net *net, struct user_namespace *user_ns) atomic_set(&net->count, 1); refcount_set(&net->passive, 1); + get_random_bytes(&net->hash_mix, sizeof(u32)); net->dev_base_seq = 1; net->user_ns = user_ns; idr_init(&net->netns_ids); -- GitLab From eea06f38eb464ab6ebdc04ca5980120dd24ee48d Mon Sep 17 00:00:00 2001 From: Li RongQing Date: Fri, 29 Mar 2019 09:18:02 +0800 Subject: [PATCH 0044/1121] net: ethtool: not call vzalloc for zero sized memory request [ Upstream commit 3d8830266ffc28c16032b859e38a0252e014b631 ] NULL or ZERO_SIZE_PTR will be returned for zero sized memory request, and derefencing them will lead to a segfault so it is unnecessory to call vzalloc for zero sized memory request and not call functions which maybe derefence the NULL allocated memory this also fixes a possible memory leak if phy_ethtool_get_stats returns error, memory should be freed before exit Signed-off-by: Li RongQing Reviewed-by: Wang Li Reviewed-by: Michal Kubecek Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/core/ethtool.c | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 3469f5053c79..145cb343c1b0 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -1815,11 +1815,15 @@ static int ethtool_get_strings(struct net_device *dev, void __user *useraddr) WARN_ON_ONCE(!ret); gstrings.len = ret; - data = vzalloc(gstrings.len * ETH_GSTRING_LEN); - if (gstrings.len && !data) - return -ENOMEM; + if (gstrings.len) { + data = vzalloc(gstrings.len * ETH_GSTRING_LEN); + if (!data) + return -ENOMEM; - __ethtool_get_strings(dev, gstrings.string_set, data); + __ethtool_get_strings(dev, gstrings.string_set, data); + } else { + data = NULL; + } ret = -EFAULT; if (copy_to_user(useraddr, &gstrings, sizeof(gstrings))) @@ -1915,11 +1919,14 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr) return -EFAULT; stats.n_stats = n_stats; - data = vzalloc(n_stats * sizeof(u64)); - if (n_stats && !data) - return -ENOMEM; - - ops->get_ethtool_stats(dev, &stats, data); + if (n_stats) { + data = vzalloc(n_stats * sizeof(u64)); + if (!data) + return -ENOMEM; + ops->get_ethtool_stats(dev, &stats, data); + } else { + data = NULL; + } ret = -EFAULT; if (copy_to_user(useraddr, &stats, sizeof(stats))) @@ -1955,13 +1962,17 @@ static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr) return -EFAULT; stats.n_stats = n_stats; - data = vzalloc(n_stats * sizeof(u64)); - if (n_stats && !data) - return -ENOMEM; + if (n_stats) { + data = vzalloc(n_stats * sizeof(u64)); + if (!data) + return -ENOMEM; - mutex_lock(&phydev->lock); - phydev->drv->get_stats(phydev, &stats, data); - mutex_unlock(&phydev->lock); + mutex_lock(&phydev->lock); + phydev->drv->get_stats(phydev, &stats, data); + mutex_unlock(&phydev->lock); + } else { + data = NULL; + } ret = -EFAULT; if (copy_to_user(useraddr, &stats, sizeof(stats))) -- GitLab From 5589e51fc8afb345561b6b880b349e6bc3bbf410 Mon Sep 17 00:00:00 2001 From: Zubin Mithra Date: Thu, 4 Apr 2019 14:33:55 -0700 Subject: [PATCH 0045/1121] ALSA: seq: Fix OOB-reads from strlcpy commit 212ac181c158c09038c474ba68068be49caecebb upstream. When ioctl calls are made with non-null-terminated userspace strings, strlcpy causes an OOB-read from within strlen. Fix by changing to use strscpy instead. Signed-off-by: Zubin Mithra Reviewed-by: Guenter Roeck Cc: Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/core/seq/seq_clientmgr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c index 350c33ec82b3..3bcd7a2f0394 100644 --- a/sound/core/seq/seq_clientmgr.c +++ b/sound/core/seq/seq_clientmgr.c @@ -1249,7 +1249,7 @@ static int snd_seq_ioctl_set_client_info(struct snd_seq_client *client, /* fill the info fields */ if (client_info->name[0]) - strlcpy(client->name, client_info->name, sizeof(client->name)); + strscpy(client->name, client_info->name, sizeof(client->name)); client->filter = client_info->filter; client->event_lost = client_info->event_lost; @@ -1527,7 +1527,7 @@ static int snd_seq_ioctl_create_queue(struct snd_seq_client *client, void *arg) /* set queue name */ if (!info->name[0]) snprintf(info->name, sizeof(info->name), "Queue-%d", q->queue); - strlcpy(q->name, info->name, sizeof(q->name)); + strscpy(q->name, info->name, sizeof(q->name)); snd_use_lock_free(&q->use_lock); return 0; @@ -1589,7 +1589,7 @@ static int snd_seq_ioctl_set_queue_info(struct snd_seq_client *client, queuefree(q); return -EPERM; } - strlcpy(q->name, info->name, sizeof(q->name)); + strscpy(q->name, info->name, sizeof(q->name)); queuefree(q); return 0; -- GitLab From bc280a1edc23afabc04c97c04841d996e0788c6d Mon Sep 17 00:00:00 2001 From: Sheena Mira-ato Date: Mon, 1 Apr 2019 13:04:42 +1300 Subject: [PATCH 0046/1121] ip6_tunnel: Match to ARPHRD_TUNNEL6 for dev type [ Upstream commit b2e54b09a3d29c4db883b920274ca8dca4d9f04d ] The device type for ip6 tunnels is set to ARPHRD_TUNNEL6. However, the ip4ip6_err function is expecting the device type of the tunnel to be ARPHRD_TUNNEL. Since the device types do not match, the function exits and the ICMP error packet is not sent to the originating host. Note that the device type for IPv4 tunnels is set to ARPHRD_TUNNEL. Fix is to expect a tunnel device type of ARPHRD_TUNNEL6 instead. Now the tunnel device type matches and the ICMP error packet is sent to the originating host. Signed-off-by: Sheena Mira-ato Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/ipv6/ip6_tunnel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 1812c2a748ff..f71c7915ff0e 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -633,7 +633,7 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, IPPROTO_IPIP, RT_TOS(eiph->tos), 0); if (IS_ERR(rt) || - rt->dst.dev->type != ARPHRD_TUNNEL) { + rt->dst.dev->type != ARPHRD_TUNNEL6) { if (!IS_ERR(rt)) ip_rt_put(rt); goto out; @@ -643,7 +643,7 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, ip_rt_put(rt); if (ip_route_input(skb2, eiph->daddr, eiph->saddr, eiph->tos, skb2->dev) || - skb_dst(skb2)->dev->type != ARPHRD_TUNNEL) + skb_dst(skb2)->dev->type != ARPHRD_TUNNEL6) goto out; } -- GitLab From 789185d40eff67b9d89367d1442b62c8f31ce872 Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Thu, 28 Mar 2019 19:40:36 +0000 Subject: [PATCH 0047/1121] hv_netvsc: Fix unwanted wakeup after tx_disable [ Upstream commit 1b704c4a1ba95574832e730f23817b651db2aa59 ] After queue stopped, the wakeup mechanism may wake it up again when ring buffer usage is lower than a threshold. This may cause send path panic on NULL pointer when we stopped all tx queues in netvsc_detach and start removing the netvsc device. This patch fix it by adding a tx_disable flag to prevent unwanted queue wakeup. Fixes: 7b2ee50c0cd5 ("hv_netvsc: common detach logic") Reported-by: Mohammed Gamal Signed-off-by: Haiyang Zhang Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/hyperv/hyperv_net.h | 1 + drivers/net/hyperv/netvsc.c | 6 ++++-- drivers/net/hyperv/netvsc_drv.c | 32 ++++++++++++++++++++++++++------ 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index e33a6c672a0a..0f07b5978fa1 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h @@ -779,6 +779,7 @@ struct netvsc_device { wait_queue_head_t wait_drain; bool destroy; + bool tx_disable; /* if true, do not wake up queue again */ /* Receive buffer allocated by us but manages by NetVSP */ void *recv_buf; diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index 806239b89990..a3bb4d5c64f5 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c @@ -107,6 +107,7 @@ static struct netvsc_device *alloc_net_device(void) init_waitqueue_head(&net_device->wait_drain); net_device->destroy = false; + net_device->tx_disable = false; atomic_set(&net_device->open_cnt, 0); net_device->max_pkt = RNDIS_MAX_PKT_DEFAULT; net_device->pkt_align = RNDIS_PKT_ALIGN_DEFAULT; @@ -712,7 +713,7 @@ static void netvsc_send_tx_complete(struct netvsc_device *net_device, } else { struct netdev_queue *txq = netdev_get_tx_queue(ndev, q_idx); - if (netif_tx_queue_stopped(txq) && + if (netif_tx_queue_stopped(txq) && !net_device->tx_disable && (hv_ringbuf_avail_percent(&channel->outbound) > RING_AVAIL_PERCENT_HIWATER || queue_sends < 1)) { netif_tx_wake_queue(txq); @@ -865,7 +866,8 @@ static inline int netvsc_send_pkt( netif_tx_stop_queue(txq); } else if (ret == -EAGAIN) { netif_tx_stop_queue(txq); - if (atomic_read(&nvchan->queue_sends) < 1) { + if (atomic_read(&nvchan->queue_sends) < 1 && + !net_device->tx_disable) { netif_tx_wake_queue(txq); ret = -ENOSPC; } diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 74b9e51b2b47..eb92720dd1c4 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -108,6 +108,15 @@ static void netvsc_set_rx_mode(struct net_device *net) rcu_read_unlock(); } +static void netvsc_tx_enable(struct netvsc_device *nvscdev, + struct net_device *ndev) +{ + nvscdev->tx_disable = false; + virt_wmb(); /* ensure queue wake up mechanism is on */ + + netif_tx_wake_all_queues(ndev); +} + static int netvsc_open(struct net_device *net) { struct net_device_context *ndev_ctx = netdev_priv(net); @@ -128,7 +137,7 @@ static int netvsc_open(struct net_device *net) rdev = nvdev->extension; if (!rdev->link_state) { netif_carrier_on(net); - netif_tx_wake_all_queues(net); + netvsc_tx_enable(nvdev, net); } if (vf_netdev) { @@ -183,6 +192,17 @@ static int netvsc_wait_until_empty(struct netvsc_device *nvdev) } } +static void netvsc_tx_disable(struct netvsc_device *nvscdev, + struct net_device *ndev) +{ + if (nvscdev) { + nvscdev->tx_disable = true; + virt_wmb(); /* ensure txq will not wake up after stop */ + } + + netif_tx_disable(ndev); +} + static int netvsc_close(struct net_device *net) { struct net_device_context *net_device_ctx = netdev_priv(net); @@ -191,7 +211,7 @@ static int netvsc_close(struct net_device *net) struct netvsc_device *nvdev = rtnl_dereference(net_device_ctx->nvdev); int ret; - netif_tx_disable(net); + netvsc_tx_disable(nvdev, net); /* No need to close rndis filter if it is removed already */ if (!nvdev) @@ -893,7 +913,7 @@ static int netvsc_detach(struct net_device *ndev, /* If device was up (receiving) then shutdown */ if (netif_running(ndev)) { - netif_tx_disable(ndev); + netvsc_tx_disable(nvdev, ndev); ret = rndis_filter_close(nvdev); if (ret) { @@ -1720,7 +1740,7 @@ static void netvsc_link_change(struct work_struct *w) if (rdev->link_state) { rdev->link_state = false; netif_carrier_on(net); - netif_tx_wake_all_queues(net); + netvsc_tx_enable(net_device, net); } else { notify = true; } @@ -1730,7 +1750,7 @@ static void netvsc_link_change(struct work_struct *w) if (!rdev->link_state) { rdev->link_state = true; netif_carrier_off(net); - netif_tx_stop_all_queues(net); + netvsc_tx_disable(net_device, net); } kfree(event); break; @@ -1739,7 +1759,7 @@ static void netvsc_link_change(struct work_struct *w) if (!rdev->link_state) { rdev->link_state = true; netif_carrier_off(net); - netif_tx_stop_all_queues(net); + netvsc_tx_disable(net_device, net); event->event = RNDIS_STATUS_MEDIA_CONNECT; spin_lock_irqsave(&ndev_ctx->lock, flags); list_add(&event->list, &ndev_ctx->reconfig_events); -- GitLab From c1d361d3b1170efe557a418f85adc7a1a24cf401 Mon Sep 17 00:00:00 2001 From: Peter Geis Date: Wed, 13 Mar 2019 19:02:30 +0000 Subject: [PATCH 0048/1121] arm64: dts: rockchip: fix rk3328 sdmmc0 write errors commit 09f91381fa5de1d44bc323d8bf345f5d57b3d9b5 upstream. Various rk3328 based boards experience occasional sdmmc0 write errors. This is due to the rk3328.dtsi tx drive levels being set to 4ma, vs 8ma per the rk3328 datasheet default settings. Fix this by setting the tx signal pins to 8ma. Inspiration from tonymac32's patch, https://github.com/ayufan-rock64/linux-kernel/commit/dc1212b347e0da17c5460bcc0a56b07d02bac3f8 Fixes issues on the rk3328-roc-cc and the rk3328-rock64 (as per the above commit message). Tested on the rk3328-roc-cc board. Fixes: 52e02d377a72 ("arm64: dts: rockchip: add core dtsi file for RK3328 SoCs") Cc: stable@vger.kernel.org Signed-off-by: Peter Geis Signed-off-by: Heiko Stuebner Signed-off-by: Greg Kroah-Hartman --- arch/arm64/boot/dts/rockchip/rk3328.dtsi | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi index efac2202b16e..cd67c65b3a47 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi @@ -1333,11 +1333,11 @@ sdmmc0 { sdmmc0_clk: sdmmc0-clk { - rockchip,pins = <1 RK_PA6 1 &pcfg_pull_none_4ma>; + rockchip,pins = <1 RK_PA6 1 &pcfg_pull_none_8ma>; }; sdmmc0_cmd: sdmmc0-cmd { - rockchip,pins = <1 RK_PA4 1 &pcfg_pull_up_4ma>; + rockchip,pins = <1 RK_PA4 1 &pcfg_pull_up_8ma>; }; sdmmc0_dectn: sdmmc0-dectn { @@ -1349,14 +1349,14 @@ }; sdmmc0_bus1: sdmmc0-bus1 { - rockchip,pins = <1 RK_PA0 1 &pcfg_pull_up_4ma>; + rockchip,pins = <1 RK_PA0 1 &pcfg_pull_up_8ma>; }; sdmmc0_bus4: sdmmc0-bus4 { - rockchip,pins = <1 RK_PA0 1 &pcfg_pull_up_4ma>, - <1 RK_PA1 1 &pcfg_pull_up_4ma>, - <1 RK_PA2 1 &pcfg_pull_up_4ma>, - <1 RK_PA3 1 &pcfg_pull_up_4ma>; + rockchip,pins = <1 RK_PA0 1 &pcfg_pull_up_8ma>, + <1 RK_PA1 1 &pcfg_pull_up_8ma>, + <1 RK_PA2 1 &pcfg_pull_up_8ma>, + <1 RK_PA3 1 &pcfg_pull_up_8ma>; }; sdmmc0_gpio: sdmmc0-gpio { -- GitLab From a1f5209663ec56deec5587013a4795cf42178360 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Tue, 2 Apr 2019 12:13:27 +0200 Subject: [PATCH 0049/1121] parisc: Detect QEMU earlier in boot process commit d006e95b5561f708d0385e9677ffe2c46f2ae345 upstream. While adding LASI support to QEMU, I noticed that the QEMU detection in the kernel happens much too late. For example, when a LASI chip is found by the kernel, it registers the LASI LED driver as well. But when we run on QEMU it makes sense to avoid spending unnecessary CPU cycles, so we need to access the running_on_QEMU flag earlier than before. This patch now makes the QEMU detection the fist task of the Linux kernel by moving it to where the kernel enters the C-coding. Fixes: 310d82784fb4 ("parisc: qemu idle sleep support") Signed-off-by: Helge Deller Cc: stable@vger.kernel.org # v4.14+ Signed-off-by: Greg Kroah-Hartman --- arch/parisc/kernel/process.c | 6 ------ arch/parisc/kernel/setup.c | 3 +++ 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index cad3e8661cd6..4d712c1d64b8 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c @@ -209,12 +209,6 @@ void __cpuidle arch_cpu_idle(void) static int __init parisc_idle_init(void) { - const char *marker; - - /* check QEMU/SeaBIOS marker in PAGE0 */ - marker = (char *) &PAGE0->pad0; - running_on_qemu = (memcmp(marker, "SeaBIOS", 8) == 0); - if (!running_on_qemu) cpu_idle_poll_ctrl(1); diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c index f7d0c3b33d70..550f80ae9c8f 100644 --- a/arch/parisc/kernel/setup.c +++ b/arch/parisc/kernel/setup.c @@ -406,6 +406,9 @@ void __init start_parisc(void) int ret, cpunum; struct pdc_coproc_cfg coproc_cfg; + /* check QEMU/SeaBIOS marker in PAGE0 */ + running_on_qemu = (memcmp(&PAGE0->pad0, "SeaBIOS", 8) == 0); + cpunum = smp_processor_id(); set_firmware_width_unlocked(); -- GitLab From 224f5ab9bc035d25a01cc7a4d52722837163a293 Mon Sep 17 00:00:00 2001 From: Sven Schnelle Date: Thu, 4 Apr 2019 18:16:03 +0200 Subject: [PATCH 0050/1121] parisc: regs_return_value() should return gpr28 commit 45efd871bf0a47648f119d1b41467f70484de5bc upstream. While working on kretprobes for PA-RISC I was wondering while the kprobes sanity test always fails on kretprobes. This is caused by returning gpr20 instead of gpr28. Signed-off-by: Sven Schnelle Signed-off-by: Helge Deller Cc: stable@vger.kernel.org # 4.14+ Signed-off-by: Greg Kroah-Hartman --- arch/parisc/include/asm/ptrace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/parisc/include/asm/ptrace.h b/arch/parisc/include/asm/ptrace.h index 46da07670c2b..c8f70f965e8e 100644 --- a/arch/parisc/include/asm/ptrace.h +++ b/arch/parisc/include/asm/ptrace.h @@ -22,7 +22,7 @@ unsigned long profile_pc(struct pt_regs *); static inline unsigned long regs_return_value(struct pt_regs *regs) { - return regs->gr[20]; + return regs->gr[28]; } #endif -- GitLab From 753ff72679f0230cf06ee56c920d1dc622acfd1a Mon Sep 17 00:00:00 2001 From: Andrei Vagin Date: Sun, 7 Apr 2019 21:15:42 -0700 Subject: [PATCH 0051/1121] alarmtimer: Return correct remaining time commit 07d7e12091f4ab869cc6a4bb276399057e73b0b3 upstream. To calculate a remaining time, it's required to subtract the current time from the expiration time. In alarm_timer_remaining() the arguments of ktime_sub are swapped. Fixes: d653d8457c76 ("alarmtimer: Implement remaining callback") Signed-off-by: Andrei Vagin Signed-off-by: Thomas Gleixner Reviewed-by: Mukesh Ojha Cc: Stephen Boyd Cc: John Stultz Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/20190408041542.26338-1-avagin@gmail.com Signed-off-by: Greg Kroah-Hartman --- kernel/time/alarmtimer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index fa5de5e8de61..fdeb9bc6affb 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -597,7 +597,7 @@ static ktime_t alarm_timer_remaining(struct k_itimer *timr, ktime_t now) { struct alarm *alarm = &timr->it.alarm.alarmtimer; - return ktime_sub(now, alarm->node.expires); + return ktime_sub(alarm->node.expires, now); } /** -- GitLab From f7a46b61d3af4ea98bf35d8791485bf35596b567 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 5 Apr 2019 13:17:13 +1000 Subject: [PATCH 0052/1121] drm/udl: add a release method and delay modeset teardown commit 9b39b013037fbfa8d4b999345d9e904d8a336fc2 upstream. If we unplug a udl device, the usb callback with deinit the mode_config struct, however userspace will still have an open file descriptor and a framebuffer on that device. When userspace closes the fd, we'll oops because it'll try and look stuff up in the object idr which we've destroyed. This punts destroying the mode objects until release time instead. Cc: stable@vger.kernel.org Reviewed-by: Daniel Vetter Signed-off-by: Dave Airlie Link: https://patchwork.freedesktop.org/patch/msgid/20190405031715.5959-2-airlied@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/udl/udl_drv.c | 1 + drivers/gpu/drm/udl/udl_drv.h | 1 + drivers/gpu/drm/udl/udl_main.c | 8 +++++++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 31421b6b586e..b45ac6bc8add 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -47,6 +47,7 @@ static struct drm_driver driver = { .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME, .load = udl_driver_load, .unload = udl_driver_unload, + .release = udl_driver_release, /* gem hooks */ .gem_free_object = udl_gem_free_object, diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h index 2c149b841cf1..307455dd6526 100644 --- a/drivers/gpu/drm/udl/udl_drv.h +++ b/drivers/gpu/drm/udl/udl_drv.h @@ -101,6 +101,7 @@ void udl_urb_completion(struct urb *urb); int udl_driver_load(struct drm_device *dev, unsigned long flags); void udl_driver_unload(struct drm_device *dev); +void udl_driver_release(struct drm_device *dev); int udl_fbdev_init(struct drm_device *dev); void udl_fbdev_cleanup(struct drm_device *dev); diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c index f8ea3c99b523..60866b422f81 100644 --- a/drivers/gpu/drm/udl/udl_main.c +++ b/drivers/gpu/drm/udl/udl_main.c @@ -378,6 +378,12 @@ void udl_driver_unload(struct drm_device *dev) udl_free_urb_list(dev); udl_fbdev_cleanup(dev); - udl_modeset_cleanup(dev); kfree(udl); } + +void udl_driver_release(struct drm_device *dev) +{ + udl_modeset_cleanup(dev); + drm_dev_fini(dev); + kfree(dev); +} -- GitLab From ed031128c2f8267f13d592961acecfae5136968b Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 5 Apr 2019 18:38:53 -0700 Subject: [PATCH 0053/1121] include/linux/bitrev.h: fix constant bitrev commit 6147e136ff5071609b54f18982dea87706288e21 upstream. clang points out with hundreds of warnings that the bitrev macros have a problem with constant input: drivers/hwmon/sht15.c:187:11: error: variable '__x' is uninitialized when used within its own initialization [-Werror,-Wuninitialized] u8 crc = bitrev8(data->val_status & 0x0F); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/bitrev.h:102:21: note: expanded from macro 'bitrev8' __constant_bitrev8(__x) : \ ~~~~~~~~~~~~~~~~~~~^~~~ include/linux/bitrev.h:67:11: note: expanded from macro '__constant_bitrev8' u8 __x = x; \ ~~~ ^ Both the bitrev and the __constant_bitrev macros use an internal variable named __x, which goes horribly wrong when passing one to the other. The obvious fix is to rename one of the variables, so this adds an extra '_'. It seems we got away with this because - there are only a few drivers using bitrev macros - usually there are no constant arguments to those - when they are constant, they tend to be either 0 or (unsigned)-1 (drivers/isdn/i4l/isdnhdlc.o, drivers/iio/amplifiers/ad8366.c) and give the correct result by pure chance. In fact, the only driver that I could find that gets different results with this is drivers/net/wan/slic_ds26522.c, which in turn is a driver for fairly rare hardware (adding the maintainer to Cc for testing). Link: http://lkml.kernel.org/r/20190322140503.123580-1-arnd@arndb.de Fixes: 556d2f055bf6 ("ARM: 8187/1: add CONFIG_HAVE_ARCH_BITREVERSE to support rbit instruction") Signed-off-by: Arnd Bergmann Reviewed-by: Nick Desaulniers Cc: Zhao Qiang Cc: Yalin Wang Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- include/linux/bitrev.h | 46 +++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/include/linux/bitrev.h b/include/linux/bitrev.h index 50fb0dee23e8..d35b8ec1c485 100644 --- a/include/linux/bitrev.h +++ b/include/linux/bitrev.h @@ -34,41 +34,41 @@ static inline u32 __bitrev32(u32 x) #define __constant_bitrev32(x) \ ({ \ - u32 __x = x; \ - __x = (__x >> 16) | (__x << 16); \ - __x = ((__x & (u32)0xFF00FF00UL) >> 8) | ((__x & (u32)0x00FF00FFUL) << 8); \ - __x = ((__x & (u32)0xF0F0F0F0UL) >> 4) | ((__x & (u32)0x0F0F0F0FUL) << 4); \ - __x = ((__x & (u32)0xCCCCCCCCUL) >> 2) | ((__x & (u32)0x33333333UL) << 2); \ - __x = ((__x & (u32)0xAAAAAAAAUL) >> 1) | ((__x & (u32)0x55555555UL) << 1); \ - __x; \ + u32 ___x = x; \ + ___x = (___x >> 16) | (___x << 16); \ + ___x = ((___x & (u32)0xFF00FF00UL) >> 8) | ((___x & (u32)0x00FF00FFUL) << 8); \ + ___x = ((___x & (u32)0xF0F0F0F0UL) >> 4) | ((___x & (u32)0x0F0F0F0FUL) << 4); \ + ___x = ((___x & (u32)0xCCCCCCCCUL) >> 2) | ((___x & (u32)0x33333333UL) << 2); \ + ___x = ((___x & (u32)0xAAAAAAAAUL) >> 1) | ((___x & (u32)0x55555555UL) << 1); \ + ___x; \ }) #define __constant_bitrev16(x) \ ({ \ - u16 __x = x; \ - __x = (__x >> 8) | (__x << 8); \ - __x = ((__x & (u16)0xF0F0U) >> 4) | ((__x & (u16)0x0F0FU) << 4); \ - __x = ((__x & (u16)0xCCCCU) >> 2) | ((__x & (u16)0x3333U) << 2); \ - __x = ((__x & (u16)0xAAAAU) >> 1) | ((__x & (u16)0x5555U) << 1); \ - __x; \ + u16 ___x = x; \ + ___x = (___x >> 8) | (___x << 8); \ + ___x = ((___x & (u16)0xF0F0U) >> 4) | ((___x & (u16)0x0F0FU) << 4); \ + ___x = ((___x & (u16)0xCCCCU) >> 2) | ((___x & (u16)0x3333U) << 2); \ + ___x = ((___x & (u16)0xAAAAU) >> 1) | ((___x & (u16)0x5555U) << 1); \ + ___x; \ }) #define __constant_bitrev8x4(x) \ ({ \ - u32 __x = x; \ - __x = ((__x & (u32)0xF0F0F0F0UL) >> 4) | ((__x & (u32)0x0F0F0F0FUL) << 4); \ - __x = ((__x & (u32)0xCCCCCCCCUL) >> 2) | ((__x & (u32)0x33333333UL) << 2); \ - __x = ((__x & (u32)0xAAAAAAAAUL) >> 1) | ((__x & (u32)0x55555555UL) << 1); \ - __x; \ + u32 ___x = x; \ + ___x = ((___x & (u32)0xF0F0F0F0UL) >> 4) | ((___x & (u32)0x0F0F0F0FUL) << 4); \ + ___x = ((___x & (u32)0xCCCCCCCCUL) >> 2) | ((___x & (u32)0x33333333UL) << 2); \ + ___x = ((___x & (u32)0xAAAAAAAAUL) >> 1) | ((___x & (u32)0x55555555UL) << 1); \ + ___x; \ }) #define __constant_bitrev8(x) \ ({ \ - u8 __x = x; \ - __x = (__x >> 4) | (__x << 4); \ - __x = ((__x & (u8)0xCCU) >> 2) | ((__x & (u8)0x33U) << 2); \ - __x = ((__x & (u8)0xAAU) >> 1) | ((__x & (u8)0x55U) << 1); \ - __x; \ + u8 ___x = x; \ + ___x = (___x >> 4) | (___x << 4); \ + ___x = ((___x & (u8)0xCCU) >> 2) | ((___x & (u8)0x33U) << 2); \ + ___x = ((___x & (u8)0xAAU) >> 1) | ((___x & (u8)0x55U) << 1); \ + ___x; \ }) #define bitrev32(x) \ -- GitLab From 541e756826fa39fd06f30ee4f1445845ff44ad2d Mon Sep 17 00:00:00 2001 From: "S.j. Wang" Date: Wed, 27 Feb 2019 06:31:12 +0000 Subject: [PATCH 0054/1121] ASoC: fsl_esai: fix channel swap issue when stream starts commit 0ff4e8c61b794a4bf6c854ab071a1abaaa80f358 upstream. There is very low possibility ( < 0.1% ) that channel swap happened in beginning when multi output/input pin is enabled. The issue is that hardware can't send data to correct pin in the beginning with the normal enable flow. This is hardware issue, but there is no errata, the workaround flow is that: Each time playback/recording, firstly clear the xSMA/xSMB, then enable TE/RE, then enable xSMB and xSMA (xSMB must be enabled before xSMA). Which is to use the xSMA as the trigger start register, previously the xCR_TE or xCR_RE is the bit for starting. Fixes commit 43d24e76b698 ("ASoC: fsl_esai: Add ESAI CPU DAI driver") Cc: Reviewed-by: Fabio Estevam Acked-by: Nicolin Chen Signed-off-by: Shengjiu Wang Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- sound/soc/fsl/fsl_esai.c | 47 +++++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index a23d6a821ff3..6152ae24772b 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c @@ -58,6 +58,8 @@ struct fsl_esai { u32 fifo_depth; u32 slot_width; u32 slots; + u32 tx_mask; + u32 rx_mask; u32 hck_rate[2]; u32 sck_rate[2]; bool hck_dir[2]; @@ -358,21 +360,13 @@ static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR, ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots)); - regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMA, - ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(tx_mask)); - regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMB, - ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(tx_mask)); - regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR, ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots)); - regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMA, - ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(rx_mask)); - regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMB, - ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(rx_mask)); - esai_priv->slot_width = slot_width; esai_priv->slots = slots; + esai_priv->tx_mask = tx_mask; + esai_priv->rx_mask = rx_mask; return 0; } @@ -593,6 +587,7 @@ static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd, bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; u8 i, channels = substream->runtime->channels; u32 pins = DIV_ROUND_UP(channels, esai_priv->slots); + u32 mask; switch (cmd) { case SNDRV_PCM_TRIGGER_START: @@ -605,15 +600,38 @@ static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd, for (i = 0; tx && i < channels; i++) regmap_write(esai_priv->regmap, REG_ESAI_ETDR, 0x0); + /* + * When set the TE/RE in the end of enablement flow, there + * will be channel swap issue for multi data line case. + * In order to workaround this issue, we switch the bit + * enablement sequence to below sequence + * 1) clear the xSMB & xSMA: which is done in probe and + * stop state. + * 2) set TE/RE + * 3) set xSMB + * 4) set xSMA: xSMA is the last one in this flow, which + * will trigger esai to start. + */ regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, tx ? ESAI_xCR_TE(pins) : ESAI_xCR_RE(pins)); + mask = tx ? esai_priv->tx_mask : esai_priv->rx_mask; + + regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMB(tx), + ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(mask)); + regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMA(tx), + ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(mask)); + break; case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, 0); + regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMA(tx), + ESAI_xSMA_xS_MASK, 0); + regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMB(tx), + ESAI_xSMB_xS_MASK, 0); /* Disable and reset FIFO */ regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), @@ -903,6 +921,15 @@ static int fsl_esai_probe(struct platform_device *pdev) return ret; } + esai_priv->tx_mask = 0xFFFFFFFF; + esai_priv->rx_mask = 0xFFFFFFFF; + + /* Clear the TSMA, TSMB, RSMA, RSMB */ + regmap_write(esai_priv->regmap, REG_ESAI_TSMA, 0); + regmap_write(esai_priv->regmap, REG_ESAI_TSMB, 0); + regmap_write(esai_priv->regmap, REG_ESAI_RSMA, 0); + regmap_write(esai_priv->regmap, REG_ESAI_RSMB, 0); + ret = devm_snd_soc_register_component(&pdev->dev, &fsl_esai_component, &fsl_esai_dai, 1); if (ret) { -- GitLab From 3eb52487d917d81e7f7ff3e46fafad221e1d3637 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Tue, 26 Mar 2019 10:49:56 +0000 Subject: [PATCH 0055/1121] Btrfs: do not allow trimming when a fs is mounted with the nologreplay option commit f35f06c35560a86e841631f0243b83a984dc11a9 upstream. Whan a filesystem is mounted with the nologreplay mount option, which requires it to be mounted in RO mode as well, we can not allow discard on free space inside block groups, because log trees refer to extents that are not pinned in a block group's free space cache (pinning the extents is precisely the first phase of replaying a log tree). So do not allow the fitrim ioctl to do anything when the filesystem is mounted with the nologreplay option, because later it can be mounted RW without that option, which causes log replay to happen and result in either a failure to replay the log trees (leading to a mount failure), a crash or some silent corruption. Reported-by: Darrick J. Wong Fixes: 96da09192cda ("btrfs: Introduce new mount option to disable tree log replay") CC: stable@vger.kernel.org # 4.9+ Reviewed-by: Nikolay Borisov Signed-off-by: Filipe Manana Reviewed-by: David Sterba Signed-off-by: David Sterba Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/ioctl.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index cddd63b9103f..dd3b4820ac30 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -357,6 +357,16 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg) if (!capable(CAP_SYS_ADMIN)) return -EPERM; + /* + * If the fs is mounted with nologreplay, which requires it to be + * mounted in RO mode as well, we can not allow discard on free space + * inside block groups, because log trees refer to extents that are not + * pinned in a block group's free space cache (pinning the extents is + * precisely the first phase of replaying a log tree). + */ + if (btrfs_test_opt(fs_info, NOLOGREPLAY)) + return -EROFS; + rcu_read_lock(); list_for_each_entry_rcu(device, &fs_info->fs_devices->devices, dev_list) { -- GitLab From 979409e6f4590e881b0eee29aab8f22f8047c91c Mon Sep 17 00:00:00 2001 From: Anand Jain Date: Tue, 2 Apr 2019 18:07:38 +0800 Subject: [PATCH 0056/1121] btrfs: prop: fix zstd compression parameter validation commit 50398fde997f6be8faebdb5f38e9c9c467370f51 upstream. We let pass zstd compression parameter even if it is not fully valid. For example: $ btrfs prop set /btrfs compression zst $ btrfs prop get /btrfs compression compression=zst zlib and lzo are fine. Fix it by checking the correct prefix length. Fixes: 5c1aab1dd544 ("btrfs: Add zstd support") CC: stable@vger.kernel.org # 4.14+ Reviewed-by: Nikolay Borisov Signed-off-by: Anand Jain Reviewed-by: David Sterba Signed-off-by: David Sterba Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/props.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/btrfs/props.c b/fs/btrfs/props.c index cbabc6f2b322..3eee2f7e1dd2 100644 --- a/fs/btrfs/props.c +++ b/fs/btrfs/props.c @@ -416,7 +416,7 @@ static int prop_compression_apply(struct inode *inode, btrfs_set_fs_incompat(fs_info, COMPRESS_LZO); } else if (!strncmp("zlib", value, 4)) { type = BTRFS_COMPRESS_ZLIB; - } else if (!strncmp("zstd", value, len)) { + } else if (!strncmp("zstd", value, 4)) { type = BTRFS_COMPRESS_ZSTD; btrfs_set_fs_incompat(fs_info, COMPRESS_ZSTD); } else { -- GitLab From 2fc37a0abf1ff4fdf35d1a90fb80ec98c588184a Mon Sep 17 00:00:00 2001 From: Anand Jain Date: Tue, 2 Apr 2019 18:07:40 +0800 Subject: [PATCH 0057/1121] btrfs: prop: fix vanished compression property after failed set commit 272e5326c7837697882ce3162029ba893059b616 upstream. The compression property resets to NULL, instead of the old value if we fail to set the new compression parameter. $ btrfs prop get /btrfs compression compression=lzo $ btrfs prop set /btrfs compression zli ERROR: failed to set compression for /btrfs: Invalid argument $ btrfs prop get /btrfs compression This is because the compression property ->validate() is successful for 'zli' as the strncmp() used the length passed from the userspace. Fix it by using the expected string length in strncmp(). Fixes: 63541927c8d1 ("Btrfs: add support for inode properties") Fixes: 5c1aab1dd544 ("btrfs: Add zstd support") CC: stable@vger.kernel.org # 4.14+ Reviewed-by: Nikolay Borisov Signed-off-by: Anand Jain Reviewed-by: David Sterba Signed-off-by: David Sterba Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/props.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/btrfs/props.c b/fs/btrfs/props.c index 3eee2f7e1dd2..266f9069307b 100644 --- a/fs/btrfs/props.c +++ b/fs/btrfs/props.c @@ -386,11 +386,11 @@ int btrfs_subvol_inherit_props(struct btrfs_trans_handle *trans, static int prop_compression_validate(const char *value, size_t len) { - if (!strncmp("lzo", value, len)) + if (!strncmp("lzo", value, 3)) return 0; - else if (!strncmp("zlib", value, len)) + else if (!strncmp("zlib", value, 4)) return 0; - else if (!strncmp("zstd", value, len)) + else if (!strncmp("zstd", value, 4)) return 0; return -EINVAL; -- GitLab From 6ec54fc43b5a43c6b456b04843f13a2dded1c4f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Glisse?= Date: Wed, 10 Apr 2019 16:27:51 -0400 Subject: [PATCH 0058/1121] block: do not leak memory in bio_copy_user_iov() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit a3761c3c91209b58b6f33bf69dd8bb8ec0c9d925 upstream. When bio_add_pc_page() fails in bio_copy_user_iov() we should free the page we just allocated otherwise we are leaking it. Cc: linux-block@vger.kernel.org Cc: Linus Torvalds Cc: stable@vger.kernel.org Reviewed-by: Chaitanya Kulkarni Signed-off-by: JĂ©rĂŽme Glisse Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- block/bio.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/block/bio.c b/block/bio.c index 2e5d881423b8..d01ab919b313 100644 --- a/block/bio.c +++ b/block/bio.c @@ -1280,8 +1280,11 @@ struct bio *bio_copy_user_iov(struct request_queue *q, } } - if (bio_add_pc_page(q, bio, page, bytes, offset) < bytes) + if (bio_add_pc_page(q, bio, page, bytes, offset) < bytes) { + if (!map_data) + __free_page(page); break; + } len -= bytes; offset = 0; -- GitLab From b6991eb26278b4b9b599a1611a6f65fa765ff403 Mon Sep 17 00:00:00 2001 From: Jason Yan Date: Fri, 12 Apr 2019 10:09:16 +0800 Subject: [PATCH 0059/1121] block: fix the return errno for direct IO commit a89afe58f1a74aac768a5eb77af95ef4ee15beaa upstream. If the last bio returned is not dio->bio, the status of the bio will not assigned to dio->bio if it is error. This will cause the whole IO status wrong. ksoftirqd/21-117 [021] ..s. 4017.966090: 8,0 C N 4883648 [0] -0 [018] ..s. 4017.970888: 8,0 C WS 4924800 + 1024 [0] -0 [018] ..s. 4017.970909: 8,0 D WS 4935424 + 1024 [] -0 [018] ..s. 4017.970924: 8,0 D WS 4936448 + 321 [] ksoftirqd/21-117 [021] ..s. 4017.995033: 8,0 C R 4883648 + 336 [65475] ksoftirqd/21-117 [021] d.s. 4018.001988: myprobe1: (blkdev_bio_end_io+0x0/0x168) bi_status=7 ksoftirqd/21-117 [021] d.s. 4018.001992: myprobe: (aio_complete_rw+0x0/0x148) x0=0xffff802f2595ad80 res=0x12a000 res2=0x0 We always have to assign bio->bi_status to dio->bio.bi_status because we will only check dio->bio.bi_status when we return the whole IO to the upper layer. Fixes: 542ff7bf18c6 ("block: new direct I/O implementation") Cc: stable@vger.kernel.org Cc: Christoph Hellwig Cc: Jens Axboe Reviewed-by: Ming Lei Signed-off-by: Jason Yan Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- fs/block_dev.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/block_dev.c b/fs/block_dev.c index 3911c1a80219..61949e3446e5 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -306,10 +306,10 @@ static void blkdev_bio_end_io(struct bio *bio) struct blkdev_dio *dio = bio->bi_private; bool should_dirty = dio->should_dirty; - if (dio->multi_bio && !atomic_dec_and_test(&dio->ref)) { - if (bio->bi_status && !dio->bio.bi_status) - dio->bio.bi_status = bio->bi_status; - } else { + if (bio->bi_status && !dio->bio.bi_status) + dio->bio.bi_status = bio->bi_status; + + if (!dio->multi_bio || atomic_dec_and_test(&dio->ref)) { if (!dio->is_sync) { struct kiocb *iocb = dio->iocb; ssize_t ret; -- GitLab From 3559f73ed6db1df2bd8a65ded63246d9e3bb21c9 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Mon, 25 Mar 2019 11:10:26 -0700 Subject: [PATCH 0060/1121] genirq: Respect IRQCHIP_SKIP_SET_WAKE in irq_chip_set_wake_parent() commit 325aa19598e410672175ed50982f902d4e3f31c5 upstream. If a child irqchip calls irq_chip_set_wake_parent() but its parent irqchip has the IRQCHIP_SKIP_SET_WAKE flag set an error is returned. This is inconsistent behaviour vs. set_irq_wake_real() which returns 0 when the irqchip has the IRQCHIP_SKIP_SET_WAKE flag set. It doesn't attempt to walk the chain of parents and set irq wake on any chips that don't have the flag set either. If the intent is to call the .irq_set_wake() callback of the parent irqchip, then we expect irqchip implementations to omit the IRQCHIP_SKIP_SET_WAKE flag and implement an .irq_set_wake() function that calls irq_chip_set_wake_parent(). The problem has been observed on a Qualcomm sdm845 device where set wake fails on any GPIO interrupts after applying work in progress wakeup irq patches to the GPIO driver. The chain of chips looks like this: QCOM GPIO -> QCOM PDC (SKIP) -> ARM GIC (SKIP) The GPIO controllers parent is the QCOM PDC irqchip which in turn has ARM GIC as parent. The QCOM PDC irqchip has the IRQCHIP_SKIP_SET_WAKE flag set, and so does the grandparent ARM GIC. The GPIO driver doesn't know if the parent needs to set wake or not, so it unconditionally calls irq_chip_set_wake_parent() causing this function to return a failure because the parent irqchip (PDC) doesn't have the .irq_set_wake() callback set. Returning 0 instead makes everything work and irqs from the GPIO controller can be configured for wakeup. Make it consistent by returning 0 (success) from irq_chip_set_wake_parent() when a parent chip has IRQCHIP_SKIP_SET_WAKE set. [ tglx: Massaged changelog ] Fixes: 08b55e2a9208e ("genirq: Add irqchip_set_wake_parent") Signed-off-by: Stephen Boyd Signed-off-by: Thomas Gleixner Acked-by: Marc Zyngier Cc: linux-arm-kernel@lists.infradead.org Cc: linux-gpio@vger.kernel.org Cc: Lina Iyer Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/20190325181026.247796-1-swboyd@chromium.org Signed-off-by: Greg Kroah-Hartman --- kernel/irq/chip.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 0fa7ef74303b..317fc759de76 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -1363,6 +1363,10 @@ int irq_chip_set_vcpu_affinity_parent(struct irq_data *data, void *vcpu_info) int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on) { data = data->parent_data; + + if (data->chip->flags & IRQCHIP_SKIP_SET_WAKE) + return 0; + if (data->chip->irq_set_wake) return data->chip->irq_set_wake(data, on); -- GitLab From 82e1fb4d3780333e5e406157b8dc48dfb0734ed1 Mon Sep 17 00:00:00 2001 From: Kefeng Wang Date: Thu, 4 Apr 2019 15:45:12 +0800 Subject: [PATCH 0061/1121] genirq: Initialize request_mutex if CONFIG_SPARSE_IRQ=n commit e8458e7afa855317b14915d7b86ab3caceea7eb6 upstream. When CONFIG_SPARSE_IRQ is disable, the request_mutex in struct irq_desc is not initialized which causes malfunction. Fixes: 9114014cf4e6 ("genirq: Add mutex to irq desc to serialize request/free_irq()") Signed-off-by: Kefeng Wang Signed-off-by: Thomas Gleixner Reviewed-by: Mukesh Ojha Cc: Marc Zyngier Cc: Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/20190404074512.145533-1-wangkefeng.wang@huawei.com Signed-off-by: Greg Kroah-Hartman --- kernel/irq/irqdesc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c index c2bfb11a9d05..aa08d4184608 100644 --- a/kernel/irq/irqdesc.c +++ b/kernel/irq/irqdesc.c @@ -535,6 +535,7 @@ int __init early_irq_init(void) alloc_masks(&desc[i], node); raw_spin_lock_init(&desc[i].lock); lockdep_set_class(&desc[i].lock, &irq_desc_lock_class); + mutex_init(&desc[i].request_mutex); desc_set_defaults(i, &desc[i], node, NULL, NULL); } return arch_early_irq_init(); -- GitLab From 1b69a78ac089b07fb919b464c35c0fcfca242c14 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Mon, 8 Apr 2019 14:33:22 +0200 Subject: [PATCH 0062/1121] virtio: Honour 'may_reduce_num' in vring_create_virtqueue commit cf94db21905333e610e479688add629397a4b384 upstream. vring_create_virtqueue() allows the caller to specify via the may_reduce_num parameter whether the vring code is allowed to allocate a smaller ring than specified. However, the split ring allocation code tries to allocate a smaller ring on allocation failure regardless of what the caller specified. This may cause trouble for e.g. virtio-pci in legacy mode, which does not support ring resizing. (The packed ring code does not resize in any case.) Let's fix this by bailing out immediately in the split ring code if the requested size cannot be allocated and may_reduce_num has not been specified. While at it, fix a typo in the usage instructions. Fixes: 2a2d1382fe9d ("virtio: Add improved queue allocation API") Cc: stable@vger.kernel.org # v4.6+ Signed-off-by: Cornelia Huck Signed-off-by: Michael S. Tsirkin Reviewed-by: Halil Pasic Reviewed-by: Jens Freimann Signed-off-by: Greg Kroah-Hartman --- drivers/virtio/virtio_ring.c | 2 ++ include/linux/virtio_ring.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 71458f493cf8..cc9d421c0929 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -1087,6 +1087,8 @@ struct virtqueue *vring_create_virtqueue( GFP_KERNEL|__GFP_NOWARN|__GFP_ZERO); if (queue) break; + if (!may_reduce_num) + return NULL; } if (!num) diff --git a/include/linux/virtio_ring.h b/include/linux/virtio_ring.h index bbf32524ab27..75007e648dfa 100644 --- a/include/linux/virtio_ring.h +++ b/include/linux/virtio_ring.h @@ -63,7 +63,7 @@ struct virtqueue; /* * Creates a virtqueue and allocates the descriptor ring. If * may_reduce_num is set, then this may allocate a smaller ring than - * expected. The caller should query virtqueue_get_ring_size to learn + * expected. The caller should query virtqueue_get_vring_size to learn * the actual size of the ring. */ struct virtqueue *vring_create_virtqueue(unsigned int index, -- GitLab From 9af55767d7fa0f06e28dc16078800f1cf84b388c Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 15 Mar 2019 12:59:17 +0200 Subject: [PATCH 0063/1121] ARM: dts: am335x-evmsk: Correct the regulators for the audio codec commit 6691370646e844be98bb6558c024269791d20bd7 upstream. Correctly map the regulators used by tlv320aic3106. Both 1.8V and 3.3V for the codec is derived from VBAT via fixed regulators. Cc: # v4.14+ Signed-off-by: Peter Ujfalusi Signed-off-by: Tony Lindgren Signed-off-by: Greg Kroah-Hartman --- arch/arm/boot/dts/am335x-evmsk.dts | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/am335x-evmsk.dts b/arch/arm/boot/dts/am335x-evmsk.dts index 9ba4b18c0cb2..bbd828892fcb 100644 --- a/arch/arm/boot/dts/am335x-evmsk.dts +++ b/arch/arm/boot/dts/am335x-evmsk.dts @@ -73,6 +73,24 @@ enable-active-high; }; + /* TPS79518 */ + v1_8d_reg: fixedregulator-v1_8d { + compatible = "regulator-fixed"; + regulator-name = "v1_8d"; + vin-supply = <&vbat>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + /* TPS78633 */ + v3_3d_reg: fixedregulator-v3_3d { + compatible = "regulator-fixed"; + regulator-name = "v3_3d"; + vin-supply = <&vbat>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + leds { pinctrl-names = "default"; pinctrl-0 = <&user_leds_s0>; @@ -493,10 +511,10 @@ status = "okay"; /* Regulators */ - AVDD-supply = <&vaux2_reg>; - IOVDD-supply = <&vaux2_reg>; - DRVDD-supply = <&vaux2_reg>; - DVDD-supply = <&vbat>; + AVDD-supply = <&v3_3d_reg>; + IOVDD-supply = <&v3_3d_reg>; + DRVDD-supply = <&v3_3d_reg>; + DVDD-supply = <&v1_8d_reg>; }; }; -- GitLab From 84a8a44a6ccdaa955901ea6f3320b7b52ae3ff93 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 15 Mar 2019 12:59:09 +0200 Subject: [PATCH 0064/1121] ARM: dts: am335x-evm: Correct the regulators for the audio codec commit 4f96dc0a3e79ec257a2b082dab3ee694ff88c317 upstream. Correctly map the regulators used by tlv320aic3106. Both 1.8V and 3.3V for the codec is derived from VBAT via fixed regulators. Cc: # v4.14+ Signed-off-by: Peter Ujfalusi Signed-off-by: Tony Lindgren Signed-off-by: Greg Kroah-Hartman --- arch/arm/boot/dts/am335x-evm.dts | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts index ddd897556e03..478434ebff92 100644 --- a/arch/arm/boot/dts/am335x-evm.dts +++ b/arch/arm/boot/dts/am335x-evm.dts @@ -57,6 +57,24 @@ enable-active-high; }; + /* TPS79501 */ + v1_8d_reg: fixedregulator-v1_8d { + compatible = "regulator-fixed"; + regulator-name = "v1_8d"; + vin-supply = <&vbat>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + /* TPS79501 */ + v3_3d_reg: fixedregulator-v3_3d { + compatible = "regulator-fixed"; + regulator-name = "v3_3d"; + vin-supply = <&vbat>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + matrix_keypad: matrix_keypad0 { compatible = "gpio-matrix-keypad"; debounce-delay-ms = <5>; @@ -492,10 +510,10 @@ status = "okay"; /* Regulators */ - AVDD-supply = <&vaux2_reg>; - IOVDD-supply = <&vaux2_reg>; - DRVDD-supply = <&vaux2_reg>; - DVDD-supply = <&vbat>; + AVDD-supply = <&v3_3d_reg>; + IOVDD-supply = <&v3_3d_reg>; + DRVDD-supply = <&v3_3d_reg>; + DVDD-supply = <&v1_8d_reg>; }; }; -- GitLab From 377b54a6fb64e026ead623dbeb8c814b5bd934b0 Mon Sep 17 00:00:00 2001 From: David Engraf Date: Mon, 11 Mar 2019 08:57:42 +0100 Subject: [PATCH 0065/1121] ARM: dts: at91: Fix typo in ISC_D0 on PC9 commit e7dfb6d04e4715be1f3eb2c60d97b753fd2e4516 upstream. The function argument for the ISC_D0 on PC9 was incorrect. According to the documentation it should be 'C' aka 3. Signed-off-by: David Engraf Reviewed-by: Nicolas Ferre Signed-off-by: Ludovic Desroches Fixes: 7f16cb676c00 ("ARM: at91/dt: add sama5d2 pinmux") Cc: # v4.4+ Signed-off-by: Greg Kroah-Hartman --- arch/arm/boot/dts/sama5d2-pinfunc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/sama5d2-pinfunc.h b/arch/arm/boot/dts/sama5d2-pinfunc.h index e57191fb83de..9daa6dfd71e0 100644 --- a/arch/arm/boot/dts/sama5d2-pinfunc.h +++ b/arch/arm/boot/dts/sama5d2-pinfunc.h @@ -518,7 +518,7 @@ #define PIN_PC9__GPIO PINMUX_PIN(PIN_PC9, 0, 0) #define PIN_PC9__FIQ PINMUX_PIN(PIN_PC9, 1, 3) #define PIN_PC9__GTSUCOMP PINMUX_PIN(PIN_PC9, 2, 1) -#define PIN_PC9__ISC_D0 PINMUX_PIN(PIN_PC9, 2, 1) +#define PIN_PC9__ISC_D0 PINMUX_PIN(PIN_PC9, 3, 1) #define PIN_PC9__TIOA4 PINMUX_PIN(PIN_PC9, 4, 2) #define PIN_PC10 74 #define PIN_PC10__GPIO PINMUX_PIN(PIN_PC10, 0, 0) -- GitLab From b8dba39c7a29f7651ad8e61fe0737d7c1ba42225 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Mon, 8 Apr 2019 12:45:09 +0100 Subject: [PATCH 0066/1121] arm64: futex: Fix FUTEX_WAKE_OP atomic ops with non-zero result value commit 045afc24124d80c6998d9c770844c67912083506 upstream. Rather embarrassingly, our futex() FUTEX_WAKE_OP implementation doesn't explicitly set the return value on the non-faulting path and instead leaves it holding the result of the underlying atomic operation. This means that any FUTEX_WAKE_OP atomic operation which computes a non-zero value will be reported as having failed. Regrettably, I wrote the buggy code back in 2011 and it was upstreamed as part of the initial arm64 support in 2012. The reasons we appear to get away with this are: 1. FUTEX_WAKE_OP is rarely used and therefore doesn't appear to get exercised by futex() test applications 2. If the result of the atomic operation is zero, the system call behaves correctly 3. Prior to version 2.25, the only operation used by GLIBC set the futex to zero, and therefore worked as expected. From 2.25 onwards, FUTEX_WAKE_OP is not used by GLIBC at all. Fix the implementation by ensuring that the return value is either 0 to indicate that the atomic operation completed successfully, or -EFAULT if we encountered a fault when accessing the user mapping. Cc: Fixes: 6170a97460db ("arm64: Atomic operations") Signed-off-by: Will Deacon Signed-off-by: Greg Kroah-Hartman --- arch/arm64/include/asm/futex.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/arm64/include/asm/futex.h b/arch/arm64/include/asm/futex.h index 07fe2479d310..b447b4db423a 100644 --- a/arch/arm64/include/asm/futex.h +++ b/arch/arm64/include/asm/futex.h @@ -30,8 +30,8 @@ do { \ " prfm pstl1strm, %2\n" \ "1: ldxr %w1, %2\n" \ insn "\n" \ -"2: stlxr %w3, %w0, %2\n" \ -" cbnz %w3, 1b\n" \ +"2: stlxr %w0, %w3, %2\n" \ +" cbnz %w0, 1b\n" \ " dmb ish\n" \ "3:\n" \ " .pushsection .fixup,\"ax\"\n" \ @@ -50,30 +50,30 @@ do { \ static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *_uaddr) { - int oldval = 0, ret, tmp; + int oldval, ret, tmp; u32 __user *uaddr = __uaccess_mask_ptr(_uaddr); pagefault_disable(); switch (op) { case FUTEX_OP_SET: - __futex_atomic_op("mov %w0, %w4", + __futex_atomic_op("mov %w3, %w4", ret, oldval, uaddr, tmp, oparg); break; case FUTEX_OP_ADD: - __futex_atomic_op("add %w0, %w1, %w4", + __futex_atomic_op("add %w3, %w1, %w4", ret, oldval, uaddr, tmp, oparg); break; case FUTEX_OP_OR: - __futex_atomic_op("orr %w0, %w1, %w4", + __futex_atomic_op("orr %w3, %w1, %w4", ret, oldval, uaddr, tmp, oparg); break; case FUTEX_OP_ANDN: - __futex_atomic_op("and %w0, %w1, %w4", + __futex_atomic_op("and %w3, %w1, %w4", ret, oldval, uaddr, tmp, ~oparg); break; case FUTEX_OP_XOR: - __futex_atomic_op("eor %w0, %w1, %w4", + __futex_atomic_op("eor %w3, %w1, %w4", ret, oldval, uaddr, tmp, oparg); break; default: -- GitLab From 9e5c0620db8bda12c235548a891f0aadb93ed5a2 Mon Sep 17 00:00:00 2001 From: Peter Geis Date: Wed, 13 Mar 2019 18:45:36 +0000 Subject: [PATCH 0067/1121] arm64: dts: rockchip: fix rk3328 rgmii high tx error rate commit 6fd8b9780ec1a49ac46e0aaf8775247205e66231 upstream. Several rk3328 based boards experience high rgmii tx error rates. This is due to several pins in the rk3328.dtsi rgmii pinmux that are missing a defined pull strength setting. This causes the pinmux driver to default to 2ma (bit mask 00). These pins are only defined in the rk3328.dtsi, and are not listed in the rk3328 specification. The TRM only lists them as "Reserved" (RK3328 TRM V1.1, 3.3.3 Detail Register Description, GRF_GPIO0B_IOMUX, GRF_GPIO0C_IOMUX, GRF_GPIO0D_IOMUX). However, removal of these pins from the rgmii pinmux definition causes the interface to fail to transmit. Also, the rgmii tx and rx pins defined in the dtsi are not consistent with the rk3328 specification, with tx pins currently set to 12ma and rx pins set to 2ma. Fix this by setting tx pins to 8ma and the rx pins to 4ma, consistent with the specification. Defining the drive strength for the undefined pins eliminated the high tx packet error rate observed under heavy data transfers. Aligning the drive strength to the TRM values eliminated the occasional packet retry errors under iperf3 testing. This allows much higher data rates with no recorded tx errors. Tested on the rk3328-roc-cc board. Fixes: 52e02d377a72 ("arm64: dts: rockchip: add core dtsi file for RK3328 SoCs") Cc: stable@vger.kernel.org Signed-off-by: Peter Geis Signed-off-by: Heiko Stuebner Signed-off-by: Greg Kroah-Hartman --- arch/arm64/boot/dts/rockchip/rk3328.dtsi | 44 ++++++++++++------------ 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi index cd67c65b3a47..f6b4b8f0260f 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi @@ -1530,50 +1530,50 @@ rgmiim1_pins: rgmiim1-pins { rockchip,pins = /* mac_txclk */ - <1 RK_PB4 2 &pcfg_pull_none_12ma>, + <1 RK_PB4 2 &pcfg_pull_none_8ma>, /* mac_rxclk */ - <1 RK_PB5 2 &pcfg_pull_none_2ma>, + <1 RK_PB5 2 &pcfg_pull_none_4ma>, /* mac_mdio */ - <1 RK_PC3 2 &pcfg_pull_none_2ma>, + <1 RK_PC3 2 &pcfg_pull_none_4ma>, /* mac_txen */ - <1 RK_PD1 2 &pcfg_pull_none_12ma>, + <1 RK_PD1 2 &pcfg_pull_none_8ma>, /* mac_clk */ - <1 RK_PC5 2 &pcfg_pull_none_2ma>, + <1 RK_PC5 2 &pcfg_pull_none_4ma>, /* mac_rxdv */ - <1 RK_PC6 2 &pcfg_pull_none_2ma>, + <1 RK_PC6 2 &pcfg_pull_none_4ma>, /* mac_mdc */ - <1 RK_PC7 2 &pcfg_pull_none_2ma>, + <1 RK_PC7 2 &pcfg_pull_none_4ma>, /* mac_rxd1 */ - <1 RK_PB2 2 &pcfg_pull_none_2ma>, + <1 RK_PB2 2 &pcfg_pull_none_4ma>, /* mac_rxd0 */ - <1 RK_PB3 2 &pcfg_pull_none_2ma>, + <1 RK_PB3 2 &pcfg_pull_none_4ma>, /* mac_txd1 */ - <1 RK_PB0 2 &pcfg_pull_none_12ma>, + <1 RK_PB0 2 &pcfg_pull_none_8ma>, /* mac_txd0 */ - <1 RK_PB1 2 &pcfg_pull_none_12ma>, + <1 RK_PB1 2 &pcfg_pull_none_8ma>, /* mac_rxd3 */ - <1 RK_PB6 2 &pcfg_pull_none_2ma>, + <1 RK_PB6 2 &pcfg_pull_none_4ma>, /* mac_rxd2 */ - <1 RK_PB7 2 &pcfg_pull_none_2ma>, + <1 RK_PB7 2 &pcfg_pull_none_4ma>, /* mac_txd3 */ - <1 RK_PC0 2 &pcfg_pull_none_12ma>, + <1 RK_PC0 2 &pcfg_pull_none_8ma>, /* mac_txd2 */ - <1 RK_PC1 2 &pcfg_pull_none_12ma>, + <1 RK_PC1 2 &pcfg_pull_none_8ma>, /* mac_txclk */ - <0 RK_PB0 1 &pcfg_pull_none>, + <0 RK_PB0 1 &pcfg_pull_none_8ma>, /* mac_txen */ - <0 RK_PB4 1 &pcfg_pull_none>, + <0 RK_PB4 1 &pcfg_pull_none_8ma>, /* mac_clk */ - <0 RK_PD0 1 &pcfg_pull_none>, + <0 RK_PD0 1 &pcfg_pull_none_4ma>, /* mac_txd1 */ - <0 RK_PC0 1 &pcfg_pull_none>, + <0 RK_PC0 1 &pcfg_pull_none_8ma>, /* mac_txd0 */ - <0 RK_PC1 1 &pcfg_pull_none>, + <0 RK_PC1 1 &pcfg_pull_none_8ma>, /* mac_txd3 */ - <0 RK_PC7 1 &pcfg_pull_none>, + <0 RK_PC7 1 &pcfg_pull_none_8ma>, /* mac_txd2 */ - <0 RK_PC6 1 &pcfg_pull_none>; + <0 RK_PC6 1 &pcfg_pull_none_8ma>; }; rmiim1_pins: rmiim1-pins { -- GitLab From 6ed78eba4b5474add9c534f25f0dfdfd5a8df38d Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Mon, 8 Apr 2019 17:56:34 +0100 Subject: [PATCH 0068/1121] arm64: backtrace: Don't bother trying to unwind the userspace stack commit 1e6f5440a6814d28c32d347f338bfef68bc3e69d upstream. Calling dump_backtrace() with a pt_regs argument corresponding to userspace doesn't make any sense and our unwinder will simply print "Call trace:" before unwinding the stack looking for user frames. Rather than go through this song and dance, just return early if we're passed a user register state. Cc: Fixes: 1149aad10b1e ("arm64: Add dump_backtrace() in show_regs") Reported-by: Kefeng Wang Signed-off-by: Will Deacon Signed-off-by: Greg Kroah-Hartman --- arch/arm64/kernel/traps.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index 4fc0e958770b..4cacc33d07ce 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -145,10 +145,16 @@ static void dump_instr(const char *lvl, struct pt_regs *regs) void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) { struct stackframe frame; - int skip; + int skip = 0; pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk); + if (regs) { + if (user_mode(regs)) + return; + skip = 1; + } + if (!tsk) tsk = current; @@ -169,7 +175,6 @@ void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) frame.graph = tsk->curr_ret_stack; #endif - skip = !!regs; printk("Call trace:\n"); while (1) { unsigned long stack; @@ -232,15 +237,13 @@ static int __die(const char *str, int err, struct pt_regs *regs) return ret; print_modules(); - __show_regs(regs); pr_emerg("Process %.*s (pid: %d, stack limit = 0x%p)\n", TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), end_of_stack(tsk)); + show_regs(regs); - if (!user_mode(regs)) { - dump_backtrace(regs, tsk); + if (!user_mode(regs)) dump_instr(KERN_EMERG, regs); - } return ret; } -- GitLab From 4f0b27cf8a73e8dbc35347891202929b0d202ba0 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 4 Apr 2019 18:12:17 +0300 Subject: [PATCH 0069/1121] xen: Prevent buffer overflow in privcmd ioctl commit 42d8644bd77dd2d747e004e367cb0c895a606f39 upstream. The "call" variable comes from the user in privcmd_ioctl_hypercall(). It's an offset into the hypercall_page[] which has (PAGE_SIZE / 32) elements. We need to put an upper bound on it to prevent an out of bounds access. Cc: stable@vger.kernel.org Fixes: 1246ae0bb992 ("xen: add variable hypercall caller") Signed-off-by: Dan Carpenter Reviewed-by: Boris Ostrovsky Signed-off-by: Juergen Gross Signed-off-by: Greg Kroah-Hartman --- arch/x86/include/asm/xen/hypercall.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h index bfd882617613..e7e625448008 100644 --- a/arch/x86/include/asm/xen/hypercall.h +++ b/arch/x86/include/asm/xen/hypercall.h @@ -217,6 +217,9 @@ privcmd_call(unsigned call, __HYPERCALL_DECLS; __HYPERCALL_5ARG(a1, a2, a3, a4, a5); + if (call >= PAGE_SIZE / sizeof(hypercall_page[0])) + return -EINVAL; + stac(); asm volatile(CALL_NOSPEC : __HYPERCALL_5PARAM -- GitLab From b711ae1252a072ed600fee34d0e06230fda0a1f4 Mon Sep 17 00:00:00 2001 From: Mel Gorman Date: Tue, 19 Mar 2019 12:36:10 +0000 Subject: [PATCH 0070/1121] sched/fair: Do not re-read ->h_load_next during hierarchical load calculation commit 0e9f02450da07fc7b1346c8c32c771555173e397 upstream. A NULL pointer dereference bug was reported on a distribution kernel but the same issue should be present on mainline kernel. It occured on s390 but should not be arch-specific. A partial oops looks like: Unable to handle kernel pointer dereference in virtual kernel address space ... Call Trace: ... try_to_wake_up+0xfc/0x450 vhost_poll_wakeup+0x3a/0x50 [vhost] __wake_up_common+0xbc/0x178 __wake_up_common_lock+0x9e/0x160 __wake_up_sync_key+0x4e/0x60 sock_def_readable+0x5e/0x98 The bug hits any time between 1 hour to 3 days. The dereference occurs in update_cfs_rq_h_load when accumulating h_load. The problem is that cfq_rq->h_load_next is not protected by any locking and can be updated by parallel calls to task_h_load. Depending on the compiler, code may be generated that re-reads cfq_rq->h_load_next after the check for NULL and then oops when reading se->avg.load_avg. The dissassembly showed that it was possible to reread h_load_next after the check for NULL. While this does not appear to be an issue for later compilers, it's still an accident if the correct code is generated. Full locking in this path would have high overhead so this patch uses READ_ONCE to read h_load_next only once and check for NULL before dereferencing. It was confirmed that there were no further oops after 10 days of testing. As Peter pointed out, it is also necessary to use WRITE_ONCE() to avoid any potential problems with store tearing. Signed-off-by: Mel Gorman Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Valentin Schneider Cc: Linus Torvalds Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: Fixes: 685207963be9 ("sched: Move h_load calculation to task_h_load()") Link: https://lkml.kernel.org/r/20190319123610.nsivgf3mjbjjesxb@techsingularity.net Signed-off-by: Ingo Molnar Signed-off-by: Greg Kroah-Hartman --- kernel/sched/fair.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 4d54c1fe9623..9829ede00498 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -7018,10 +7018,10 @@ static void update_cfs_rq_h_load(struct cfs_rq *cfs_rq) if (cfs_rq->last_h_load_update == now) return; - cfs_rq->h_load_next = NULL; + WRITE_ONCE(cfs_rq->h_load_next, NULL); for_each_sched_entity(se) { cfs_rq = cfs_rq_of(se); - cfs_rq->h_load_next = se; + WRITE_ONCE(cfs_rq->h_load_next, se); if (cfs_rq->last_h_load_update == now) break; } @@ -7031,7 +7031,7 @@ static void update_cfs_rq_h_load(struct cfs_rq *cfs_rq) cfs_rq->last_h_load_update = now; } - while ((se = cfs_rq->h_load_next) != NULL) { + while ((se = READ_ONCE(cfs_rq->h_load_next)) != NULL) { load = cfs_rq->h_load; load = div64_ul(load * se->avg.load_avg, cfs_rq_load_avg(cfs_rq) + 1); -- GitLab From 9ab04e849f5b6c2d679a5ae383187997e7e98232 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Thu, 4 Apr 2019 11:08:40 -0700 Subject: [PATCH 0071/1121] xtensa: fix return_address commit ada770b1e74a77fff2d5f539bf6c42c25f4784db upstream. return_address returns the address that is one level higher in the call stack than requested in its argument, because level 0 corresponds to its caller's return address. Use requested level as the number of stack frames to skip. This fixes the address reported by might_sleep and friends. Cc: stable@vger.kernel.org Signed-off-by: Max Filippov Signed-off-by: Greg Kroah-Hartman --- arch/xtensa/kernel/stacktrace.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/xtensa/kernel/stacktrace.c b/arch/xtensa/kernel/stacktrace.c index 0df4080fa20f..a94da7dd3eae 100644 --- a/arch/xtensa/kernel/stacktrace.c +++ b/arch/xtensa/kernel/stacktrace.c @@ -253,10 +253,14 @@ static int return_address_cb(struct stackframe *frame, void *data) return 1; } +/* + * level == 0 is for the return address from the caller of this function, + * not from this function itself. + */ unsigned long return_address(unsigned level) { struct return_addr_data r = { - .skip = level + 1, + .skip = level, }; walk_stackframe(stack_pointer(NULL), return_address_cb, &r); return r.addr; -- GitLab From 58d78a4342ff61a15025283f28ebb390773e7ad8 Mon Sep 17 00:00:00 2001 From: "Lendacky, Thomas" Date: Tue, 2 Apr 2019 15:21:14 +0000 Subject: [PATCH 0072/1121] x86/perf/amd: Resolve race condition when disabling PMC commit 914123fa39042e651d79eaf86bbf63a1b938dddf upstream. On AMD processors, the detection of an overflowed counter in the NMI handler relies on the current value of the counter. So, for example, to check for overflow on a 48 bit counter, bit 47 is checked to see if it is 1 (not overflowed) or 0 (overflowed). There is currently a race condition present when disabling and then updating the PMC. Increased NMI latency in newer AMD processors makes this race condition more pronounced. If the counter value has overflowed, it is possible to update the PMC value before the NMI handler can run. The updated PMC value is not an overflowed value, so when the perf NMI handler does run, it will not find an overflowed counter. This may appear as an unknown NMI resulting in either a panic or a series of messages, depending on how the kernel is configured. To eliminate this race condition, the PMC value must be checked after disabling the counter. Add an AMD function, amd_pmu_disable_all(), that will wait for the NMI handler to reset any active and overflowed counter after calling x86_pmu_disable_all(). Signed-off-by: Tom Lendacky Signed-off-by: Peter Zijlstra (Intel) Cc: # 4.14.x- Cc: Alexander Shishkin Cc: Arnaldo Carvalho de Melo Cc: Arnaldo Carvalho de Melo Cc: Borislav Petkov Cc: Jiri Olsa Cc: Linus Torvalds Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Vince Weaver Link: https://lkml.kernel.org/r/Message-ID: Signed-off-by: Ingo Molnar Signed-off-by: Greg Kroah-Hartman --- arch/x86/events/amd/core.c | 65 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 3 deletions(-) diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c index c84584bb9402..67f7f2525c8c 100644 --- a/arch/x86/events/amd/core.c +++ b/arch/x86/events/amd/core.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include "../perf_event.h" @@ -429,6 +430,64 @@ static void amd_pmu_cpu_dead(int cpu) } } +/* + * When a PMC counter overflows, an NMI is used to process the event and + * reset the counter. NMI latency can result in the counter being updated + * before the NMI can run, which can result in what appear to be spurious + * NMIs. This function is intended to wait for the NMI to run and reset + * the counter to avoid possible unhandled NMI messages. + */ +#define OVERFLOW_WAIT_COUNT 50 + +static void amd_pmu_wait_on_overflow(int idx) +{ + unsigned int i; + u64 counter; + + /* + * Wait for the counter to be reset if it has overflowed. This loop + * should exit very, very quickly, but just in case, don't wait + * forever... + */ + for (i = 0; i < OVERFLOW_WAIT_COUNT; i++) { + rdmsrl(x86_pmu_event_addr(idx), counter); + if (counter & (1ULL << (x86_pmu.cntval_bits - 1))) + break; + + /* Might be in IRQ context, so can't sleep */ + udelay(1); + } +} + +static void amd_pmu_disable_all(void) +{ + struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); + int idx; + + x86_pmu_disable_all(); + + /* + * This shouldn't be called from NMI context, but add a safeguard here + * to return, since if we're in NMI context we can't wait for an NMI + * to reset an overflowed counter value. + */ + if (in_nmi()) + return; + + /* + * Check each counter for overflow and wait for it to be reset by the + * NMI if it has overflowed. This relies on the fact that all active + * counters are always enabled when this function is caled and + * ARCH_PERFMON_EVENTSEL_INT is always set. + */ + for (idx = 0; idx < x86_pmu.num_counters; idx++) { + if (!test_bit(idx, cpuc->active_mask)) + continue; + + amd_pmu_wait_on_overflow(idx); + } +} + static struct event_constraint * amd_get_event_constraints(struct cpu_hw_events *cpuc, int idx, struct perf_event *event) @@ -622,7 +681,7 @@ static ssize_t amd_event_sysfs_show(char *page, u64 config) static __initconst const struct x86_pmu amd_pmu = { .name = "AMD", .handle_irq = x86_pmu_handle_irq, - .disable_all = x86_pmu_disable_all, + .disable_all = amd_pmu_disable_all, .enable_all = x86_pmu_enable_all, .enable = x86_pmu_enable_event, .disable = x86_pmu_disable_event, @@ -728,7 +787,7 @@ void amd_pmu_enable_virt(void) cpuc->perf_ctr_virt_mask = 0; /* Reload all events */ - x86_pmu_disable_all(); + amd_pmu_disable_all(); x86_pmu_enable_all(0); } EXPORT_SYMBOL_GPL(amd_pmu_enable_virt); @@ -746,7 +805,7 @@ void amd_pmu_disable_virt(void) cpuc->perf_ctr_virt_mask = AMD64_EVENTSEL_HOSTONLY; /* Reload all events */ - x86_pmu_disable_all(); + amd_pmu_disable_all(); x86_pmu_enable_all(0); } EXPORT_SYMBOL_GPL(amd_pmu_disable_virt); -- GitLab From b09d75485316570a05209ddc8fa23e3a998f4cc2 Mon Sep 17 00:00:00 2001 From: "Lendacky, Thomas" Date: Tue, 2 Apr 2019 15:21:16 +0000 Subject: [PATCH 0073/1121] x86/perf/amd: Resolve NMI latency issues for active PMCs commit 6d3edaae16c6c7d238360f2841212c2b26774d5e upstream. On AMD processors, the detection of an overflowed PMC counter in the NMI handler relies on the current value of the PMC. So, for example, to check for overflow on a 48-bit counter, bit 47 is checked to see if it is 1 (not overflowed) or 0 (overflowed). When the perf NMI handler executes it does not know in advance which PMC counters have overflowed. As such, the NMI handler will process all active PMC counters that have overflowed. NMI latency in newer AMD processors can result in multiple overflowed PMC counters being processed in one NMI and then a subsequent NMI, that does not appear to be a back-to-back NMI, not finding any PMC counters that have overflowed. This may appear to be an unhandled NMI resulting in either a panic or a series of messages, depending on how the kernel was configured. To mitigate this issue, add an AMD handle_irq callback function, amd_pmu_handle_irq(), that will invoke the common x86_pmu_handle_irq() function and upon return perform some additional processing that will indicate if the NMI has been handled or would have been handled had an earlier NMI not handled the overflowed PMC. Using a per-CPU variable, a minimum value of the number of active PMCs or 2 will be set whenever a PMC is active. This is used to indicate the possible number of NMIs that can still occur. The value of 2 is used for when an NMI does not arrive at the LAPIC in time to be collapsed into an already pending NMI. Each time the function is called without having handled an overflowed counter, the per-CPU value is checked. If the value is non-zero, it is decremented and the NMI indicates that it handled the NMI. If the value is zero, then the NMI indicates that it did not handle the NMI. Signed-off-by: Tom Lendacky Signed-off-by: Peter Zijlstra (Intel) Cc: # 4.14.x- Cc: Alexander Shishkin Cc: Arnaldo Carvalho de Melo Cc: Arnaldo Carvalho de Melo Cc: Borislav Petkov Cc: Jiri Olsa Cc: Linus Torvalds Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Vince Weaver Link: https://lkml.kernel.org/r/Message-ID: Signed-off-by: Ingo Molnar Signed-off-by: Greg Kroah-Hartman --- arch/x86/events/amd/core.c | 56 +++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c index 67f7f2525c8c..9ceab2a8869d 100644 --- a/arch/x86/events/amd/core.c +++ b/arch/x86/events/amd/core.c @@ -4,10 +4,13 @@ #include #include #include +#include #include #include "../perf_event.h" +static DEFINE_PER_CPU(unsigned int, perf_nmi_counter); + static __initconst const u64 amd_hw_cache_event_ids [PERF_COUNT_HW_CACHE_MAX] [PERF_COUNT_HW_CACHE_OP_MAX] @@ -488,6 +491,57 @@ static void amd_pmu_disable_all(void) } } +/* + * Because of NMI latency, if multiple PMC counters are active or other sources + * of NMIs are received, the perf NMI handler can handle one or more overflowed + * PMC counters outside of the NMI associated with the PMC overflow. If the NMI + * doesn't arrive at the LAPIC in time to become a pending NMI, then the kernel + * back-to-back NMI support won't be active. This PMC handler needs to take into + * account that this can occur, otherwise this could result in unknown NMI + * messages being issued. Examples of this is PMC overflow while in the NMI + * handler when multiple PMCs are active or PMC overflow while handling some + * other source of an NMI. + * + * Attempt to mitigate this by using the number of active PMCs to determine + * whether to return NMI_HANDLED if the perf NMI handler did not handle/reset + * any PMCs. The per-CPU perf_nmi_counter variable is set to a minimum of the + * number of active PMCs or 2. The value of 2 is used in case an NMI does not + * arrive at the LAPIC in time to be collapsed into an already pending NMI. + */ +static int amd_pmu_handle_irq(struct pt_regs *regs) +{ + struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); + int active, handled; + + /* + * Obtain the active count before calling x86_pmu_handle_irq() since + * it is possible that x86_pmu_handle_irq() may make a counter + * inactive (through x86_pmu_stop). + */ + active = __bitmap_weight(cpuc->active_mask, X86_PMC_IDX_MAX); + + /* Process any counter overflows */ + handled = x86_pmu_handle_irq(regs); + + /* + * If a counter was handled, record the number of possible remaining + * NMIs that can occur. + */ + if (handled) { + this_cpu_write(perf_nmi_counter, + min_t(unsigned int, 2, active)); + + return handled; + } + + if (!this_cpu_read(perf_nmi_counter)) + return NMI_DONE; + + this_cpu_dec(perf_nmi_counter); + + return NMI_HANDLED; +} + static struct event_constraint * amd_get_event_constraints(struct cpu_hw_events *cpuc, int idx, struct perf_event *event) @@ -680,7 +734,7 @@ static ssize_t amd_event_sysfs_show(char *page, u64 config) static __initconst const struct x86_pmu amd_pmu = { .name = "AMD", - .handle_irq = x86_pmu_handle_irq, + .handle_irq = amd_pmu_handle_irq, .disable_all = amd_pmu_disable_all, .enable_all = x86_pmu_enable_all, .enable = x86_pmu_enable_event, -- GitLab From 52abad475c06b54bbd009927aac56ff15f5c2552 Mon Sep 17 00:00:00 2001 From: "Lendacky, Thomas" Date: Tue, 2 Apr 2019 15:21:18 +0000 Subject: [PATCH 0074/1121] x86/perf/amd: Remove need to check "running" bit in NMI handler commit 3966c3feca3fd10b2935caa0b4a08c7dd59469e5 upstream. Spurious interrupt support was added to perf in the following commit, almost a decade ago: 63e6be6d98e1 ("perf, x86: Catch spurious interrupts after disabling counters") The two previous patches (resolving the race condition when disabling a PMC and NMI latency mitigation) allow for the removal of this older spurious interrupt support. Currently in x86_pmu_stop(), the bit for the PMC in the active_mask bitmap is cleared before disabling the PMC, which sets up a race condition. This race condition was mitigated by introducing the running bitmap. That race condition can be eliminated by first disabling the PMC, waiting for PMC reset on overflow and then clearing the bit for the PMC in the active_mask bitmap. The NMI handler will not re-enable a disabled counter. If x86_pmu_stop() is called from the perf NMI handler, the NMI latency mitigation support will guard against any unhandled NMI messages. Signed-off-by: Tom Lendacky Signed-off-by: Peter Zijlstra (Intel) Cc: # 4.14.x- Cc: Alexander Shishkin Cc: Arnaldo Carvalho de Melo Cc: Arnaldo Carvalho de Melo Cc: Borislav Petkov Cc: Jiri Olsa Cc: Linus Torvalds Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Vince Weaver Link: https://lkml.kernel.org/r/Message-ID: Signed-off-by: Ingo Molnar Signed-off-by: Greg Kroah-Hartman --- arch/x86/events/amd/core.c | 21 +++++++++++++++++++-- arch/x86/events/core.c | 13 +++---------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c index 9ceab2a8869d..3e5dd85b019a 100644 --- a/arch/x86/events/amd/core.c +++ b/arch/x86/events/amd/core.c @@ -4,8 +4,8 @@ #include #include #include -#include #include +#include #include "../perf_event.h" @@ -491,6 +491,23 @@ static void amd_pmu_disable_all(void) } } +static void amd_pmu_disable_event(struct perf_event *event) +{ + x86_pmu_disable_event(event); + + /* + * This can be called from NMI context (via x86_pmu_stop). The counter + * may have overflowed, but either way, we'll never see it get reset + * by the NMI if we're already in the NMI. And the NMI latency support + * below will take care of any pending NMI that might have been + * generated by the overflow. + */ + if (in_nmi()) + return; + + amd_pmu_wait_on_overflow(event->hw.idx); +} + /* * Because of NMI latency, if multiple PMC counters are active or other sources * of NMIs are received, the perf NMI handler can handle one or more overflowed @@ -738,7 +755,7 @@ static __initconst const struct x86_pmu amd_pmu = { .disable_all = amd_pmu_disable_all, .enable_all = x86_pmu_enable_all, .enable = x86_pmu_enable_event, - .disable = x86_pmu_disable_event, + .disable = amd_pmu_disable_event, .hw_config = amd_pmu_hw_config, .schedule_events = x86_schedule_events, .eventsel = MSR_K7_EVNTSEL0, diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c index 65e44f0588e2..6ed99de2ddf5 100644 --- a/arch/x86/events/core.c +++ b/arch/x86/events/core.c @@ -1328,8 +1328,9 @@ void x86_pmu_stop(struct perf_event *event, int flags) struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); struct hw_perf_event *hwc = &event->hw; - if (__test_and_clear_bit(hwc->idx, cpuc->active_mask)) { + if (test_bit(hwc->idx, cpuc->active_mask)) { x86_pmu.disable(event); + __clear_bit(hwc->idx, cpuc->active_mask); cpuc->events[hwc->idx] = NULL; WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED); hwc->state |= PERF_HES_STOPPED; @@ -1426,16 +1427,8 @@ int x86_pmu_handle_irq(struct pt_regs *regs) apic_write(APIC_LVTPC, APIC_DM_NMI); for (idx = 0; idx < x86_pmu.num_counters; idx++) { - if (!test_bit(idx, cpuc->active_mask)) { - /* - * Though we deactivated the counter some cpus - * might still deliver spurious interrupts still - * in flight. Catch them: - */ - if (__test_and_clear_bit(idx, cpuc->running)) - handled++; + if (!test_bit(idx, cpuc->active_mask)) continue; - } event = cpuc->events[idx]; -- GitLab From 5b5832ca0c6f7a8de496db56509c2e56721bcb12 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 5 Apr 2019 16:20:47 +0100 Subject: [PATCH 0075/1121] PCI: Add function 1 DMA alias quirk for Marvell 9170 SATA controller commit 9cde402a59770a0669d895399c13407f63d7d209 upstream. There is a Marvell 88SE9170 PCIe SATA controller I found on a board here. Some quick testing with the ARM SMMU enabled reveals that it suffers from the same requester ID mixup problems as the other Marvell chips listed already. Add the PCI vendor/device ID to the list of chips which need the workaround. Signed-off-by: Andre Przywara Signed-off-by: Bjorn Helgaas CC: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/pci/quirks.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index d442afa195ab..867056395d48 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -3888,6 +3888,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9128, /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c14 */ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9130, quirk_dma_func1_alias); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9170, + quirk_dma_func1_alias); /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c47 + c57 */ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9172, quirk_dma_func1_alias); -- GitLab From 2f51343153e69aad32e0520bd1e77bcc315b6d16 Mon Sep 17 00:00:00 2001 From: Ilya Dryomov Date: Tue, 26 Mar 2019 20:20:58 +0100 Subject: [PATCH 0076/1121] dm table: propagate BDI_CAP_STABLE_WRITES to fix sporadic checksum errors commit eb40c0acdc342b815d4d03ae6abb09e80c0f2988 upstream. Some devices don't use blk_integrity but still want stable pages because they do their own checksumming. Examples include rbd and iSCSI when data digests are negotiated. Stacking DM (and thus LVM) on top of these devices results in sporadic checksum errors. Set BDI_CAP_STABLE_WRITES if any underlying device has it set. Cc: stable@vger.kernel.org Signed-off-by: Ilya Dryomov Signed-off-by: Mike Snitzer Signed-off-by: Greg Kroah-Hartman --- drivers/md/dm-table.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index f9cd81375f28..d76e685206b3 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -1789,6 +1789,36 @@ static bool dm_table_supports_discards(struct dm_table *t) return true; } +static int device_requires_stable_pages(struct dm_target *ti, + struct dm_dev *dev, sector_t start, + sector_t len, void *data) +{ + struct request_queue *q = bdev_get_queue(dev->bdev); + + return q && bdi_cap_stable_pages_required(q->backing_dev_info); +} + +/* + * If any underlying device requires stable pages, a table must require + * them as well. Only targets that support iterate_devices are considered: + * don't want error, zero, etc to require stable pages. + */ +static bool dm_table_requires_stable_pages(struct dm_table *t) +{ + struct dm_target *ti; + unsigned i; + + for (i = 0; i < dm_table_get_num_targets(t); i++) { + ti = dm_table_get_target(t, i); + + if (ti->type->iterate_devices && + ti->type->iterate_devices(ti, device_requires_stable_pages, NULL)) + return true; + } + + return false; +} + void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, struct queue_limits *limits) { @@ -1837,6 +1867,15 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, dm_table_verify_integrity(t); + /* + * Some devices don't use blk_integrity but still want stable pages + * because they do their own checksumming. + */ + if (dm_table_requires_stable_pages(t)) + q->backing_dev_info->capabilities |= BDI_CAP_STABLE_WRITES; + else + q->backing_dev_info->capabilities &= ~BDI_CAP_STABLE_WRITES; + /* * Determine whether or not this queue's I/O timings contribute * to the entropy pool, Only request-based targets use this. -- GitLab From 1debe428dd6d56114abe3333f245c58ac64d89c1 Mon Sep 17 00:00:00 2001 From: Katsuhiro Suzuki Date: Fri, 7 Sep 2018 00:39:47 +0900 Subject: [PATCH 0077/1121] arm64: dts: rockchip: fix vcc_host1_5v pin assign on rk3328-rock64 commit ef05bcb60c1a8841e38c91923ba998181117a87c upstream. This patch fixes pin assign of vcc_host1_5v. This regulator is controlled by USB20_HOST_DRV signal. ROCK64 schematic says that GPIO0_A2 pin is used as USB20_HOST_DRV. GPIO0_D3 pin is for SPDIF_TX_M0. Signed-off-by: Katsuhiro Suzuki Signed-off-by: Heiko Stuebner Signed-off-by: Greg Kroah-Hartman --- arch/arm64/boot/dts/rockchip/rk3328-rock64.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts index 28257724a56e..520cc1831158 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts @@ -83,7 +83,7 @@ vcc_host1_5v: vcc_otg_5v: vcc-host1-5v-regulator { compatible = "regulator-fixed"; enable-active-high; - gpio = <&gpio0 RK_PD3 GPIO_ACTIVE_HIGH>; + gpio = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&usb20_host_drv>; regulator-name = "vcc_host1_5v"; @@ -275,7 +275,7 @@ usb2 { usb20_host_drv: usb20-host-drv { - rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>; + rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; }; }; -- GitLab From aadf60280ad3dd71ca4867cc5de2ee7af16a2bb9 Mon Sep 17 00:00:00 2001 From: Tomohiro Mayama Date: Sun, 10 Mar 2019 01:10:12 +0900 Subject: [PATCH 0078/1121] arm64: dts: rockchip: Fix vcc_host1_5v GPIO polarity on rk3328-rock64 commit a8772e5d826d0f61f8aa9c284b3ab49035d5273d upstream. This patch makes USB ports functioning again. Fixes: 955bebde057e ("arm64: dts: rockchip: add rk3328-rock64 board") Cc: stable@vger.kernel.org Suggested-by: Robin Murphy Signed-off-by: Tomohiro Mayama Tested-by: Katsuhiro Suzuki Signed-off-by: Heiko Stuebner Signed-off-by: Greg Kroah-Hartman --- arch/arm64/boot/dts/rockchip/rk3328-rock64.dts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts index 520cc1831158..e720f40bbd5d 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts @@ -82,8 +82,7 @@ vcc_host1_5v: vcc_otg_5v: vcc-host1-5v-regulator { compatible = "regulator-fixed"; - enable-active-high; - gpio = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; + gpio = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&usb20_host_drv>; regulator-name = "vcc_host1_5v"; -- GitLab From 58b454ebf81e5ae9391957d99cf89566d9eec1b1 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 17 Apr 2019 08:37:55 +0200 Subject: [PATCH 0079/1121] Linux 4.14.112 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 85753250984c..94673d2a6a27 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 4 PATCHLEVEL = 14 -SUBLEVEL = 111 +SUBLEVEL = 112 EXTRAVERSION = NAME = Petit Gorille -- GitLab From d9a62b438b481dc434a1687485f48054e8c5e3be Mon Sep 17 00:00:00 2001 From: Greg Hartman Date: Wed, 17 Apr 2019 12:58:54 -0700 Subject: [PATCH 0080/1121] Make arm64 serial port config compatible with crosvm BUG: 118442619 Test: Ran ~/bin/crosvm run --disable-sandbox ~/image, saw output Change-Id: If086af28b69eca5353a101228ae986653bc1465e Signed-off-by: Greg Hartman (cherry picked from commit 2860dfe869a94c8c1950effb55da116f83ebc740) --- arch/arm64/configs/cuttlefish_defconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig index ee06eafc68c6..6f1beae135b0 100644 --- a/arch/arm64/configs/cuttlefish_defconfig +++ b/arch/arm64/configs/cuttlefish_defconfig @@ -59,8 +59,6 @@ CONFIG_SETEND_EMULATION=y CONFIG_ARM64_SW_TTBR0_PAN=y CONFIG_ARM64_LSE_ATOMICS=y CONFIG_RANDOMIZE_BASE=y -CONFIG_CMDLINE="console=ttyAMA0" -CONFIG_CMDLINE_EXTEND=y # CONFIG_EFI is not set # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_COMPAT=y @@ -286,6 +284,7 @@ CONFIG_SERIAL_8250_NR_UARTS=48 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y CONFIG_VIRTIO_CONSOLE=y @@ -385,6 +384,7 @@ CONFIG_MMC=y # CONFIG_MMC_BLOCK is not set CONFIG_RTC_CLASS=y # CONFIG_RTC_SYSTOHC is not set +CONFIG_RTC_DRV_PL030=y CONFIG_RTC_DRV_PL031=y CONFIG_VIRTIO_PCI=y # CONFIG_VIRTIO_PCI_LEGACY is not set -- GitLab From cec361536f1eaf85788bfec8a25c7580cb809f74 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Wed, 17 Apr 2019 10:52:26 -0700 Subject: [PATCH 0081/1121] ANDROID: Makefile: Properly resolve 4.14.112 merge The merge removed commit 9ff6ab2fbc00 ("ANDROID: Kbuild, LLVMLinux: allow overriding clang target triple"). This keeps commit 1efb2caed0ad ("kbuild: clang: choose GCC_TOOLCHAIN_DIR not on LD"), which caused the conflict. Change-Id: I72b7f69204a801ff6ef6405e24317a7b08428901 Signed-off-by: Nathan Chancellor --- Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 64ae5a996767..1c7863b1276b 100644 --- a/Makefile +++ b/Makefile @@ -480,7 +480,11 @@ endif ifeq ($(cc-name),clang) ifneq ($(CROSS_COMPILE),) -CLANG_FLAGS := --target=$(notdir $(CROSS_COMPILE:%-=%)) +CLANG_TRIPLE ?= $(CROSS_COMPILE) +CLANG_FLAGS := --target=$(notdir $(CLANG_TRIPLE:%-=%)) +ifeq ($(shell $(srctree)/scripts/clang-android.sh $(CC) $(CLANG_FLAGS)), y) +$(error "Clang with Android --target detected. Did you specify CLANG_TRIPLE?") +endif GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE)elfedit)) CLANG_FLAGS += --prefix=$(GCC_TOOLCHAIN_DIR) GCC_TOOLCHAIN := $(realpath $(GCC_TOOLCHAIN_DIR)/..) -- GitLab From 4353393c9d4a13a8be013e84a7318591c5e33602 Mon Sep 17 00:00:00 2001 From: Alistair Strachan Date: Fri, 19 Apr 2019 15:36:33 -0700 Subject: [PATCH 0082/1121] ANDROID: cuttlefish_defconfig: Enable L2TP/PPTP Bug: 120439617 Bug: 130907753 Change-Id: Idac940561eb454ffaba4560e17c167409395c2a3 Signed-off-by: Alistair Strachan --- arch/x86/configs/x86_64_cuttlefish_defconfig | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig index 3af7bfc85a3f..99e766f8dac3 100644 --- a/arch/x86/configs/x86_64_cuttlefish_defconfig +++ b/arch/x86/configs/x86_64_cuttlefish_defconfig @@ -89,6 +89,7 @@ CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_MULTIPATH=y CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_NET_IPGRE_DEMUX=y CONFIG_IP_MROUTE=y CONFIG_IP_PIMSM_V1=y CONFIG_IP_PIMSM_V2=y @@ -146,6 +147,7 @@ CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y CONFIG_NETFILTER_XT_MATCH_HELPER=y CONFIG_NETFILTER_XT_MATCH_IPRANGE=y +# CONFIG_NETFILTER_XT_MATCH_L2TP is not set CONFIG_NETFILTER_XT_MATCH_LENGTH=y CONFIG_NETFILTER_XT_MATCH_LIMIT=y CONFIG_NETFILTER_XT_MATCH_MAC=y @@ -188,6 +190,7 @@ CONFIG_IP6_NF_FILTER=y CONFIG_IP6_NF_TARGET_REJECT=y CONFIG_IP6_NF_MANGLE=y CONFIG_IP6_NF_RAW=y +CONFIG_L2TP=y CONFIG_NET_SCHED=y CONFIG_NET_SCH_HTB=y CONFIG_NET_SCH_NETEM=y @@ -242,6 +245,8 @@ CONFIG_PPP=y CONFIG_PPP_BSDCOMP=y CONFIG_PPP_DEFLATE=y CONFIG_PPP_MPPE=y +CONFIG_PPTP=y +CONFIG_PPPOL2TP=y CONFIG_USB_RTL8152=y CONFIG_USB_USBNET=y # CONFIG_USB_NET_AX8817X is not set -- GitLab From 8232cdfd5643909f30abe17d8ad9d81459f7feae Mon Sep 17 00:00:00 2001 From: Eugeniy Paltsev Date: Mon, 25 Feb 2019 20:16:01 +0300 Subject: [PATCH 0083/1121] ARC: u-boot args: check that magic number is correct [ Upstream commit edb64bca50cd736c6894cc6081d5263c007ce005 ] In case of devboards we really often disable bootloader and load Linux image in memory via JTAG. Even if kernel tries to verify uboot_tag and uboot_arg there is sill a chance that we treat some garbage in registers as valid u-boot arguments in JTAG case. E.g. it is enough to have '1' in r0 to treat any value in r2 as a boot command line. So check that magic number passed from u-boot is correct and drop u-boot arguments otherwise. That helps to reduce the possibility of using garbage as u-boot arguments in JTAG case. We can safely check U-boot magic value (0x0) in linux passed via r1 register as U-boot pass it from the beginning. So there is no backward-compatibility issues. Signed-off-by: Eugeniy Paltsev Signed-off-by: Vineet Gupta Signed-off-by: Sasha Levin --- arch/arc/kernel/head.S | 1 + arch/arc/kernel/setup.c | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/arch/arc/kernel/head.S b/arch/arc/kernel/head.S index 1f945d0f40da..208bf2c9e7b0 100644 --- a/arch/arc/kernel/head.S +++ b/arch/arc/kernel/head.S @@ -107,6 +107,7 @@ ENTRY(stext) ; r2 = pointer to uboot provided cmdline or external DTB in mem ; These are handled later in handle_uboot_args() st r0, [@uboot_tag] + st r1, [@uboot_magic] st r2, [@uboot_arg] #endif diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c index 709649e5f9bc..6b8d106e0d53 100644 --- a/arch/arc/kernel/setup.c +++ b/arch/arc/kernel/setup.c @@ -35,6 +35,7 @@ unsigned int intr_to_DE_cnt; /* Part of U-boot ABI: see head.S */ int __initdata uboot_tag; +int __initdata uboot_magic; char __initdata *uboot_arg; const struct machine_desc *machine_desc; @@ -433,6 +434,8 @@ static inline bool uboot_arg_invalid(unsigned long addr) #define UBOOT_TAG_NONE 0 #define UBOOT_TAG_CMDLINE 1 #define UBOOT_TAG_DTB 2 +/* We always pass 0 as magic from U-boot */ +#define UBOOT_MAGIC_VALUE 0 void __init handle_uboot_args(void) { @@ -448,6 +451,11 @@ void __init handle_uboot_args(void) goto ignore_uboot_args; } + if (uboot_magic != UBOOT_MAGIC_VALUE) { + pr_warn(IGNORE_ARGS "non zero uboot magic\n"); + goto ignore_uboot_args; + } + if (uboot_tag != UBOOT_TAG_NONE && uboot_arg_invalid((unsigned long)uboot_arg)) { pr_warn(IGNORE_ARGS "invalid uboot arg: '%px'\n", uboot_arg); -- GitLab From 2d6453a3e9e08b40c93b1049a591c6caa5dfa06a Mon Sep 17 00:00:00 2001 From: Corentin Labbe Date: Mon, 25 Feb 2019 09:45:38 +0000 Subject: [PATCH 0084/1121] arc: hsdk_defconfig: Enable CONFIG_BLK_DEV_RAM [ Upstream commit 0728aeb7ead99a9b0dac2f3c92b3752b4e02ff97 ] We have now a HSDK device in our kernelci lab, but kernel builded via the hsdk_defconfig lacks ramfs supports, so it cannot boot kernelci jobs yet. So this patch enable CONFIG_BLK_DEV_RAM in hsdk_defconfig. Signed-off-by: Corentin Labbe Acked-by: Alexey Brodkin Signed-off-by: Vineet Gupta Signed-off-by: Sasha Levin --- arch/arc/configs/hsdk_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arc/configs/hsdk_defconfig b/arch/arc/configs/hsdk_defconfig index 083560e9e571..4dac1169f528 100644 --- a/arch/arc/configs/hsdk_defconfig +++ b/arch/arc/configs/hsdk_defconfig @@ -9,6 +9,7 @@ CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set # CONFIG_PID_NS is not set CONFIG_BLK_DEV_INITRD=y +CONFIG_BLK_DEV_RAM=y CONFIG_EMBEDDED=y CONFIG_PERF_EVENTS=y # CONFIG_VM_EVENT_COUNTERS is not set -- GitLab From 103eb70cf4eb7fb263d1e337811217e2e4c53731 Mon Sep 17 00:00:00 2001 From: Stephane Eranian Date: Thu, 7 Mar 2019 10:52:33 -0800 Subject: [PATCH 0085/1121] perf/core: Restore mmap record type correctly [ Upstream commit d9c1bb2f6a2157b38e8eb63af437cb22701d31ee ] On mmap(), perf_events generates a RECORD_MMAP record and then checks which events are interested in this record. There are currently 2 versions of mmap records: RECORD_MMAP and RECORD_MMAP2. MMAP2 is larger. The event configuration controls which version the user level tool accepts. If the event->attr.mmap2=1 field then MMAP2 record is returned. The perf_event_mmap_output() takes care of this. It checks attr->mmap2 and corrects the record fields before putting it in the sampling buffer of the event. At the end the function restores the modified MMAP record fields. The problem is that the function restores the size but not the type. Thus, if a subsequent event only accepts MMAP type, then it would instead receive an MMAP2 record with a size of MMAP record. This patch fixes the problem by restoring the record type on exit. Signed-off-by: Stephane Eranian Acked-by: Peter Zijlstra (Intel) Cc: Andi Kleen Cc: Jiri Olsa Cc: Kan Liang Fixes: 13d7a2410fa6 ("perf: Add attr->mmap2 attribute to an event") Link: http://lkml.kernel.org/r/20190307185233.225521-1-eranian@google.com Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Sasha Levin --- kernel/events/core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/events/core.c b/kernel/events/core.c index 92939b5397df..580616e6fcee 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -6923,6 +6923,7 @@ static void perf_event_mmap_output(struct perf_event *event, struct perf_output_handle handle; struct perf_sample_data sample; int size = mmap_event->event_id.header.size; + u32 type = mmap_event->event_id.header.type; int ret; if (!perf_event_mmap_match(event, data)) @@ -6966,6 +6967,7 @@ static void perf_event_mmap_output(struct perf_event *event, perf_output_end(&handle); out: mmap_event->event_id.header.size = size; + mmap_event->event_id.header.type = type; } static void perf_event_mmap_event(struct perf_mmap_event *mmap_event) -- GitLab From 7a82651d06cbaf2447f4f1193f4a7b325c1ab53a Mon Sep 17 00:00:00 2001 From: Lukas Czerner Date: Fri, 15 Mar 2019 00:15:32 -0400 Subject: [PATCH 0086/1121] ext4: add missing brelse() in add_new_gdb_meta_bg() [ Upstream commit d64264d6218e6892edd832dc3a5a5857c2856c53 ] Currently in add_new_gdb_meta_bg() there is a missing brelse of gdb_bh in case ext4_journal_get_write_access() fails. Additionally kvfree() is missing in the same error path. Fix it by moving the ext4_journal_get_write_access() before the ext4 sb update as Ted suggested and release n_group_desc and gdb_bh in case it fails. Fixes: 61a9c11e5e7a ("ext4: add missing brelse() add_new_gdb_meta_bg()'s error path") Signed-off-by: Lukas Czerner Signed-off-by: Theodore Ts'o Signed-off-by: Sasha Levin --- fs/ext4/resize.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index 6f0acfe31418..fb9fbf993e22 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c @@ -907,11 +907,18 @@ static int add_new_gdb_meta_bg(struct super_block *sb, memcpy(n_group_desc, o_group_desc, EXT4_SB(sb)->s_gdb_count * sizeof(struct buffer_head *)); n_group_desc[gdb_num] = gdb_bh; + + BUFFER_TRACE(gdb_bh, "get_write_access"); + err = ext4_journal_get_write_access(handle, gdb_bh); + if (err) { + kvfree(n_group_desc); + brelse(gdb_bh); + return err; + } + EXT4_SB(sb)->s_group_desc = n_group_desc; EXT4_SB(sb)->s_gdb_count++; kvfree(o_group_desc); - BUFFER_TRACE(gdb_bh, "get_write_access"); - err = ext4_journal_get_write_access(handle, gdb_bh); return err; } -- GitLab From ce1bdbed2097bffb0cabc8381f3727f8698ff991 Mon Sep 17 00:00:00 2001 From: Lukas Czerner Date: Fri, 15 Mar 2019 00:22:28 -0400 Subject: [PATCH 0087/1121] ext4: report real fs size after failed resize [ Upstream commit 6c7328400e0488f7d49e19e02290ba343b6811b2 ] Currently when the file system resize using ext4_resize_fs() fails it will report into log that "resized filesystem to ". However this may not be true in the case of failure. Use the current block count as returned by ext4_blocks_count() to report the block count. Additionally, report a warning that "error occurred during file system resize" Signed-off-by: Lukas Czerner Signed-off-by: Theodore Ts'o Signed-off-by: Sasha Levin --- fs/ext4/resize.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index fb9fbf993e22..333fba05e1a5 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c @@ -2049,6 +2049,10 @@ int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count) free_flex_gd(flex_gd); if (resize_inode != NULL) iput(resize_inode); - ext4_msg(sb, KERN_INFO, "resized filesystem to %llu", n_blocks_count); + if (err) + ext4_warning(sb, "error (%d) occurred during " + "file system resize", err); + ext4_msg(sb, KERN_INFO, "resized filesystem to %llu", + ext4_blocks_count(es)); return err; } -- GitLab From 7d831a0512987fc2af6b3a23ed44a4e96b79f26a Mon Sep 17 00:00:00 2001 From: Kangjie Lu Date: Thu, 14 Mar 2019 22:58:29 -0500 Subject: [PATCH 0088/1121] ALSA: echoaudio: add a check for ioremap_nocache [ Upstream commit 6ade657d6125ec3ec07f95fa51e28138aef6208f ] In case ioremap_nocache fails, the fix releases chip and returns an error code upstream to avoid NULL pointer dereference. Signed-off-by: Kangjie Lu Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/pci/echoaudio/echoaudio.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c index d68f99e076a8..e1f0bcd45c37 100644 --- a/sound/pci/echoaudio/echoaudio.c +++ b/sound/pci/echoaudio/echoaudio.c @@ -1953,6 +1953,11 @@ static int snd_echo_create(struct snd_card *card, } chip->dsp_registers = (volatile u32 __iomem *) ioremap_nocache(chip->dsp_registers_phys, sz); + if (!chip->dsp_registers) { + dev_err(chip->card->dev, "ioremap failed\n"); + snd_echo_free(chip); + return -ENOMEM; + } if (request_irq(pci->irq, snd_echo_interrupt, IRQF_SHARED, KBUILD_MODNAME, chip)) { -- GitLab From b042245be24b0e663bcf45f0ae77910bb3f11829 Mon Sep 17 00:00:00 2001 From: Kangjie Lu Date: Thu, 14 Mar 2019 23:04:14 -0500 Subject: [PATCH 0089/1121] ALSA: sb8: add a check for request_region [ Upstream commit dcd0feac9bab901d5739de51b3f69840851f8919 ] In case request_region fails, the fix returns an error code to avoid NULL pointer dereference. Signed-off-by: Kangjie Lu Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/isa/sb/sb8.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c index d77dcba276b5..1eb8b61a185b 100644 --- a/sound/isa/sb/sb8.c +++ b/sound/isa/sb/sb8.c @@ -111,6 +111,10 @@ static int snd_sb8_probe(struct device *pdev, unsigned int dev) /* block the 0x388 port to avoid PnP conflicts */ acard->fm_res = request_region(0x388, 4, "SoundBlaster FM"); + if (!acard->fm_res) { + err = -EBUSY; + goto _err; + } if (port[dev] != SNDRV_AUTO_PORT) { if ((err = snd_sbdsp_create(card, port[dev], irq[dev], -- GitLab From bfd5834e38886031625fe39dc6f3907b9c382729 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 12 Mar 2019 16:44:28 +0200 Subject: [PATCH 0090/1121] auxdisplay: hd44780: Fix memory leak on ->remove() [ Upstream commit 41c8d0adf3c4df1867d98cee4a2c4531352a33ad ] We have to free on ->remove() the allocated resources on ->probe(). Fixes: d47d88361fee ("auxdisplay: Add HD44780 Character LCD support") Reviewed-by: Geert Uytterhoeven Signed-off-by: Andy Shevchenko Signed-off-by: Miguel Ojeda Signed-off-by: Sasha Levin --- drivers/auxdisplay/hd44780.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/auxdisplay/hd44780.c b/drivers/auxdisplay/hd44780.c index 036eec404289..2d927feb3db4 100644 --- a/drivers/auxdisplay/hd44780.c +++ b/drivers/auxdisplay/hd44780.c @@ -302,6 +302,8 @@ static int hd44780_remove(struct platform_device *pdev) struct charlcd *lcd = platform_get_drvdata(pdev); charlcd_unregister(lcd); + + kfree(lcd); return 0; } -- GitLab From e04dc07f620a11d73b201cb4d7bb4712c607856d Mon Sep 17 00:00:00 2001 From: Jack Morgenstein Date: Wed, 6 Mar 2019 19:17:56 +0200 Subject: [PATCH 0091/1121] IB/mlx4: Fix race condition between catas error reset and aliasguid flows [ Upstream commit 587443e7773e150ae29e643ee8f41a1eed226565 ] Code review revealed a race condition which could allow the catas error flow to interrupt the alias guid query post mechanism at random points. Thiis is fixed by doing cancel_delayed_work_sync() instead of cancel_delayed_work() during the alias guid mechanism destroy flow. Fixes: a0c64a17aba8 ("mlx4: Add alias_guid mechanism") Signed-off-by: Jack Morgenstein Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe Signed-off-by: Sasha Levin --- drivers/infiniband/hw/mlx4/alias_GUID.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/mlx4/alias_GUID.c b/drivers/infiniband/hw/mlx4/alias_GUID.c index 155b4dfc0ae8..baab9afa9174 100644 --- a/drivers/infiniband/hw/mlx4/alias_GUID.c +++ b/drivers/infiniband/hw/mlx4/alias_GUID.c @@ -804,8 +804,8 @@ void mlx4_ib_destroy_alias_guid_service(struct mlx4_ib_dev *dev) unsigned long flags; for (i = 0 ; i < dev->num_ports; i++) { - cancel_delayed_work(&dev->sriov.alias_guid.ports_guid[i].alias_guid_work); det = &sriov->alias_guid.ports_guid[i]; + cancel_delayed_work_sync(&det->alias_guid_work); spin_lock_irqsave(&sriov->alias_guid.ag_work_lock, flags); while (!list_empty(&det->cb_list)) { cb_ctx = list_entry(det->cb_list.next, -- GitLab From eebec30d6b7ae4d60b1002e4dc31ffec38a0d4a5 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 7 Mar 2019 11:10:11 +0100 Subject: [PATCH 0092/1121] mmc: davinci: remove extraneous __init annotation [ Upstream commit 9ce58dd7d9da3ca0d7cb8c9568f1c6f4746da65a ] Building with clang finds a mistaken __init tag: WARNING: vmlinux.o(.text+0x5e4250): Section mismatch in reference from the function davinci_mmcsd_probe() to the function .init.text:init_mmcsd_host() The function davinci_mmcsd_probe() references the function __init init_mmcsd_host(). This is often because davinci_mmcsd_probe lacks a __init annotation or the annotation of init_mmcsd_host is wrong. Signed-off-by: Arnd Bergmann Acked-by: Wolfram Sang Reviewed-by: Nathan Chancellor Signed-off-by: Ulf Hansson Signed-off-by: Sasha Levin --- drivers/mmc/host/davinci_mmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c index 351330dfb954..1bd1819cca7d 100644 --- a/drivers/mmc/host/davinci_mmc.c +++ b/drivers/mmc/host/davinci_mmc.c @@ -1118,7 +1118,7 @@ static inline void mmc_davinci_cpufreq_deregister(struct mmc_davinci_host *host) { } #endif -static void __init init_mmcsd_host(struct mmc_davinci_host *host) +static void init_mmcsd_host(struct mmc_davinci_host *host) { mmc_davinci_reset_ctrl(host, 1); -- GitLab From 4467b4fdad62644814f13417b6fd54546db6a7ae Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Sun, 17 Mar 2019 23:21:24 +0000 Subject: [PATCH 0093/1121] ALSA: opl3: fix mismatch between snd_opl3_drum_switch definition and declaration [ Upstream commit b4748e7ab731e436cf5db4786358ada5dd2db6dd ] The function snd_opl3_drum_switch declaration in the header file has the order of the two arguments on_off and vel swapped when compared to the definition arguments of vel and on_off. Fix this by swapping them around to match the definition. This error predates the git history, so no idea when this error was introduced. Signed-off-by: Colin Ian King Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/drivers/opl3/opl3_voice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/drivers/opl3/opl3_voice.h b/sound/drivers/opl3/opl3_voice.h index eaef435e0528..abf6c23a721c 100644 --- a/sound/drivers/opl3/opl3_voice.h +++ b/sound/drivers/opl3/opl3_voice.h @@ -41,7 +41,7 @@ void snd_opl3_timer_func(unsigned long data); /* Prototypes for opl3_drums.c */ void snd_opl3_load_drums(struct snd_opl3 *opl3); -void snd_opl3_drum_switch(struct snd_opl3 *opl3, int note, int on_off, int vel, struct snd_midi_channel *chan); +void snd_opl3_drum_switch(struct snd_opl3 *opl3, int note, int vel, int on_off, struct snd_midi_channel *chan); /* Prototypes for opl3_oss.c */ #if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS) -- GitLab From 643deb59cee632f326f1865dc3b5ea8e91ff8c35 Mon Sep 17 00:00:00 2001 From: Luc Van Oostenryck Date: Sat, 19 Jan 2019 17:15:23 +0100 Subject: [PATCH 0094/1121] thermal/intel_powerclamp: fix __percpu declaration of worker_data [ Upstream commit aa36e3616532f82a920b5ebf4e059fbafae63d88 ] This variable is declared as: static struct powerclamp_worker_data * __percpu worker_data; In other words, a percpu pointer to struct ... But this variable not used like so but as a pointer to a percpu struct powerclamp_worker_data. So fix the declaration as: static struct powerclamp_worker_data __percpu *worker_data; This also quiets Sparse's warnings from __verify_pcpu_ptr(), like: 494:49: warning: incorrect type in initializer (different address spaces) 494:49: expected void const [noderef] *__vpp_verify 494:49: got struct powerclamp_worker_data * Signed-off-by: Luc Van Oostenryck Reviewed-by: Petr Mladek Signed-off-by: Zhang Rui Signed-off-by: Sasha Levin --- drivers/thermal/intel_powerclamp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/thermal/intel_powerclamp.c b/drivers/thermal/intel_powerclamp.c index d718cd179ddb..45d9840491bd 100644 --- a/drivers/thermal/intel_powerclamp.c +++ b/drivers/thermal/intel_powerclamp.c @@ -101,7 +101,7 @@ struct powerclamp_worker_data { bool clamping; }; -static struct powerclamp_worker_data * __percpu worker_data; +static struct powerclamp_worker_data __percpu *worker_data; static struct thermal_cooling_device *cooling_dev; static unsigned long *cpu_clamping_mask; /* bit map for tracking per cpu * clamping kthread worker -- GitLab From 6aa84e8a9fcba8aee8a1437bb4ab134cdc256d4a Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 29 Jan 2019 09:55:57 +0000 Subject: [PATCH 0095/1121] thermal: bcm2835: Fix crash in bcm2835_thermal_debugfs [ Upstream commit 35122495a8c6683e863acf7b05a7036b2be64c7a ] "cat /sys/kernel/debug/bcm2835_thermal/regset" causes a NULL pointer dereference in bcm2835_thermal_debugfs. The driver makes use of the implementation details of the thermal framework to retrieve a pointer to its private data from a struct thermal_zone_device, and gets it wrong - leading to the crash. Instead, store its private data as the drvdata and retrieve the thermal_zone_device pointer from it. Fixes: bcb7dd9ef206 ("thermal: bcm2835: add thermal driver for bcm2835 SoC") Signed-off-by: Phil Elwell Signed-off-by: Zhang Rui Signed-off-by: Sasha Levin --- drivers/thermal/broadcom/bcm2835_thermal.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/thermal/broadcom/bcm2835_thermal.c b/drivers/thermal/broadcom/bcm2835_thermal.c index 24b006a95142..8646fb7425f2 100644 --- a/drivers/thermal/broadcom/bcm2835_thermal.c +++ b/drivers/thermal/broadcom/bcm2835_thermal.c @@ -128,8 +128,7 @@ static const struct debugfs_reg32 bcm2835_thermal_regs[] = { static void bcm2835_thermal_debugfs(struct platform_device *pdev) { - struct thermal_zone_device *tz = platform_get_drvdata(pdev); - struct bcm2835_thermal_data *data = tz->devdata; + struct bcm2835_thermal_data *data = platform_get_drvdata(pdev); struct debugfs_regset32 *regset; data->debugfsdir = debugfs_create_dir("bcm2835_thermal", NULL); @@ -275,7 +274,7 @@ static int bcm2835_thermal_probe(struct platform_device *pdev) data->tz = tz; - platform_set_drvdata(pdev, tz); + platform_set_drvdata(pdev, data); /* * Thermal_zone doesn't enable hwmon as default, @@ -299,8 +298,8 @@ static int bcm2835_thermal_probe(struct platform_device *pdev) static int bcm2835_thermal_remove(struct platform_device *pdev) { - struct thermal_zone_device *tz = platform_get_drvdata(pdev); - struct bcm2835_thermal_data *data = tz->devdata; + struct bcm2835_thermal_data *data = platform_get_drvdata(pdev); + struct thermal_zone_device *tz = data->tz; debugfs_remove_recursive(data->debugfsdir); thermal_zone_of_sensor_unregister(&pdev->dev, tz); -- GitLab From f37079c7dc6aaa6fd392c1f5426f77c71361f15b Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Wed, 10 Oct 2018 01:30:06 -0700 Subject: [PATCH 0096/1121] thermal/int340x_thermal: Add additional UUIDs [ Upstream commit 16fc8eca1975358111dbd7ce65e4ce42d1a848fb ] Add more supported DPTF policies than the driver currently exposes. Signed-off-by: Matthew Garrett Cc: Nisha Aram Signed-off-by: Zhang Rui Signed-off-by: Sasha Levin --- drivers/thermal/int340x_thermal/int3400_thermal.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/thermal/int340x_thermal/int3400_thermal.c b/drivers/thermal/int340x_thermal/int3400_thermal.c index 43b90fd577e4..34dc4d6dda66 100644 --- a/drivers/thermal/int340x_thermal/int3400_thermal.c +++ b/drivers/thermal/int340x_thermal/int3400_thermal.c @@ -22,6 +22,13 @@ enum int3400_thermal_uuid { INT3400_THERMAL_PASSIVE_1, INT3400_THERMAL_ACTIVE, INT3400_THERMAL_CRITICAL, + INT3400_THERMAL_ADAPTIVE_PERFORMANCE, + INT3400_THERMAL_EMERGENCY_CALL_MODE, + INT3400_THERMAL_PASSIVE_2, + INT3400_THERMAL_POWER_BOSS, + INT3400_THERMAL_VIRTUAL_SENSOR, + INT3400_THERMAL_COOLING_MODE, + INT3400_THERMAL_HARDWARE_DUTY_CYCLING, INT3400_THERMAL_MAXIMUM_UUID, }; @@ -29,6 +36,13 @@ static char *int3400_thermal_uuids[INT3400_THERMAL_MAXIMUM_UUID] = { "42A441D6-AE6A-462b-A84B-4A8CE79027D3", "3A95C389-E4B8-4629-A526-C52C88626BAE", "97C68AE7-15FA-499c-B8C9-5DA81D606E0A", + "63BE270F-1C11-48FD-A6F7-3AF253FF3E2D", + "5349962F-71E6-431D-9AE8-0A635B710AEE", + "9E04115A-AE87-4D1C-9500-0F3E340BFE75", + "F5A35014-C209-46A4-993A-EB56DE7530A1", + "6ED722A7-9240-48A5-B479-31EEF723D7CF", + "16CAF1B7-DD38-40ED-B1C1-1B8A1913D531", + "BE84BABF-C4D4-403D-B495-3128FD44dAC1", }; struct int3400_thermal_priv { -- GitLab From 637f86d25097b565a5c9a17094bc4d06df3dc1dc Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Wed, 10 Oct 2018 01:30:07 -0700 Subject: [PATCH 0097/1121] thermal/int340x_thermal: fix mode setting [ Upstream commit 396ee4d0cd52c13b3f6421b8d324d65da5e7e409 ] int3400 only pushes the UUID into the firmware when the mode is flipped to "enable". The current code only exposes the mode flag if the firmware supports the PASSIVE_1 UUID, which not all machines do. Remove the restriction. Signed-off-by: Matthew Garrett Signed-off-by: Zhang Rui Signed-off-by: Sasha Levin --- drivers/thermal/int340x_thermal/int3400_thermal.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/thermal/int340x_thermal/int3400_thermal.c b/drivers/thermal/int340x_thermal/int3400_thermal.c index 34dc4d6dda66..4a20f4d47b1d 100644 --- a/drivers/thermal/int340x_thermal/int3400_thermal.c +++ b/drivers/thermal/int340x_thermal/int3400_thermal.c @@ -316,10 +316,9 @@ static int int3400_thermal_probe(struct platform_device *pdev) platform_set_drvdata(pdev, priv); - if (priv->uuid_bitmap & 1 << INT3400_THERMAL_PASSIVE_1) { - int3400_thermal_ops.get_mode = int3400_thermal_get_mode; - int3400_thermal_ops.set_mode = int3400_thermal_set_mode; - } + int3400_thermal_ops.get_mode = int3400_thermal_get_mode; + int3400_thermal_ops.set_mode = int3400_thermal_set_mode; + priv->thermal = thermal_zone_device_register("INT3400 Thermal", 0, 0, priv, &int3400_thermal_ops, &int3400_thermal_params, 0, 0); -- GitLab From f1e062e8ce7934e2f4a80e53b2ca2fbbf71ce24d Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 18 Mar 2019 22:26:33 +0800 Subject: [PATCH 0098/1121] thermal/intel_powerclamp: fix truncated kthread name [ Upstream commit e925b5be5751f6a7286bbd9a4cbbc4ac90cc5fa6 ] kthread name only allows 15 characters (TASK_COMMON_LEN is 16). Thus rename the kthreads created by intel_powerclamp driver from "kidle_inject/ + decimal cpuid" to "kidle_inj/ + decimal cpuid" to avoid truncated kthead name for cpu 100 and later. Signed-off-by: Zhang Rui Signed-off-by: Sasha Levin --- drivers/thermal/intel_powerclamp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/thermal/intel_powerclamp.c b/drivers/thermal/intel_powerclamp.c index 45d9840491bd..c3293fa2bb1b 100644 --- a/drivers/thermal/intel_powerclamp.c +++ b/drivers/thermal/intel_powerclamp.c @@ -494,7 +494,7 @@ static void start_power_clamp_worker(unsigned long cpu) struct powerclamp_worker_data *w_data = per_cpu_ptr(worker_data, cpu); struct kthread_worker *worker; - worker = kthread_create_worker_on_cpu(cpu, 0, "kidle_inject/%ld", cpu); + worker = kthread_create_worker_on_cpu(cpu, 0, "kidle_inj/%ld", cpu); if (IS_ERR(worker)) return; -- GitLab From 58ad2f1b020a114d0ecdcc77fb4ff6766ad0c53e Mon Sep 17 00:00:00 2001 From: Maurizio Lombardi Date: Mon, 28 Jan 2019 15:24:42 +0100 Subject: [PATCH 0099/1121] scsi: iscsi: flush running unbind operations when removing a session [ Upstream commit 165aa2bfb42904b1bec4bf2fa257c8c603c14a06 ] In some cases, the iscsi_remove_session() function is called while an unbind_work operation is still running. This may cause a situation where sysfs objects are removed in an incorrect order, triggering a kernel warning. [ 605.249442] ------------[ cut here ]------------ [ 605.259180] sysfs group 'power' not found for kobject 'target2:0:0' [ 605.321371] WARNING: CPU: 1 PID: 26794 at fs/sysfs/group.c:235 sysfs_remove_group+0x76/0x80 [ 605.341266] Modules linked in: dm_service_time target_core_user target_core_pscsi target_core_file target_core_iblock iscsi_target_mod target_core_mod nls_utf8 isofs ppdev bochs_drm nfit ttm libnvdimm drm_kms_helper syscopyarea sysfillrect sysimgblt joydev pcspkr fb_sys_fops drm i2c_piix4 sg parport_pc parport xfs libcrc32c dm_multipath sr_mod sd_mod cdrom ata_generic 8021q garp mrp ata_piix stp crct10dif_pclmul crc32_pclmul llc libata crc32c_intel virtio_net net_failover ghash_clmulni_intel serio_raw failover sunrpc dm_mirror dm_region_hash dm_log dm_mod be2iscsi bnx2i cnic uio cxgb4i cxgb4 libcxgbi libcxgb qla4xxx iscsi_boot_sysfs iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi [ 605.627479] CPU: 1 PID: 26794 Comm: kworker/u32:2 Not tainted 4.18.0-60.el8.x86_64 #1 [ 605.721401] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS ?-20180724_192412-buildhw-07.phx2.fedoraproject.org-1.fc29 04/01/2014 [ 605.823651] Workqueue: scsi_wq_2 __iscsi_unbind_session [scsi_transport_iscsi] [ 605.830940] RIP: 0010:sysfs_remove_group+0x76/0x80 [ 605.922907] Code: 48 89 df 5b 5d 41 5c e9 38 c4 ff ff 48 89 df e8 e0 bf ff ff eb cb 49 8b 14 24 48 8b 75 00 48 c7 c7 38 73 cb a7 e8 24 77 d7 ff <0f> 0b 5b 5d 41 5c c3 0f 1f 00 0f 1f 44 00 00 41 56 41 55 41 54 55 [ 606.122304] RSP: 0018:ffffbadcc8d1bda8 EFLAGS: 00010286 [ 606.218492] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000 [ 606.326381] RDX: ffff98bdfe85eb40 RSI: ffff98bdfe856818 RDI: ffff98bdfe856818 [ 606.514498] RBP: ffffffffa7ab73e0 R08: 0000000000000268 R09: 0000000000000007 [ 606.529469] R10: 0000000000000000 R11: ffffffffa860d9ad R12: ffff98bdf978e838 [ 606.630535] R13: ffff98bdc2cd4010 R14: ffff98bdc2cd3ff0 R15: ffff98bdc2cd4000 [ 606.824707] FS: 0000000000000000(0000) GS:ffff98bdfe840000(0000) knlGS:0000000000000000 [ 607.018333] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 607.117844] CR2: 00007f84b78ac024 CR3: 000000002c00a003 CR4: 00000000003606e0 [ 607.117844] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 607.420926] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 607.524236] Call Trace: [ 607.530591] device_del+0x56/0x350 [ 607.624393] ? ata_tlink_match+0x30/0x30 [libata] [ 607.727805] ? attribute_container_device_trigger+0xb4/0xf0 [ 607.829911] scsi_target_reap_ref_release+0x39/0x50 [ 607.928572] scsi_remove_target+0x1a2/0x1d0 [ 608.017350] __iscsi_unbind_session+0xb3/0x160 [scsi_transport_iscsi] [ 608.117435] process_one_work+0x1a7/0x360 [ 608.132917] worker_thread+0x30/0x390 [ 608.222900] ? pwq_unbound_release_workfn+0xd0/0xd0 [ 608.323989] kthread+0x112/0x130 [ 608.418318] ? kthread_bind+0x30/0x30 [ 608.513821] ret_from_fork+0x35/0x40 [ 608.613909] ---[ end trace 0b98c310c8a6138c ]--- Signed-off-by: Maurizio Lombardi Acked-by: Chris Leech Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/scsi_transport_iscsi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index f6542c159ed6..b4d06bd9ed51 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -2185,6 +2185,8 @@ void iscsi_remove_session(struct iscsi_cls_session *session) scsi_target_unblock(&session->dev, SDEV_TRANSPORT_OFFLINE); /* flush running scans then delete devices */ flush_work(&session->scan_work); + /* flush running unbind operations */ + flush_work(&session->unbind_work); __iscsi_unbind_session(&session->unbind_work); /* hw iscsi may not have removed all connections from session */ -- GitLab From 3fb2d0a276294a7625216395bc329e917e0643e2 Mon Sep 17 00:00:00 2001 From: Matteo Croce Date: Mon, 18 Mar 2019 22:24:03 +0100 Subject: [PATCH 0100/1121] x86/mm: Don't leak kernel addresses [ Upstream commit a3151724437f54076cc10bc02b1c4f0003ae36cd ] Since commit: ad67b74d2469d9b8 ("printk: hash addresses printed with %p") at boot "____ptrval____" is printed instead of actual addresses: found SMP MP-table at [mem 0x000f5cc0-0x000f5ccf] mapped at [(____ptrval____)] Instead of changing the print to "%px", and leaking a kernel addresses, just remove the print completely, like in: 071929dbdd865f77 ("arm64: Stop printing the virtual memory layout"). Signed-off-by: Matteo Croce Cc: Borislav Petkov Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Sasha Levin --- arch/x86/kernel/mpparse.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index bc6bc6689e68..1c52acaa5bec 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c @@ -596,8 +596,8 @@ static int __init smp_scan_config(unsigned long base, unsigned long length) mpf_base = base; mpf_found = true; - pr_info("found SMP MP-table at [mem %#010lx-%#010lx] mapped at [%p]\n", - base, base + sizeof(*mpf) - 1, mpf); + pr_info("found SMP MP-table at [mem %#010lx-%#010lx]\n", + base, base + sizeof(*mpf) - 1); memblock_reserve(base, sizeof(*mpf)); if (mpf->physptr) -- GitLab From 182d26496e045247939c8697c6448a4830f0dff6 Mon Sep 17 00:00:00 2001 From: David Arcari Date: Tue, 12 Feb 2019 09:34:39 -0500 Subject: [PATCH 0101/1121] tools/power turbostat: return the exit status of a command [ Upstream commit 2a95496634a017c19641f26f00907af75b962f01 ] turbostat failed to return a non-zero exit status even though the supplied command (turbostat ) failed. Currently when turbostat forks a command it returns zero instead of the actual exit status of the command. Modify the code to return the exit status. Signed-off-by: David Arcari Acked-by: Len Brown Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- tools/power/x86/turbostat/turbostat.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 7a1b20ec5216..d1b2348db0f9 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -4588,6 +4588,9 @@ int fork_it(char **argv) signal(SIGQUIT, SIG_IGN); if (waitpid(child_pid, &status, 0) == -1) err(status, "waitpid"); + + if (WIFEXITED(status)) + status = WEXITSTATUS(status); } /* * n.b. fork_it() does not check for errors from for_all_cpus() -- GitLab From 96f74822311f010c50f339e85d87c190419e8ee0 Mon Sep 17 00:00:00 2001 From: Changbin Du Date: Sat, 16 Mar 2019 16:05:42 +0800 Subject: [PATCH 0102/1121] perf list: Don't forget to drop the reference to the allocated thread_map [ Upstream commit 39df730b09774bd860e39ea208a48d15078236cb ] Detected via gcc's ASan: Direct leak of 2048 byte(s) in 64 object(s) allocated from: 6 #0 0x7f606512e370 in __interceptor_realloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0xee370) 7 #1 0x556b0f1d7ddd in thread_map__realloc util/thread_map.c:43 8 #2 0x556b0f1d84c7 in thread_map__new_by_tid util/thread_map.c:85 9 #3 0x556b0f0e045e in is_event_supported util/parse-events.c:2250 10 #4 0x556b0f0e1aa1 in print_hwcache_events util/parse-events.c:2382 11 #5 0x556b0f0e3231 in print_events util/parse-events.c:2514 12 #6 0x556b0ee0a66e in cmd_list /home/changbin/work/linux/tools/perf/builtin-list.c:58 13 #7 0x556b0f01e0ae in run_builtin /home/changbin/work/linux/tools/perf/perf.c:302 14 #8 0x556b0f01e859 in handle_internal_command /home/changbin/work/linux/tools/perf/perf.c:354 15 #9 0x556b0f01edc8 in run_argv /home/changbin/work/linux/tools/perf/perf.c:398 16 #10 0x556b0f01f71f in main /home/changbin/work/linux/tools/perf/perf.c:520 17 #11 0x7f6062ccf09a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2409a) Signed-off-by: Changbin Du Reviewed-by: Jiri Olsa Cc: Alexei Starovoitov Cc: Daniel Borkmann Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Steven Rostedt (VMware) Fixes: 89896051f8da ("perf tools: Do not put a variable sized type not at the end of a struct") Link: http://lkml.kernel.org/r/20190316080556.3075-3-changbin.du@gmail.com Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Sasha Levin --- tools/perf/util/parse-events.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index d0b92d374ba9..ec3517326a68 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -2109,6 +2109,7 @@ static bool is_event_supported(u8 type, unsigned config) perf_evsel__delete(evsel); } + thread_map__put(tmap); return ret; } -- GitLab From 0d85f280c1b3bc1747a8b83e9f764086db8a69fc Mon Sep 17 00:00:00 2001 From: Changbin Du Date: Sat, 16 Mar 2019 16:05:44 +0800 Subject: [PATCH 0103/1121] perf config: Fix an error in the config template documentation [ Upstream commit 9b40dff7ba3caaf0d1919f98e136fa3400bd34aa ] The option 'sort-order' should be 'sort_order'. Signed-off-by: Changbin Du Reviewed-by: Jiri Olsa Cc: Alexei Starovoitov Cc: Daniel Borkmann Cc: Milian Wolff Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Steven Rostedt (VMware) Fixes: 893c5c798be9 ("perf config: Show default report configuration in example and docs") Link: http://lkml.kernel.org/r/20190316080556.3075-5-changbin.du@gmail.com Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Sasha Levin --- tools/perf/Documentation/perf-config.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index 5b4fff3adc4b..782a8966b721 100644 --- a/tools/perf/Documentation/perf-config.txt +++ b/tools/perf/Documentation/perf-config.txt @@ -114,7 +114,7 @@ Given a $HOME/.perfconfig like this: [report] # Defaults - sort-order = comm,dso,symbol + sort_order = comm,dso,symbol percent-limit = 0 queue-size = 0 children = true -- GitLab From b820793ac523ba28cda45f86fbc031a06feaf720 Mon Sep 17 00:00:00 2001 From: Changbin Du Date: Sat, 16 Mar 2019 16:05:45 +0800 Subject: [PATCH 0104/1121] perf config: Fix a memory leak in collect_config() [ Upstream commit 54569ba4b06d5baedae4614bde33a25a191473ba ] Detected with gcc's ASan: Direct leak of 66 byte(s) in 5 object(s) allocated from: #0 0x7ff3b1f32070 in __interceptor_strdup (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x3b070) #1 0x560c8761034d in collect_config util/config.c:597 #2 0x560c8760d9cb in get_value util/config.c:169 #3 0x560c8760dfd7 in perf_parse_file util/config.c:285 #4 0x560c8760e0d2 in perf_config_from_file util/config.c:476 #5 0x560c876108fd in perf_config_set__init util/config.c:661 #6 0x560c87610c72 in perf_config_set__new util/config.c:709 #7 0x560c87610d2f in perf_config__init util/config.c:718 #8 0x560c87610e5d in perf_config util/config.c:730 #9 0x560c875ddea0 in main /home/changbin/work/linux/tools/perf/perf.c:442 #10 0x7ff3afb8609a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2409a) Signed-off-by: Changbin Du Reviewed-by: Jiri Olsa Cc: Alexei Starovoitov Cc: Daniel Borkmann Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Steven Rostedt (VMware) Cc: Taeung Song Fixes: 20105ca1240c ("perf config: Introduce perf_config_set class") Link: http://lkml.kernel.org/r/20190316080556.3075-6-changbin.du@gmail.com Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Sasha Levin --- tools/perf/util/config.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index 4b893c622236..a0c9ff27c7bf 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c @@ -628,11 +628,10 @@ static int collect_config(const char *var, const char *value, } ret = set_value(item, value); - return ret; out_free: free(key); - return -1; + return ret; } int perf_config_set__collect(struct perf_config_set *set, const char *file_name, -- GitLab From 801a59019383eefb821b66b22ca50a11636045a2 Mon Sep 17 00:00:00 2001 From: Changbin Du Date: Sat, 16 Mar 2019 16:05:46 +0800 Subject: [PATCH 0105/1121] perf build-id: Fix memory leak in print_sdt_events() [ Upstream commit 8bde8516893da5a5fdf06121f74d11b52ab92df5 ] Detected with gcc's ASan: Direct leak of 4356 byte(s) in 120 object(s) allocated from: #0 0x7ff1a2b5a070 in __interceptor_strdup (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x3b070) #1 0x55719aef4814 in build_id_cache__origname util/build-id.c:215 #2 0x55719af649b6 in print_sdt_events util/parse-events.c:2339 #3 0x55719af66272 in print_events util/parse-events.c:2542 #4 0x55719ad1ecaa in cmd_list /home/changbin/work/linux/tools/perf/builtin-list.c:58 #5 0x55719aec745d in run_builtin /home/changbin/work/linux/tools/perf/perf.c:302 #6 0x55719aec7d1a in handle_internal_command /home/changbin/work/linux/tools/perf/perf.c:354 #7 0x55719aec8184 in run_argv /home/changbin/work/linux/tools/perf/perf.c:398 #8 0x55719aeca41a in main /home/changbin/work/linux/tools/perf/perf.c:520 #9 0x7ff1a07ae09a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2409a) Signed-off-by: Changbin Du Reviewed-by: Jiri Olsa Cc: Alexei Starovoitov Cc: Daniel Borkmann Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Steven Rostedt (VMware) Fixes: 40218daea1db ("perf list: Show SDT and pre-cached events") Link: http://lkml.kernel.org/r/20190316080556.3075-7-changbin.du@gmail.com Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Sasha Levin --- tools/perf/util/build-id.c | 1 + tools/perf/util/parse-events.c | 1 + 2 files changed, 2 insertions(+) diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index 7f8553630c4d..69910deab6e0 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -185,6 +185,7 @@ char *build_id_cache__linkname(const char *sbuild_id, char *bf, size_t size) return bf; } +/* The caller is responsible to free the returned buffer. */ char *build_id_cache__origname(const char *sbuild_id) { char *linkname; diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index ec3517326a68..29e2bb304168 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -2180,6 +2180,7 @@ void print_sdt_events(const char *subsys_glob, const char *event_glob, printf(" %-50s [%s]\n", buf, "SDT event"); free(buf); } + free(path); } else printf(" %-50s [%s]\n", nd->s, "SDT event"); if (nd2) { -- GitLab From dac5fedfc9070bf1fcb14b0dd9ef812aa5c5c2a6 Mon Sep 17 00:00:00 2001 From: Changbin Du Date: Sat, 16 Mar 2019 16:05:48 +0800 Subject: [PATCH 0106/1121] perf top: Fix error handling in cmd_top() [ Upstream commit 70c819e4bf1c5f492768b399d898d458ccdad2b6 ] We should go to the cleanup path, to avoid leaks, detected using gcc's ASan. Signed-off-by: Changbin Du Reviewed-by: Jiri Olsa Cc: Alexei Starovoitov Cc: Daniel Borkmann Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Steven Rostedt (VMware) Link: http://lkml.kernel.org/r/20190316080556.3075-9-changbin.du@gmail.com Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Sasha Levin --- tools/perf/builtin-top.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 3103a33c13a8..133eb7949321 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -1345,8 +1345,9 @@ int cmd_top(int argc, const char **argv) goto out_delete_evlist; symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL); - if (symbol__init(NULL) < 0) - return -1; + status = symbol__init(NULL); + if (status < 0) + goto out_delete_evlist; sort__setup_elide(stdout); -- GitLab From ff22178b282675fa3542763f8e67cbb40f3f9bfd Mon Sep 17 00:00:00 2001 From: Changbin Du Date: Sat, 16 Mar 2019 16:05:49 +0800 Subject: [PATCH 0107/1121] perf hist: Add missing map__put() in error case [ Upstream commit cb6186aeffda4d27e56066c79e9579e7831541d3 ] We need to map__put() before returning from failure of sample__resolve_callchain(). Detected with gcc's ASan. Signed-off-by: Changbin Du Reviewed-by: Jiri Olsa Cc: Alexei Starovoitov Cc: Daniel Borkmann Cc: Krister Johansen Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Steven Rostedt (VMware) Fixes: 9c68ae98c6f7 ("perf callchain: Reference count maps") Link: http://lkml.kernel.org/r/20190316080556.3075-10-changbin.du@gmail.com Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Sasha Levin --- tools/perf/util/hist.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 5d420209505e..5b8bc1fd943d 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -1040,8 +1040,10 @@ int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al, err = sample__resolve_callchain(iter->sample, &callchain_cursor, &iter->parent, iter->evsel, al, max_stack_depth); - if (err) + if (err) { + map__put(alm); return err; + } err = iter->ops->prepare_entry(iter, al); if (err) -- GitLab From 952d449dbf3e753c009e04f55fe31dcc3b27a9b9 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 18 Mar 2019 16:41:28 -0300 Subject: [PATCH 0108/1121] perf evsel: Free evsel->counts in perf_evsel__exit() [ Upstream commit 42dfa451d825a2ad15793c476f73e7bbc0f9d312 ] Using gcc's ASan, Changbin reports: ================================================================= ==7494==ERROR: LeakSanitizer: detected memory leaks Direct leak of 48 byte(s) in 1 object(s) allocated from: #0 0x7f0333a89138 in calloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0xee138) #1 0x5625e5330a5e in zalloc util/util.h:23 #2 0x5625e5330a9b in perf_counts__new util/counts.c:10 #3 0x5625e5330ca0 in perf_evsel__alloc_counts util/counts.c:47 #4 0x5625e520d8e5 in __perf_evsel__read_on_cpu util/evsel.c:1505 #5 0x5625e517a985 in perf_evsel__read_on_cpu /home/work/linux/tools/perf/util/evsel.h:347 #6 0x5625e517ad1a in test__openat_syscall_event tests/openat-syscall.c:47 #7 0x5625e51528e6 in run_test tests/builtin-test.c:358 #8 0x5625e5152baf in test_and_print tests/builtin-test.c:388 #9 0x5625e51543fe in __cmd_test tests/builtin-test.c:583 #10 0x5625e515572f in cmd_test tests/builtin-test.c:722 #11 0x5625e51c3fb8 in run_builtin /home/changbin/work/linux/tools/perf/perf.c:302 #12 0x5625e51c44f7 in handle_internal_command /home/changbin/work/linux/tools/perf/perf.c:354 #13 0x5625e51c48fb in run_argv /home/changbin/work/linux/tools/perf/perf.c:398 #14 0x5625e51c5069 in main /home/changbin/work/linux/tools/perf/perf.c:520 #15 0x7f033214d09a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2409a) Indirect leak of 72 byte(s) in 1 object(s) allocated from: #0 0x7f0333a89138 in calloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0xee138) #1 0x5625e532560d in zalloc util/util.h:23 #2 0x5625e532566b in xyarray__new util/xyarray.c:10 #3 0x5625e5330aba in perf_counts__new util/counts.c:15 #4 0x5625e5330ca0 in perf_evsel__alloc_counts util/counts.c:47 #5 0x5625e520d8e5 in __perf_evsel__read_on_cpu util/evsel.c:1505 #6 0x5625e517a985 in perf_evsel__read_on_cpu /home/work/linux/tools/perf/util/evsel.h:347 #7 0x5625e517ad1a in test__openat_syscall_event tests/openat-syscall.c:47 #8 0x5625e51528e6 in run_test tests/builtin-test.c:358 #9 0x5625e5152baf in test_and_print tests/builtin-test.c:388 #10 0x5625e51543fe in __cmd_test tests/builtin-test.c:583 #11 0x5625e515572f in cmd_test tests/builtin-test.c:722 #12 0x5625e51c3fb8 in run_builtin /home/changbin/work/linux/tools/perf/perf.c:302 #13 0x5625e51c44f7 in handle_internal_command /home/changbin/work/linux/tools/perf/perf.c:354 #14 0x5625e51c48fb in run_argv /home/changbin/work/linux/tools/perf/perf.c:398 #15 0x5625e51c5069 in main /home/changbin/work/linux/tools/perf/perf.c:520 #16 0x7f033214d09a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2409a) His patch took care of evsel->prev_raw_counts, but the above backtraces are about evsel->counts, so fix that instead. Reported-by: Changbin Du Cc: Alexei Starovoitov Cc: Daniel Borkmann Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Steven Rostedt (VMware) Link: https://lkml.kernel.org/n/tip-hd1x13g59f0nuhe4anxhsmfp@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Sasha Levin --- tools/perf/util/evsel.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 44c2f62b47a3..0cf6f537f980 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1229,6 +1229,7 @@ void perf_evsel__exit(struct perf_evsel *evsel) { assert(list_empty(&evsel->node)); assert(evsel->evlist == NULL); + perf_evsel__free_counts(evsel); perf_evsel__free_fd(evsel); perf_evsel__free_id(evsel); perf_evsel__free_config_terms(evsel); -- GitLab From a0898f576b7a0ca83ca35faf4e25ab1d1198e5ab Mon Sep 17 00:00:00 2001 From: Changbin Du Date: Sat, 16 Mar 2019 16:05:54 +0800 Subject: [PATCH 0109/1121] perf tests: Fix a memory leak of cpu_map object in the openat_syscall_event_on_all_cpus test [ Upstream commit 93faa52e8371f0291ee1ff4994edae2b336b6233 ] ================================================================= ==7497==ERROR: LeakSanitizer: detected memory leaks Direct leak of 40 byte(s) in 1 object(s) allocated from: #0 0x7f0333a88f30 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0xedf30) #1 0x5625e5326213 in cpu_map__trim_new util/cpumap.c:45 #2 0x5625e5326703 in cpu_map__read util/cpumap.c:103 #3 0x5625e53267ef in cpu_map__read_all_cpu_map util/cpumap.c:120 #4 0x5625e5326915 in cpu_map__new util/cpumap.c:135 #5 0x5625e517b355 in test__openat_syscall_event_on_all_cpus tests/openat-syscall-all-cpus.c:36 #6 0x5625e51528e6 in run_test tests/builtin-test.c:358 #7 0x5625e5152baf in test_and_print tests/builtin-test.c:388 #8 0x5625e51543fe in __cmd_test tests/builtin-test.c:583 #9 0x5625e515572f in cmd_test tests/builtin-test.c:722 #10 0x5625e51c3fb8 in run_builtin /home/changbin/work/linux/tools/perf/perf.c:302 #11 0x5625e51c44f7 in handle_internal_command /home/changbin/work/linux/tools/perf/perf.c:354 #12 0x5625e51c48fb in run_argv /home/changbin/work/linux/tools/perf/perf.c:398 #13 0x5625e51c5069 in main /home/changbin/work/linux/tools/perf/perf.c:520 #14 0x7f033214d09a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2409a) Signed-off-by: Changbin Du Reviewed-by: Jiri Olsa Cc: Alexei Starovoitov Cc: Daniel Borkmann Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Steven Rostedt (VMware) Fixes: f30a79b012e5 ("perf tools: Add reference counting for cpu_map object") Link: http://lkml.kernel.org/r/20190316080556.3075-15-changbin.du@gmail.com Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Sasha Levin --- tools/perf/tests/openat-syscall-all-cpus.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c index c531e6deb104..493ecb611540 100644 --- a/tools/perf/tests/openat-syscall-all-cpus.c +++ b/tools/perf/tests/openat-syscall-all-cpus.c @@ -45,7 +45,7 @@ int test__openat_syscall_event_on_all_cpus(struct test *test __maybe_unused, int if (IS_ERR(evsel)) { tracing_path__strerror_open_tp(errno, errbuf, sizeof(errbuf), "syscalls", "sys_enter_openat"); pr_debug("%s\n", errbuf); - goto out_thread_map_delete; + goto out_cpu_map_delete; } if (perf_evsel__open(evsel, cpus, threads) < 0) { @@ -119,6 +119,8 @@ int test__openat_syscall_event_on_all_cpus(struct test *test __maybe_unused, int perf_evsel__close_fd(evsel); out_evsel_delete: perf_evsel__delete(evsel); +out_cpu_map_delete: + cpu_map__put(cpus); out_thread_map_delete: thread_map__put(threads); return err; -- GitLab From 4c66a273f6b3829a641017084b029a58a5559493 Mon Sep 17 00:00:00 2001 From: Changbin Du Date: Sat, 16 Mar 2019 16:05:55 +0800 Subject: [PATCH 0110/1121] perf tests: Fix memory leak by expr__find_other() in test__expr() [ Upstream commit f97a8991d3b998e518f56794d879f645964de649 ] ================================================================= ==7506==ERROR: LeakSanitizer: detected memory leaks Direct leak of 13 byte(s) in 3 object(s) allocated from: #0 0x7f03339d6070 in __interceptor_strdup (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x3b070) #1 0x5625e53aaef0 in expr__find_other util/expr.y:221 #2 0x5625e51bcd3f in test__expr tests/expr.c:52 #3 0x5625e51528e6 in run_test tests/builtin-test.c:358 #4 0x5625e5152baf in test_and_print tests/builtin-test.c:388 #5 0x5625e51543fe in __cmd_test tests/builtin-test.c:583 #6 0x5625e515572f in cmd_test tests/builtin-test.c:722 #7 0x5625e51c3fb8 in run_builtin /home/changbin/work/linux/tools/perf/perf.c:302 #8 0x5625e51c44f7 in handle_internal_command /home/changbin/work/linux/tools/perf/perf.c:354 #9 0x5625e51c48fb in run_argv /home/changbin/work/linux/tools/perf/perf.c:398 #10 0x5625e51c5069 in main /home/changbin/work/linux/tools/perf/perf.c:520 #11 0x7f033214d09a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2409a) Signed-off-by: Changbin Du Cc: Alexei Starovoitov Cc: Andi Kleen Cc: Daniel Borkmann Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Steven Rostedt (VMware) Fixes: 075167363f8b ("perf tools: Add a simple expression parser for JSON") Link: http://lkml.kernel.org/r/20190316080556.3075-16-changbin.du@gmail.com Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Sasha Levin --- tools/perf/tests/expr.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c index 01f0706995a9..9acc1e80b936 100644 --- a/tools/perf/tests/expr.c +++ b/tools/perf/tests/expr.c @@ -19,7 +19,7 @@ int test__expr(struct test *t __maybe_unused, int subtest __maybe_unused) const char *p; const char **other; double val; - int ret; + int i, ret; struct parse_ctx ctx; int num_other; @@ -56,6 +56,9 @@ int test__expr(struct test *t __maybe_unused, int subtest __maybe_unused) TEST_ASSERT_VAL("find other", !strcmp(other[1], "BAZ")); TEST_ASSERT_VAL("find other", !strcmp(other[2], "BOZO")); TEST_ASSERT_VAL("find other", other[3] == NULL); + + for (i = 0; i < num_other; i++) + free((void *)other[i]); free((void *)other); return 0; -- GitLab From b1930a27c81bf14be77e5c30401e1f50345a3e99 Mon Sep 17 00:00:00 2001 From: Changbin Du Date: Sat, 16 Mar 2019 16:05:56 +0800 Subject: [PATCH 0111/1121] perf tests: Fix a memory leak in test__perf_evsel__tp_sched_test() [ Upstream commit d982b33133284fa7efa0e52ae06b88f9be3ea764 ] ================================================================= ==20875==ERROR: LeakSanitizer: detected memory leaks Direct leak of 1160 byte(s) in 1 object(s) allocated from: #0 0x7f1b6fc84138 in calloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0xee138) #1 0x55bd50005599 in zalloc util/util.h:23 #2 0x55bd500068f5 in perf_evsel__newtp_idx util/evsel.c:327 #3 0x55bd4ff810fc in perf_evsel__newtp /home/work/linux/tools/perf/util/evsel.h:216 #4 0x55bd4ff81608 in test__perf_evsel__tp_sched_test tests/evsel-tp-sched.c:69 #5 0x55bd4ff528e6 in run_test tests/builtin-test.c:358 #6 0x55bd4ff52baf in test_and_print tests/builtin-test.c:388 #7 0x55bd4ff543fe in __cmd_test tests/builtin-test.c:583 #8 0x55bd4ff5572f in cmd_test tests/builtin-test.c:722 #9 0x55bd4ffc4087 in run_builtin /home/changbin/work/linux/tools/perf/perf.c:302 #10 0x55bd4ffc45c6 in handle_internal_command /home/changbin/work/linux/tools/perf/perf.c:354 #11 0x55bd4ffc49ca in run_argv /home/changbin/work/linux/tools/perf/perf.c:398 #12 0x55bd4ffc5138 in main /home/changbin/work/linux/tools/perf/perf.c:520 #13 0x7f1b6e34809a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2409a) Indirect leak of 19 byte(s) in 1 object(s) allocated from: #0 0x7f1b6fc83f30 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0xedf30) #1 0x7f1b6e3ac30f in vasprintf (/lib/x86_64-linux-gnu/libc.so.6+0x8830f) Signed-off-by: Changbin Du Reviewed-by: Jiri Olsa Cc: Alexei Starovoitov Cc: Daniel Borkmann Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Steven Rostedt (VMware) Fixes: 6a6cd11d4e57 ("perf test: Add test for the sched tracepoint format fields") Link: http://lkml.kernel.org/r/20190316080556.3075-17-changbin.du@gmail.com Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Sasha Levin --- tools/perf/tests/evsel-tp-sched.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/tests/evsel-tp-sched.c b/tools/perf/tests/evsel-tp-sched.c index d0406116c905..926a8e1b5e94 100644 --- a/tools/perf/tests/evsel-tp-sched.c +++ b/tools/perf/tests/evsel-tp-sched.c @@ -85,5 +85,6 @@ int test__perf_evsel__tp_sched_test(struct test *test __maybe_unused, int subtes if (perf_evsel__test_field(evsel, "target_cpu", 4, true)) ret = -1; + perf_evsel__delete(evsel); return ret; } -- GitLab From 04260753ba278303c9a9a551b56867cb6590d0a7 Mon Sep 17 00:00:00 2001 From: Jianguo Chen Date: Wed, 20 Mar 2019 18:54:21 +0000 Subject: [PATCH 0112/1121] irqchip/mbigen: Don't clear eventid when freeing an MSI [ Upstream commit fca269f201a8d9985c0a31fb60b15d4eb57cef80 ] mbigen_write_msg clears eventid bits of a mbigen register when free a interrupt, because msi_domain_deactivate memset struct msg to zero. Then multiple mbigen pins with zero eventid will report the same interrupt number. The eventid clear call trace: free_irq __free_irq irq_shutdown irq_domain_deactivate_irq __irq_domain_deactivate_irq __irq_domain_deactivate_irq msi_domain_deactivate platform_msi_write_msg mbigen_write_msg Signed-off-by: Jianguo Chen [maz: massaged subject] Signed-off-by: Marc Zyngier Signed-off-by: Sasha Levin --- drivers/irqchip/irq-mbigen.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c index 567b29c47608..98b6e1d4b1a6 100644 --- a/drivers/irqchip/irq-mbigen.c +++ b/drivers/irqchip/irq-mbigen.c @@ -161,6 +161,9 @@ static void mbigen_write_msg(struct msi_desc *desc, struct msi_msg *msg) void __iomem *base = d->chip_data; u32 val; + if (!msg->address_lo && !msg->address_hi) + return; + base += get_mbigen_vec_reg(d->hwirq); val = readl_relaxed(base); -- GitLab From c65812de901537e6dec45a66fd86f4f535925644 Mon Sep 17 00:00:00 2001 From: Aditya Pakki Date: Mon, 18 Mar 2019 21:19:56 -0500 Subject: [PATCH 0113/1121] x86/hpet: Prevent potential NULL pointer dereference [ Upstream commit 2e84f116afca3719c9d0a1a78b47b48f75fd5724 ] hpet_virt_address may be NULL when ioremap_nocache fail, but the code lacks a check. Add a check to prevent NULL pointer dereference. Signed-off-by: Aditya Pakki Signed-off-by: Thomas Gleixner Cc: kjlu@umn.edu Cc: Borislav Petkov Cc: "H. Peter Anvin" Cc: Kees Cook Cc: Joe Perches Cc: Nicolai Stange Cc: Roland Dreier Link: https://lkml.kernel.org/r/20190319021958.17275-1-pakki001@umn.edu Signed-off-by: Sasha Levin --- arch/x86/kernel/hpet.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index afa1a204bc6d..df767e6de8dd 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c @@ -909,6 +909,8 @@ int __init hpet_enable(void) return 0; hpet_set_mapping(); + if (!hpet_virt_address) + return 0; /* * Read the period and check for a sane value: -- GitLab From 20afb90f730982882e65b01fb8bdfe83914339c5 Mon Sep 17 00:00:00 2001 From: Matthew Whitehead Date: Thu, 14 Mar 2019 16:46:00 -0400 Subject: [PATCH 0114/1121] x86/cpu/cyrix: Use correct macros for Cyrix calls on Geode processors [ Upstream commit 18fb053f9b827bd98cfc64f2a35df8ab19745a1d ] There are comments in processor-cyrix.h advising you to _not_ make calls using the deprecated macros in this style: setCx86_old(CX86_CCR4, getCx86_old(CX86_CCR4) | 0x80); This is because it expands the macro into a non-functioning calling sequence. The calling order must be: outb(CX86_CCR2, 0x22); inb(0x23); From the comments: * When using the old macros a line like * setCx86(CX86_CCR2, getCx86(CX86_CCR2) | 0x88); * gets expanded to: * do { * outb((CX86_CCR2), 0x22); * outb((({ * outb((CX86_CCR2), 0x22); * inb(0x23); * }) | 0x88), 0x23); * } while (0); The new macros fix this problem, so use them instead. Tested on an actual Geode processor. Signed-off-by: Matthew Whitehead Signed-off-by: Thomas Gleixner Cc: luto@kernel.org Link: https://lkml.kernel.org/r/1552596361-8967-2-git-send-email-tedheadster@gmail.com Signed-off-by: Sasha Levin --- arch/x86/kernel/cpu/cyrix.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/x86/kernel/cpu/cyrix.c b/arch/x86/kernel/cpu/cyrix.c index 8949b7ae6d92..fa61c870ada9 100644 --- a/arch/x86/kernel/cpu/cyrix.c +++ b/arch/x86/kernel/cpu/cyrix.c @@ -124,7 +124,7 @@ static void set_cx86_reorder(void) setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN */ /* Load/Store Serialize to mem access disable (=reorder it) */ - setCx86_old(CX86_PCR0, getCx86_old(CX86_PCR0) & ~0x80); + setCx86(CX86_PCR0, getCx86(CX86_PCR0) & ~0x80); /* set load/store serialize from 1GB to 4GB */ ccr3 |= 0xe0; setCx86(CX86_CCR3, ccr3); @@ -135,11 +135,11 @@ static void set_cx86_memwb(void) pr_info("Enable Memory-Write-back mode on Cyrix/NSC processor.\n"); /* CCR2 bit 2: unlock NW bit */ - setCx86_old(CX86_CCR2, getCx86_old(CX86_CCR2) & ~0x04); + setCx86(CX86_CCR2, getCx86(CX86_CCR2) & ~0x04); /* set 'Not Write-through' */ write_cr0(read_cr0() | X86_CR0_NW); /* CCR2 bit 2: lock NW bit and set WT1 */ - setCx86_old(CX86_CCR2, getCx86_old(CX86_CCR2) | 0x14); + setCx86(CX86_CCR2, getCx86(CX86_CCR2) | 0x14); } /* @@ -153,14 +153,14 @@ static void geode_configure(void) local_irq_save(flags); /* Suspend on halt power saving and enable #SUSP pin */ - setCx86_old(CX86_CCR2, getCx86_old(CX86_CCR2) | 0x88); + setCx86(CX86_CCR2, getCx86(CX86_CCR2) | 0x88); ccr3 = getCx86(CX86_CCR3); setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN */ /* FPU fast, DTE cache, Mem bypass */ - setCx86_old(CX86_CCR4, getCx86_old(CX86_CCR4) | 0x38); + setCx86(CX86_CCR4, getCx86(CX86_CCR4) | 0x38); setCx86(CX86_CCR3, ccr3); /* disable MAPEN */ set_cx86_memwb(); @@ -296,7 +296,7 @@ static void init_cyrix(struct cpuinfo_x86 *c) /* GXm supports extended cpuid levels 'ala' AMD */ if (c->cpuid_level == 2) { /* Enable cxMMX extensions (GX1 Datasheet 54) */ - setCx86_old(CX86_CCR7, getCx86_old(CX86_CCR7) | 1); + setCx86(CX86_CCR7, getCx86(CX86_CCR7) | 1); /* * GXm : 0x30 ... 0x5f GXm datasheet 51 @@ -319,7 +319,7 @@ static void init_cyrix(struct cpuinfo_x86 *c) if (dir1 > 7) { dir0_msn++; /* M II */ /* Enable MMX extensions (App note 108) */ - setCx86_old(CX86_CCR7, getCx86_old(CX86_CCR7)|1); + setCx86(CX86_CCR7, getCx86(CX86_CCR7)|1); } else { /* A 6x86MX - it has the bug. */ set_cpu_bug(c, X86_BUG_COMA); -- GitLab From 19525f7b031f1018a74ed3760b81a4f0f3940fa3 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Thu, 28 Feb 2019 20:24:59 +0800 Subject: [PATCH 0115/1121] drm/nouveau/debugfs: Fix check of pm_runtime_get_sync failure [ Upstream commit 909e9c9c428376e2a43d178ed4b0a2d5ba9cb7d3 ] pm_runtime_get_sync returns negative on failure. Fixes: eaeb9010bb4b ("drm/nouveau/debugfs: Wake up GPU before doing any reclocking") Signed-off-by: YueHaibing Signed-off-by: Ben Skeggs Signed-off-by: Sasha Levin --- drivers/gpu/drm/nouveau/nouveau_debugfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_debugfs.c b/drivers/gpu/drm/nouveau/nouveau_debugfs.c index 9109b69cd052..9635704a1d86 100644 --- a/drivers/gpu/drm/nouveau/nouveau_debugfs.c +++ b/drivers/gpu/drm/nouveau/nouveau_debugfs.c @@ -161,7 +161,7 @@ nouveau_debugfs_pstate_set(struct file *file, const char __user *ubuf, } ret = pm_runtime_get_sync(drm->dev); - if (IS_ERR_VALUE(ret) && ret != -EACCES) + if (ret < 0 && ret != -EACCES) return ret; ret = nvif_mthd(ctrl, NVIF_CONTROL_PSTATE_USER, &args, sizeof(args)); pm_runtime_put_autosuspend(drm->dev); -- GitLab From 486d82206c3bfd21f9ea4a3b6bca8ca7c9060285 Mon Sep 17 00:00:00 2001 From: Lu Baolu Date: Wed, 20 Mar 2019 09:58:33 +0800 Subject: [PATCH 0116/1121] iommu/vt-d: Check capability before disabling protected memory [ Upstream commit 5bb71fc790a88d063507dc5d445ab8b14e845591 ] The spec states in 10.4.16 that the Protected Memory Enable Register should be treated as read-only for implementations not supporting protected memory regions (PLMR and PHMR fields reported as Clear in the Capability register). Cc: Jacob Pan Cc: mark gross Suggested-by: Ashok Raj Fixes: f8bab73515ca5 ("intel-iommu: PMEN support") Signed-off-by: Lu Baolu Signed-off-by: Joerg Roedel Signed-off-by: Sasha Levin --- drivers/iommu/intel-iommu.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 802ba7b16e09..fe935293fa7b 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -1646,6 +1646,9 @@ static void iommu_disable_protect_mem_regions(struct intel_iommu *iommu) u32 pmen; unsigned long flags; + if (!cap_plmr(iommu->cap) && !cap_phmr(iommu->cap)) + return; + raw_spin_lock_irqsave(&iommu->register_lock, flags); pmen = readl(iommu->reg + DMAR_PMEN_REG); pmen &= ~DMA_PMEN_EPM; -- GitLab From 727344f1bb2d517b921cdf2e1e2508c4c4de2104 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Thu, 7 Mar 2019 14:27:56 -0700 Subject: [PATCH 0117/1121] x86/hw_breakpoints: Make default case in hw_breakpoint_arch_parse() return an error [ Upstream commit e898e69d6b9475bf123f99b3c5d1a67bb7cb2361 ] When building with -Wsometimes-uninitialized, Clang warns: arch/x86/kernel/hw_breakpoint.c:355:2: warning: variable 'align' is used uninitialized whenever switch default is taken [-Wsometimes-uninitialized] The default cannot be reached because arch_build_bp_info() initializes hw->len to one of the specified cases. Nevertheless the warning is valid and returning -EINVAL makes sure that this cannot be broken by future modifications. Suggested-by: Nick Desaulniers Signed-off-by: Nathan Chancellor Signed-off-by: Thomas Gleixner Reviewed-by: Nick Desaulniers Cc: Borislav Petkov Cc: "H. Peter Anvin" Cc: clang-built-linux@googlegroups.com Link: https://github.com/ClangBuiltLinux/linux/issues/392 Link: https://lkml.kernel.org/r/20190307212756.4648-1-natechancellor@gmail.com Signed-off-by: Sasha Levin --- arch/x86/kernel/hw_breakpoint.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/kernel/hw_breakpoint.c b/arch/x86/kernel/hw_breakpoint.c index 8771766d46b6..9954a604a822 100644 --- a/arch/x86/kernel/hw_breakpoint.c +++ b/arch/x86/kernel/hw_breakpoint.c @@ -352,6 +352,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp) #endif default: WARN_ON_ONCE(1); + return -EINVAL; } /* -- GitLab From 329f34e8cddf66b21e3ad0082fcb410fdc5e61ac Mon Sep 17 00:00:00 2001 From: Steve French Date: Sun, 17 Mar 2019 15:58:38 -0500 Subject: [PATCH 0118/1121] fix incorrect error code mapping for OBJECTID_NOT_FOUND [ Upstream commit 85f9987b236cf46e06ffdb5c225cf1f3c0acb789 ] It was mapped to EIO which can be confusing when user space queries for an object GUID for an object for which the server file system doesn't support (or hasn't saved one). As Amir Goldstein suggested this is similar to ENOATTR (equivalently ENODATA in Linux errno definitions) so changing NT STATUS code mapping for OBJECTID_NOT_FOUND to ENODATA. Signed-off-by: Steve French CC: Amir Goldstein Signed-off-by: Sasha Levin --- fs/cifs/smb2maperror.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/cifs/smb2maperror.c b/fs/cifs/smb2maperror.c index d7e839cb773f..92c9cdf4704d 100644 --- a/fs/cifs/smb2maperror.c +++ b/fs/cifs/smb2maperror.c @@ -1035,7 +1035,8 @@ static const struct status_to_posix_error smb2_error_map_table[] = { {STATUS_UNFINISHED_CONTEXT_DELETED, -EIO, "STATUS_UNFINISHED_CONTEXT_DELETED"}, {STATUS_NO_TGT_REPLY, -EIO, "STATUS_NO_TGT_REPLY"}, - {STATUS_OBJECTID_NOT_FOUND, -EIO, "STATUS_OBJECTID_NOT_FOUND"}, + /* Note that ENOATTTR and ENODATA are the same errno */ + {STATUS_OBJECTID_NOT_FOUND, -ENODATA, "STATUS_OBJECTID_NOT_FOUND"}, {STATUS_NO_IP_ADDRESSES, -EIO, "STATUS_NO_IP_ADDRESSES"}, {STATUS_WRONG_CREDENTIAL_HANDLE, -EIO, "STATUS_WRONG_CREDENTIAL_HANDLE"}, -- GitLab From 6fee657dfd593ad45c762fa2613c0c14406188ba Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Sat, 23 Mar 2019 12:10:29 -0400 Subject: [PATCH 0119/1121] ext4: prohibit fstrim in norecovery mode [ Upstream commit 18915b5873f07e5030e6fb108a050fa7c71c59fb ] The ext4 fstrim implementation uses the block bitmaps to find free space that can be discarded. If we haven't replayed the journal, the bitmaps will be stale and we absolutely *cannot* use stale metadata to zap the underlying storage. Signed-off-by: Darrick J. Wong Signed-off-by: Theodore Ts'o Signed-off-by: Sasha Levin --- fs/ext4/ioctl.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index 7917cc89ab21..3dbf4e414706 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c @@ -940,6 +940,13 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (!blk_queue_discard(q)) return -EOPNOTSUPP; + /* + * We haven't replayed the journal, so we cannot use our + * block-bitmap-guided storage zapping commands. + */ + if (test_opt(sb, NOLOAD) && ext4_has_feature_journal(sb)) + return -EROFS; + if (copy_from_user(&range, (struct fstrim_range __user *)arg, sizeof(range))) return -EFAULT; -- GitLab From 15fbb1fe07a338d9228524873bc881813b83e834 Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Sat, 25 Aug 2018 10:44:17 +0200 Subject: [PATCH 0120/1121] gpio: pxa: handle corner case of unprobed device [ Upstream commit 9ce3ebe973bf4073426f35f282c6b955ed802765 ] In the corner case where the gpio driver probe fails, for whatever reason, the suspend and resume handlers will still be called as they have to be registered as syscore operations. This applies as well when no probe was called while the driver has been built in the kernel. Nicolas tracked this in : https://bugzilla.kernel.org/show_bug.cgi?id=200905 Therefore, add a failsafe in these function, and test if a proper probe succeeded and the driver is functional. Signed-off-by: Robert Jarzmik Reported-by: Nicolas Chauvet Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin --- drivers/gpio/gpio-pxa.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c index 2943dfc4c470..822ad220f0af 100644 --- a/drivers/gpio/gpio-pxa.c +++ b/drivers/gpio/gpio-pxa.c @@ -776,6 +776,9 @@ static int pxa_gpio_suspend(void) struct pxa_gpio_bank *c; int gpio; + if (!pchip) + return 0; + for_each_gpio_bank(gpio, c, pchip) { c->saved_gplr = readl_relaxed(c->regbase + GPLR_OFFSET); c->saved_gpdr = readl_relaxed(c->regbase + GPDR_OFFSET); @@ -794,6 +797,9 @@ static void pxa_gpio_resume(void) struct pxa_gpio_bank *c; int gpio; + if (!pchip) + return; + for_each_gpio_bank(gpio, c, pchip) { /* restore level with set/clear */ writel_relaxed(c->saved_gplr, c->regbase + GPSR_OFFSET); -- GitLab From ad78e2e057ab8d914a2b5e3e6acf29c3c8a428a3 Mon Sep 17 00:00:00 2001 From: Siva Rebbagondla Date: Mon, 27 Aug 2018 17:05:15 +0530 Subject: [PATCH 0121/1121] rsi: improve kernel thread handling to fix kernel panic [ Upstream commit 4c62764d0fc21a34ffc44eec1210038c3a2e4473 ] While running regressions, observed below kernel panic when sdio disconnect called. This is because of, kthread_stop() is taking care of wait_for_completion() by default. When wait_for_completion triggered in kthread_stop and as it was done already, giving kernel panic. Hence, removing redundant wait_for_completion() from rsi_kill_thread(). ... skipping ... BUG: unable to handle kernel NULL pointer dereference at (null) IP: [] exit_creds+0x1f/0x50 PGD 0 Oops: 0002 [#1] SMP CPU: 0 PID: 6502 Comm: rmmod Tainted: G OE 4.15.9-Generic #154-Ubuntu Hardware name: Dell Inc. Edge Gateway 3003/ , BIOS 01.00.00 04/17/2017 Stack: ffff88007392e600 ffff880075847dc0 ffffffff8108160a 0000000000000000 ffff88007392e600 ffff880075847de8 ffffffff810a484b ffff880076127000 ffff88003cd3a800 ffff880074f12a00 ffff880075847e28 ffffffffc09bed15 Call Trace: [] __put_task_struct+0x5a/0x140 [] kthread_stop+0x10b/0x110 [] rsi_disconnect+0x2f5/0x300 [ven_rsi_sdio] [] ? __pm_runtime_resume+0x5b/0x80 [] sdio_bus_remove+0x38/0x100 [] __device_release_driver+0xa4/0x150 [] driver_detach+0xb5/0xc0 [] bus_remove_driver+0x55/0xd0 [] driver_unregister+0x2c/0x50 [] sdio_unregister_driver+0x1a/0x20 [] rsi_module_exit+0x15/0x30 [ven_rsi_sdio] [] SyS_delete_module+0x1b8/0x210 [] entry_SYSCALL_64_fastpath+0x1c/0xbb Signed-off-by: Siva Rebbagondla Signed-off-by: Kalle Valo Signed-off-by: Sasha Levin --- drivers/net/wireless/rsi/rsi_common.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/rsi/rsi_common.h b/drivers/net/wireless/rsi/rsi_common.h index e579d694d13c..21986ba56a3c 100644 --- a/drivers/net/wireless/rsi/rsi_common.h +++ b/drivers/net/wireless/rsi/rsi_common.h @@ -74,7 +74,6 @@ static inline int rsi_kill_thread(struct rsi_thread *handle) atomic_inc(&handle->thread_done); rsi_set_event(&handle->event); - wait_for_completion(&handle->completion); return kthread_stop(handle->task); } -- GitLab From fdf0c593ec3e7924952f195933f676e53b319302 Mon Sep 17 00:00:00 2001 From: Gertjan Halkes Date: Wed, 5 Sep 2018 15:41:29 +0900 Subject: [PATCH 0122/1121] 9p: do not trust pdu content for stat item size [ Upstream commit 2803cf4379ed252894f046cb8812a48db35294e3 ] v9fs_dir_readdir() could deadloop if a struct was sent with a size set to -2 Link: http://lkml.kernel.org/r/1536134432-11997-1-git-send-email-asmadeus@codewreck.org Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=88021 Signed-off-by: Gertjan Halkes Signed-off-by: Dominique Martinet Signed-off-by: Sasha Levin --- fs/9p/vfs_dir.c | 8 +++----- net/9p/protocol.c | 3 ++- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c index 48db9a9f13f9..cb6c4031af55 100644 --- a/fs/9p/vfs_dir.c +++ b/fs/9p/vfs_dir.c @@ -105,7 +105,6 @@ static int v9fs_dir_readdir(struct file *file, struct dir_context *ctx) int err = 0; struct p9_fid *fid; int buflen; - int reclen = 0; struct p9_rdir *rdir; struct kvec kvec; @@ -138,11 +137,10 @@ static int v9fs_dir_readdir(struct file *file, struct dir_context *ctx) while (rdir->head < rdir->tail) { err = p9stat_read(fid->clnt, rdir->buf + rdir->head, rdir->tail - rdir->head, &st); - if (err) { + if (err <= 0) { p9_debug(P9_DEBUG_VFS, "returned %d\n", err); return -EIO; } - reclen = st.size+2; over = !dir_emit(ctx, st.name, strlen(st.name), v9fs_qid2ino(&st.qid), dt_type(&st)); @@ -150,8 +148,8 @@ static int v9fs_dir_readdir(struct file *file, struct dir_context *ctx) if (over) return 0; - rdir->head += reclen; - ctx->pos += reclen; + rdir->head += err; + ctx->pos += err; } } } diff --git a/net/9p/protocol.c b/net/9p/protocol.c index 9743837aebc6..766d1ef4640a 100644 --- a/net/9p/protocol.c +++ b/net/9p/protocol.c @@ -570,9 +570,10 @@ int p9stat_read(struct p9_client *clnt, char *buf, int len, struct p9_wstat *st) if (ret) { p9_debug(P9_DEBUG_9P, "<<< p9stat_read failed: %d\n", ret); trace_9p_protocol_dump(clnt, &fake_pdu); + return ret; } - return ret; + return fake_pdu.offset; } EXPORT_SYMBOL(p9stat_read); -- GitLab From 85a2ad155826deef3cab4f5c704c620aeba3292b Mon Sep 17 00:00:00 2001 From: Dinu-Razvan Chis-Serban Date: Wed, 5 Sep 2018 16:44:12 +0900 Subject: [PATCH 0123/1121] 9p locks: add mount option for lock retry interval [ Upstream commit 5e172f75e51e3de1b4274146d9b990f803cb5c2a ] The default P9_LOCK_TIMEOUT can be too long for some users exporting a local file system to a guest VM (30s), make this configurable at mount time. Link: http://lkml.kernel.org/r/1536295827-3181-1-git-send-email-asmadeus@codewreck.org Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=195727 Signed-off-by: Dinu-Razvan Chis-Serban Signed-off-by: Dominique Martinet Signed-off-by: Sasha Levin --- fs/9p/v9fs.c | 21 +++++++++++++++++++++ fs/9p/v9fs.h | 1 + fs/9p/vfs_file.c | 6 +++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index 8fb89ddc6cc7..c52f10efdc9c 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c @@ -61,6 +61,8 @@ enum { Opt_cache_loose, Opt_fscache, Opt_mmap, /* Access options */ Opt_access, Opt_posixacl, + /* Lock timeout option */ + Opt_locktimeout, /* Error token */ Opt_err }; @@ -80,6 +82,7 @@ static const match_table_t tokens = { {Opt_cachetag, "cachetag=%s"}, {Opt_access, "access=%s"}, {Opt_posixacl, "posixacl"}, + {Opt_locktimeout, "locktimeout=%u"}, {Opt_err, NULL} }; @@ -187,6 +190,7 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts) #ifdef CONFIG_9P_FSCACHE v9ses->cachetag = NULL; #endif + v9ses->session_lock_timeout = P9_LOCK_TIMEOUT; if (!opts) return 0; @@ -360,6 +364,23 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts) #endif break; + case Opt_locktimeout: + r = match_int(&args[0], &option); + if (r < 0) { + p9_debug(P9_DEBUG_ERROR, + "integer field, but no integer?\n"); + ret = r; + continue; + } + if (option < 1) { + p9_debug(P9_DEBUG_ERROR, + "locktimeout must be a greater than zero integer.\n"); + ret = -EINVAL; + continue; + } + v9ses->session_lock_timeout = (long)option * HZ; + break; + default: continue; } diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h index 982e017acadb..129e5243a6bf 100644 --- a/fs/9p/v9fs.h +++ b/fs/9p/v9fs.h @@ -116,6 +116,7 @@ struct v9fs_session_info { struct p9_client *clnt; /* 9p client */ struct list_head slist; /* list of sessions registered with v9fs */ struct rw_semaphore rename_sem; + long session_lock_timeout; /* retry interval for blocking locks */ }; /* cache_validity flags */ diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index af8cac975a74..89e69904976a 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c @@ -154,6 +154,7 @@ static int v9fs_file_do_lock(struct file *filp, int cmd, struct file_lock *fl) uint8_t status = P9_LOCK_ERROR; int res = 0; unsigned char fl_type; + struct v9fs_session_info *v9ses; fid = filp->private_data; BUG_ON(fid == NULL); @@ -189,6 +190,8 @@ static int v9fs_file_do_lock(struct file *filp, int cmd, struct file_lock *fl) if (IS_SETLKW(cmd)) flock.flags = P9_LOCK_FLAGS_BLOCK; + v9ses = v9fs_inode2v9ses(file_inode(filp)); + /* * if its a blocked request and we get P9_LOCK_BLOCKED as the status * for lock request, keep on trying @@ -202,7 +205,8 @@ static int v9fs_file_do_lock(struct file *filp, int cmd, struct file_lock *fl) break; if (status == P9_LOCK_BLOCKED && !IS_SETLKW(cmd)) break; - if (schedule_timeout_interruptible(P9_LOCK_TIMEOUT) != 0) + if (schedule_timeout_interruptible(v9ses->session_lock_timeout) + != 0) break; /* * p9_client_lock_dotl overwrites flock.client_id with the -- GitLab From 40e8d128f5ed918bc9f19708e1320efea1c0c24a Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Thu, 6 Sep 2018 20:34:12 +0800 Subject: [PATCH 0124/1121] f2fs: fix to do sanity check with current segment number [ Upstream commit 042be0f849e5fc24116d0afecfaf926eed5cac63 ] https://bugzilla.kernel.org/show_bug.cgi?id=200219 Reproduction way: - mount image - run poc code - umount image F2FS-fs (loop1): Bitmap was wrongly set, blk:15364 ------------[ cut here ]------------ kernel BUG at /home/yuchao/git/devf2fs/segment.c:2061! invalid opcode: 0000 [#1] PREEMPT SMP CPU: 2 PID: 17686 Comm: umount Tainted: G W O 4.18.0-rc2+ #39 Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006 EIP: update_sit_entry+0x459/0x4e0 [f2fs] Code: e8 1c b5 fd ff 0f 0b 0f 0b 8b 45 e4 c7 44 24 08 9c 7a 6c f8 c7 44 24 04 bc 4a 6c f8 89 44 24 0c 8b 06 89 04 24 e8 f7 b4 fd ff <0f> 0b 8b 45 e4 0f b6 d2 89 54 24 10 c7 44 24 08 60 7a 6c f8 c7 44 EAX: 00000032 EBX: 000000f8 ECX: 00000002 EDX: 00000001 ESI: d7177000 EDI: f520fe68 EBP: d6477c6c ESP: d6477c34 DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 EFLAGS: 00010282 CR0: 80050033 CR2: b7fbe000 CR3: 2a99b3c0 CR4: 000406f0 Call Trace: f2fs_allocate_data_block+0x124/0x580 [f2fs] do_write_page+0x78/0x150 [f2fs] f2fs_do_write_node_page+0x25/0xa0 [f2fs] __write_node_page+0x2bf/0x550 [f2fs] f2fs_sync_node_pages+0x60e/0x6d0 [f2fs] ? sync_inode_metadata+0x2f/0x40 ? f2fs_write_checkpoint+0x28f/0x7d0 [f2fs] ? up_write+0x1e/0x80 f2fs_write_checkpoint+0x2a9/0x7d0 [f2fs] ? mark_held_locks+0x5d/0x80 ? _raw_spin_unlock_irq+0x27/0x50 kill_f2fs_super+0x68/0x90 [f2fs] deactivate_locked_super+0x3d/0x70 deactivate_super+0x40/0x60 cleanup_mnt+0x39/0x70 __cleanup_mnt+0x10/0x20 task_work_run+0x81/0xa0 exit_to_usermode_loop+0x59/0xa7 do_fast_syscall_32+0x1f5/0x22c entry_SYSENTER_32+0x53/0x86 EIP: 0xb7f95c51 Code: c1 1e f7 ff ff 89 e5 8b 55 08 85 d2 8b 81 64 cd ff ff 74 02 89 02 5d c3 8b 0c 24 c3 8b 1c 24 c3 90 51 52 55 89 e5 0f 34 cd 80 <5d> 5a 59 c3 90 90 90 90 8d 76 00 58 b8 77 00 00 00 cd 80 90 8d 76 EAX: 00000000 EBX: 0871ab90 ECX: bfb2cd00 EDX: 00000000 ESI: 00000000 EDI: 0871ab90 EBP: 0871ab90 ESP: bfb2cd7c DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 007b EFLAGS: 00000246 Modules linked in: f2fs(O) crc32_generic bnep rfcomm bluetooth ecdh_generic snd_intel8x0 snd_ac97_codec ac97_bus snd_pcm snd_seq_midi snd_seq_midi_event snd_rawmidi snd_seq pcbc joydev aesni_intel snd_seq_device aes_i586 snd_timer crypto_simd snd cryptd soundcore mac_hid serio_raw video i2c_piix4 parport_pc ppdev lp parport hid_generic psmouse usbhid hid e1000 [last unloaded: f2fs] ---[ end trace d423f83982cfcdc5 ]--- The reason is, different log headers using the same segment, once one log's next block address is used by another log, it will cause panic as above. Main area: 24 segs, 24 secs 24 zones - COLD data: 0, 0, 0 - WARM data: 1, 1, 1 - HOT data: 20, 20, 20 - Dir dnode: 22, 22, 22 - File dnode: 22, 22, 22 - Indir nodes: 21, 21, 21 So this patch adds sanity check to detect such condition to avoid this issue. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Sasha Levin --- fs/f2fs/super.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index fc5c41257e68..4c169ba50c0f 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1959,7 +1959,7 @@ int sanity_check_ckpt(struct f2fs_sb_info *sbi) unsigned int segment_count_main; unsigned int cp_pack_start_sum, cp_payload; block_t user_block_count; - int i; + int i, j; total = le32_to_cpu(raw_super->segment_count); fsmeta = le32_to_cpu(raw_super->segment_count_ckpt); @@ -2000,11 +2000,43 @@ int sanity_check_ckpt(struct f2fs_sb_info *sbi) if (le32_to_cpu(ckpt->cur_node_segno[i]) >= main_segs || le16_to_cpu(ckpt->cur_node_blkoff[i]) >= blocks_per_seg) return 1; + for (j = i + 1; j < NR_CURSEG_NODE_TYPE; j++) { + if (le32_to_cpu(ckpt->cur_node_segno[i]) == + le32_to_cpu(ckpt->cur_node_segno[j])) { + f2fs_msg(sbi->sb, KERN_ERR, + "Node segment (%u, %u) has the same " + "segno: %u", i, j, + le32_to_cpu(ckpt->cur_node_segno[i])); + return 1; + } + } } for (i = 0; i < NR_CURSEG_DATA_TYPE; i++) { if (le32_to_cpu(ckpt->cur_data_segno[i]) >= main_segs || le16_to_cpu(ckpt->cur_data_blkoff[i]) >= blocks_per_seg) return 1; + for (j = i + 1; j < NR_CURSEG_DATA_TYPE; j++) { + if (le32_to_cpu(ckpt->cur_data_segno[i]) == + le32_to_cpu(ckpt->cur_data_segno[j])) { + f2fs_msg(sbi->sb, KERN_ERR, + "Data segment (%u, %u) has the same " + "segno: %u", i, j, + le32_to_cpu(ckpt->cur_data_segno[i])); + return 1; + } + } + } + for (i = 0; i < NR_CURSEG_NODE_TYPE; i++) { + for (j = i; j < NR_CURSEG_DATA_TYPE; j++) { + if (le32_to_cpu(ckpt->cur_node_segno[i]) == + le32_to_cpu(ckpt->cur_data_segno[j])) { + f2fs_msg(sbi->sb, KERN_ERR, + "Data segment (%u) and Data segment (%u)" + " has the same segno: %u", i, j, + le32_to_cpu(ckpt->cur_node_segno[i])); + return 1; + } + } } sit_bitmap_size = le32_to_cpu(ckpt->sit_ver_bitmap_bytesize); -- GitLab From edbcdafac3e44346b8f8321a03b5434c26cddb80 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 4 Sep 2018 12:07:55 +0200 Subject: [PATCH 0125/1121] netfilter: xt_cgroup: shrink size of v2 path [ Upstream commit 0d704967f4a49cc2212350b3e4a8231f8b4283ed ] cgroup v2 path field is PATH_MAX which is too large, this is placing too much pressure on memory allocation for people with many rules doing cgroup v1 classid matching, side effects of this are bug reports like: https://bugzilla.kernel.org/show_bug.cgi?id=200639 This patch registers a new revision that shrinks the cgroup path to 512 bytes, which is the same approach we follow in similar extensions that have a path field. Cc: Tejun Heo Signed-off-by: Pablo Neira Ayuso Acked-by: Tejun Heo Signed-off-by: Sasha Levin --- include/uapi/linux/netfilter/xt_cgroup.h | 16 ++++++ net/netfilter/xt_cgroup.c | 72 ++++++++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/include/uapi/linux/netfilter/xt_cgroup.h b/include/uapi/linux/netfilter/xt_cgroup.h index e96dfa1b34f7..b74e370d6133 100644 --- a/include/uapi/linux/netfilter/xt_cgroup.h +++ b/include/uapi/linux/netfilter/xt_cgroup.h @@ -22,4 +22,20 @@ struct xt_cgroup_info_v1 { void *priv __attribute__((aligned(8))); }; +#define XT_CGROUP_PATH_MAX 512 + +struct xt_cgroup_info_v2 { + __u8 has_path; + __u8 has_classid; + __u8 invert_path; + __u8 invert_classid; + union { + char path[XT_CGROUP_PATH_MAX]; + __u32 classid; + }; + + /* kernel internal data */ + void *priv __attribute__((aligned(8))); +}; + #endif /* _UAPI_XT_CGROUP_H */ diff --git a/net/netfilter/xt_cgroup.c b/net/netfilter/xt_cgroup.c index 891f4e7e8ea7..db18c0177b0f 100644 --- a/net/netfilter/xt_cgroup.c +++ b/net/netfilter/xt_cgroup.c @@ -66,6 +66,38 @@ static int cgroup_mt_check_v1(const struct xt_mtchk_param *par) return 0; } +static int cgroup_mt_check_v2(const struct xt_mtchk_param *par) +{ + struct xt_cgroup_info_v2 *info = par->matchinfo; + struct cgroup *cgrp; + + if ((info->invert_path & ~1) || (info->invert_classid & ~1)) + return -EINVAL; + + if (!info->has_path && !info->has_classid) { + pr_info("xt_cgroup: no path or classid specified\n"); + return -EINVAL; + } + + if (info->has_path && info->has_classid) { + pr_info_ratelimited("path and classid specified\n"); + return -EINVAL; + } + + info->priv = NULL; + if (info->has_path) { + cgrp = cgroup_get_from_path(info->path); + if (IS_ERR(cgrp)) { + pr_info_ratelimited("invalid path, errno=%ld\n", + PTR_ERR(cgrp)); + return -EINVAL; + } + info->priv = cgrp; + } + + return 0; +} + static bool cgroup_mt_v0(const struct sk_buff *skb, struct xt_action_param *par) { @@ -95,6 +127,24 @@ static bool cgroup_mt_v1(const struct sk_buff *skb, struct xt_action_param *par) info->invert_classid; } +static bool cgroup_mt_v2(const struct sk_buff *skb, struct xt_action_param *par) +{ + const struct xt_cgroup_info_v2 *info = par->matchinfo; + struct sock_cgroup_data *skcd = &skb->sk->sk_cgrp_data; + struct cgroup *ancestor = info->priv; + struct sock *sk = skb->sk; + + if (!sk || !sk_fullsock(sk) || !net_eq(xt_net(par), sock_net(sk))) + return false; + + if (ancestor) + return cgroup_is_descendant(sock_cgroup_ptr(skcd), ancestor) ^ + info->invert_path; + else + return (info->classid == sock_cgroup_classid(skcd)) ^ + info->invert_classid; +} + static void cgroup_mt_destroy_v1(const struct xt_mtdtor_param *par) { struct xt_cgroup_info_v1 *info = par->matchinfo; @@ -103,6 +153,14 @@ static void cgroup_mt_destroy_v1(const struct xt_mtdtor_param *par) cgroup_put(info->priv); } +static void cgroup_mt_destroy_v2(const struct xt_mtdtor_param *par) +{ + struct xt_cgroup_info_v2 *info = par->matchinfo; + + if (info->priv) + cgroup_put(info->priv); +} + static struct xt_match cgroup_mt_reg[] __read_mostly = { { .name = "cgroup", @@ -130,6 +188,20 @@ static struct xt_match cgroup_mt_reg[] __read_mostly = { (1 << NF_INET_POST_ROUTING) | (1 << NF_INET_LOCAL_IN), }, + { + .name = "cgroup", + .revision = 2, + .family = NFPROTO_UNSPEC, + .checkentry = cgroup_mt_check_v2, + .match = cgroup_mt_v2, + .matchsize = sizeof(struct xt_cgroup_info_v2), + .usersize = offsetof(struct xt_cgroup_info_v2, priv), + .destroy = cgroup_mt_destroy_v2, + .me = THIS_MODULE, + .hooks = (1 << NF_INET_LOCAL_OUT) | + (1 << NF_INET_POST_ROUTING) | + (1 << NF_INET_LOCAL_IN), + }, }; static int __init cgroup_mt_init(void) -- GitLab From 1fa5208a30e645355b8946bf8645710381d4e735 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 3 Sep 2018 15:10:49 +0200 Subject: [PATCH 0126/1121] serial: uartps: console_setup() can't be placed to init section [ Upstream commit 4bb1ce2350a598502b23088b169e16b43d4bc639 ] When console device is rebinded, console_setup() is called again. But marking it as __init means that function will be clear after boot is complete. If console device is binded again console_setup() is not found and error "Unable to handle kernel paging request at virtual address" is reported. Signed-off-by: Michal Simek Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/tty/serial/xilinx_uartps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index f438a2158006..b0da63737aa1 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c @@ -1270,7 +1270,7 @@ static void cdns_uart_console_write(struct console *co, const char *s, * * Return: 0 on success, negative errno otherwise. */ -static int __init cdns_uart_console_setup(struct console *co, char *options) +static int cdns_uart_console_setup(struct console *co, char *options) { struct uart_port *port = &cdns_uart_port[co->index]; int baud = 9600; -- GitLab From 8b8fa9879d44d9b488ebbadee2ca1da4ac76e033 Mon Sep 17 00:00:00 2001 From: Nathan Fontenot Date: Mon, 10 Sep 2018 09:57:00 -0500 Subject: [PATCH 0127/1121] powerpc/pseries: Remove prrn_work workqueue [ Upstream commit cd24e457fd8b2d087d9236700c8d2957054598bf ] When a PRRN event is received we are already running in a worker thread. Instead of spawning off another worker thread on the prrn_work workqueue to handle the PRRN event we can just call the PRRN handler routine directly. With this update we can also pass the scope variable for the PRRN event directly to the handler instead of it being a global variable. This patch fixes the following oops mnessage we are seeing in PRRN testing: Oops: Bad kernel stack pointer, sig: 6 [#1] SMP NR_CPUS=2048 NUMA pSeries Modules linked in: nfsv3 nfs_acl rpcsec_gss_krb5 auth_rpcgss nfsv4 dns_resolver nfs lockd grace sunrpc fscache binfmt_misc reiserfs vfat fat rpadlpar_io(X) rpaphp(X) tcp_diag udp_diag inet_diag unix_diag af_packet_diag netlink_diag af_packet xfs libcrc32c dm_service_time ibmveth(X) ses enclosure scsi_transport_sas rtc_generic btrfs xor raid6_pq sd_mod ibmvscsi(X) scsi_transport_srp ipr(X) libata sg dm_multipath dm_mod scsi_dh_rdac scsi_dh_emc scsi_dh_alua scsi_mod autofs4 Supported: Yes, External 54 CPU: 7 PID: 18967 Comm: kworker/u96:0 Tainted: G X 4.4.126-94.22-default #1 Workqueue: pseries hotplug workque pseries_hp_work_fn task: c000000775367790 ti: c00000001ebd4000 task.ti: c00000070d140000 NIP: 0000000000000000 LR: 000000001fb3d050 CTR: 0000000000000000 REGS: c00000001ebd7d40 TRAP: 0700 Tainted: G X (4.4.126-94.22-default) MSR: 8000000102081000 <41,VEC,ME5 CR: 28000002 XER: 20040018 4 CFAR: 000000001fb3d084 40 419 1 3 GPR00: 000000000000000040000000000010007 000000001ffff400 000000041fffe200 GPR04: 000000000000008050000000000000000 000000001fb15fa8 0000000500000500 GPR08: 000000000001f40040000000000000001 0000000000000000 000005:5200040002 GPR12: 00000000000000005c000000007a05400 c0000000000e89f8 000000001ed9f668 GPR16: 000000001fbeff944000000001fbeff94 000000001fb545e4 0000006000000060 GPR20: ffffffffffffffff4ffffffffffffffff 0000000000000000 0000000000000000 GPR24: 00000000000000005400000001fb3c000 0000000000000000 000000001fb1b040 GPR28: 000000001fb240004000000001fb440d8 0000000000000008 0000000000000000 NIP [0000000000000000] 5 (null) LR [000000001fb3d050] 031fb3d050 Call Trace: 4 Instruction dump: 4 5:47 12 2 XXXXXXXX XXXXXXXX XXXXX4XX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXX5XX XXXXXXXX 60000000 60000000 60000000 60000000 ---[ end trace aa5627b04a7d9d6b ]--- 3NMI watchdog: BUG: soft lockup - CPU#27 stuck for 23s! [kworker/27:0:13903] Modules linked in: nfsv3 nfs_acl rpcsec_gss_krb5 auth_rpcgss nfsv4 dns_resolver nfs lockd grace sunrpc fscache binfmt_misc reiserfs vfat fat rpadlpar_io(X) rpaphp(X) tcp_diag udp_diag inet_diag unix_diag af_packet_diag netlink_diag af_packet xfs libcrc32c dm_service_time ibmveth(X) ses enclosure scsi_transport_sas rtc_generic btrfs xor raid6_pq sd_mod ibmvscsi(X) scsi_transport_srp ipr(X) libata sg dm_multipath dm_mod scsi_dh_rdac scsi_dh_emc scsi_dh_alua scsi_mod autofs4 Supported: Yes, External CPU: 27 PID: 13903 Comm: kworker/27:0 Tainted: G D X 4.4.126-94.22-default #1 Workqueue: events prrn_work_fn task: c000000747cfa390 ti: c00000074712c000 task.ti: c00000074712c000 NIP: c0000000008002a8 LR: c000000000090770 CTR: 000000000032e088 REGS: c00000074712f7b0 TRAP: 0901 Tainted: G D X (4.4.126-94.22-default) MSR: 8000000100009033 CR: 22482044 XER: 20040000 CFAR: c0000000008002c4 SOFTE: 1 GPR00: c000000000090770 c00000074712fa30 c000000000f09800 c000000000fa1928 6:02 GPR04: c000000775f5e000 fffffffffffffffe 0000000000000001 c000000000f42db8 GPR08: 0000000000000001 0000000080000007 0000000000000000 0000000000000000 GPR12: 8006210083180000 c000000007a14400 NIP [c0000000008002a8] _raw_spin_lock+0x68/0xd0 LR [c000000000090770] mobility_rtas_call+0x50/0x100 Call Trace: 59 5 [c00000074712fa60] [c000000000090770] mobility_rtas_call+0x50/0x100 [c00000074712faf0] [c000000000090b08] pseries_devicetree_update+0xf8/0x530 [c00000074712fc20] [c000000000031ba4] prrn_work_fn+0x34/0x50 [c00000074712fc40] [c0000000000e0390] process_one_work+0x1a0/0x4e0 [c00000074712fcd0] [c0000000000e0870] worker_thread+0x1a0/0x6105:57 2 [c00000074712fd80] [c0000000000e8b18] kthread+0x128/0x150 [c00000074712fe30] [c0000000000096f8] ret_from_kernel_thread+0x5c/0x64 Instruction dump: 2c090000 40c20010 7d40192d 40c2fff0 7c2004ac 2fa90000 40de0018 5:540030 3 e8010010 ebe1fff8 7c0803a6 4e800020 <7c210b78> e92d0000 89290009 792affe3 Signed-off-by: John Allen Signed-off-by: Haren Myneni Signed-off-by: Nathan Fontenot Signed-off-by: Michael Ellerman Signed-off-by: Sasha Levin --- arch/powerpc/kernel/rtasd.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c index 0f0b1b2f3b60..7caeae73348d 100644 --- a/arch/powerpc/kernel/rtasd.c +++ b/arch/powerpc/kernel/rtasd.c @@ -274,27 +274,16 @@ void pSeries_log_error(char *buf, unsigned int err_type, int fatal) } #ifdef CONFIG_PPC_PSERIES -static s32 prrn_update_scope; - -static void prrn_work_fn(struct work_struct *work) +static void handle_prrn_event(s32 scope) { /* * For PRRN, we must pass the negative of the scope value in * the RTAS event. */ - pseries_devicetree_update(-prrn_update_scope); + pseries_devicetree_update(-scope); numa_update_cpu_topology(false); } -static DECLARE_WORK(prrn_work, prrn_work_fn); - -static void prrn_schedule_update(u32 scope) -{ - flush_work(&prrn_work); - prrn_update_scope = scope; - schedule_work(&prrn_work); -} - static void handle_rtas_event(const struct rtas_error_log *log) { if (rtas_error_type(log) != RTAS_TYPE_PRRN || !prrn_is_enabled()) @@ -303,7 +292,7 @@ static void handle_rtas_event(const struct rtas_error_log *log) /* For PRRN Events the extended log length is used to denote * the scope for calling rtas update-nodes. */ - prrn_schedule_update(rtas_error_extended_log_length(log)); + handle_prrn_event(rtas_error_extended_log_length(log)); } #else -- GitLab From fec306b2ef690030a799d1643a2216c4df8d02ce Mon Sep 17 00:00:00 2001 From: Brad Love Date: Thu, 6 Sep 2018 17:07:48 -0400 Subject: [PATCH 0128/1121] media: au0828: cannot kfree dev before usb disconnect [ Upstream commit 4add7104919f9e94e0db03e234caeadbfcc02ea9 ] If au0828_analog_register fails, the dev is kfree'd and then flow jumps to done, which can call au0828_usb_disconnect. Since all USB error codes are negative, au0828_usb_disconnect will be called. The problem is au0828_usb_disconnect uses dev, if dev is NULL then there is immediate oops encountered. [ 7.454307] au0828: au0828_usb_probe() au0282_dev_register failed to register on V4L2 [ 7.454323] BUG: unable to handle kernel NULL pointer dereference at 0000000000000050 [ 7.454421] PGD 0 P4D 0 [ 7.454457] Oops: 0002 [#1] SMP PTI [ 7.454500] CPU: 1 PID: 262 Comm: systemd-udevd Tainted: P O 4.18.3 #1 [ 7.454584] Hardware name: Google Panther/Panther, BIOS MattDevo 04/27/2015 [ 7.454670] RIP: 0010:_raw_spin_lock_irqsave+0x2c/0x50 [ 7.454725] Code: 44 00 00 55 48 89 e5 41 54 53 48 89 fb 9c 58 0f 1f 44 00 00 49 89 c4 fa 66 0f 1f 44 00 00 e8 db 23 1b ff 31 c0 ba 01 00 00 00 0f b1 13 85 c0 75 08 4c 89 e0 5b 41 5c 5d c3 89 c6 48 89 df e8 [ 7.455004] RSP: 0018:ffff9130f53ef988 EFLAGS: 00010046 [ 7.455063] RAX: 0000000000000000 RBX: 0000000000000050 RCX: 0000000000000000 [ 7.455139] RDX: 0000000000000001 RSI: 0000000000000003 RDI: 0000000000000050 [ 7.455216] RBP: ffff9130f53ef998 R08: 0000000000000018 R09: 0000000000000090 [ 7.455292] R10: ffffed4cc53cb000 R11: ffffed4cc53cb108 R12: 0000000000000082 [ 7.455369] R13: ffff9130cf2c6188 R14: 0000000000000000 R15: 0000000000000018 [ 7.455447] FS: 00007f2ff8514cc0(0000) GS:ffff9130fcb00000(0000) knlGS:0000000000000000 [ 7.455535] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 7.455597] CR2: 0000000000000050 CR3: 00000001753f0002 CR4: 00000000000606a0 [ 7.455675] Call Trace: [ 7.455713] __wake_up_common_lock+0x65/0xc0 [ 7.455764] __wake_up+0x13/0x20 [ 7.455808] ir_lirc_unregister+0x57/0xe0 [rc_core] [ 7.455865] rc_unregister_device+0xa0/0xc0 [rc_core] [ 7.455935] au0828_rc_unregister+0x25/0x40 [au0828] [ 7.455999] au0828_usb_disconnect+0x33/0x80 [au0828] [ 7.456064] au0828_usb_probe.cold.16+0x8d/0x2aa [au0828] [ 7.456130] usb_probe_interface+0xf1/0x300 [ 7.456184] driver_probe_device+0x2e3/0x460 [ 7.456235] __driver_attach+0xe4/0x110 [ 7.456282] ? driver_probe_device+0x460/0x460 [ 7.456335] bus_for_each_dev+0x74/0xb0 [ 7.456385] ? kmem_cache_alloc_trace+0x15d/0x1d0 [ 7.456441] driver_attach+0x1e/0x20 [ 7.456485] bus_add_driver+0x159/0x230 [ 7.456532] driver_register+0x70/0xc0 [ 7.456578] usb_register_driver+0x7f/0x140 [ 7.456626] ? 0xffffffffc0474000 [ 7.456674] au0828_init+0xbc/0x1000 [au0828] [ 7.456725] do_one_initcall+0x4a/0x1c9 [ 7.456771] ? _cond_resched+0x19/0x30 [ 7.456817] ? kmem_cache_alloc_trace+0x15d/0x1d0 [ 7.456873] do_init_module+0x60/0x210 [ 7.456918] load_module+0x221b/0x2710 [ 7.456966] ? vfs_read+0xf5/0x120 [ 7.457010] __do_sys_finit_module+0xbd/0x120 [ 7.457061] ? __do_sys_finit_module+0xbd/0x120 [ 7.457115] __x64_sys_finit_module+0x1a/0x20 [ 7.457166] do_syscall_64+0x5b/0x110 [ 7.457210] entry_SYSCALL_64_after_hwframe+0x49/0xbe Signed-off-by: Brad Love Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/usb/au0828/au0828-core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index cd363a2100d4..257ae0d8cfe2 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -629,7 +629,6 @@ static int au0828_usb_probe(struct usb_interface *interface, pr_err("%s() au0282_dev_register failed to register on V4L2\n", __func__); mutex_unlock(&dev->lock); - kfree(dev); goto done; } -- GitLab From e058a6e56e38f90d649fbedb8bfaebb82aea46eb Mon Sep 17 00:00:00 2001 From: Julian Sax Date: Wed, 19 Sep 2018 11:46:23 +0200 Subject: [PATCH 0129/1121] HID: i2c-hid: override HID descriptors for certain devices [ Upstream commit 9ee3e06610fdb8a601cde59c92089fb6c1deb4aa ] A particular touchpad (SIPODEV SP1064) refuses to supply the HID descriptors. This patch provides the framework for overriding these descriptors based on DMI data. It also includes the descriptors for said touchpad, which were extracted by listening to the traffic of the windows filter driver, as well as the DMI data for the laptops known to use this device. Relevant Bug: https://bugzilla.redhat.com/show_bug.cgi?id=1526312 Cc: Hans de Goede Reported-and-tested-by: ahormann@gmx.net Reported-and-tested-by: Bruno Jesus Reported-and-tested-by: Dietrich Reported-and-tested-by: kloxdami@yahoo.com Signed-off-by: Julian Sax Reviewed-by: Benjamin Tissoires Signed-off-by: Jiri Kosina Signed-off-by: Sasha Levin --- drivers/hid/i2c-hid/Makefile | 3 + .../hid/i2c-hid/{i2c-hid.c => i2c-hid-core.c} | 56 ++- drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c | 376 ++++++++++++++++++ drivers/hid/i2c-hid/i2c-hid.h | 20 + 4 files changed, 437 insertions(+), 18 deletions(-) rename drivers/hid/i2c-hid/{i2c-hid.c => i2c-hid-core.c} (96%) create mode 100644 drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c create mode 100644 drivers/hid/i2c-hid/i2c-hid.h diff --git a/drivers/hid/i2c-hid/Makefile b/drivers/hid/i2c-hid/Makefile index 832d8f9aaba2..099e1ce2f234 100644 --- a/drivers/hid/i2c-hid/Makefile +++ b/drivers/hid/i2c-hid/Makefile @@ -3,3 +3,6 @@ # obj-$(CONFIG_I2C_HID) += i2c-hid.o + +i2c-hid-objs = i2c-hid-core.o +i2c-hid-$(CONFIG_DMI) += i2c-hid-dmi-quirks.o diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid-core.c similarity index 96% rename from drivers/hid/i2c-hid/i2c-hid.c rename to drivers/hid/i2c-hid/i2c-hid-core.c index 136a34dc31b8..7842d76aa813 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c @@ -43,6 +43,7 @@ #include #include "../hid-ids.h" +#include "i2c-hid.h" /* quirks to control the device */ #define I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV BIT(0) @@ -663,6 +664,7 @@ static int i2c_hid_parse(struct hid_device *hid) char *rdesc; int ret; int tries = 3; + char *use_override; i2c_hid_dbg(ihid, "entering %s\n", __func__); @@ -681,26 +683,37 @@ static int i2c_hid_parse(struct hid_device *hid) if (ret) return ret; - rdesc = kzalloc(rsize, GFP_KERNEL); + use_override = i2c_hid_get_dmi_hid_report_desc_override(client->name, + &rsize); - if (!rdesc) { - dbg_hid("couldn't allocate rdesc memory\n"); - return -ENOMEM; - } + if (use_override) { + rdesc = use_override; + i2c_hid_dbg(ihid, "Using a HID report descriptor override\n"); + } else { + rdesc = kzalloc(rsize, GFP_KERNEL); - i2c_hid_dbg(ihid, "asking HID report descriptor\n"); + if (!rdesc) { + dbg_hid("couldn't allocate rdesc memory\n"); + return -ENOMEM; + } - ret = i2c_hid_command(client, &hid_report_descr_cmd, rdesc, rsize); - if (ret) { - hid_err(hid, "reading report descriptor failed\n"); - kfree(rdesc); - return -EIO; + i2c_hid_dbg(ihid, "asking HID report descriptor\n"); + + ret = i2c_hid_command(client, &hid_report_descr_cmd, + rdesc, rsize); + if (ret) { + hid_err(hid, "reading report descriptor failed\n"); + kfree(rdesc); + return -EIO; + } } i2c_hid_dbg(ihid, "Report Descriptor: %*ph\n", rsize, rdesc); ret = hid_parse_report(hid, rdesc, rsize); - kfree(rdesc); + if (!use_override) + kfree(rdesc); + if (ret) { dbg_hid("parsing report descriptor failed\n"); return ret; @@ -827,12 +840,19 @@ static int i2c_hid_fetch_hid_descriptor(struct i2c_hid *ihid) int ret; /* i2c hid fetch using a fixed descriptor size (30 bytes) */ - i2c_hid_dbg(ihid, "Fetching the HID descriptor\n"); - ret = i2c_hid_command(client, &hid_descr_cmd, ihid->hdesc_buffer, - sizeof(struct i2c_hid_desc)); - if (ret) { - dev_err(&client->dev, "hid_descr_cmd failed\n"); - return -ENODEV; + if (i2c_hid_get_dmi_i2c_hid_desc_override(client->name)) { + i2c_hid_dbg(ihid, "Using a HID descriptor override\n"); + ihid->hdesc = + *i2c_hid_get_dmi_i2c_hid_desc_override(client->name); + } else { + i2c_hid_dbg(ihid, "Fetching the HID descriptor\n"); + ret = i2c_hid_command(client, &hid_descr_cmd, + ihid->hdesc_buffer, + sizeof(struct i2c_hid_desc)); + if (ret) { + dev_err(&client->dev, "hid_descr_cmd failed\n"); + return -ENODEV; + } } /* Validate the length of HID descriptor, the 4 first bytes: diff --git a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c new file mode 100644 index 000000000000..1d645c9ab417 --- /dev/null +++ b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c @@ -0,0 +1,376 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/* + * Quirks for I2C-HID devices that do not supply proper descriptors + * + * Copyright (c) 2018 Julian Sax + * + */ + +#include +#include +#include + +#include "i2c-hid.h" + + +struct i2c_hid_desc_override { + union { + struct i2c_hid_desc *i2c_hid_desc; + uint8_t *i2c_hid_desc_buffer; + }; + uint8_t *hid_report_desc; + unsigned int hid_report_desc_size; + uint8_t *i2c_name; +}; + + +/* + * descriptors for the SIPODEV SP1064 touchpad + * + * This device does not supply any descriptors and on windows a filter + * driver operates between the i2c-hid layer and the device and injects + * these descriptors when the device is prompted. The descriptors were + * extracted by listening to the i2c-hid traffic that occurs between the + * windows filter driver and the windows i2c-hid driver. + */ + +static const struct i2c_hid_desc_override sipodev_desc = { + .i2c_hid_desc_buffer = (uint8_t []) + {0x1e, 0x00, /* Length of descriptor */ + 0x00, 0x01, /* Version of descriptor */ + 0xdb, 0x01, /* Length of report descriptor */ + 0x21, 0x00, /* Location of report descriptor */ + 0x24, 0x00, /* Location of input report */ + 0x1b, 0x00, /* Max input report length */ + 0x25, 0x00, /* Location of output report */ + 0x11, 0x00, /* Max output report length */ + 0x22, 0x00, /* Location of command register */ + 0x23, 0x00, /* Location of data register */ + 0x11, 0x09, /* Vendor ID */ + 0x88, 0x52, /* Product ID */ + 0x06, 0x00, /* Version ID */ + 0x00, 0x00, 0x00, 0x00 /* Reserved */ + }, + + .hid_report_desc = (uint8_t []) + {0x05, 0x01, /* Usage Page (Desktop), */ + 0x09, 0x02, /* Usage (Mouse), */ + 0xA1, 0x01, /* Collection (Application), */ + 0x85, 0x01, /* Report ID (1), */ + 0x09, 0x01, /* Usage (Pointer), */ + 0xA1, 0x00, /* Collection (Physical), */ + 0x05, 0x09, /* Usage Page (Button), */ + 0x19, 0x01, /* Usage Minimum (01h), */ + 0x29, 0x02, /* Usage Maximum (02h), */ + 0x25, 0x01, /* Logical Maximum (1), */ + 0x75, 0x01, /* Report Size (1), */ + 0x95, 0x02, /* Report Count (2), */ + 0x81, 0x02, /* Input (Variable), */ + 0x95, 0x06, /* Report Count (6), */ + 0x81, 0x01, /* Input (Constant), */ + 0x05, 0x01, /* Usage Page (Desktop), */ + 0x09, 0x30, /* Usage (X), */ + 0x09, 0x31, /* Usage (Y), */ + 0x15, 0x81, /* Logical Minimum (-127), */ + 0x25, 0x7F, /* Logical Maximum (127), */ + 0x75, 0x08, /* Report Size (8), */ + 0x95, 0x02, /* Report Count (2), */ + 0x81, 0x06, /* Input (Variable, Relative), */ + 0xC0, /* End Collection, */ + 0xC0, /* End Collection, */ + 0x05, 0x0D, /* Usage Page (Digitizer), */ + 0x09, 0x05, /* Usage (Touchpad), */ + 0xA1, 0x01, /* Collection (Application), */ + 0x85, 0x04, /* Report ID (4), */ + 0x05, 0x0D, /* Usage Page (Digitizer), */ + 0x09, 0x22, /* Usage (Finger), */ + 0xA1, 0x02, /* Collection (Logical), */ + 0x15, 0x00, /* Logical Minimum (0), */ + 0x25, 0x01, /* Logical Maximum (1), */ + 0x09, 0x47, /* Usage (Touch Valid), */ + 0x09, 0x42, /* Usage (Tip Switch), */ + 0x95, 0x02, /* Report Count (2), */ + 0x75, 0x01, /* Report Size (1), */ + 0x81, 0x02, /* Input (Variable), */ + 0x95, 0x01, /* Report Count (1), */ + 0x75, 0x03, /* Report Size (3), */ + 0x25, 0x05, /* Logical Maximum (5), */ + 0x09, 0x51, /* Usage (Contact Identifier), */ + 0x81, 0x02, /* Input (Variable), */ + 0x75, 0x01, /* Report Size (1), */ + 0x95, 0x03, /* Report Count (3), */ + 0x81, 0x03, /* Input (Constant, Variable), */ + 0x05, 0x01, /* Usage Page (Desktop), */ + 0x26, 0x44, 0x0A, /* Logical Maximum (2628), */ + 0x75, 0x10, /* Report Size (16), */ + 0x55, 0x0E, /* Unit Exponent (14), */ + 0x65, 0x11, /* Unit (Centimeter), */ + 0x09, 0x30, /* Usage (X), */ + 0x46, 0x1A, 0x04, /* Physical Maximum (1050), */ + 0x95, 0x01, /* Report Count (1), */ + 0x81, 0x02, /* Input (Variable), */ + 0x46, 0xBC, 0x02, /* Physical Maximum (700), */ + 0x26, 0x34, 0x05, /* Logical Maximum (1332), */ + 0x09, 0x31, /* Usage (Y), */ + 0x81, 0x02, /* Input (Variable), */ + 0xC0, /* End Collection, */ + 0x05, 0x0D, /* Usage Page (Digitizer), */ + 0x09, 0x22, /* Usage (Finger), */ + 0xA1, 0x02, /* Collection (Logical), */ + 0x25, 0x01, /* Logical Maximum (1), */ + 0x09, 0x47, /* Usage (Touch Valid), */ + 0x09, 0x42, /* Usage (Tip Switch), */ + 0x95, 0x02, /* Report Count (2), */ + 0x75, 0x01, /* Report Size (1), */ + 0x81, 0x02, /* Input (Variable), */ + 0x95, 0x01, /* Report Count (1), */ + 0x75, 0x03, /* Report Size (3), */ + 0x25, 0x05, /* Logical Maximum (5), */ + 0x09, 0x51, /* Usage (Contact Identifier), */ + 0x81, 0x02, /* Input (Variable), */ + 0x75, 0x01, /* Report Size (1), */ + 0x95, 0x03, /* Report Count (3), */ + 0x81, 0x03, /* Input (Constant, Variable), */ + 0x05, 0x01, /* Usage Page (Desktop), */ + 0x26, 0x44, 0x0A, /* Logical Maximum (2628), */ + 0x75, 0x10, /* Report Size (16), */ + 0x09, 0x30, /* Usage (X), */ + 0x46, 0x1A, 0x04, /* Physical Maximum (1050), */ + 0x95, 0x01, /* Report Count (1), */ + 0x81, 0x02, /* Input (Variable), */ + 0x46, 0xBC, 0x02, /* Physical Maximum (700), */ + 0x26, 0x34, 0x05, /* Logical Maximum (1332), */ + 0x09, 0x31, /* Usage (Y), */ + 0x81, 0x02, /* Input (Variable), */ + 0xC0, /* End Collection, */ + 0x05, 0x0D, /* Usage Page (Digitizer), */ + 0x09, 0x22, /* Usage (Finger), */ + 0xA1, 0x02, /* Collection (Logical), */ + 0x25, 0x01, /* Logical Maximum (1), */ + 0x09, 0x47, /* Usage (Touch Valid), */ + 0x09, 0x42, /* Usage (Tip Switch), */ + 0x95, 0x02, /* Report Count (2), */ + 0x75, 0x01, /* Report Size (1), */ + 0x81, 0x02, /* Input (Variable), */ + 0x95, 0x01, /* Report Count (1), */ + 0x75, 0x03, /* Report Size (3), */ + 0x25, 0x05, /* Logical Maximum (5), */ + 0x09, 0x51, /* Usage (Contact Identifier), */ + 0x81, 0x02, /* Input (Variable), */ + 0x75, 0x01, /* Report Size (1), */ + 0x95, 0x03, /* Report Count (3), */ + 0x81, 0x03, /* Input (Constant, Variable), */ + 0x05, 0x01, /* Usage Page (Desktop), */ + 0x26, 0x44, 0x0A, /* Logical Maximum (2628), */ + 0x75, 0x10, /* Report Size (16), */ + 0x09, 0x30, /* Usage (X), */ + 0x46, 0x1A, 0x04, /* Physical Maximum (1050), */ + 0x95, 0x01, /* Report Count (1), */ + 0x81, 0x02, /* Input (Variable), */ + 0x46, 0xBC, 0x02, /* Physical Maximum (700), */ + 0x26, 0x34, 0x05, /* Logical Maximum (1332), */ + 0x09, 0x31, /* Usage (Y), */ + 0x81, 0x02, /* Input (Variable), */ + 0xC0, /* End Collection, */ + 0x05, 0x0D, /* Usage Page (Digitizer), */ + 0x09, 0x22, /* Usage (Finger), */ + 0xA1, 0x02, /* Collection (Logical), */ + 0x25, 0x01, /* Logical Maximum (1), */ + 0x09, 0x47, /* Usage (Touch Valid), */ + 0x09, 0x42, /* Usage (Tip Switch), */ + 0x95, 0x02, /* Report Count (2), */ + 0x75, 0x01, /* Report Size (1), */ + 0x81, 0x02, /* Input (Variable), */ + 0x95, 0x01, /* Report Count (1), */ + 0x75, 0x03, /* Report Size (3), */ + 0x25, 0x05, /* Logical Maximum (5), */ + 0x09, 0x51, /* Usage (Contact Identifier), */ + 0x81, 0x02, /* Input (Variable), */ + 0x75, 0x01, /* Report Size (1), */ + 0x95, 0x03, /* Report Count (3), */ + 0x81, 0x03, /* Input (Constant, Variable), */ + 0x05, 0x01, /* Usage Page (Desktop), */ + 0x26, 0x44, 0x0A, /* Logical Maximum (2628), */ + 0x75, 0x10, /* Report Size (16), */ + 0x09, 0x30, /* Usage (X), */ + 0x46, 0x1A, 0x04, /* Physical Maximum (1050), */ + 0x95, 0x01, /* Report Count (1), */ + 0x81, 0x02, /* Input (Variable), */ + 0x46, 0xBC, 0x02, /* Physical Maximum (700), */ + 0x26, 0x34, 0x05, /* Logical Maximum (1332), */ + 0x09, 0x31, /* Usage (Y), */ + 0x81, 0x02, /* Input (Variable), */ + 0xC0, /* End Collection, */ + 0x05, 0x0D, /* Usage Page (Digitizer), */ + 0x55, 0x0C, /* Unit Exponent (12), */ + 0x66, 0x01, 0x10, /* Unit (Seconds), */ + 0x47, 0xFF, 0xFF, 0x00, 0x00,/* Physical Maximum (65535), */ + 0x27, 0xFF, 0xFF, 0x00, 0x00,/* Logical Maximum (65535), */ + 0x75, 0x10, /* Report Size (16), */ + 0x95, 0x01, /* Report Count (1), */ + 0x09, 0x56, /* Usage (Scan Time), */ + 0x81, 0x02, /* Input (Variable), */ + 0x09, 0x54, /* Usage (Contact Count), */ + 0x25, 0x7F, /* Logical Maximum (127), */ + 0x75, 0x08, /* Report Size (8), */ + 0x81, 0x02, /* Input (Variable), */ + 0x05, 0x09, /* Usage Page (Button), */ + 0x09, 0x01, /* Usage (01h), */ + 0x25, 0x01, /* Logical Maximum (1), */ + 0x75, 0x01, /* Report Size (1), */ + 0x95, 0x01, /* Report Count (1), */ + 0x81, 0x02, /* Input (Variable), */ + 0x95, 0x07, /* Report Count (7), */ + 0x81, 0x03, /* Input (Constant, Variable), */ + 0x05, 0x0D, /* Usage Page (Digitizer), */ + 0x85, 0x02, /* Report ID (2), */ + 0x09, 0x55, /* Usage (Contact Count Maximum), */ + 0x09, 0x59, /* Usage (59h), */ + 0x75, 0x04, /* Report Size (4), */ + 0x95, 0x02, /* Report Count (2), */ + 0x25, 0x0F, /* Logical Maximum (15), */ + 0xB1, 0x02, /* Feature (Variable), */ + 0x05, 0x0D, /* Usage Page (Digitizer), */ + 0x85, 0x07, /* Report ID (7), */ + 0x09, 0x60, /* Usage (60h), */ + 0x75, 0x01, /* Report Size (1), */ + 0x95, 0x01, /* Report Count (1), */ + 0x25, 0x01, /* Logical Maximum (1), */ + 0xB1, 0x02, /* Feature (Variable), */ + 0x95, 0x07, /* Report Count (7), */ + 0xB1, 0x03, /* Feature (Constant, Variable), */ + 0x85, 0x06, /* Report ID (6), */ + 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ + 0x09, 0xC5, /* Usage (C5h), */ + 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ + 0x75, 0x08, /* Report Size (8), */ + 0x96, 0x00, 0x01, /* Report Count (256), */ + 0xB1, 0x02, /* Feature (Variable), */ + 0xC0, /* End Collection, */ + 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ + 0x09, 0x01, /* Usage (01h), */ + 0xA1, 0x01, /* Collection (Application), */ + 0x85, 0x0D, /* Report ID (13), */ + 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ + 0x19, 0x01, /* Usage Minimum (01h), */ + 0x29, 0x02, /* Usage Maximum (02h), */ + 0x75, 0x08, /* Report Size (8), */ + 0x95, 0x02, /* Report Count (2), */ + 0xB1, 0x02, /* Feature (Variable), */ + 0xC0, /* End Collection, */ + 0x05, 0x0D, /* Usage Page (Digitizer), */ + 0x09, 0x0E, /* Usage (Configuration), */ + 0xA1, 0x01, /* Collection (Application), */ + 0x85, 0x03, /* Report ID (3), */ + 0x09, 0x22, /* Usage (Finger), */ + 0xA1, 0x02, /* Collection (Logical), */ + 0x09, 0x52, /* Usage (Device Mode), */ + 0x25, 0x0A, /* Logical Maximum (10), */ + 0x95, 0x01, /* Report Count (1), */ + 0xB1, 0x02, /* Feature (Variable), */ + 0xC0, /* End Collection, */ + 0x09, 0x22, /* Usage (Finger), */ + 0xA1, 0x00, /* Collection (Physical), */ + 0x85, 0x05, /* Report ID (5), */ + 0x09, 0x57, /* Usage (57h), */ + 0x09, 0x58, /* Usage (58h), */ + 0x75, 0x01, /* Report Size (1), */ + 0x95, 0x02, /* Report Count (2), */ + 0x25, 0x01, /* Logical Maximum (1), */ + 0xB1, 0x02, /* Feature (Variable), */ + 0x95, 0x06, /* Report Count (6), */ + 0xB1, 0x03, /* Feature (Constant, Variable),*/ + 0xC0, /* End Collection, */ + 0xC0 /* End Collection */ + }, + .hid_report_desc_size = 475, + .i2c_name = "SYNA3602:00" +}; + + +static const struct dmi_system_id i2c_hid_dmi_desc_override_table[] = { + { + .ident = "Teclast F6 Pro", + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TECLAST"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "F6 Pro"), + }, + .driver_data = (void *)&sipodev_desc + }, + { + .ident = "Teclast F7", + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TECLAST"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "F7"), + }, + .driver_data = (void *)&sipodev_desc + }, + { + .ident = "Trekstor Primebook C13", + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TREKSTOR"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Primebook C13"), + }, + .driver_data = (void *)&sipodev_desc + }, + { + .ident = "Trekstor Primebook C11", + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TREKSTOR"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Primebook C11"), + }, + .driver_data = (void *)&sipodev_desc + }, + { + .ident = "Direkt-Tek DTLAPY116-2", + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Direkt-Tek"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "DTLAPY116-2"), + }, + .driver_data = (void *)&sipodev_desc + }, + { + .ident = "Mediacom Flexbook Edge 11", + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "MEDIACOM"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "FlexBook edge11 - M-FBE11"), + }, + .driver_data = (void *)&sipodev_desc + } +}; + + +struct i2c_hid_desc *i2c_hid_get_dmi_i2c_hid_desc_override(uint8_t *i2c_name) +{ + struct i2c_hid_desc_override *override; + const struct dmi_system_id *system_id; + + system_id = dmi_first_match(i2c_hid_dmi_desc_override_table); + if (!system_id) + return NULL; + + override = system_id->driver_data; + if (strcmp(override->i2c_name, i2c_name)) + return NULL; + + return override->i2c_hid_desc; +} + +char *i2c_hid_get_dmi_hid_report_desc_override(uint8_t *i2c_name, + unsigned int *size) +{ + struct i2c_hid_desc_override *override; + const struct dmi_system_id *system_id; + + system_id = dmi_first_match(i2c_hid_dmi_desc_override_table); + if (!system_id) + return NULL; + + override = system_id->driver_data; + if (strcmp(override->i2c_name, i2c_name)) + return NULL; + + *size = override->hid_report_desc_size; + return override->hid_report_desc; +} diff --git a/drivers/hid/i2c-hid/i2c-hid.h b/drivers/hid/i2c-hid/i2c-hid.h new file mode 100644 index 000000000000..a8c19aef5824 --- /dev/null +++ b/drivers/hid/i2c-hid/i2c-hid.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#ifndef I2C_HID_H +#define I2C_HID_H + + +#ifdef CONFIG_DMI +struct i2c_hid_desc *i2c_hid_get_dmi_i2c_hid_desc_override(uint8_t *i2c_name); +char *i2c_hid_get_dmi_hid_report_desc_override(uint8_t *i2c_name, + unsigned int *size); +#else +static inline struct i2c_hid_desc + *i2c_hid_get_dmi_i2c_hid_desc_override(uint8_t *i2c_name) +{ return NULL; } +static inline char *i2c_hid_get_dmi_hid_report_desc_override(uint8_t *i2c_name, + unsigned int *size) +{ return NULL; } +#endif + +#endif -- GitLab From ef9f432612e56651d2aa2984763ff1ba69621e82 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 28 Sep 2018 15:32:46 +0200 Subject: [PATCH 0130/1121] ARM: samsung: Limit SAMSUNG_PM_CHECK config option to non-Exynos platforms [ Upstream commit 6862fdf2201ab67cd962dbf0643d37db909f4860 ] "S3C2410 PM Suspend Memory CRC" feature (controlled by SAMSUNG_PM_CHECK config option) is incompatible with highmem (uses phys_to_virt() instead of proper mapping) which is used by the majority of Exynos boards. The issue manifests itself in OOPS on affected boards, i.e. on Odroid-U3 I got the following one: Unable to handle kernel paging request at virtual address f0000000 pgd = 1c0f9bb4 [f0000000] *pgd=00000000 Internal error: Oops: 5 [#1] PREEMPT SMP ARM [] (crc32_le) from [] (s3c_pm_makecheck+0x34/0x54) [] (s3c_pm_makecheck) from [] (s3c_pm_run_res+0x74/0x8c) [] (s3c_pm_run_res) from [] (s3c_pm_run_res+0x44/0x8c) [] (s3c_pm_run_res) from [] (exynos_suspend_enter+0x64/0x148) [] (exynos_suspend_enter) from [] (suspend_devices_and_enter+0x9ec/0xe74) [] (suspend_devices_and_enter) from [] (pm_suspend+0x770/0xc04) [] (pm_suspend) from [] (state_store+0x6c/0xcc) [] (state_store) from [] (kobj_attr_store+0x14/0x20) [] (kobj_attr_store) from [] (sysfs_kf_write+0x4c/0x50) [] (sysfs_kf_write) from [] (kernfs_fop_write+0xfc/0x1e4) [] (kernfs_fop_write) from [] (__vfs_write+0x2c/0x140) [] (__vfs_write) from [] (vfs_write+0xa4/0x160) [] (vfs_write) from [] (ksys_write+0x40/0x8c) [] (ksys_write) from [] (ret_fast_syscall+0x0/0x28) Add PLAT_S3C24XX, ARCH_S3C64XX and ARCH_S5PV210 dependencies to SAMSUNG_PM_CHECK config option to hide it on Exynos platforms. Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Krzysztof Kozlowski Signed-off-by: Sasha Levin --- arch/arm/plat-samsung/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index e8229b9fee4a..3265b8f86069 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig @@ -258,7 +258,7 @@ config S3C_PM_DEBUG_LED_SMDK config SAMSUNG_PM_CHECK bool "S3C2410 PM Suspend Memory CRC" - depends on PM + depends on PM && (PLAT_S3C24XX || ARCH_S3C64XX || ARCH_S5PV210) select CRC32 help Enable the PM code's memory area checksum over sleep. This option -- GitLab From 0dd663753b0afcc47c9c6b93e36bb62530de68be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= Date: Thu, 20 Sep 2018 13:29:42 -0700 Subject: [PATCH 0131/1121] usbip: fix vhci_hcd controller counting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit e0a2e73e501c77037c8756137e87b12c7c3c9793 ] Without this usbip fails on a machine with devices that lexicographically come after vhci_hcd. ie. $ ls -l /sys/devices/platform ... drwxr-xr-x. 4 root root 0 Sep 19 16:21 serial8250 -rw-r--r--. 1 root root 4096 Sep 19 23:50 uevent drwxr-xr-x. 6 root root 0 Sep 20 13:15 vhci_hcd.0 drwxr-xr-x. 4 root root 0 Sep 19 16:22 w83627hf.656 Because it detects 'w83627hf.656' as another vhci_hcd controller, and then fails to be able to talk to it. Note: this doesn't actually fix usbip's support for multiple controllers... that's still broken for other reasons ("vhci_hcd.0" is hardcoded in a string macro), but is enough to actually make it work on the above machine. See also: https://bugzilla.redhat.com/show_bug.cgi?id=1631148 Cc: Jonathan Dieter Cc: Valentina Manea Cc: Shuah Khan Cc: linux-usb@vger.kernel.org Signed-off-by: Maciej Ć»enczykowski Acked-by: Shuah Khan (Samsung OSG) Tested-by: Jonathan Dieter Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- tools/usb/usbip/libsrc/vhci_driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index ed8c9d360c0f..4225d462701d 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -150,7 +150,7 @@ static int get_nports(struct udev_device *hc_device) static int vhci_hcd_filter(const struct dirent *dirent) { - return strcmp(dirent->d_name, "vhci_hcd") >= 0; + return !strncmp(dirent->d_name, "vhci_hcd.", 9); } static int get_ncontrollers(void) -- GitLab From 00254adf3db21a6cfb6d7bdac367e774662198f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ronald=20Tschal=C3=A4r?= Date: Sun, 30 Sep 2018 19:52:51 -0700 Subject: [PATCH 0132/1121] ACPI / SBS: Fix GPE storm on recent MacBookPro's MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit ca1721c5bee77105829cbd7baab8ee0eab85b06d ] On Apple machines, plugging-in or unplugging the power triggers a GPE for the EC. Since these machines expose an SBS device, this GPE ends up triggering the acpi_sbs_callback(). This in turn tries to get the status of the SBS charger. However, on MBP13,* and MBP14,* machines, performing the smbus-read operation to get the charger's status triggers the EC's GPE again. The result is an endless re-triggering and handling of that GPE, consuming significant CPU resources (> 50% in irq). In the end this is quite similar to commit 3031cddea633 (ACPI / SBS: Don't assume the existence of an SBS charger), except that on the above machines a status of all 1's is returned. And like there, we just want ignore the charger here. Link: https://bugzilla.kernel.org/show_bug.cgi?id=198169 Signed-off-by: Ronald TschalÀr Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/acpi/sbs.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index a2428e9462dd..3c092f07d7e3 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -441,9 +441,13 @@ static int acpi_ac_get_present(struct acpi_sbs *sbs) /* * The spec requires that bit 4 always be 1. If it's not set, assume - * that the implementation doesn't support an SBS charger + * that the implementation doesn't support an SBS charger. + * + * And on some MacBooks a status of 0xffff is always returned, no + * matter whether the charger is plugged in or not, which is also + * wrong, so ignore the SBS charger for those too. */ - if (!((status >> 4) & 0x1)) + if (!((status >> 4) & 0x1) || status == 0xffff) return -ENODEV; sbs->charger_present = (status >> 15) & 0x1; -- GitLab From 05e788500b46cb3c45231ea51a3e4b36c2ccd3c0 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Wed, 22 Aug 2018 14:57:07 -0700 Subject: [PATCH 0133/1121] KVM: nVMX: restore host state in nested_vmx_vmexit for VMFail MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit bd18bffca35397214ae68d85cf7203aca25c3c1d ] A VMEnter that VMFails (as opposed to VMExits) does not touch host state beyond registers that are explicitly noted in the VMFail path, e.g. EFLAGS. Host state does not need to be loaded because VMFail is only signaled for consistency checks that occur before the CPU starts to load guest state, i.e. there is no need to restore any state as nothing has been modified. But in the case where a VMFail is detected by hardware and not by KVM (due to deferring consistency checks to hardware), KVM has already loaded some amount of guest state. Luckily, "loaded" only means loaded to KVM's software model, i.e. vmcs01 has not been modified. So, unwind our software model to the pre-VMEntry host state. Not restoring host state in this VMFail path leads to a variety of failures because we end up with stale data in vcpu->arch, e.g. CR0, CR4, EFER, etc... will all be out of sync relative to vmcs01. Any significant delta in the stale data is all but guaranteed to crash L1, e.g. emulation of SMEP, SMAP, UMIP, WP, etc... will be wrong. An alternative to this "soft" reload would be to load host state from vmcs12 as if we triggered a VMExit (as opposed to VMFail), but that is wildly inconsistent with respect to the VMX architecture, e.g. an L1 VMM with separate VMExit and VMFail paths would explode. Note that this approach does not mean KVM is 100% accurate with respect to VMX hardware behavior, even at an architectural level (the exact order of consistency checks is microarchitecture specific). But 100% emulation accuracy isn't the goal (with this patch), rather the goal is to be consistent in the information delivered to L1, e.g. a VMExit should not fall-through VMENTER, and a VMFail should not jump to HOST_RIP. This technically reverts commit "5af4157388ad (KVM: nVMX: Fix mmu context after VMLAUNCH/VMRESUME failure)", but retains the core aspects of that patch, just in an open coded form due to the need to pull state from vmcs01 instead of vmcs12. Restoring host state resolves a variety of issues introduced by commit "4f350c6dbcb9 (kvm: nVMX: Handle deferred early VMLAUNCH/VMRESUME failure properly)", which remedied the incorrect behavior of treating VMFail like VMExit but in doing so neglected to restore arch state that had been modified prior to attempting nested VMEnter. A sample failure that occurs due to stale vcpu.arch state is a fault of some form while emulating an LGDT (due to emulated UMIP) from L1 after a failed VMEntry to L3, in this case when running the KVM unit test test_tpr_threshold_values in L1. L0 also hits a WARN in this case due to a stale arch.cr4.UMIP. L1: BUG: unable to handle kernel paging request at ffffc90000663b9e PGD 276512067 P4D 276512067 PUD 276513067 PMD 274efa067 PTE 8000000271de2163 Oops: 0009 [#1] SMP CPU: 5 PID: 12495 Comm: qemu-system-x86 Tainted: G W 4.18.0-rc2+ #2 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015 RIP: 0010:native_load_gdt+0x0/0x10 ... Call Trace: load_fixmap_gdt+0x22/0x30 __vmx_load_host_state+0x10e/0x1c0 [kvm_intel] vmx_switch_vmcs+0x2d/0x50 [kvm_intel] nested_vmx_vmexit+0x222/0x9c0 [kvm_intel] vmx_handle_exit+0x246/0x15a0 [kvm_intel] kvm_arch_vcpu_ioctl_run+0x850/0x1830 [kvm] kvm_vcpu_ioctl+0x3a1/0x5c0 [kvm] do_vfs_ioctl+0x9f/0x600 ksys_ioctl+0x66/0x70 __x64_sys_ioctl+0x16/0x20 do_syscall_64+0x4f/0x100 entry_SYSCALL_64_after_hwframe+0x44/0xa9 L0: WARNING: CPU: 2 PID: 3529 at arch/x86/kvm/vmx.c:6618 handle_desc+0x28/0x30 [kvm_intel] ... CPU: 2 PID: 3529 Comm: qemu-system-x86 Not tainted 4.17.2-coffee+ #76 Hardware name: Intel Corporation Kabylake Client platform/KBL S RIP: 0010:handle_desc+0x28/0x30 [kvm_intel] ... Call Trace: kvm_arch_vcpu_ioctl_run+0x863/0x1840 [kvm] kvm_vcpu_ioctl+0x3a1/0x5c0 [kvm] do_vfs_ioctl+0x9f/0x5e0 ksys_ioctl+0x66/0x70 __x64_sys_ioctl+0x16/0x20 do_syscall_64+0x49/0xf0 entry_SYSCALL_64_after_hwframe+0x44/0xa9 Fixes: 5af4157388ad (KVM: nVMX: Fix mmu context after VMLAUNCH/VMRESUME failure) Fixes: 4f350c6dbcb9 (kvm: nVMX: Handle deferred early VMLAUNCH/VMRESUME failure properly) Cc: Jim Mattson Cc: Krish Sadhukhan Cc: Paolo Bonzini Cc: Radim KrÄmáÅℱ Cc: Wanpeng Li Signed-off-by: Sean Christopherson Signed-off-by: Paolo Bonzini Signed-off-by: Sasha Levin --- arch/x86/kvm/vmx.c | 173 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 153 insertions(+), 20 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 4bd878c9f7d2..90b7eee6d0f9 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -11846,24 +11846,6 @@ static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12, kvm_clear_interrupt_queue(vcpu); } -static void load_vmcs12_mmu_host_state(struct kvm_vcpu *vcpu, - struct vmcs12 *vmcs12) -{ - u32 entry_failure_code; - - nested_ept_uninit_mmu_context(vcpu); - - /* - * Only PDPTE load can fail as the value of cr3 was checked on entry and - * couldn't have changed. - */ - if (nested_vmx_load_cr3(vcpu, vmcs12->host_cr3, false, &entry_failure_code)) - nested_vmx_abort(vcpu, VMX_ABORT_LOAD_HOST_PDPTE_FAIL); - - if (!enable_ept) - vcpu->arch.walk_mmu->inject_page_fault = kvm_inject_page_fault; -} - /* * A part of what we need to when the nested L2 guest exits and we want to * run its L1 parent, is to reset L1's guest state to the host state specified @@ -11877,6 +11859,7 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) { struct kvm_segment seg; + u32 entry_failure_code; if (vmcs12->vm_exit_controls & VM_EXIT_LOAD_IA32_EFER) vcpu->arch.efer = vmcs12->host_ia32_efer; @@ -11903,7 +11886,17 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu, vcpu->arch.cr4_guest_owned_bits = ~vmcs_readl(CR4_GUEST_HOST_MASK); vmx_set_cr4(vcpu, vmcs12->host_cr4); - load_vmcs12_mmu_host_state(vcpu, vmcs12); + nested_ept_uninit_mmu_context(vcpu); + + /* + * Only PDPTE load can fail as the value of cr3 was checked on entry and + * couldn't have changed. + */ + if (nested_vmx_load_cr3(vcpu, vmcs12->host_cr3, false, &entry_failure_code)) + nested_vmx_abort(vcpu, VMX_ABORT_LOAD_HOST_PDPTE_FAIL); + + if (!enable_ept) + vcpu->arch.walk_mmu->inject_page_fault = kvm_inject_page_fault; if (enable_vpid) { /* @@ -11994,6 +11987,140 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu, nested_vmx_abort(vcpu, VMX_ABORT_LOAD_HOST_MSR_FAIL); } +static inline u64 nested_vmx_get_vmcs01_guest_efer(struct vcpu_vmx *vmx) +{ + struct shared_msr_entry *efer_msr; + unsigned int i; + + if (vm_entry_controls_get(vmx) & VM_ENTRY_LOAD_IA32_EFER) + return vmcs_read64(GUEST_IA32_EFER); + + if (cpu_has_load_ia32_efer) + return host_efer; + + for (i = 0; i < vmx->msr_autoload.guest.nr; ++i) { + if (vmx->msr_autoload.guest.val[i].index == MSR_EFER) + return vmx->msr_autoload.guest.val[i].value; + } + + efer_msr = find_msr_entry(vmx, MSR_EFER); + if (efer_msr) + return efer_msr->data; + + return host_efer; +} + +static void nested_vmx_restore_host_state(struct kvm_vcpu *vcpu) +{ + struct vmcs12 *vmcs12 = get_vmcs12(vcpu); + struct vcpu_vmx *vmx = to_vmx(vcpu); + struct vmx_msr_entry g, h; + struct msr_data msr; + gpa_t gpa; + u32 i, j; + + vcpu->arch.pat = vmcs_read64(GUEST_IA32_PAT); + + if (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_DEBUG_CONTROLS) { + /* + * L1's host DR7 is lost if KVM_GUESTDBG_USE_HW_BP is set + * as vmcs01.GUEST_DR7 contains a userspace defined value + * and vcpu->arch.dr7 is not squirreled away before the + * nested VMENTER (not worth adding a variable in nested_vmx). + */ + if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) + kvm_set_dr(vcpu, 7, DR7_FIXED_1); + else + WARN_ON(kvm_set_dr(vcpu, 7, vmcs_readl(GUEST_DR7))); + } + + /* + * Note that calling vmx_set_{efer,cr0,cr4} is important as they + * handle a variety of side effects to KVM's software model. + */ + vmx_set_efer(vcpu, nested_vmx_get_vmcs01_guest_efer(vmx)); + + vcpu->arch.cr0_guest_owned_bits = X86_CR0_TS; + vmx_set_cr0(vcpu, vmcs_readl(CR0_READ_SHADOW)); + + vcpu->arch.cr4_guest_owned_bits = ~vmcs_readl(CR4_GUEST_HOST_MASK); + vmx_set_cr4(vcpu, vmcs_readl(CR4_READ_SHADOW)); + + nested_ept_uninit_mmu_context(vcpu); + vcpu->arch.cr3 = vmcs_readl(GUEST_CR3); + __set_bit(VCPU_EXREG_CR3, (ulong *)&vcpu->arch.regs_avail); + + /* + * Use ept_save_pdptrs(vcpu) to load the MMU's cached PDPTRs + * from vmcs01 (if necessary). The PDPTRs are not loaded on + * VMFail, like everything else we just need to ensure our + * software model is up-to-date. + */ + ept_save_pdptrs(vcpu); + + kvm_mmu_reset_context(vcpu); + + if (cpu_has_vmx_msr_bitmap()) + vmx_update_msr_bitmap(vcpu); + + /* + * This nasty bit of open coding is a compromise between blindly + * loading L1's MSRs using the exit load lists (incorrect emulation + * of VMFail), leaving the nested VM's MSRs in the software model + * (incorrect behavior) and snapshotting the modified MSRs (too + * expensive since the lists are unbound by hardware). For each + * MSR that was (prematurely) loaded from the nested VMEntry load + * list, reload it from the exit load list if it exists and differs + * from the guest value. The intent is to stuff host state as + * silently as possible, not to fully process the exit load list. + */ + msr.host_initiated = false; + for (i = 0; i < vmcs12->vm_entry_msr_load_count; i++) { + gpa = vmcs12->vm_entry_msr_load_addr + (i * sizeof(g)); + if (kvm_vcpu_read_guest(vcpu, gpa, &g, sizeof(g))) { + pr_debug_ratelimited( + "%s read MSR index failed (%u, 0x%08llx)\n", + __func__, i, gpa); + goto vmabort; + } + + for (j = 0; j < vmcs12->vm_exit_msr_load_count; j++) { + gpa = vmcs12->vm_exit_msr_load_addr + (j * sizeof(h)); + if (kvm_vcpu_read_guest(vcpu, gpa, &h, sizeof(h))) { + pr_debug_ratelimited( + "%s read MSR failed (%u, 0x%08llx)\n", + __func__, j, gpa); + goto vmabort; + } + if (h.index != g.index) + continue; + if (h.value == g.value) + break; + + if (nested_vmx_load_msr_check(vcpu, &h)) { + pr_debug_ratelimited( + "%s check failed (%u, 0x%x, 0x%x)\n", + __func__, j, h.index, h.reserved); + goto vmabort; + } + + msr.index = h.index; + msr.data = h.value; + if (kvm_set_msr(vcpu, &msr)) { + pr_debug_ratelimited( + "%s WRMSR failed (%u, 0x%x, 0x%llx)\n", + __func__, j, h.index, h.value); + goto vmabort; + } + } + } + + return; + +vmabort: + nested_vmx_abort(vcpu, VMX_ABORT_LOAD_HOST_MSR_FAIL); +} + /* * Emulate an exit from nested guest (L2) to L1, i.e., prepare to run L1 * and modify vmcs12 to make it see what it would expect to see there if @@ -12126,7 +12253,13 @@ static void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason, */ nested_vmx_failValid(vcpu, VMXERR_ENTRY_INVALID_CONTROL_FIELD); - load_vmcs12_mmu_host_state(vcpu, vmcs12); + /* + * Restore L1's host state to KVM's software model. We're here + * because a consistency check was caught by hardware, which + * means some amount of guest state has been propagated to KVM's + * model and needs to be unwound to the host's state. + */ + nested_vmx_restore_host_state(vcpu); /* * The emulated instruction was already skipped in -- GitLab From 82017e26e51596ee577171a33f357377ec6513b5 Mon Sep 17 00:00:00 2001 From: "ndesaulniers@google.com" Date: Mon, 15 Oct 2018 10:22:21 -0700 Subject: [PATCH 0134/1121] compiler.h: update definition of unreachable() [ Upstream commit fe0640eb30b7da261ae84d252ed9ed3c7e68dfd8 ] Fixes the objtool warning seen with Clang: arch/x86/mm/fault.o: warning: objtool: no_context()+0x220: unreachable instruction Fixes commit 815f0ddb346c ("include/linux/compiler*.h: make compiler-*.h mutually exclusive") Josh noted that the fallback definition was meant to work around a pre-gcc-4.6 bug. GCC still needs to work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82365, so compiler-gcc.h defines its own version of unreachable(). Clang and ICC can use this shared definition. Link: https://github.com/ClangBuiltLinux/linux/issues/204 Suggested-by: Andy Lutomirski Suggested-by: Josh Poimboeuf Tested-by: Nathan Chancellor Signed-off-by: Nick Desaulniers Signed-off-by: Miguel Ojeda Signed-off-by: Sasha Levin --- include/linux/compiler.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/linux/compiler.h b/include/linux/compiler.h index a704d032713b..67c3934fb9ed 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -119,7 +119,10 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val, # define ASM_UNREACHABLE #endif #ifndef unreachable -# define unreachable() do { annotate_reachable(); do { } while (1); } while (0) +# define unreachable() do { \ + annotate_unreachable(); \ + __builtin_unreachable(); \ +} while (0) #endif /* -- GitLab From 1d41cd12307f96ebefbd856cfe26719c23d8d8ec Mon Sep 17 00:00:00 2001 From: Steve French Date: Fri, 19 Oct 2018 01:58:22 -0500 Subject: [PATCH 0135/1121] cifs: fallback to older infolevels on findfirst queryinfo retry [ Upstream commit 3b7960caceafdfc2cdfe2850487f8d091eb41144 ] In cases where queryinfo fails, we have cases in cifs (vers=1.0) where with backupuid mounts we retry the query info with findfirst. This doesn't work to some NetApp servers which don't support WindowsXP (and later) infolevel 261 (SMB_FIND_FILE_ID_FULL_DIR_INFO) so in this case use other info levels (in this case it will usually be level 257, SMB_FIND_FILE_DIRECTORY_INFO). (Also fixes some indentation) See kernel bugzilla 201435 Signed-off-by: Steve French Signed-off-by: Sasha Levin --- fs/cifs/inode.c | 67 +++++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index a90a637ae79a..6fd4a6a75234 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -779,43 +779,50 @@ cifs_get_inode_info(struct inode **inode, const char *full_path, } else if ((rc == -EACCES) && backup_cred(cifs_sb) && (strcmp(server->vals->version_string, SMB1_VERSION_STRING) == 0)) { - /* - * For SMB2 and later the backup intent flag is already - * sent if needed on open and there is no path based - * FindFirst operation to use to retry with - */ + /* + * For SMB2 and later the backup intent flag is already + * sent if needed on open and there is no path based + * FindFirst operation to use to retry with + */ - srchinf = kzalloc(sizeof(struct cifs_search_info), - GFP_KERNEL); - if (srchinf == NULL) { - rc = -ENOMEM; - goto cgii_exit; - } + srchinf = kzalloc(sizeof(struct cifs_search_info), + GFP_KERNEL); + if (srchinf == NULL) { + rc = -ENOMEM; + goto cgii_exit; + } - srchinf->endOfSearch = false; + srchinf->endOfSearch = false; + if (tcon->unix_ext) + srchinf->info_level = SMB_FIND_FILE_UNIX; + else if ((tcon->ses->capabilities & + tcon->ses->server->vals->cap_nt_find) == 0) + srchinf->info_level = SMB_FIND_FILE_INFO_STANDARD; + else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) srchinf->info_level = SMB_FIND_FILE_ID_FULL_DIR_INFO; + else /* no srvino useful for fallback to some netapp */ + srchinf->info_level = SMB_FIND_FILE_DIRECTORY_INFO; - srchflgs = CIFS_SEARCH_CLOSE_ALWAYS | - CIFS_SEARCH_CLOSE_AT_END | - CIFS_SEARCH_BACKUP_SEARCH; + srchflgs = CIFS_SEARCH_CLOSE_ALWAYS | + CIFS_SEARCH_CLOSE_AT_END | + CIFS_SEARCH_BACKUP_SEARCH; - rc = CIFSFindFirst(xid, tcon, full_path, - cifs_sb, NULL, srchflgs, srchinf, false); - if (!rc) { - data = - (FILE_ALL_INFO *)srchinf->srch_entries_start; + rc = CIFSFindFirst(xid, tcon, full_path, + cifs_sb, NULL, srchflgs, srchinf, false); + if (!rc) { + data = (FILE_ALL_INFO *)srchinf->srch_entries_start; - cifs_dir_info_to_fattr(&fattr, - (FILE_DIRECTORY_INFO *)data, cifs_sb); - fattr.cf_uniqueid = le64_to_cpu( - ((SEARCH_ID_FULL_DIR_INFO *)data)->UniqueId); - validinum = true; + cifs_dir_info_to_fattr(&fattr, + (FILE_DIRECTORY_INFO *)data, cifs_sb); + fattr.cf_uniqueid = le64_to_cpu( + ((SEARCH_ID_FULL_DIR_INFO *)data)->UniqueId); + validinum = true; - cifs_buf_release(srchinf->ntwrk_buf_start); - } - kfree(srchinf); - if (rc) - goto cgii_exit; + cifs_buf_release(srchinf->ntwrk_buf_start); + } + kfree(srchinf); + if (rc) + goto cgii_exit; } else goto cgii_exit; -- GitLab From 507f2f17e044b3efc6516ad0ae66fb244752c569 Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Wed, 17 Oct 2018 13:23:55 +0200 Subject: [PATCH 0136/1121] kernel: hung_task.c: disable on suspend [ Upstream commit a1c6ca3c6de763459a6e93b644ec6518c890ba1c ] It is possible to observe hung_task complaints when system goes to suspend-to-idle state: # echo freeze > /sys/power/state PM: Syncing filesystems ... done. Freezing user space processes ... (elapsed 0.001 seconds) done. OOM killer disabled. Freezing remaining freezable tasks ... (elapsed 0.002 seconds) done. sd 0:0:0:0: [sda] Synchronizing SCSI cache INFO: task bash:1569 blocked for more than 120 seconds. Not tainted 4.19.0-rc3_+ #687 "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. bash D 0 1569 604 0x00000000 Call Trace: ? __schedule+0x1fe/0x7e0 schedule+0x28/0x80 suspend_devices_and_enter+0x4ac/0x750 pm_suspend+0x2c0/0x310 Register a PM notifier to disable the detector on suspend and re-enable back on wakeup. Signed-off-by: Vitaly Kuznetsov Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- kernel/hung_task.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/kernel/hung_task.c b/kernel/hung_task.c index f9aaf4994062..2e4869fa66c9 100644 --- a/kernel/hung_task.c +++ b/kernel/hung_task.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -232,6 +233,28 @@ void reset_hung_task_detector(void) } EXPORT_SYMBOL_GPL(reset_hung_task_detector); +static bool hung_detector_suspended; + +static int hungtask_pm_notify(struct notifier_block *self, + unsigned long action, void *hcpu) +{ + switch (action) { + case PM_SUSPEND_PREPARE: + case PM_HIBERNATION_PREPARE: + case PM_RESTORE_PREPARE: + hung_detector_suspended = true; + break; + case PM_POST_SUSPEND: + case PM_POST_HIBERNATION: + case PM_POST_RESTORE: + hung_detector_suspended = false; + break; + default: + break; + } + return NOTIFY_OK; +} + /* * kthread which checks for tasks stuck in D state */ @@ -246,7 +269,8 @@ static int watchdog(void *dummy) long t = hung_timeout_jiffies(hung_last_checked, timeout); if (t <= 0) { - if (!atomic_xchg(&reset_hung_task, 0)) + if (!atomic_xchg(&reset_hung_task, 0) && + !hung_detector_suspended) check_hung_uninterruptible_tasks(timeout); hung_last_checked = jiffies; continue; @@ -260,6 +284,10 @@ static int watchdog(void *dummy) static int __init hung_task_init(void) { atomic_notifier_chain_register(&panic_notifier_list, &panic_block); + + /* Disable hung task detector on suspend */ + pm_notifier(hungtask_pm_notify, 0); + watchdog_task = kthread_run(watchdog, NULL, "khungtaskd"); return 0; -- GitLab From 92562a9fc5dfab7dc2102ca81d96a067d104cccc Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Sat, 16 Feb 2019 14:51:25 +0100 Subject: [PATCH 0137/1121] crypto: sha256/arm - fix crash bug in Thumb2 build [ Upstream commit 69216a545cf81b2b32d01948f7039315abaf75a0 ] The SHA256 code we adopted from the OpenSSL project uses a rather peculiar way to take the address of the round constant table: it takes the address of the sha256_block_data_order() routine, and substracts a constant known quantity to arrive at the base of the table, which is emitted by the same assembler code right before the routine's entry point. However, recent versions of binutils have helpfully changed the behavior of references emitted via an ADR instruction when running in Thumb2 mode: it now takes the Thumb execution mode bit into account, which is bit 0 af the address. This means the produced table address also has bit 0 set, and so we end up with an address value pointing 1 byte past the start of the table, which results in crashes such as Unable to handle kernel paging request at virtual address bf825000 pgd = 42f44b11 [bf825000] *pgd=80000040206003, *pmd=5f1bd003, *pte=00000000 Internal error: Oops: 207 [#1] PREEMPT SMP THUMB2 Modules linked in: sha256_arm(+) sha1_arm_ce sha1_arm ... CPU: 7 PID: 396 Comm: cryptomgr_test Not tainted 5.0.0-rc6+ #144 Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 02/06/2015 PC is at sha256_block_data_order+0xaaa/0xb30 [sha256_arm] LR is at __this_module+0x17fd/0xffffe800 [sha256_arm] pc : [] lr : [] psr: 800b0033 sp : ebc8bbe8 ip : faaabe1c fp : 2fdd3433 r10: 4c5f1692 r9 : e43037df r8 : b04b0a5a r7 : c369d722 r6 : 39c3693e r5 : 7a013189 r4 : 1580d26b r3 : 8762a9b0 r2 : eea9c2cd r1 : 3e9ab536 r0 : 1dea4ae7 Flags: Nzcv IRQs on FIQs on Mode SVC_32 ISA Thumb Segment user Control: 70c5383d Table: 6b8467c0 DAC: dbadc0de Process cryptomgr_test (pid: 396, stack limit = 0x69e1fe23) Stack: (0xebc8bbe8 to 0xebc8c000) ... unwind: Unknown symbol address bf820bca unwind: Index not found bf820bca Code: 441a ea80 40f9 440a (f85e) 3b04 ---[ end trace e560cce92700ef8a ]--- Given that this affects older kernels as well, in case they are built with a recent toolchain, apply a minimal backportable fix, which is to emit another non-code label at the start of the routine, and reference that instead. (This is similar to the current upstream state of this file in OpenSSL) Signed-off-by: Ard Biesheuvel Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- arch/arm/crypto/sha256-armv4.pl | 3 ++- arch/arm/crypto/sha256-core.S_shipped | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/arm/crypto/sha256-armv4.pl b/arch/arm/crypto/sha256-armv4.pl index fac0533ea633..f64e8413ab9a 100644 --- a/arch/arm/crypto/sha256-armv4.pl +++ b/arch/arm/crypto/sha256-armv4.pl @@ -205,10 +205,11 @@ K256: .global sha256_block_data_order .type sha256_block_data_order,%function sha256_block_data_order: +.Lsha256_block_data_order: #if __ARM_ARCH__<7 sub r3,pc,#8 @ sha256_block_data_order #else - adr r3,sha256_block_data_order + adr r3,.Lsha256_block_data_order #endif #if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) ldr r12,.LOPENSSL_armcap diff --git a/arch/arm/crypto/sha256-core.S_shipped b/arch/arm/crypto/sha256-core.S_shipped index 555a1a8eec90..72c248081d27 100644 --- a/arch/arm/crypto/sha256-core.S_shipped +++ b/arch/arm/crypto/sha256-core.S_shipped @@ -86,10 +86,11 @@ K256: .global sha256_block_data_order .type sha256_block_data_order,%function sha256_block_data_order: +.Lsha256_block_data_order: #if __ARM_ARCH__<7 sub r3,pc,#8 @ sha256_block_data_order #else - adr r3,sha256_block_data_order + adr r3,.Lsha256_block_data_order #endif #if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) ldr r12,.LOPENSSL_armcap -- GitLab From 29b56343c85169c42e31fbf3b0facdb01d034aa1 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Sat, 16 Feb 2019 14:51:26 +0100 Subject: [PATCH 0138/1121] crypto: sha512/arm - fix crash bug in Thumb2 build [ Upstream commit c64316502008064c158fa40cc250665e461b0f2a ] The SHA512 code we adopted from the OpenSSL project uses a rather peculiar way to take the address of the round constant table: it takes the address of the sha256_block_data_order() routine, and substracts a constant known quantity to arrive at the base of the table, which is emitted by the same assembler code right before the routine's entry point. However, recent versions of binutils have helpfully changed the behavior of references emitted via an ADR instruction when running in Thumb2 mode: it now takes the Thumb execution mode bit into account, which is bit 0 af the address. This means the produced table address also has bit 0 set, and so we end up with an address value pointing 1 byte past the start of the table, which results in crashes such as Unable to handle kernel paging request at virtual address bf825000 pgd = 42f44b11 [bf825000] *pgd=80000040206003, *pmd=5f1bd003, *pte=00000000 Internal error: Oops: 207 [#1] PREEMPT SMP THUMB2 Modules linked in: sha256_arm(+) sha1_arm_ce sha1_arm ... CPU: 7 PID: 396 Comm: cryptomgr_test Not tainted 5.0.0-rc6+ #144 Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 02/06/2015 PC is at sha256_block_data_order+0xaaa/0xb30 [sha256_arm] LR is at __this_module+0x17fd/0xffffe800 [sha256_arm] pc : [] lr : [] psr: 800b0033 sp : ebc8bbe8 ip : faaabe1c fp : 2fdd3433 r10: 4c5f1692 r9 : e43037df r8 : b04b0a5a r7 : c369d722 r6 : 39c3693e r5 : 7a013189 r4 : 1580d26b r3 : 8762a9b0 r2 : eea9c2cd r1 : 3e9ab536 r0 : 1dea4ae7 Flags: Nzcv IRQs on FIQs on Mode SVC_32 ISA Thumb Segment user Control: 70c5383d Table: 6b8467c0 DAC: dbadc0de Process cryptomgr_test (pid: 396, stack limit = 0x69e1fe23) Stack: (0xebc8bbe8 to 0xebc8c000) ... unwind: Unknown symbol address bf820bca unwind: Index not found bf820bca Code: 441a ea80 40f9 440a (f85e) 3b04 ---[ end trace e560cce92700ef8a ]--- Given that this affects older kernels as well, in case they are built with a recent toolchain, apply a minimal backportable fix, which is to emit another non-code label at the start of the routine, and reference that instead. (This is similar to the current upstream state of this file in OpenSSL) Signed-off-by: Ard Biesheuvel Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- arch/arm/crypto/sha512-armv4.pl | 3 ++- arch/arm/crypto/sha512-core.S_shipped | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/arm/crypto/sha512-armv4.pl b/arch/arm/crypto/sha512-armv4.pl index a2b11a844357..5fe336420bcf 100644 --- a/arch/arm/crypto/sha512-armv4.pl +++ b/arch/arm/crypto/sha512-armv4.pl @@ -267,10 +267,11 @@ WORD64(0x5fcb6fab,0x3ad6faec, 0x6c44198c,0x4a475817) .global sha512_block_data_order .type sha512_block_data_order,%function sha512_block_data_order: +.Lsha512_block_data_order: #if __ARM_ARCH__<7 sub r3,pc,#8 @ sha512_block_data_order #else - adr r3,sha512_block_data_order + adr r3,.Lsha512_block_data_order #endif #if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) ldr r12,.LOPENSSL_armcap diff --git a/arch/arm/crypto/sha512-core.S_shipped b/arch/arm/crypto/sha512-core.S_shipped index 3694c4d4ca2b..de9bd7f55242 100644 --- a/arch/arm/crypto/sha512-core.S_shipped +++ b/arch/arm/crypto/sha512-core.S_shipped @@ -134,10 +134,11 @@ WORD64(0x5fcb6fab,0x3ad6faec, 0x6c44198c,0x4a475817) .global sha512_block_data_order .type sha512_block_data_order,%function sha512_block_data_order: +.Lsha512_block_data_order: #if __ARM_ARCH__<7 sub r3,pc,#8 @ sha512_block_data_order #else - adr r3,sha512_block_data_order + adr r3,.Lsha512_block_data_order #endif #if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) ldr r12,.LOPENSSL_armcap -- GitLab From e2f0e69fd9969b9940c3d8c48316dbc5ec16dd99 Mon Sep 17 00:00:00 2001 From: Julia Cartwright Date: Wed, 20 Feb 2019 16:46:31 +0000 Subject: [PATCH 0139/1121] iommu/dmar: Fix buffer overflow during PCI bus notification [ Upstream commit cffaaf0c816238c45cd2d06913476c83eb50f682 ] Commit 57384592c433 ("iommu/vt-d: Store bus information in RMRR PCI device path") changed the type of the path data, however, the change in path type was not reflected in size calculations. Update to use the correct type and prevent a buffer overflow. This bug manifests in systems with deep PCI hierarchies, and can lead to an overflow of the static allocated buffer (dmar_pci_notify_info_buf), or can lead to overflow of slab-allocated data. BUG: KASAN: global-out-of-bounds in dmar_alloc_pci_notify_info+0x1d5/0x2e0 Write of size 1 at addr ffffffff90445d80 by task swapper/0/1 CPU: 0 PID: 1 Comm: swapper/0 Tainted: G W 4.14.87-rt49-02406-gd0a0e96 #1 Call Trace: ? dump_stack+0x46/0x59 ? print_address_description+0x1df/0x290 ? dmar_alloc_pci_notify_info+0x1d5/0x2e0 ? kasan_report+0x256/0x340 ? dmar_alloc_pci_notify_info+0x1d5/0x2e0 ? e820__memblock_setup+0xb0/0xb0 ? dmar_dev_scope_init+0x424/0x48f ? __down_write_common+0x1ec/0x230 ? dmar_dev_scope_init+0x48f/0x48f ? dmar_free_unused_resources+0x109/0x109 ? cpumask_next+0x16/0x20 ? __kmem_cache_create+0x392/0x430 ? kmem_cache_create+0x135/0x2f0 ? e820__memblock_setup+0xb0/0xb0 ? intel_iommu_init+0x170/0x1848 ? _raw_spin_unlock_irqrestore+0x32/0x60 ? migrate_enable+0x27a/0x5b0 ? sched_setattr+0x20/0x20 ? migrate_disable+0x1fc/0x380 ? task_rq_lock+0x170/0x170 ? try_to_run_init_process+0x40/0x40 ? locks_remove_file+0x85/0x2f0 ? dev_prepare_static_identity_mapping+0x78/0x78 ? rt_spin_unlock+0x39/0x50 ? lockref_put_or_lock+0x2a/0x40 ? dput+0x128/0x2f0 ? __rcu_read_unlock+0x66/0x80 ? __fput+0x250/0x300 ? __rcu_read_lock+0x1b/0x30 ? mntput_no_expire+0x38/0x290 ? e820__memblock_setup+0xb0/0xb0 ? pci_iommu_init+0x25/0x63 ? pci_iommu_init+0x25/0x63 ? do_one_initcall+0x7e/0x1c0 ? initcall_blacklisted+0x120/0x120 ? kernel_init_freeable+0x27b/0x307 ? rest_init+0xd0/0xd0 ? kernel_init+0xf/0x120 ? rest_init+0xd0/0xd0 ? ret_from_fork+0x1f/0x40 The buggy address belongs to the variable: dmar_pci_notify_info_buf+0x40/0x60 Fixes: 57384592c433 ("iommu/vt-d: Store bus information in RMRR PCI device path") Signed-off-by: Julia Cartwright Signed-off-by: Joerg Roedel Signed-off-by: Sasha Levin --- drivers/iommu/dmar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c index c0d1c4db5794..38d0128b8135 100644 --- a/drivers/iommu/dmar.c +++ b/drivers/iommu/dmar.c @@ -144,7 +144,7 @@ dmar_alloc_pci_notify_info(struct pci_dev *dev, unsigned long event) for (tmp = dev; tmp; tmp = tmp->bus->self) level++; - size = sizeof(*info) + level * sizeof(struct acpi_dmar_pci_path); + size = sizeof(*info) + level * sizeof(info->path[0]); if (size <= sizeof(dmar_pci_notify_info_buf)) { info = (struct dmar_pci_notify_info *)dmar_pci_notify_info_buf; } else { -- GitLab From 201aee309a2964a3f8f8e82a57b7e29305c4b610 Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Sun, 21 Oct 2018 21:36:14 +0300 Subject: [PATCH 0140/1121] soc/tegra: pmc: Drop locking from tegra_powergate_is_powered() [ Upstream commit b6e1fd17a38bd1d97c11d69fd3207b3ef9bfa4b3 ] This fixes splats like the one below if CONFIG_DEBUG_ATOMIC_SLEEP=y and machine (Tegra30) booted with SMP=n or all secondary CPU's are put offline. Locking isn't needed because it protects atomic operation. BUG: sleeping function called from invalid context at kernel/locking/mutex.c:254 in_atomic(): 1, irqs_disabled(): 128, pid: 0, name: swapper/0 CPU: 0 PID: 0 Comm: swapper/0 Tainted: G C 4.18.0-next-20180821-00180-gc3ebb6544e44-dirty #823 Hardware name: NVIDIA Tegra SoC (Flattened Device Tree) [] (unwind_backtrace) from [] (show_stack+0x20/0x24) [] (show_stack) from [] (dump_stack+0x94/0xa8) [] (dump_stack) from [] (___might_sleep+0x13c/0x174) [] (___might_sleep) from [] (__might_sleep+0x70/0xa8) [] (__might_sleep) from [] (mutex_lock+0x2c/0x70) [] (mutex_lock) from [] (tegra_powergate_is_powered+0x44/0xa8) [] (tegra_powergate_is_powered) from [] (tegra30_cpu_rail_off_ready+0x30/0x74) [] (tegra30_cpu_rail_off_ready) from [] (tegra30_idle_lp2+0xa0/0x108) [] (tegra30_idle_lp2) from [] (cpuidle_enter_state+0x140/0x540) [] (cpuidle_enter_state) from [] (cpuidle_enter+0x40/0x4c) [] (cpuidle_enter) from [] (call_cpuidle+0x30/0x48) [] (call_cpuidle) from [] (do_idle+0x238/0x28c) [] (do_idle) from [] (cpu_startup_entry+0x28/0x2c) [] (cpu_startup_entry) from [] (rest_init+0xd8/0xdc) [] (rest_init) from [] (start_kernel+0x41c/0x430) Signed-off-by: Dmitry Osipenko Acked-by: Jon Hunter Signed-off-by: Thierry Reding Signed-off-by: Sasha Levin --- drivers/soc/tegra/pmc.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index 7e9ef3431bea..2422ed56895a 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -521,16 +521,10 @@ EXPORT_SYMBOL(tegra_powergate_power_off); */ int tegra_powergate_is_powered(unsigned int id) { - int status; - if (!tegra_powergate_is_valid(id)) return -EINVAL; - mutex_lock(&pmc->powergates_lock); - status = tegra_powergate_state(id); - mutex_unlock(&pmc->powergates_lock); - - return status; + return tegra_powergate_state(id); } /** -- GitLab From b035faf50706d45ce8a5967b4efc1ccf5559f655 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Wed, 7 Nov 2018 20:14:10 +0000 Subject: [PATCH 0141/1121] lkdtm: Print real addresses [ Upstream commit 4c411157a42f122051ae3469bee0b5cabe89e139 ] Today, when doing a lkdtm test before the readiness of the random generator, (ptrval) is printed instead of the address at which it perform the fault: [ 1597.337030] lkdtm: Performing direct entry EXEC_USERSPACE [ 1597.337142] lkdtm: attempting ok execution at (ptrval) [ 1597.337398] lkdtm: attempting bad execution at (ptrval) [ 1597.337460] kernel tried to execute user page (77858000) -exploit attempt? (uid: 0) [ 1597.344769] Unable to handle kernel paging request for instruction fetch [ 1597.351392] Faulting instruction address: 0x77858000 [ 1597.356312] Oops: Kernel access of bad area, sig: 11 [#1] If the lkdtm test is done later on, it prints an hashed address. In both cases this is pointless. The purpose of the test is to ensure the kernel generates an Oops at the expected address, so real addresses needs to be printed. This patch fixes that. Signed-off-by: Christophe Leroy Signed-off-by: Kees Cook Signed-off-by: Sasha Levin --- drivers/misc/lkdtm_perms.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/misc/lkdtm_perms.c b/drivers/misc/lkdtm_perms.c index 53b85c9d16b8..fa54add6375a 100644 --- a/drivers/misc/lkdtm_perms.c +++ b/drivers/misc/lkdtm_perms.c @@ -47,7 +47,7 @@ static noinline void execute_location(void *dst, bool write) { void (*func)(void) = dst; - pr_info("attempting ok execution at %p\n", do_nothing); + pr_info("attempting ok execution at %px\n", do_nothing); do_nothing(); if (write == CODE_WRITE) { @@ -55,7 +55,7 @@ static noinline void execute_location(void *dst, bool write) flush_icache_range((unsigned long)dst, (unsigned long)dst + EXEC_SIZE); } - pr_info("attempting bad execution at %p\n", func); + pr_info("attempting bad execution at %px\n", func); func(); } @@ -66,14 +66,14 @@ static void execute_user_location(void *dst) /* Intentionally crossing kernel/user memory boundary. */ void (*func)(void) = dst; - pr_info("attempting ok execution at %p\n", do_nothing); + pr_info("attempting ok execution at %px\n", do_nothing); do_nothing(); copied = access_process_vm(current, (unsigned long)dst, do_nothing, EXEC_SIZE, FOLL_WRITE); if (copied < EXEC_SIZE) return; - pr_info("attempting bad execution at %p\n", func); + pr_info("attempting bad execution at %px\n", func); func(); } @@ -82,7 +82,7 @@ void lkdtm_WRITE_RO(void) /* Explicitly cast away "const" for the test. */ unsigned long *ptr = (unsigned long *)&rodata; - pr_info("attempting bad rodata write at %p\n", ptr); + pr_info("attempting bad rodata write at %px\n", ptr); *ptr ^= 0xabcd1234; } @@ -100,7 +100,7 @@ void lkdtm_WRITE_RO_AFTER_INIT(void) return; } - pr_info("attempting bad ro_after_init write at %p\n", ptr); + pr_info("attempting bad ro_after_init write at %px\n", ptr); *ptr ^= 0xabcd1234; } @@ -112,7 +112,7 @@ void lkdtm_WRITE_KERN(void) size = (unsigned long)do_overwritten - (unsigned long)do_nothing; ptr = (unsigned char *)do_overwritten; - pr_info("attempting bad %zu byte write at %p\n", size, ptr); + pr_info("attempting bad %zu byte write at %px\n", size, ptr); memcpy(ptr, (unsigned char *)do_nothing, size); flush_icache_range((unsigned long)ptr, (unsigned long)(ptr + size)); @@ -185,11 +185,11 @@ void lkdtm_ACCESS_USERSPACE(void) ptr = (unsigned long *)user_addr; - pr_info("attempting bad read at %p\n", ptr); + pr_info("attempting bad read at %px\n", ptr); tmp = *ptr; tmp += 0xc0dec0de; - pr_info("attempting bad write at %p\n", ptr); + pr_info("attempting bad write at %px\n", ptr); *ptr = tmp; vm_munmap(user_addr, PAGE_SIZE); -- GitLab From f2778b3522da89d5fd4a95aa95dc6d01a45a3710 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Fri, 14 Dec 2018 15:26:20 +0000 Subject: [PATCH 0142/1121] lkdtm: Add tests for NULL pointer dereference [ Upstream commit 59a12205d3c32aee4c13ca36889fdf7cfed31126 ] Introduce lkdtm tests for NULL pointer dereference: check access or exec at NULL address, since these errors tend to be reported differently from the general fault error text. For example from x86: pr_alert("BUG: unable to handle kernel %s at %px\n", address < PAGE_SIZE ? "NULL pointer dereference" : "paging request", (void *)address); Signed-off-by: Christophe Leroy Signed-off-by: Kees Cook Signed-off-by: Sasha Levin --- drivers/misc/lkdtm.h | 2 ++ drivers/misc/lkdtm_core.c | 2 ++ drivers/misc/lkdtm_perms.c | 18 ++++++++++++++++++ 3 files changed, 22 insertions(+) diff --git a/drivers/misc/lkdtm.h b/drivers/misc/lkdtm.h index 687a0dbbe199..614612325332 100644 --- a/drivers/misc/lkdtm.h +++ b/drivers/misc/lkdtm.h @@ -45,7 +45,9 @@ void lkdtm_EXEC_KMALLOC(void); void lkdtm_EXEC_VMALLOC(void); void lkdtm_EXEC_RODATA(void); void lkdtm_EXEC_USERSPACE(void); +void lkdtm_EXEC_NULL(void); void lkdtm_ACCESS_USERSPACE(void); +void lkdtm_ACCESS_NULL(void); /* lkdtm_refcount.c */ void lkdtm_REFCOUNT_INC_OVERFLOW(void); diff --git a/drivers/misc/lkdtm_core.c b/drivers/misc/lkdtm_core.c index 981b3ef71e47..199271708aed 100644 --- a/drivers/misc/lkdtm_core.c +++ b/drivers/misc/lkdtm_core.c @@ -220,7 +220,9 @@ struct crashtype crashtypes[] = { CRASHTYPE(EXEC_VMALLOC), CRASHTYPE(EXEC_RODATA), CRASHTYPE(EXEC_USERSPACE), + CRASHTYPE(EXEC_NULL), CRASHTYPE(ACCESS_USERSPACE), + CRASHTYPE(ACCESS_NULL), CRASHTYPE(WRITE_RO), CRASHTYPE(WRITE_RO_AFTER_INIT), CRASHTYPE(WRITE_KERN), diff --git a/drivers/misc/lkdtm_perms.c b/drivers/misc/lkdtm_perms.c index fa54add6375a..62f76d506f04 100644 --- a/drivers/misc/lkdtm_perms.c +++ b/drivers/misc/lkdtm_perms.c @@ -164,6 +164,11 @@ void lkdtm_EXEC_USERSPACE(void) vm_munmap(user_addr, PAGE_SIZE); } +void lkdtm_EXEC_NULL(void) +{ + execute_location(NULL, CODE_AS_IS); +} + void lkdtm_ACCESS_USERSPACE(void) { unsigned long user_addr, tmp = 0; @@ -195,6 +200,19 @@ void lkdtm_ACCESS_USERSPACE(void) vm_munmap(user_addr, PAGE_SIZE); } +void lkdtm_ACCESS_NULL(void) +{ + unsigned long tmp; + unsigned long *ptr = (unsigned long *)NULL; + + pr_info("attempting bad read at %px\n", ptr); + tmp = *ptr; + tmp += 0xc0dec0de; + + pr_info("attempting bad write at %px\n", ptr); + *ptr = tmp; +} + void __init lkdtm_perms_init(void) { /* Make sure we can write to __ro_after_init values during __init */ -- GitLab From 61bea6ad5c99a3d1adb28b17d25b21d71998b65b Mon Sep 17 00:00:00 2001 From: "Hsin-Yi, Wang" Date: Wed, 9 Jan 2019 14:59:22 +0800 Subject: [PATCH 0143/1121] drm/panel: panel-innolux: set display off in innolux_panel_unprepare [ Upstream commit 46f3ceaffa81e846677bca8668e0ad40e643cffd ] Move mipi_dsi_dcs_set_display_off() from innolux_panel_disable() to innolux_panel_unprepare(), so they are consistent with innolux_panel_enable() and innolux_panel_prepare(). This also fixes some mode check and irq timeout issue in MTK dsi code. Since some dsi code (e.g. mtk_dsi) have following call trace: 1. drm_panel_disable(), which calls innolux_panel_disable() 2. switch to cmd mode 3. drm_panel_unprepare(), which calls innolux_panel_unprepare() However, mtk_dsi needs to be in cmd mode to be able to send commands (e.g. mipi_dsi_dcs_set_display_off() and mipi_dsi_dcs_enter_sleep_mode()), so we need these functions to be called after the switch to cmd mode happens, i.e. in innolux_panel_unprepare. Signed-off-by: Hsin-Yi, Wang Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20190109065922.231753-1-hsinyi@chromium.org Signed-off-by: Sasha Levin --- drivers/gpu/drm/panel/panel-innolux-p079zca.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-innolux-p079zca.c b/drivers/gpu/drm/panel/panel-innolux-p079zca.c index 6ba93449fcfb..58b67e0cc385 100644 --- a/drivers/gpu/drm/panel/panel-innolux-p079zca.c +++ b/drivers/gpu/drm/panel/panel-innolux-p079zca.c @@ -40,7 +40,6 @@ static inline struct innolux_panel *to_innolux_panel(struct drm_panel *panel) static int innolux_panel_disable(struct drm_panel *panel) { struct innolux_panel *innolux = to_innolux_panel(panel); - int err; if (!innolux->enabled) return 0; @@ -48,11 +47,6 @@ static int innolux_panel_disable(struct drm_panel *panel) innolux->backlight->props.power = FB_BLANK_POWERDOWN; backlight_update_status(innolux->backlight); - err = mipi_dsi_dcs_set_display_off(innolux->link); - if (err < 0) - DRM_DEV_ERROR(panel->dev, "failed to set display off: %d\n", - err); - innolux->enabled = false; return 0; @@ -66,6 +60,11 @@ static int innolux_panel_unprepare(struct drm_panel *panel) if (!innolux->prepared) return 0; + err = mipi_dsi_dcs_set_display_off(innolux->link); + if (err < 0) + DRM_DEV_ERROR(panel->dev, "failed to set display off: %d\n", + err); + err = mipi_dsi_dcs_enter_sleep_mode(innolux->link); if (err < 0) { DRM_DEV_ERROR(panel->dev, "failed to enter sleep mode: %d\n", -- GitLab From 56828309878bae0d8ff5e9851dca080cd7eea224 Mon Sep 17 00:00:00 2001 From: Lars Persson Date: Wed, 23 Jan 2019 12:59:42 +0100 Subject: [PATCH 0144/1121] crypto: axis - fix for recursive locking from bottom half [ Upstream commit c34a83820f59bb275e5f2d55cd5ea99c64f6ef23 ] Clients may submit a new requests from the completion callback context. The driver was not prepared to receive a request in this state because it already held the request queue lock and a recursive lock error is triggered. Now all completions are queued up until we are ready to drop the queue lock and then delivered. The fault was triggered by TCP over an IPsec connection in the LTP test suite: LTP: starting tcp4_ipsec02 (tcp_ipsec.sh -p ah -m transport -s "100 1000 65535") BUG: spinlock recursion on CPU#1, genload/943 lock: 0xbf3c3094, .magic: dead4ead, .owner: genload/943, .owner_cpu: 1 CPU: 1 PID: 943 Comm: genload Tainted: G O 4.9.62-axis5-devel #6 Hardware name: Axis ARTPEC-6 Platform (unwind_backtrace) from [<8010d134>] (show_stack+0x18/0x1c) (show_stack) from [<803a289c>] (dump_stack+0x84/0x98) (dump_stack) from [<8016e164>] (do_raw_spin_lock+0x124/0x128) (do_raw_spin_lock) from [<804de1a4>] (artpec6_crypto_submit+0x2c/0xa0) (artpec6_crypto_submit) from [<804def38>] (artpec6_crypto_prepare_submit_hash+0xd0/0x54c) (artpec6_crypto_prepare_submit_hash) from [<7f3165f0>] (ah_output+0x2a4/0x3dc [ah4]) (ah_output [ah4]) from [<805df9bc>] (xfrm_output_resume+0x178/0x4a4) (xfrm_output_resume) from [<805d283c>] (xfrm4_output+0xac/0xbc) (xfrm4_output) from [<80587928>] (ip_queue_xmit+0x140/0x3b4) (ip_queue_xmit) from [<805a13b4>] (tcp_transmit_skb+0x4c4/0x95c) (tcp_transmit_skb) from [<8059f218>] (tcp_rcv_state_process+0xdf4/0xdfc) (tcp_rcv_state_process) from [<805a7530>] (tcp_v4_do_rcv+0x64/0x1ac) (tcp_v4_do_rcv) from [<805a9724>] (tcp_v4_rcv+0xa34/0xb74) (tcp_v4_rcv) from [<80581d34>] (ip_local_deliver_finish+0x78/0x2b0) (ip_local_deliver_finish) from [<8058259c>] (ip_local_deliver+0xe4/0x104) (ip_local_deliver) from [<805d23ec>] (xfrm4_transport_finish+0xf4/0x144) (xfrm4_transport_finish) from [<805df564>] (xfrm_input+0x4f4/0x74c) (xfrm_input) from [<804de420>] (artpec6_crypto_task+0x208/0x38c) (artpec6_crypto_task) from [<801271b0>] (tasklet_action+0x60/0xec) (tasklet_action) from [<801266d4>] (__do_softirq+0xcc/0x3a4) (__do_softirq) from [<80126d20>] (irq_exit+0xf4/0x15c) (irq_exit) from [<801741e8>] (__handle_domain_irq+0x68/0xbc) (__handle_domain_irq) from [<801014f0>] (gic_handle_irq+0x50/0x94) (gic_handle_irq) from [<80657370>] (__irq_usr+0x50/0x80) Signed-off-by: Lars Persson Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/axis/artpec6_crypto.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/drivers/crypto/axis/artpec6_crypto.c b/drivers/crypto/axis/artpec6_crypto.c index 6eb5cb92b986..9f82e14983f6 100644 --- a/drivers/crypto/axis/artpec6_crypto.c +++ b/drivers/crypto/axis/artpec6_crypto.c @@ -284,6 +284,7 @@ enum artpec6_crypto_hash_flags { struct artpec6_crypto_req_common { struct list_head list; + struct list_head complete_in_progress; struct artpec6_crypto_dma_descriptors *dma; struct crypto_async_request *req; void (*complete)(struct crypto_async_request *req); @@ -2046,7 +2047,8 @@ static int artpec6_crypto_prepare_aead(struct aead_request *areq) return artpec6_crypto_dma_map_descs(common); } -static void artpec6_crypto_process_queue(struct artpec6_crypto *ac) +static void artpec6_crypto_process_queue(struct artpec6_crypto *ac, + struct list_head *completions) { struct artpec6_crypto_req_common *req; @@ -2057,7 +2059,7 @@ static void artpec6_crypto_process_queue(struct artpec6_crypto *ac) list_move_tail(&req->list, &ac->pending); artpec6_crypto_start_dma(req); - req->req->complete(req->req, -EINPROGRESS); + list_add_tail(&req->complete_in_progress, completions); } /* @@ -2087,6 +2089,11 @@ static void artpec6_crypto_task(unsigned long data) struct artpec6_crypto *ac = (struct artpec6_crypto *)data; struct artpec6_crypto_req_common *req; struct artpec6_crypto_req_common *n; + struct list_head complete_done; + struct list_head complete_in_progress; + + INIT_LIST_HEAD(&complete_done); + INIT_LIST_HEAD(&complete_in_progress); if (list_empty(&ac->pending)) { pr_debug("Spurious IRQ\n"); @@ -2120,19 +2127,30 @@ static void artpec6_crypto_task(unsigned long data) pr_debug("Completing request %p\n", req); - list_del(&req->list); + list_move_tail(&req->list, &complete_done); artpec6_crypto_dma_unmap_all(req); artpec6_crypto_copy_bounce_buffers(req); ac->pending_count--; artpec6_crypto_common_destroy(req); - req->complete(req->req); } - artpec6_crypto_process_queue(ac); + artpec6_crypto_process_queue(ac, &complete_in_progress); spin_unlock_bh(&ac->queue_lock); + + /* Perform the completion callbacks without holding the queue lock + * to allow new request submissions from the callbacks. + */ + list_for_each_entry_safe(req, n, &complete_done, list) { + req->complete(req->req); + } + + list_for_each_entry_safe(req, n, &complete_in_progress, + complete_in_progress) { + req->req->complete(req->req, -EINPROGRESS); + } } static void artpec6_crypto_complete_crypto(struct crypto_async_request *req) -- GitLab From 3e3adeb25d440147ae00eefbe9d62cff56dcc7c6 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Fri, 1 Feb 2019 14:13:41 +0800 Subject: [PATCH 0145/1121] Revert "ACPI / EC: Remove old CLEAR_ON_RESUME quirk" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit b6a3e1475b0220378ad32bdf4d8692f058b1fc03 ] On some Samsung hardware, it is necessary to clear events accumulated by the EC during sleep. These ECs stop reporting GPEs until they are manually polled, if too many events are accumulated. Thus the CLEAR_ON_RESUME quirk is introduced to send EC query commands unconditionally after resume to clear all the EC query events on those platforms. Later, commit 4c237371f290 ("ACPI / EC: Remove old CLEAR_ON_RESUME quirk") removes the CLEAR_ON_RESUME quirk because we thought the new EC IRQ polling logic should handle this case. Now it has been proved that the EC IRQ Polling logic does not fix the issue actually because we got regression report on these Samsung platforms after removing the quirk. Thus revert commit 4c237371f290 ("ACPI / EC: Remove old CLEAR_ON_RESUME quirk") to introduce back the Samsung quirk in this patch. Link: https://bugzilla.kernel.org/show_bug.cgi?id=44161 Tested-by: Ortwin GlĂŒck Tested-by: Francisco Cribari Tested-by: Balazs Varga Signed-off-by: Zhang Rui Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/acpi/ec.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 3d624c72c6c2..ebfc06f29f7b 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -194,6 +194,7 @@ static struct workqueue_struct *ec_query_wq; static int EC_FLAGS_QUERY_HANDSHAKE; /* Needs QR_EC issued when SCI_EVT set */ static int EC_FLAGS_CORRECT_ECDT; /* Needs ECDT port address correction */ static int EC_FLAGS_IGNORE_DSDT_GPE; /* Needs ECDT GPE as correction setting */ +static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */ /* -------------------------------------------------------------------------- * Logging/Debugging @@ -499,6 +500,26 @@ static inline void __acpi_ec_disable_event(struct acpi_ec *ec) ec_log_drv("event blocked"); } +/* + * Process _Q events that might have accumulated in the EC. + * Run with locked ec mutex. + */ +static void acpi_ec_clear(struct acpi_ec *ec) +{ + int i, status; + u8 value = 0; + + for (i = 0; i < ACPI_EC_CLEAR_MAX; i++) { + status = acpi_ec_query(ec, &value); + if (status || !value) + break; + } + if (unlikely(i == ACPI_EC_CLEAR_MAX)) + pr_warn("Warning: Maximum of %d stale EC events cleared\n", i); + else + pr_info("%d stale EC events cleared\n", i); +} + static void acpi_ec_enable_event(struct acpi_ec *ec) { unsigned long flags; @@ -507,6 +528,10 @@ static void acpi_ec_enable_event(struct acpi_ec *ec) if (acpi_ec_started(ec)) __acpi_ec_enable_event(ec); spin_unlock_irqrestore(&ec->lock, flags); + + /* Drain additional events if hardware requires that */ + if (EC_FLAGS_CLEAR_ON_RESUME) + acpi_ec_clear(ec); } #ifdef CONFIG_PM_SLEEP @@ -1802,6 +1827,31 @@ static int ec_flag_query_handshake(const struct dmi_system_id *id) } #endif +/* + * On some hardware it is necessary to clear events accumulated by the EC during + * sleep. These ECs stop reporting GPEs until they are manually polled, if too + * many events are accumulated. (e.g. Samsung Series 5/9 notebooks) + * + * https://bugzilla.kernel.org/show_bug.cgi?id=44161 + * + * Ideally, the EC should also be instructed NOT to accumulate events during + * sleep (which Windows seems to do somehow), but the interface to control this + * behaviour is not known at this time. + * + * Models known to be affected are Samsung 530Uxx/535Uxx/540Uxx/550Pxx/900Xxx, + * however it is very likely that other Samsung models are affected. + * + * On systems which don't accumulate _Q events during sleep, this extra check + * should be harmless. + */ +static int ec_clear_on_resume(const struct dmi_system_id *id) +{ + pr_debug("Detected system needing EC poll on resume.\n"); + EC_FLAGS_CLEAR_ON_RESUME = 1; + ec_event_clearing = ACPI_EC_EVT_TIMING_STATUS; + return 0; +} + /* * Some ECDTs contain wrong register addresses. * MSI MS-171F @@ -1851,6 +1901,9 @@ static const struct dmi_system_id ec_dmi_table[] __initconst = { ec_honor_ecdt_gpe, "ASUS X580VD", { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), DMI_MATCH(DMI_PRODUCT_NAME, "X580VD"),}, NULL}, + { + ec_clear_on_resume, "Samsung hardware", { + DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD.")}, NULL}, {}, }; -- GitLab From a68ee104ae03e4309f40de3443923773c97411db Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Tue, 5 Feb 2019 16:24:53 -0700 Subject: [PATCH 0146/1121] coresight: cpu-debug: Support for CA73 CPUs [ Upstream commit a0f890aba2be33377f4eb24e13633c4a76a68f38 ] This patch is to add the AMBA device ID for CA73 CPU, so that CPU debug module can be initialized successfully when a SoC contain CA73 CPUs. This patch has been verified on 96boards Hikey960. Signed-off-by: Leo Yan Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/hwtracing/coresight/coresight-cpu-debug.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/hwtracing/coresight/coresight-cpu-debug.c b/drivers/hwtracing/coresight/coresight-cpu-debug.c index 9cdb3fbc8c1f..2f6f46ea68e9 100644 --- a/drivers/hwtracing/coresight/coresight-cpu-debug.c +++ b/drivers/hwtracing/coresight/coresight-cpu-debug.c @@ -680,6 +680,10 @@ static const struct amba_id debug_ids[] = { .id = 0x000bbd08, .mask = 0x000fffff, }, + { /* Debug for Cortex-A73 */ + .id = 0x000bbd09, + .mask = 0x000fffff, + }, { 0, 0 }, }; -- GitLab From 03e67ed367d4763f0ff9a8fc80b8a880df6c666e Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Sun, 13 Jan 2019 17:50:10 -0500 Subject: [PATCH 0147/1121] drm/nouveau/volt/gf117: fix speedo readout register [ Upstream commit fc782242749fa4235592854fafe1a1297583c1fb ] GF117 appears to use the same register as GK104 (but still with the general Fermi readout mechanism). Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=108980 Signed-off-by: Ilia Mirkin Signed-off-by: Ben Skeggs Signed-off-by: Sasha Levin --- .../drm/nouveau/include/nvkm/subdev/volt.h | 1 + .../gpu/drm/nouveau/nvkm/engine/device/base.c | 2 +- .../gpu/drm/nouveau/nvkm/subdev/volt/Kbuild | 1 + .../gpu/drm/nouveau/nvkm/subdev/volt/gf117.c | 60 +++++++++++++++++++ 4 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/volt/gf117.c diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/volt.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/volt.h index 8a0f85f5fc1a..6a765682fbfa 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/volt.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/volt.h @@ -38,6 +38,7 @@ int nvkm_volt_set_id(struct nvkm_volt *, u8 id, u8 min_id, u8 temp, int nv40_volt_new(struct nvkm_device *, int, struct nvkm_volt **); int gf100_volt_new(struct nvkm_device *, int, struct nvkm_volt **); +int gf117_volt_new(struct nvkm_device *, int, struct nvkm_volt **); int gk104_volt_new(struct nvkm_device *, int, struct nvkm_volt **); int gk20a_volt_new(struct nvkm_device *, int, struct nvkm_volt **); int gm20b_volt_new(struct nvkm_device *, int, struct nvkm_volt **); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index e096a5d9c292..f8dd78e21456 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -1612,7 +1612,7 @@ nvd7_chipset = { .pci = gf106_pci_new, .therm = gf119_therm_new, .timer = nv41_timer_new, - .volt = gf100_volt_new, + .volt = gf117_volt_new, .ce[0] = gf100_ce_new, .disp = gf119_disp_new, .dma = gf119_dma_new, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/Kbuild index bcd179ba11d0..146adcdd316a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/Kbuild @@ -2,6 +2,7 @@ nvkm-y += nvkm/subdev/volt/base.o nvkm-y += nvkm/subdev/volt/gpio.o nvkm-y += nvkm/subdev/volt/nv40.o nvkm-y += nvkm/subdev/volt/gf100.o +nvkm-y += nvkm/subdev/volt/gf117.o nvkm-y += nvkm/subdev/volt/gk104.o nvkm-y += nvkm/subdev/volt/gk20a.o nvkm-y += nvkm/subdev/volt/gm20b.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gf117.c b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gf117.c new file mode 100644 index 000000000000..547a58f0aeac --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gf117.c @@ -0,0 +1,60 @@ +/* + * Copyright 2019 Ilia Mirkin + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ilia Mirkin + */ +#include "priv.h" + +#include + +static int +gf117_volt_speedo_read(struct nvkm_volt *volt) +{ + struct nvkm_device *device = volt->subdev.device; + struct nvkm_fuse *fuse = device->fuse; + + if (!fuse) + return -EINVAL; + + return nvkm_fuse_read(fuse, 0x3a8); +} + +static const struct nvkm_volt_func +gf117_volt = { + .oneinit = gf100_volt_oneinit, + .vid_get = nvkm_voltgpio_get, + .vid_set = nvkm_voltgpio_set, + .speedo_read = gf117_volt_speedo_read, +}; + +int +gf117_volt_new(struct nvkm_device *device, int index, struct nvkm_volt **pvolt) +{ + struct nvkm_volt *volt; + int ret; + + ret = nvkm_volt_new_(&gf117_volt, device, index, &volt); + *pvolt = volt; + if (ret) + return ret; + + return nvkm_voltgpio_init(volt); +} -- GitLab From 5e3f6ba82ed450d62ac7910b0fe026d31eb2aa5b Mon Sep 17 00:00:00 2001 From: Yang Shi Date: Wed, 13 Feb 2019 17:14:23 +0100 Subject: [PATCH 0148/1121] ARM: 8839/1: kprobe: make patch_lock a raw_spinlock_t [ Upstream commit 143c2a89e0e5fda6c6fd08d7bc1126438c19ae90 ] When running kprobe on -rt kernel, the below bug is caught: |BUG: sleeping function called from invalid context at kernel/locking/rtmutex.c:931 |in_atomic(): 1, irqs_disabled(): 128, pid: 14, name: migration/0 |Preemption disabled at:[<802f2b98>] cpu_stopper_thread+0xc0/0x140 |CPU: 0 PID: 14 Comm: migration/0 Tainted: G O 4.8.3-rt2 #1 |Hardware name: Freescale LS1021A |[<8025a43c>] (___might_sleep) |[<80b5b324>] (rt_spin_lock) |[<80b5c31c>] (__patch_text_real) |[<80b5c3ac>] (patch_text_stop_machine) |[<802f2920>] (multi_cpu_stop) Since patch_text_stop_machine() is called in stop_machine() which disables IRQ, sleepable lock should be not used in this atomic context, so replace patch_lock to raw lock. Signed-off-by: Yang Shi Signed-off-by: Sebastian Andrzej Siewior Reviewed-by: Arnd Bergmann Signed-off-by: Russell King Signed-off-by: Sasha Levin --- arch/arm/kernel/patch.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/kernel/patch.c b/arch/arm/kernel/patch.c index a50dc00d79a2..d0a05a3bdb96 100644 --- a/arch/arm/kernel/patch.c +++ b/arch/arm/kernel/patch.c @@ -16,7 +16,7 @@ struct patch { unsigned int insn; }; -static DEFINE_SPINLOCK(patch_lock); +static DEFINE_RAW_SPINLOCK(patch_lock); static void __kprobes *patch_map(void *addr, int fixmap, unsigned long *flags) __acquires(&patch_lock) @@ -33,7 +33,7 @@ static void __kprobes *patch_map(void *addr, int fixmap, unsigned long *flags) return addr; if (flags) - spin_lock_irqsave(&patch_lock, *flags); + raw_spin_lock_irqsave(&patch_lock, *flags); else __acquire(&patch_lock); @@ -48,7 +48,7 @@ static void __kprobes patch_unmap(int fixmap, unsigned long *flags) clear_fixmap(fixmap); if (flags) - spin_unlock_irqrestore(&patch_lock, *flags); + raw_spin_unlock_irqrestore(&patch_lock, *flags); else __release(&patch_lock); } -- GitLab From 86c7f76a8930556ec515095363ddaa0604486cdd Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Fri, 22 Feb 2019 12:36:49 +0800 Subject: [PATCH 0149/1121] drm/amdkfd: use init_mqd function to allocate object for hid_mqd (CI) [ Upstream commit cac734c2dbd2514f14c8c6a17caba1990d83bf1d ] if use the legacy method to allocate object, when mqd_hiq need to run uninit code, it will be cause WARNING call trace. eg: (s3 suspend test) [ 34.918944] Call Trace: [ 34.918948] [] dump_stack+0x19/0x1b [ 34.918950] [] __warn+0xd8/0x100 [ 34.918951] [] warn_slowpath_null+0x1d/0x20 [ 34.918991] [] uninit_mqd_hiq_sdma+0x4e/0x50 [amdgpu] [ 34.919028] [] uninitialize+0x37/0xe0 [amdgpu] [ 34.919064] [] kernel_queue_uninit+0x16/0x30 [amdgpu] [ 34.919086] [] pm_uninit+0x12/0x20 [amdgpu] [ 34.919107] [] stop_nocpsch+0x15/0x20 [amdgpu] [ 34.919129] [] kgd2kfd_suspend.part.4+0x2e/0x50 [amdgpu] [ 34.919150] [] kgd2kfd_suspend+0x17/0x20 [amdgpu] [ 34.919171] [] amdgpu_amdkfd_suspend+0x1a/0x20 [amdgpu] [ 34.919187] [] amdgpu_device_suspend+0x88/0x3a0 [amdgpu] [ 34.919189] [] ? enqueue_entity+0x2ef/0xbe0 [ 34.919205] [] amdgpu_pmops_suspend+0x20/0x30 [amdgpu] [ 34.919207] [] pci_pm_suspend+0x6f/0x150 [ 34.919208] [] ? pci_pm_freeze+0xf0/0xf0 [ 34.919210] [] dpm_run_callback+0x46/0x90 [ 34.919212] [] __device_suspend+0xfb/0x2a0 [ 34.919213] [] async_suspend+0x1f/0xa0 [ 34.919214] [] async_run_entry_fn+0x3f/0x130 [ 34.919216] [] process_one_work+0x17f/0x440 [ 34.919217] [] worker_thread+0x126/0x3c0 [ 34.919218] [] ? manage_workers.isra.25+0x2a0/0x2a0 [ 34.919220] [] kthread+0xd1/0xe0 [ 34.919221] [] ? insert_kthread_work+0x40/0x40 [ 34.919222] [] ret_from_fork_nospec_begin+0x7/0x21 [ 34.919224] [] ? insert_kthread_work+0x40/0x40 [ 34.919224] ---[ end trace 38cd9f65c963adad ]--- Signed-off-by: Kevin Wang Reviewed-by: Oak Zeng Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- .../gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c | 52 +------------------ 1 file changed, 1 insertion(+), 51 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c index 164fa4b1f9a9..732b8fbbca68 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c @@ -285,57 +285,7 @@ static int init_mqd_hiq(struct mqd_manager *mm, void **mqd, struct kfd_mem_obj **mqd_mem_obj, uint64_t *gart_addr, struct queue_properties *q) { - uint64_t addr; - struct cik_mqd *m; - int retval; - - retval = kfd_gtt_sa_allocate(mm->dev, sizeof(struct cik_mqd), - mqd_mem_obj); - - if (retval != 0) - return -ENOMEM; - - m = (struct cik_mqd *) (*mqd_mem_obj)->cpu_ptr; - addr = (*mqd_mem_obj)->gpu_addr; - - memset(m, 0, ALIGN(sizeof(struct cik_mqd), 256)); - - m->header = 0xC0310800; - m->compute_pipelinestat_enable = 1; - m->compute_static_thread_mgmt_se0 = 0xFFFFFFFF; - m->compute_static_thread_mgmt_se1 = 0xFFFFFFFF; - m->compute_static_thread_mgmt_se2 = 0xFFFFFFFF; - m->compute_static_thread_mgmt_se3 = 0xFFFFFFFF; - - m->cp_hqd_persistent_state = DEFAULT_CP_HQD_PERSISTENT_STATE | - PRELOAD_REQ; - m->cp_hqd_quantum = QUANTUM_EN | QUANTUM_SCALE_1MS | - QUANTUM_DURATION(10); - - m->cp_mqd_control = MQD_CONTROL_PRIV_STATE_EN; - m->cp_mqd_base_addr_lo = lower_32_bits(addr); - m->cp_mqd_base_addr_hi = upper_32_bits(addr); - - m->cp_hqd_ib_control = DEFAULT_MIN_IB_AVAIL_SIZE; - - /* - * Pipe Priority - * Identifies the pipe relative priority when this queue is connected - * to the pipeline. The pipe priority is against the GFX pipe and HP3D. - * In KFD we are using a fixed pipe priority set to CS_MEDIUM. - * 0 = CS_LOW (typically below GFX) - * 1 = CS_MEDIUM (typically between HP3D and GFX - * 2 = CS_HIGH (typically above HP3D) - */ - m->cp_hqd_pipe_priority = 1; - m->cp_hqd_queue_priority = 15; - - *mqd = m; - if (gart_addr) - *gart_addr = addr; - retval = mm->update_mqd(mm, m, q); - - return retval; + return init_mqd(mm, mqd, mqd_mem_obj, gart_addr, q); } static int update_mqd_hiq(struct mqd_manager *mm, void *mqd, -- GitLab From 0ba1fa56351e6e9c2f8db4ffc823cb7057e4ea82 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Fri, 1 Mar 2019 10:57:57 +0800 Subject: [PATCH 0150/1121] appletalk: Fix use-after-free in atalk_proc_exit [ Upstream commit 6377f787aeb945cae7abbb6474798de129e1f3ac ] KASAN report this: BUG: KASAN: use-after-free in pde_subdir_find+0x12d/0x150 fs/proc/generic.c:71 Read of size 8 at addr ffff8881f41fe5b0 by task syz-executor.0/2806 CPU: 0 PID: 2806 Comm: syz-executor.0 Not tainted 5.0.0-rc7+ #45 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1 04/01/2014 Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0xfa/0x1ce lib/dump_stack.c:113 print_address_description+0x65/0x270 mm/kasan/report.c:187 kasan_report+0x149/0x18d mm/kasan/report.c:317 pde_subdir_find+0x12d/0x150 fs/proc/generic.c:71 remove_proc_entry+0xe8/0x420 fs/proc/generic.c:667 atalk_proc_exit+0x18/0x820 [appletalk] atalk_exit+0xf/0x5a [appletalk] __do_sys_delete_module kernel/module.c:1018 [inline] __se_sys_delete_module kernel/module.c:961 [inline] __x64_sys_delete_module+0x3dc/0x5e0 kernel/module.c:961 do_syscall_64+0x147/0x600 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x49/0xbe RIP: 0033:0x462e99 Code: f7 d8 64 89 02 b8 ff ff ff ff c3 66 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 bc ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007fb2de6b9c58 EFLAGS: 00000246 ORIG_RAX: 00000000000000b0 RAX: ffffffffffffffda RBX: 000000000073bf00 RCX: 0000000000462e99 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 00000000200001c0 RBP: 0000000000000002 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 00007fb2de6ba6bc R13: 00000000004bccaa R14: 00000000006f6bc8 R15: 00000000ffffffff Allocated by task 2806: set_track mm/kasan/common.c:85 [inline] __kasan_kmalloc.constprop.3+0xa0/0xd0 mm/kasan/common.c:496 slab_post_alloc_hook mm/slab.h:444 [inline] slab_alloc_node mm/slub.c:2739 [inline] slab_alloc mm/slub.c:2747 [inline] kmem_cache_alloc+0xcf/0x250 mm/slub.c:2752 kmem_cache_zalloc include/linux/slab.h:730 [inline] __proc_create+0x30f/0xa20 fs/proc/generic.c:408 proc_mkdir_data+0x47/0x190 fs/proc/generic.c:469 0xffffffffc10c01bb 0xffffffffc10c0166 do_one_initcall+0xfa/0x5ca init/main.c:887 do_init_module+0x204/0x5f6 kernel/module.c:3460 load_module+0x66b2/0x8570 kernel/module.c:3808 __do_sys_finit_module+0x238/0x2a0 kernel/module.c:3902 do_syscall_64+0x147/0x600 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x49/0xbe Freed by task 2806: set_track mm/kasan/common.c:85 [inline] __kasan_slab_free+0x130/0x180 mm/kasan/common.c:458 slab_free_hook mm/slub.c:1409 [inline] slab_free_freelist_hook mm/slub.c:1436 [inline] slab_free mm/slub.c:2986 [inline] kmem_cache_free+0xa6/0x2a0 mm/slub.c:3002 pde_put+0x6e/0x80 fs/proc/generic.c:647 remove_proc_entry+0x1d3/0x420 fs/proc/generic.c:684 0xffffffffc10c031c 0xffffffffc10c0166 do_one_initcall+0xfa/0x5ca init/main.c:887 do_init_module+0x204/0x5f6 kernel/module.c:3460 load_module+0x66b2/0x8570 kernel/module.c:3808 __do_sys_finit_module+0x238/0x2a0 kernel/module.c:3902 do_syscall_64+0x147/0x600 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x49/0xbe The buggy address belongs to the object at ffff8881f41fe500 which belongs to the cache proc_dir_entry of size 256 The buggy address is located 176 bytes inside of 256-byte region [ffff8881f41fe500, ffff8881f41fe600) The buggy address belongs to the page: page:ffffea0007d07f80 count:1 mapcount:0 mapping:ffff8881f6e69a00 index:0x0 flags: 0x2fffc0000000200(slab) raw: 02fffc0000000200 dead000000000100 dead000000000200 ffff8881f6e69a00 raw: 0000000000000000 00000000800c000c 00000001ffffffff 0000000000000000 page dumped because: kasan: bad access detected Memory state around the buggy address: ffff8881f41fe480: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc ffff8881f41fe500: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb >ffff8881f41fe580: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ^ ffff8881f41fe600: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb ffff8881f41fe680: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb It should check the return value of atalk_proc_init fails, otherwise atalk_exit will trgger use-after-free in pde_subdir_find while unload the module.This patch fix error cleanup path of atalk_init Reported-by: Hulk Robot Signed-off-by: YueHaibing Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- include/linux/atalk.h | 2 +- net/appletalk/atalk_proc.c | 2 +- net/appletalk/ddp.c | 37 ++++++++++++++++++++++++++------ net/appletalk/sysctl_net_atalk.c | 5 ++++- 4 files changed, 37 insertions(+), 9 deletions(-) diff --git a/include/linux/atalk.h b/include/linux/atalk.h index 4d356e168692..212eb8c7fed6 100644 --- a/include/linux/atalk.h +++ b/include/linux/atalk.h @@ -151,7 +151,7 @@ extern int sysctl_aarp_retransmit_limit; extern int sysctl_aarp_resolve_time; #ifdef CONFIG_SYSCTL -extern void atalk_register_sysctl(void); +extern int atalk_register_sysctl(void); extern void atalk_unregister_sysctl(void); #else #define atalk_register_sysctl() do { } while(0) diff --git a/net/appletalk/atalk_proc.c b/net/appletalk/atalk_proc.c index af46bc49e1e9..b5f84f428aa6 100644 --- a/net/appletalk/atalk_proc.c +++ b/net/appletalk/atalk_proc.c @@ -293,7 +293,7 @@ int __init atalk_proc_init(void) goto out; } -void __exit atalk_proc_exit(void) +void atalk_proc_exit(void) { remove_proc_entry("interface", atalk_proc_dir); remove_proc_entry("route", atalk_proc_dir); diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index 5d035c1f1156..d1b68cc7da89 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c @@ -1912,12 +1912,16 @@ static const char atalk_err_snap[] __initconst = /* Called by proto.c on kernel start up */ static int __init atalk_init(void) { - int rc = proto_register(&ddp_proto, 0); + int rc; - if (rc != 0) + rc = proto_register(&ddp_proto, 0); + if (rc) goto out; - (void)sock_register(&atalk_family_ops); + rc = sock_register(&atalk_family_ops); + if (rc) + goto out_proto; + ddp_dl = register_snap_client(ddp_snap_id, atalk_rcv); if (!ddp_dl) printk(atalk_err_snap); @@ -1925,12 +1929,33 @@ static int __init atalk_init(void) dev_add_pack(<alk_packet_type); dev_add_pack(&ppptalk_packet_type); - register_netdevice_notifier(&ddp_notifier); + rc = register_netdevice_notifier(&ddp_notifier); + if (rc) + goto out_sock; + aarp_proto_init(); - atalk_proc_init(); - atalk_register_sysctl(); + rc = atalk_proc_init(); + if (rc) + goto out_aarp; + + rc = atalk_register_sysctl(); + if (rc) + goto out_proc; out: return rc; +out_proc: + atalk_proc_exit(); +out_aarp: + aarp_cleanup_module(); + unregister_netdevice_notifier(&ddp_notifier); +out_sock: + dev_remove_pack(&ppptalk_packet_type); + dev_remove_pack(<alk_packet_type); + unregister_snap_client(ddp_dl); + sock_unregister(PF_APPLETALK); +out_proto: + proto_unregister(&ddp_proto); + goto out; } module_init(atalk_init); diff --git a/net/appletalk/sysctl_net_atalk.c b/net/appletalk/sysctl_net_atalk.c index c744a853fa5f..d945b7c0176d 100644 --- a/net/appletalk/sysctl_net_atalk.c +++ b/net/appletalk/sysctl_net_atalk.c @@ -45,9 +45,12 @@ static struct ctl_table atalk_table[] = { static struct ctl_table_header *atalk_table_header; -void atalk_register_sysctl(void) +int __init atalk_register_sysctl(void) { atalk_table_header = register_net_sysctl(&init_net, "net/appletalk", atalk_table); + if (!atalk_table_header) + return -ENOMEM; + return 0; } void atalk_unregister_sysctl(void) -- GitLab From 6dc75ccba5680b67a4bcc72e96ec851326e66690 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Thu, 7 Mar 2019 16:28:18 -0800 Subject: [PATCH 0151/1121] lib/div64.c: off by one in shift [ Upstream commit cdc94a37493135e355dfc0b0e086d84e3eadb50d ] fls counts bits starting from 1 to 32 (returns 0 for zero argument). If we add 1 we shift right one bit more and loose precision from divisor, what cause function incorect results with some numbers. Corrected code was tested in user-space, see bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=202391 Link: http://lkml.kernel.org/r/1548686944-11891-1-git-send-email-sgruszka@redhat.com Fixes: 658716d19f8f ("div64_u64(): improve precision on 32bit platforms") Signed-off-by: Stanislaw Gruszka Reported-by: Siarhei Volkau Tested-by: Siarhei Volkau Acked-by: Oleg Nesterov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Sasha Levin --- lib/div64.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/div64.c b/lib/div64.c index 58e2a404097e..a2688b882461 100644 --- a/lib/div64.c +++ b/lib/div64.c @@ -103,7 +103,7 @@ u64 div64_u64_rem(u64 dividend, u64 divisor, u64 *remainder) quot = div_u64_rem(dividend, divisor, &rem32); *remainder = rem32; } else { - int n = 1 + fls(high); + int n = fls(high); quot = div_u64(dividend >> n, divisor >> n); if (quot != 0) @@ -141,7 +141,7 @@ u64 div64_u64(u64 dividend, u64 divisor) if (high == 0) { quot = div_u64(dividend, divisor); } else { - int n = 1 + fls(high); + int n = fls(high); quot = div_u64(dividend >> n, divisor >> n); if (quot != 0) -- GitLab From c43e2bdd14941e969dac515efadc3d379f333fdf Mon Sep 17 00:00:00 2001 From: Pi-Hsun Shih Date: Wed, 13 Mar 2019 11:44:33 -0700 Subject: [PATCH 0152/1121] include/linux/swap.h: use offsetof() instead of custom __swapoffset macro [ Upstream commit a4046c06be50a4f01d435aa7fe57514818e6cc82 ] Use offsetof() to calculate offset of a field to take advantage of compiler built-in version when possible, and avoid UBSAN warning when compiling with Clang: UBSAN: Undefined behaviour in mm/swapfile.c:3010:38 member access within null pointer of type 'union swap_header' CPU: 6 PID: 1833 Comm: swapon Tainted: G S 4.19.23 #43 Call trace: dump_backtrace+0x0/0x194 show_stack+0x20/0x2c __dump_stack+0x20/0x28 dump_stack+0x70/0x94 ubsan_epilogue+0x14/0x44 ubsan_type_mismatch_common+0xf4/0xfc __ubsan_handle_type_mismatch_v1+0x34/0x54 __se_sys_swapon+0x654/0x1084 __arm64_sys_swapon+0x1c/0x24 el0_svc_common+0xa8/0x150 el0_svc_compat_handler+0x2c/0x38 el0_svc_compat+0x8/0x18 Link: http://lkml.kernel.org/r/20190312081902.223764-1-pihsun@chromium.org Signed-off-by: Pi-Hsun Shih Acked-by: Michal Hocko Reviewed-by: Andrew Morton Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Sasha Levin --- include/linux/swap.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/swap.h b/include/linux/swap.h index 4fd1ab9565ba..e643866912b7 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -155,9 +155,9 @@ struct swap_extent { /* * Max bad pages in the new format.. */ -#define __swapoffset(x) ((unsigned long)&((union swap_header *)0)->x) #define MAX_SWAP_BADPAGES \ - ((__swapoffset(magic.magic) - __swapoffset(info.badpages)) / sizeof(int)) + ((offsetof(union swap_header, magic.magic) - \ + offsetof(union swap_header, info.badpages)) / sizeof(int)) enum { SWP_USED = (1 << 0), /* is slot in swap_info[] used? */ -- GitLab From 02c2de9be3d031d5c0ee953ec342e5e0cabb3ed5 Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Mon, 25 Mar 2019 15:54:43 +0100 Subject: [PATCH 0153/1121] bpf: fix use after free in bpf_evict_inode [ Upstream commit 1da6c4d9140cb7c13e87667dc4e1488d6c8fc10f ] syzkaller was able to generate the following UAF in bpf: BUG: KASAN: use-after-free in lookup_last fs/namei.c:2269 [inline] BUG: KASAN: use-after-free in path_lookupat.isra.43+0x9f8/0xc00 fs/namei.c:2318 Read of size 1 at addr ffff8801c4865c47 by task syz-executor2/9423 CPU: 0 PID: 9423 Comm: syz-executor2 Not tainted 4.20.0-rc1-next-20181109+ #110 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x244/0x39d lib/dump_stack.c:113 print_address_description.cold.7+0x9/0x1ff mm/kasan/report.c:256 kasan_report_error mm/kasan/report.c:354 [inline] kasan_report.cold.8+0x242/0x309 mm/kasan/report.c:412 __asan_report_load1_noabort+0x14/0x20 mm/kasan/report.c:430 lookup_last fs/namei.c:2269 [inline] path_lookupat.isra.43+0x9f8/0xc00 fs/namei.c:2318 filename_lookup+0x26a/0x520 fs/namei.c:2348 user_path_at_empty+0x40/0x50 fs/namei.c:2608 user_path include/linux/namei.h:62 [inline] do_mount+0x180/0x1ff0 fs/namespace.c:2980 ksys_mount+0x12d/0x140 fs/namespace.c:3258 __do_sys_mount fs/namespace.c:3272 [inline] __se_sys_mount fs/namespace.c:3269 [inline] __x64_sys_mount+0xbe/0x150 fs/namespace.c:3269 do_syscall_64+0x1b9/0x820 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x49/0xbe RIP: 0033:0x457569 Code: fd b3 fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 cb b3 fb ff c3 66 2e 0f 1f 84 00 00 00 00 RSP: 002b:00007fde6ed96c78 EFLAGS: 00000246 ORIG_RAX: 00000000000000a5 RAX: ffffffffffffffda RBX: 0000000000000005 RCX: 0000000000457569 RDX: 0000000020000040 RSI: 0000000020000000 RDI: 0000000000000000 RBP: 000000000072bf00 R08: 0000000020000340 R09: 0000000000000000 R10: 0000000000200000 R11: 0000000000000246 R12: 00007fde6ed976d4 R13: 00000000004c2c24 R14: 00000000004d4990 R15: 00000000ffffffff Allocated by task 9424: save_stack+0x43/0xd0 mm/kasan/kasan.c:448 set_track mm/kasan/kasan.c:460 [inline] kasan_kmalloc+0xc7/0xe0 mm/kasan/kasan.c:553 __do_kmalloc mm/slab.c:3722 [inline] __kmalloc_track_caller+0x157/0x760 mm/slab.c:3737 kstrdup+0x39/0x70 mm/util.c:49 bpf_symlink+0x26/0x140 kernel/bpf/inode.c:356 vfs_symlink+0x37a/0x5d0 fs/namei.c:4127 do_symlinkat+0x242/0x2d0 fs/namei.c:4154 __do_sys_symlink fs/namei.c:4173 [inline] __se_sys_symlink fs/namei.c:4171 [inline] __x64_sys_symlink+0x59/0x80 fs/namei.c:4171 do_syscall_64+0x1b9/0x820 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x49/0xbe Freed by task 9425: save_stack+0x43/0xd0 mm/kasan/kasan.c:448 set_track mm/kasan/kasan.c:460 [inline] __kasan_slab_free+0x102/0x150 mm/kasan/kasan.c:521 kasan_slab_free+0xe/0x10 mm/kasan/kasan.c:528 __cache_free mm/slab.c:3498 [inline] kfree+0xcf/0x230 mm/slab.c:3817 bpf_evict_inode+0x11f/0x150 kernel/bpf/inode.c:565 evict+0x4b9/0x980 fs/inode.c:558 iput_final fs/inode.c:1550 [inline] iput+0x674/0xa90 fs/inode.c:1576 do_unlinkat+0x733/0xa30 fs/namei.c:4069 __do_sys_unlink fs/namei.c:4110 [inline] __se_sys_unlink fs/namei.c:4108 [inline] __x64_sys_unlink+0x42/0x50 fs/namei.c:4108 do_syscall_64+0x1b9/0x820 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x49/0xbe In this scenario path lookup under RCU is racing with the final unlink in case of symlinks. As Linus puts it in his analysis: [...] We actually RCU-delay the inode freeing itself, but when we do the final iput(), the "evict()" function is called synchronously. Now, the simple fix would seem to just RCU-delay the kfree() of the symlink data in bpf_evict_inode(). Maybe that's the right thing to do. [...] Al suggested to piggy-back on the ->destroy_inode() callback in order to implement RCU deferral there which can then kfree() the inode->i_link eventually right before putting inode back into inode cache. By reusing free_inode_nonrcu() from there we can avoid the need for our own inode cache and just reuse generic one as we currently do. And in-fact on top of all this we should just get rid of the bpf_evict_inode() entirely. This means truncate_inode_pages_final() and clear_inode() will then simply be called by the fs core via evict(). Dropping the reference should really only be done when inode is unhashed and nothing reachable anymore, so it's better also moved into the final ->destroy_inode() callback. Fixes: 0f98621bef5d ("bpf, inode: add support for symlinks and fix mtime/ctime") Reported-by: syzbot+fb731ca573367b7f6564@syzkaller.appspotmail.com Reported-by: syzbot+a13e5ead792d6df37818@syzkaller.appspotmail.com Reported-by: syzbot+7a8ba368b47fdefca61e@syzkaller.appspotmail.com Suggested-by: Al Viro Analyzed-by: Linus Torvalds Signed-off-by: Daniel Borkmann Acked-by: Alexei Starovoitov Acked-by: Linus Torvalds Acked-by: Al Viro Link: https://lore.kernel.org/lkml/0000000000006946d2057bbd0eef@google.com/T/ Signed-off-by: Sasha Levin (Microsoft) --- kernel/bpf/inode.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/kernel/bpf/inode.c b/kernel/bpf/inode.c index be1dde967208..ccf9ffd5da78 100644 --- a/kernel/bpf/inode.c +++ b/kernel/bpf/inode.c @@ -365,19 +365,6 @@ int bpf_obj_get_user(const char __user *pathname) } EXPORT_SYMBOL_GPL(bpf_obj_get_user); -static void bpf_evict_inode(struct inode *inode) -{ - enum bpf_type type; - - truncate_inode_pages_final(&inode->i_data); - clear_inode(inode); - - if (S_ISLNK(inode->i_mode)) - kfree(inode->i_link); - if (!bpf_inode_type(inode, &type)) - bpf_any_put(inode->i_private, type); -} - /* * Display the mount options in /proc/mounts. */ @@ -390,11 +377,28 @@ static int bpf_show_options(struct seq_file *m, struct dentry *root) return 0; } +static void bpf_destroy_inode_deferred(struct rcu_head *head) +{ + struct inode *inode = container_of(head, struct inode, i_rcu); + enum bpf_type type; + + if (S_ISLNK(inode->i_mode)) + kfree(inode->i_link); + if (!bpf_inode_type(inode, &type)) + bpf_any_put(inode->i_private, type); + free_inode_nonrcu(inode); +} + +static void bpf_destroy_inode(struct inode *inode) +{ + call_rcu(&inode->i_rcu, bpf_destroy_inode_deferred); +} + static const struct super_operations bpf_super_ops = { .statfs = simple_statfs, .drop_inode = generic_delete_inode, .show_options = bpf_show_options, - .evict_inode = bpf_evict_inode, + .destroy_inode = bpf_destroy_inode, }; enum { -- GitLab From 8991f1af962d939c3f3456990f5a826c3aa628fd Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Wed, 5 Sep 2018 09:17:45 -0400 Subject: [PATCH 0154/1121] dm: disable CRYPTO_TFM_REQ_MAY_SLEEP to fix a GFP_KERNEL recursion deadlock [ Upstream commit 432061b3da64e488be3403124a72a9250bbe96d4 ] There's a XFS on dm-crypt deadlock, recursing back to itself due to the crypto subsystems use of GFP_KERNEL, reported here: https://bugzilla.kernel.org/show_bug.cgi?id=200835 * dm-crypt calls crypt_convert in xts mode * init_crypt from xts.c calls kmalloc(GFP_KERNEL) * kmalloc(GFP_KERNEL) recurses into the XFS filesystem, the filesystem tries to submit some bios and wait for them, causing a deadlock Fix this by updating both the DM crypt and integrity targets to no longer use the CRYPTO_TFM_REQ_MAY_SLEEP flag, which will change the crypto allocations from GFP_KERNEL to GFP_ATOMIC, therefore they can't recurse into a filesystem. A GFP_ATOMIC allocation can fail, but init_crypt() in xts.c handles the allocation failure gracefully - it will fall back to preallocated buffer if the allocation fails. The crypto API maintainer says that the crypto API only needs to allocate memory when dealing with unaligned buffers and therefore turning CRYPTO_TFM_REQ_MAY_SLEEP off is safe (see this discussion: https://www.redhat.com/archives/dm-devel/2018-August/msg00195.html ) Cc: stable@vger.kernel.org Signed-off-by: Mikulas Patocka Signed-off-by: Mike Snitzer Signed-off-by: Sasha Levin (Microsoft) --- drivers/md/dm-crypt.c | 10 +++++----- drivers/md/dm-integrity.c | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 0d2005e5b24c..94b8d81f6020 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -334,7 +334,7 @@ static int crypt_iv_essiv_init(struct crypt_config *cc) sg_init_one(&sg, cc->key, cc->key_size); ahash_request_set_tfm(req, essiv->hash_tfm); - ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL); + ahash_request_set_callback(req, 0, NULL, NULL); ahash_request_set_crypt(req, &sg, essiv->salt, cc->key_size); err = crypto_ahash_digest(req); @@ -609,7 +609,7 @@ static int crypt_iv_lmk_one(struct crypt_config *cc, u8 *iv, int i, r; desc->tfm = lmk->hash_tfm; - desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; + desc->flags = 0; r = crypto_shash_init(desc); if (r) @@ -771,7 +771,7 @@ static int crypt_iv_tcw_whitening(struct crypt_config *cc, /* calculate crc32 for every 32bit part and xor it */ desc->tfm = tcw->crc32_tfm; - desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; + desc->flags = 0; for (i = 0; i < 4; i++) { r = crypto_shash_init(desc); if (r) @@ -1254,7 +1254,7 @@ static void crypt_alloc_req_skcipher(struct crypt_config *cc, * requests if driver request queue is full. */ skcipher_request_set_callback(ctx->r.req, - CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, + CRYPTO_TFM_REQ_MAY_BACKLOG, kcryptd_async_done, dmreq_of_req(cc, ctx->r.req)); } @@ -1271,7 +1271,7 @@ static void crypt_alloc_req_aead(struct crypt_config *cc, * requests if driver request queue is full. */ aead_request_set_callback(ctx->r.req_aead, - CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, + CRYPTO_TFM_REQ_MAY_BACKLOG, kcryptd_async_done, dmreq_of_req(cc, ctx->r.req_aead)); } diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c index da4baea9cf83..036379a23499 100644 --- a/drivers/md/dm-integrity.c +++ b/drivers/md/dm-integrity.c @@ -493,7 +493,7 @@ static void section_mac(struct dm_integrity_c *ic, unsigned section, __u8 result unsigned j, size; desc->tfm = ic->journal_mac; - desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; + desc->flags = 0; r = crypto_shash_init(desc); if (unlikely(r)) { @@ -637,7 +637,7 @@ static void complete_journal_encrypt(struct crypto_async_request *req, int err) static bool do_crypt(bool encrypt, struct skcipher_request *req, struct journal_completion *comp) { int r; - skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, + skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, complete_journal_encrypt, comp); if (likely(encrypt)) r = crypto_skcipher_encrypt(req); -- GitLab From 28356c21ac32d49d15a3ea7383b0a96052d15394 Mon Sep 17 00:00:00 2001 From: Alexei Starovoitov Date: Wed, 3 Apr 2019 18:39:01 +0000 Subject: [PATCH 0155/1121] bpf: reduce verifier memory consumption commit 638f5b90d46016372a8e3e0a434f199cc5e12b8c upstream. the verifier got progressively smarter over time and size of its internal state grew as well. Time to reduce the memory consumption. Before: sizeof(struct bpf_verifier_state) = 6520 After: sizeof(struct bpf_verifier_state) = 896 It's done by observing that majority of BPF programs use little to no stack whereas verifier kept all of 512 stack slots ready always. Instead dynamically reallocate struct verifier state when stack access is detected. Runtime difference before vs after is within a noise. The number of processed instructions stays the same. Cc: jakub.kicinski@netronome.com Signed-off-by: Alexei Starovoitov Acked-by: Daniel Borkmann Signed-off-by: David S. Miller [Backported to 4.14 by sblbir] Signed-off-by: Balbir Singh Signed-off-by: Greg Kroah-Hartman --- .../net/ethernet/netronome/nfp/bpf/verifier.c | 9 +- include/linux/bpf_verifier.h | 16 +- kernel/bpf/verifier.c | 433 ++++++++++++------ 3 files changed, 304 insertions(+), 154 deletions(-) diff --git a/drivers/net/ethernet/netronome/nfp/bpf/verifier.c b/drivers/net/ethernet/netronome/nfp/bpf/verifier.c index 5b783a91b115..8793fa57f844 100644 --- a/drivers/net/ethernet/netronome/nfp/bpf/verifier.c +++ b/drivers/net/ethernet/netronome/nfp/bpf/verifier.c @@ -76,9 +76,9 @@ nfp_bpf_goto_meta(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta, static int nfp_bpf_check_exit(struct nfp_prog *nfp_prog, - const struct bpf_verifier_env *env) + struct bpf_verifier_env *env) { - const struct bpf_reg_state *reg0 = &env->cur_state.regs[0]; + const struct bpf_reg_state *reg0 = cur_regs(env) + BPF_REG_0; u64 imm; if (nfp_prog->act == NN_ACT_XDP) @@ -113,9 +113,10 @@ nfp_bpf_check_exit(struct nfp_prog *nfp_prog, static int nfp_bpf_check_ctx_ptr(struct nfp_prog *nfp_prog, - const struct bpf_verifier_env *env, u8 reg) + struct bpf_verifier_env *env, u8 reg_no) { - if (env->cur_state.regs[reg].type != PTR_TO_CTX) + const struct bpf_reg_state *reg = cur_regs(env) + reg_no; + if (reg->type != PTR_TO_CTX) return -EINVAL; return 0; diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h index 8458cc5fbce5..0fc3d9afb8bf 100644 --- a/include/linux/bpf_verifier.h +++ b/include/linux/bpf_verifier.h @@ -91,14 +91,19 @@ enum bpf_stack_slot_type { #define BPF_REG_SIZE 8 /* size of eBPF register in bytes */ +struct bpf_stack_state { + struct bpf_reg_state spilled_ptr; + u8 slot_type[BPF_REG_SIZE]; +}; + /* state of the program: * type of all registers and stack info */ struct bpf_verifier_state { struct bpf_reg_state regs[MAX_BPF_REG]; - u8 stack_slot_type[MAX_BPF_STACK]; - struct bpf_reg_state spilled_regs[MAX_BPF_STACK / BPF_REG_SIZE]; struct bpf_verifier_state *parent; + int allocated_stack; + struct bpf_stack_state *stack; }; /* linked list of verifier states used to prune search */ @@ -133,7 +138,7 @@ struct bpf_verifier_env { struct bpf_verifier_stack_elem *head; /* stack of verifier states to be processed */ int stack_size; /* number of states to be processed */ bool strict_alignment; /* perform strict pointer alignment checks */ - struct bpf_verifier_state cur_state; /* current verifier state */ + struct bpf_verifier_state *cur_state; /* current verifier state */ struct bpf_verifier_state_list **explored_states; /* search pruning optimization */ const struct bpf_ext_analyzer_ops *analyzer_ops; /* external analyzer ops */ void *analyzer_priv; /* pointer to external analyzer's private data */ @@ -145,6 +150,11 @@ struct bpf_verifier_env { struct bpf_insn_aux_data *insn_aux_data; /* array of per-insn state */ }; +static inline struct bpf_reg_state *cur_regs(struct bpf_verifier_env *env) +{ + return env->cur_state->regs; +} + int bpf_analyzer(struct bpf_prog *prog, const struct bpf_ext_analyzer_ops *ops, void *priv); diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index f6755fd5bae2..805bc218150d 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -265,10 +265,11 @@ static void print_verifier_state(struct bpf_verifier_state *state) verbose(")"); } } - for (i = 0; i < MAX_BPF_STACK; i += BPF_REG_SIZE) { - if (state->stack_slot_type[i] == STACK_SPILL) - verbose(" fp%d=%s", -MAX_BPF_STACK + i, - reg_type_str[state->spilled_regs[i / BPF_REG_SIZE].type]); + for (i = 0; i < state->allocated_stack / BPF_REG_SIZE; i++) { + if (state->stack[i].slot_type[0] == STACK_SPILL) + verbose(" fp%d=%s", + -MAX_BPF_STACK + i * BPF_REG_SIZE, + reg_type_str[state->stack[i].spilled_ptr.type]); } verbose("\n"); } @@ -434,35 +435,123 @@ static void print_bpf_insn(const struct bpf_verifier_env *env, } } -static int pop_stack(struct bpf_verifier_env *env, int *prev_insn_idx) +static int copy_stack_state(struct bpf_verifier_state *dst, + const struct bpf_verifier_state *src) { - struct bpf_verifier_stack_elem *elem; - int insn_idx; + if (!src->stack) + return 0; + if (WARN_ON_ONCE(dst->allocated_stack < src->allocated_stack)) { + /* internal bug, make state invalid to reject the program */ + memset(dst, 0, sizeof(*dst)); + return -EFAULT; + } + memcpy(dst->stack, src->stack, + sizeof(*src->stack) * (src->allocated_stack / BPF_REG_SIZE)); + return 0; +} + +/* do_check() starts with zero-sized stack in struct bpf_verifier_state to + * make it consume minimal amount of memory. check_stack_write() access from + * the program calls into realloc_verifier_state() to grow the stack size. + * Note there is a non-zero 'parent' pointer inside bpf_verifier_state + * which this function copies over. It points to previous bpf_verifier_state + * which is never reallocated + */ +static int realloc_verifier_state(struct bpf_verifier_state *state, int size, + bool copy_old) +{ + u32 old_size = state->allocated_stack; + struct bpf_stack_state *new_stack; + int slot = size / BPF_REG_SIZE; + + if (size <= old_size || !size) { + if (copy_old) + return 0; + state->allocated_stack = slot * BPF_REG_SIZE; + if (!size && old_size) { + kfree(state->stack); + state->stack = NULL; + } + return 0; + } + new_stack = kmalloc_array(slot, sizeof(struct bpf_stack_state), + GFP_KERNEL); + if (!new_stack) + return -ENOMEM; + if (copy_old) { + if (state->stack) + memcpy(new_stack, state->stack, + sizeof(*new_stack) * (old_size / BPF_REG_SIZE)); + memset(new_stack + old_size / BPF_REG_SIZE, 0, + sizeof(*new_stack) * (size - old_size) / BPF_REG_SIZE); + } + state->allocated_stack = slot * BPF_REG_SIZE; + kfree(state->stack); + state->stack = new_stack; + return 0; +} + +static void free_verifier_state(struct bpf_verifier_state *state) +{ + kfree(state->stack); + kfree(state); +} + +/* copy verifier state from src to dst growing dst stack space + * when necessary to accommodate larger src stack + */ +static int copy_verifier_state(struct bpf_verifier_state *dst, + const struct bpf_verifier_state *src) +{ + int err; + + err = realloc_verifier_state(dst, src->allocated_stack, false); + if (err) + return err; + memcpy(dst, src, offsetof(struct bpf_verifier_state, allocated_stack)); + return copy_stack_state(dst, src); +} + +static int pop_stack(struct bpf_verifier_env *env, int *prev_insn_idx, + int *insn_idx) +{ + struct bpf_verifier_state *cur = env->cur_state; + struct bpf_verifier_stack_elem *elem, *head = env->head; + int err; if (env->head == NULL) - return -1; + return -ENOENT; - memcpy(&env->cur_state, &env->head->st, sizeof(env->cur_state)); - insn_idx = env->head->insn_idx; + if (cur) { + err = copy_verifier_state(cur, &head->st); + if (err) + return err; + } + if (insn_idx) + *insn_idx = head->insn_idx; if (prev_insn_idx) - *prev_insn_idx = env->head->prev_insn_idx; - elem = env->head->next; - kfree(env->head); + *prev_insn_idx = head->prev_insn_idx; + elem = head->next; + kfree(head); env->head = elem; env->stack_size--; - return insn_idx; + return 0; } static struct bpf_verifier_state *push_stack(struct bpf_verifier_env *env, int insn_idx, int prev_insn_idx) { struct bpf_verifier_stack_elem *elem; + struct bpf_verifier_state *cur = env->cur_state; + int err; - elem = kmalloc(sizeof(struct bpf_verifier_stack_elem), GFP_KERNEL); + elem = kzalloc(sizeof(struct bpf_verifier_stack_elem), GFP_KERNEL); if (!elem) goto err; - memcpy(&elem->st, &env->cur_state, sizeof(env->cur_state)); + err = copy_verifier_state(&elem->st, cur); + if (err) + return NULL; elem->insn_idx = insn_idx; elem->prev_insn_idx = prev_insn_idx; elem->next = env->head; @@ -475,7 +564,7 @@ static struct bpf_verifier_state *push_stack(struct bpf_verifier_env *env, return &elem->st; err: /* pop all elements and return */ - while (pop_stack(env, NULL) >= 0); + while (!pop_stack(env, NULL, NULL)); return NULL; } @@ -671,7 +760,7 @@ static void mark_reg_read(const struct bpf_verifier_state *state, u32 regno) static int check_reg_arg(struct bpf_verifier_env *env, u32 regno, enum reg_arg_type t) { - struct bpf_reg_state *regs = env->cur_state.regs; + struct bpf_reg_state *regs = env->cur_state->regs; if (regno >= MAX_BPF_REG) { verbose("R%d is invalid\n", regno); @@ -684,7 +773,7 @@ static int check_reg_arg(struct bpf_verifier_env *env, u32 regno, verbose("R%d !read_ok\n", regno); return -EACCES; } - mark_reg_read(&env->cur_state, regno); + mark_reg_read(env->cur_state, regno); } else { /* check whether register used as dest operand can be written to */ if (regno == BPF_REG_FP) { @@ -721,10 +810,21 @@ static int check_stack_write(struct bpf_verifier_env *env, struct bpf_verifier_state *state, int off, int size, int value_regno, int insn_idx) { - int i, spi = (MAX_BPF_STACK + off) / BPF_REG_SIZE; + int i, slot = -off - 1, spi = slot / BPF_REG_SIZE, err; + + err = realloc_verifier_state(state, round_up(slot + 1, BPF_REG_SIZE), + true); + if (err) + return err; /* caller checked that off % size == 0 and -MAX_BPF_STACK <= off < 0, * so it's aligned access and [off, off + size) are within stack limits */ + if (!env->allow_ptr_leaks && + state->stack[spi].slot_type[0] == STACK_SPILL && + size != BPF_REG_SIZE) { + verbose("attempt to corrupt spilled pointer on stack\n"); + return -EACCES; + } if (value_regno >= 0 && is_spillable_regtype(state->regs[value_regno].type)) { @@ -736,11 +836,11 @@ static int check_stack_write(struct bpf_verifier_env *env, } /* save register state */ - state->spilled_regs[spi] = state->regs[value_regno]; - state->spilled_regs[spi].live |= REG_LIVE_WRITTEN; + state->stack[spi].spilled_ptr = state->regs[value_regno]; + state->stack[spi].spilled_ptr.live |= REG_LIVE_WRITTEN; for (i = 0; i < BPF_REG_SIZE; i++) { - if (state->stack_slot_type[MAX_BPF_STACK + off + i] == STACK_MISC && + if (state->stack[spi].slot_type[i] == STACK_MISC && !env->allow_ptr_leaks) { int *poff = &env->insn_aux_data[insn_idx].sanitize_stack_off; int soff = (-spi - 1) * BPF_REG_SIZE; @@ -763,14 +863,15 @@ static int check_stack_write(struct bpf_verifier_env *env, } *poff = soff; } - state->stack_slot_type[MAX_BPF_STACK + off + i] = STACK_SPILL; + state->stack[spi].slot_type[i] = STACK_SPILL; } } else { /* regular write of data into stack */ - state->spilled_regs[spi] = (struct bpf_reg_state) {}; + state->stack[spi].spilled_ptr = (struct bpf_reg_state) {}; for (i = 0; i < size; i++) - state->stack_slot_type[MAX_BPF_STACK + off + i] = STACK_MISC; + state->stack[spi].slot_type[(slot - i) % BPF_REG_SIZE] = + STACK_MISC; } return 0; } @@ -781,10 +882,10 @@ static void mark_stack_slot_read(const struct bpf_verifier_state *state, int slo while (parent) { /* if read wasn't screened by an earlier write ... */ - if (state->spilled_regs[slot].live & REG_LIVE_WRITTEN) + if (state->stack[slot].spilled_ptr.live & REG_LIVE_WRITTEN) break; /* ... then we depend on parent's value */ - parent->spilled_regs[slot].live |= REG_LIVE_READ; + parent->stack[slot].spilled_ptr.live |= REG_LIVE_READ; state = parent; parent = state->parent; } @@ -793,34 +894,37 @@ static void mark_stack_slot_read(const struct bpf_verifier_state *state, int slo static int check_stack_read(struct bpf_verifier_state *state, int off, int size, int value_regno) { - u8 *slot_type; - int i, spi; + int i, slot = -off - 1, spi = slot / BPF_REG_SIZE; + u8 *stype; - slot_type = &state->stack_slot_type[MAX_BPF_STACK + off]; + if (state->allocated_stack <= slot) { + verbose("invalid read from stack off %d+0 size %d\n", + off, size); + return -EACCES; + } + stype = state->stack[spi].slot_type; - if (slot_type[0] == STACK_SPILL) { + if (stype[0] == STACK_SPILL) { if (size != BPF_REG_SIZE) { verbose("invalid size of register spill\n"); return -EACCES; } for (i = 1; i < BPF_REG_SIZE; i++) { - if (slot_type[i] != STACK_SPILL) { + if (stype[(slot - i) % BPF_REG_SIZE] != STACK_SPILL) { verbose("corrupted spill memory\n"); return -EACCES; } } - spi = (MAX_BPF_STACK + off) / BPF_REG_SIZE; - if (value_regno >= 0) { /* restore register state from stack */ - state->regs[value_regno] = state->spilled_regs[spi]; + state->regs[value_regno] = state->stack[spi].spilled_ptr; mark_stack_slot_read(state, spi); } return 0; } else { for (i = 0; i < size; i++) { - if (slot_type[i] != STACK_MISC) { + if (stype[(slot - i) % BPF_REG_SIZE] != STACK_MISC) { verbose("invalid read from stack off %d+%d size %d\n", off, i, size); return -EACCES; @@ -837,7 +941,8 @@ static int check_stack_read(struct bpf_verifier_state *state, int off, int size, static int __check_map_access(struct bpf_verifier_env *env, u32 regno, int off, int size) { - struct bpf_map *map = env->cur_state.regs[regno].map_ptr; + struct bpf_reg_state *regs = cur_regs(env); + struct bpf_map *map = regs[regno].map_ptr; if (off < 0 || size <= 0 || off + size > map->value_size) { verbose("invalid access to map value, value_size=%d off=%d size=%d\n", @@ -849,9 +954,9 @@ static int __check_map_access(struct bpf_verifier_env *env, u32 regno, int off, /* check read/write into a map element with possible variable offset */ static int check_map_access(struct bpf_verifier_env *env, u32 regno, - int off, int size) + int off, int size) { - struct bpf_verifier_state *state = &env->cur_state; + struct bpf_verifier_state *state = env->cur_state; struct bpf_reg_state *reg = &state->regs[regno]; int err; @@ -924,7 +1029,7 @@ static bool may_access_direct_pkt_data(struct bpf_verifier_env *env, static int __check_packet_access(struct bpf_verifier_env *env, u32 regno, int off, int size) { - struct bpf_reg_state *regs = env->cur_state.regs; + struct bpf_reg_state *regs = cur_regs(env); struct bpf_reg_state *reg = ®s[regno]; if (off < 0 || size <= 0 || (u64)off + size > reg->range) { @@ -938,7 +1043,7 @@ static int __check_packet_access(struct bpf_verifier_env *env, u32 regno, static int check_packet_access(struct bpf_verifier_env *env, u32 regno, int off, int size) { - struct bpf_reg_state *regs = env->cur_state.regs; + struct bpf_reg_state *regs = cur_regs(env); struct bpf_reg_state *reg = ®s[regno]; int err; @@ -1008,19 +1113,19 @@ static bool __is_pointer_value(bool allow_ptr_leaks, static bool is_pointer_value(struct bpf_verifier_env *env, int regno) { - return __is_pointer_value(env->allow_ptr_leaks, &env->cur_state.regs[regno]); + return __is_pointer_value(env->allow_ptr_leaks, cur_regs(env) + regno); } static bool is_ctx_reg(struct bpf_verifier_env *env, int regno) { - const struct bpf_reg_state *reg = &env->cur_state.regs[regno]; + const struct bpf_reg_state *reg = cur_regs(env) + regno; return reg->type == PTR_TO_CTX; } static bool is_pkt_reg(struct bpf_verifier_env *env, int regno) { - const struct bpf_reg_state *reg = &env->cur_state.regs[regno]; + const struct bpf_reg_state *reg = cur_regs(env) + regno; return reg->type == PTR_TO_PACKET; } @@ -1145,8 +1250,9 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn int off, int bpf_size, enum bpf_access_type t, int value_regno, bool strict_alignment_once) { - struct bpf_verifier_state *state = &env->cur_state; - struct bpf_reg_state *reg = &state->regs[regno]; + struct bpf_verifier_state *state = env->cur_state; + struct bpf_reg_state *regs = cur_regs(env); + struct bpf_reg_state *reg = regs + regno; int size, err = 0; size = bpf_size_to_bytes(bpf_size); @@ -1170,7 +1276,7 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn err = check_map_access(env, regno, off, size); if (!err && t == BPF_READ && value_regno >= 0) - mark_reg_unknown(state->regs, value_regno); + mark_reg_unknown(regs, value_regno); } else if (reg->type == PTR_TO_CTX) { enum bpf_reg_type reg_type = SCALAR_VALUE; @@ -1203,13 +1309,13 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn * the offset is zero. */ if (reg_type == SCALAR_VALUE) - mark_reg_unknown(state->regs, value_regno); + mark_reg_unknown(regs, value_regno); else - mark_reg_known_zero(state->regs, value_regno); - state->regs[value_regno].id = 0; - state->regs[value_regno].off = 0; - state->regs[value_regno].range = 0; - state->regs[value_regno].type = reg_type; + mark_reg_known_zero(regs, value_regno); + regs[value_regno].id = 0; + regs[value_regno].off = 0; + regs[value_regno].range = 0; + regs[value_regno].type = reg_type; } } else if (reg->type == PTR_TO_STACK) { @@ -1234,18 +1340,11 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn if (env->prog->aux->stack_depth < -off) env->prog->aux->stack_depth = -off; - if (t == BPF_WRITE) { - if (!env->allow_ptr_leaks && - state->stack_slot_type[MAX_BPF_STACK + off] == STACK_SPILL && - size != BPF_REG_SIZE) { - verbose("attempt to corrupt spilled pointer on stack\n"); - return -EACCES; - } + if (t == BPF_WRITE) err = check_stack_write(env, state, off, size, value_regno, insn_idx); - } else { + else err = check_stack_read(state, off, size, value_regno); - } } else if (reg->type == PTR_TO_PACKET) { if (t == BPF_WRITE && !may_access_direct_pkt_data(env, NULL, t)) { verbose("cannot write into packet\n"); @@ -1258,7 +1357,7 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn } err = check_packet_access(env, regno, off, size); if (!err && t == BPF_READ && value_regno >= 0) - mark_reg_unknown(state->regs, value_regno); + mark_reg_unknown(regs, value_regno); } else { verbose("R%d invalid mem access '%s'\n", regno, reg_type_str[reg->type]); @@ -1266,9 +1365,9 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn } if (!err && size < BPF_REG_SIZE && value_regno >= 0 && t == BPF_READ && - state->regs[value_regno].type == SCALAR_VALUE) { + regs[value_regno].type == SCALAR_VALUE) { /* b/h/w load zero-extends, mark upper bits as known 0 */ - coerce_reg_to_size(&state->regs[value_regno], size); + coerce_reg_to_size(®s[value_regno], size); } return err; } @@ -1333,9 +1432,9 @@ static int check_stack_boundary(struct bpf_verifier_env *env, int regno, int access_size, bool zero_size_allowed, struct bpf_call_arg_meta *meta) { - struct bpf_verifier_state *state = &env->cur_state; + struct bpf_verifier_state *state = env->cur_state; struct bpf_reg_state *regs = state->regs; - int off, i; + int off, i, slot, spi; if (regs[regno].type != PTR_TO_STACK) { /* Allow zero-byte read from NULL, regardless of pointer type */ @@ -1376,7 +1475,11 @@ static int check_stack_boundary(struct bpf_verifier_env *env, int regno, } for (i = 0; i < access_size; i++) { - if (state->stack_slot_type[MAX_BPF_STACK + off + i] != STACK_MISC) { + slot = -(off + i) - 1; + spi = slot / BPF_REG_SIZE; + if (state->allocated_stack <= slot || + state->stack[spi].slot_type[slot % BPF_REG_SIZE] != + STACK_MISC) { verbose("invalid indirect read from stack off %d+%d size %d\n", off, i, access_size); return -EACCES; @@ -1389,7 +1492,7 @@ static int check_helper_mem_access(struct bpf_verifier_env *env, int regno, int access_size, bool zero_size_allowed, struct bpf_call_arg_meta *meta) { - struct bpf_reg_state *regs = env->cur_state.regs, *reg = ®s[regno]; + struct bpf_reg_state *regs = cur_regs(env), *reg = ®s[regno]; switch (reg->type) { case PTR_TO_PACKET: @@ -1406,7 +1509,7 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 regno, enum bpf_arg_type arg_type, struct bpf_call_arg_meta *meta) { - struct bpf_reg_state *regs = env->cur_state.regs, *reg = ®s[regno]; + struct bpf_reg_state *regs = cur_regs(env), *reg = ®s[regno]; enum bpf_reg_type expected_type, type = reg->type; int err = 0; @@ -1678,7 +1781,7 @@ static int check_raw_mode(const struct bpf_func_proto *fn) */ static void clear_all_pkt_pointers(struct bpf_verifier_env *env) { - struct bpf_verifier_state *state = &env->cur_state; + struct bpf_verifier_state *state = env->cur_state; struct bpf_reg_state *regs = state->regs, *reg; int i; @@ -1687,10 +1790,10 @@ static void clear_all_pkt_pointers(struct bpf_verifier_env *env) regs[i].type == PTR_TO_PACKET_END) mark_reg_unknown(regs, i); - for (i = 0; i < MAX_BPF_STACK; i += BPF_REG_SIZE) { - if (state->stack_slot_type[i] != STACK_SPILL) + for (i = 0; i < state->allocated_stack / BPF_REG_SIZE; i++) { + if (state->stack[i].slot_type[0] != STACK_SPILL) continue; - reg = &state->spilled_regs[i / BPF_REG_SIZE]; + reg = &state->stack[i].spilled_ptr; if (reg->type != PTR_TO_PACKET && reg->type != PTR_TO_PACKET_END) continue; @@ -1700,9 +1803,8 @@ static void clear_all_pkt_pointers(struct bpf_verifier_env *env) static int check_call(struct bpf_verifier_env *env, int func_id, int insn_idx) { - struct bpf_verifier_state *state = &env->cur_state; const struct bpf_func_proto *fn = NULL; - struct bpf_reg_state *regs = state->regs; + struct bpf_reg_state *regs; struct bpf_call_arg_meta meta; bool changes_data; int i, err; @@ -1776,6 +1878,7 @@ static int check_call(struct bpf_verifier_env *env, int func_id, int insn_idx) return err; } + regs = cur_regs(env); /* reset caller saved regs */ for (i = 0; i < CALLER_SAVED_REGS; i++) { mark_reg_not_init(regs, caller_saved[i]); @@ -1890,7 +1993,7 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, const struct bpf_reg_state *ptr_reg, const struct bpf_reg_state *off_reg) { - struct bpf_reg_state *regs = env->cur_state.regs, *dst_reg; + struct bpf_reg_state *regs = cur_regs(env), *dst_reg; bool known = tnum_is_const(off_reg->var_off); s64 smin_val = off_reg->smin_value, smax_val = off_reg->smax_value, smin_ptr = ptr_reg->smin_value, smax_ptr = ptr_reg->smax_value; @@ -2097,7 +2200,7 @@ static int adjust_scalar_min_max_vals(struct bpf_verifier_env *env, struct bpf_reg_state *dst_reg, struct bpf_reg_state src_reg) { - struct bpf_reg_state *regs = env->cur_state.regs; + struct bpf_reg_state *regs = cur_regs(env); u8 opcode = BPF_OP(insn->code); bool src_known, dst_known; s64 smin_val, smax_val; @@ -2345,7 +2448,7 @@ static int adjust_scalar_min_max_vals(struct bpf_verifier_env *env, static int adjust_reg_min_max_vals(struct bpf_verifier_env *env, struct bpf_insn *insn) { - struct bpf_reg_state *regs = env->cur_state.regs, *dst_reg, *src_reg; + struct bpf_reg_state *regs = cur_regs(env), *dst_reg, *src_reg; struct bpf_reg_state *ptr_reg = NULL, off_reg = {0}; u8 opcode = BPF_OP(insn->code); int rc; @@ -2419,12 +2522,12 @@ static int adjust_reg_min_max_vals(struct bpf_verifier_env *env, /* Got here implies adding two SCALAR_VALUEs */ if (WARN_ON_ONCE(ptr_reg)) { - print_verifier_state(&env->cur_state); + print_verifier_state(env->cur_state); verbose("verifier internal error: unexpected ptr_reg\n"); return -EINVAL; } if (WARN_ON(!src_reg)) { - print_verifier_state(&env->cur_state); + print_verifier_state(env->cur_state); verbose("verifier internal error: no src_reg\n"); return -EINVAL; } @@ -2434,7 +2537,7 @@ static int adjust_reg_min_max_vals(struct bpf_verifier_env *env, /* check validity of 32-bit and 64-bit arithmetic operations */ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn) { - struct bpf_reg_state *regs = env->cur_state.regs; + struct bpf_reg_state *regs = cur_regs(env); u8 opcode = BPF_OP(insn->code); int err; @@ -2661,10 +2764,10 @@ static void find_good_pkt_pointers(struct bpf_verifier_state *state, /* keep the maximum range already checked */ regs[i].range = max(regs[i].range, new_range); - for (i = 0; i < MAX_BPF_STACK; i += BPF_REG_SIZE) { - if (state->stack_slot_type[i] != STACK_SPILL) + for (i = 0; i < state->allocated_stack / BPF_REG_SIZE; i++) { + if (state->stack[i].slot_type[0] != STACK_SPILL) continue; - reg = &state->spilled_regs[i / BPF_REG_SIZE]; + reg = &state->stack[i].spilled_ptr; if (reg->type == PTR_TO_PACKET && reg->id == dst_reg->id) reg->range = max(reg->range, new_range); } @@ -2914,17 +3017,17 @@ static void mark_map_regs(struct bpf_verifier_state *state, u32 regno, for (i = 0; i < MAX_BPF_REG; i++) mark_map_reg(regs, i, id, is_null); - for (i = 0; i < MAX_BPF_STACK; i += BPF_REG_SIZE) { - if (state->stack_slot_type[i] != STACK_SPILL) + for (i = 0; i < state->allocated_stack / BPF_REG_SIZE; i++) { + if (state->stack[i].slot_type[0] != STACK_SPILL) continue; - mark_map_reg(state->spilled_regs, i / BPF_REG_SIZE, id, is_null); + mark_map_reg(&state->stack[i].spilled_ptr, 0, id, is_null); } } static int check_cond_jmp_op(struct bpf_verifier_env *env, struct bpf_insn *insn, int *insn_idx) { - struct bpf_verifier_state *other_branch, *this_branch = &env->cur_state; + struct bpf_verifier_state *other_branch, *this_branch = env->cur_state; struct bpf_reg_state *regs = this_branch->regs, *dst_reg; u8 opcode = BPF_OP(insn->code); int err; @@ -3087,7 +3190,7 @@ static struct bpf_map *ld_imm64_to_map_ptr(struct bpf_insn *insn) /* verify BPF_LD_IMM64 instruction */ static int check_ld_imm(struct bpf_verifier_env *env, struct bpf_insn *insn) { - struct bpf_reg_state *regs = env->cur_state.regs; + struct bpf_reg_state *regs = cur_regs(env); int err; if (BPF_SIZE(insn->code) != BPF_DW) { @@ -3148,7 +3251,7 @@ static bool may_access_skb(enum bpf_prog_type type) */ static int check_ld_abs(struct bpf_verifier_env *env, struct bpf_insn *insn) { - struct bpf_reg_state *regs = env->cur_state.regs; + struct bpf_reg_state *regs = cur_regs(env); u8 mode = BPF_MODE(insn->code); int i, err; @@ -3534,6 +3637,57 @@ static bool regsafe(struct bpf_reg_state *rold, struct bpf_reg_state *rcur, return false; } +static bool stacksafe(struct bpf_verifier_state *old, + struct bpf_verifier_state *cur, + struct idpair *idmap) +{ + int i, spi; + + /* if explored stack has more populated slots than current stack + * such stacks are not equivalent + */ + if (old->allocated_stack > cur->allocated_stack) + return false; + + /* walk slots of the explored stack and ignore any additional + * slots in the current stack, since explored(safe) state + * didn't use them + */ + for (i = 0; i < old->allocated_stack; i++) { + spi = i / BPF_REG_SIZE; + + if (old->stack[spi].slot_type[i % BPF_REG_SIZE] == STACK_INVALID) + continue; + if (old->stack[spi].slot_type[i % BPF_REG_SIZE] != + cur->stack[spi].slot_type[i % BPF_REG_SIZE]) + /* Ex: old explored (safe) state has STACK_SPILL in + * this stack slot, but current has has STACK_MISC -> + * this verifier states are not equivalent, + * return false to continue verification of this path + */ + return false; + if (i % BPF_REG_SIZE) + continue; + if (old->stack[spi].slot_type[0] != STACK_SPILL) + continue; + if (!regsafe(&old->stack[spi].spilled_ptr, + &cur->stack[spi].spilled_ptr, + idmap)) + /* when explored and current stack slot are both storing + * spilled registers, check that stored pointers types + * are the same as well. + * Ex: explored safe path could have stored + * (bpf_reg_state) {.type = PTR_TO_STACK, .off = -8} + * but current path has stored: + * (bpf_reg_state) {.type = PTR_TO_STACK, .off = -16} + * such verifier states are not equivalent. + * return false to continue verification of this path + */ + return false; + } + return true; +} + /* compare two verifier states * * all states stored in state_list are known to be valid, since @@ -3578,37 +3732,8 @@ static bool states_equal(struct bpf_verifier_env *env, goto out_free; } - for (i = 0; i < MAX_BPF_STACK; i++) { - if (old->stack_slot_type[i] == STACK_INVALID) - continue; - if (old->stack_slot_type[i] != cur->stack_slot_type[i]) - /* Ex: old explored (safe) state has STACK_SPILL in - * this stack slot, but current has has STACK_MISC -> - * this verifier states are not equivalent, - * return false to continue verification of this path - */ - goto out_free; - if (i % BPF_REG_SIZE) - continue; - if (old->stack_slot_type[i] != STACK_SPILL) - continue; - if (!regsafe(&old->spilled_regs[i / BPF_REG_SIZE], - &cur->spilled_regs[i / BPF_REG_SIZE], - idmap)) - /* when explored and current stack slot are both storing - * spilled registers, check that stored pointers types - * are the same as well. - * Ex: explored safe path could have stored - * (bpf_reg_state) {.type = PTR_TO_STACK, .off = -8} - * but current path has stored: - * (bpf_reg_state) {.type = PTR_TO_STACK, .off = -16} - * such verifier states are not equivalent. - * return false to continue verification of this path - */ - goto out_free; - else - continue; - } + if (!stacksafe(old, cur, idmap)) + goto out_free; ret = true; out_free: kfree(idmap); @@ -3644,17 +3769,19 @@ static bool do_propagate_liveness(const struct bpf_verifier_state *state, } } /* ... and stack slots */ - for (i = 0; i < MAX_BPF_STACK / BPF_REG_SIZE; i++) { - if (parent->stack_slot_type[i * BPF_REG_SIZE] != STACK_SPILL) + for (i = 0; i < state->allocated_stack / BPF_REG_SIZE && + i < parent->allocated_stack / BPF_REG_SIZE; i++) { + if (parent->stack[i].slot_type[0] != STACK_SPILL) continue; - if (state->stack_slot_type[i * BPF_REG_SIZE] != STACK_SPILL) + if (state->stack[i].slot_type[0] != STACK_SPILL) continue; - if (parent->spilled_regs[i].live & REG_LIVE_READ) + if (parent->stack[i].spilled_ptr.live & REG_LIVE_READ) continue; - if (writes && (state->spilled_regs[i].live & REG_LIVE_WRITTEN)) + if (writes && + (state->stack[i].spilled_ptr.live & REG_LIVE_WRITTEN)) continue; - if (state->spilled_regs[i].live & REG_LIVE_READ) { - parent->spilled_regs[i].live |= REG_LIVE_READ; + if (state->stack[i].spilled_ptr.live & REG_LIVE_READ) { + parent->stack[i].spilled_ptr.live |= REG_LIVE_READ; touched = true; } } @@ -3684,6 +3811,7 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx) { struct bpf_verifier_state_list *new_sl; struct bpf_verifier_state_list *sl; + struct bpf_verifier_state *cur = env->cur_state; int i; sl = env->explored_states[insn_idx]; @@ -3694,7 +3822,7 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx) return 0; while (sl != STATE_LIST_MARK) { - if (states_equal(env, &sl->state, &env->cur_state)) { + if (states_equal(env, &sl->state, cur)) { /* reached equivalent register/stack state, * prune the search. * Registers read by the continuation are read by us. @@ -3705,7 +3833,7 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx) * they'll be immediately forgotten as we're pruning * this state and will pop a new one. */ - propagate_liveness(&sl->state, &env->cur_state); + propagate_liveness(&sl->state, cur); return 1; } sl = sl->next; @@ -3717,16 +3845,16 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx) * it will be rejected. Since there are no loops, we won't be * seeing this 'insn_idx' instruction again on the way to bpf_exit */ - new_sl = kmalloc(sizeof(struct bpf_verifier_state_list), GFP_USER); + new_sl = kzalloc(sizeof(struct bpf_verifier_state_list), GFP_KERNEL); if (!new_sl) return -ENOMEM; /* add new state to the head of linked list */ - memcpy(&new_sl->state, &env->cur_state, sizeof(env->cur_state)); + copy_verifier_state(&new_sl->state, cur); new_sl->next = env->explored_states[insn_idx]; env->explored_states[insn_idx] = new_sl; /* connect new state to parentage chain */ - env->cur_state.parent = &new_sl->state; + cur->parent = &new_sl->state; /* clear write marks in current state: the writes we did are not writes * our child did, so they don't screen off its reads from us. * (There are no read marks in current state, because reads always mark @@ -3734,10 +3862,10 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx) * explored_states can get read marks.) */ for (i = 0; i < BPF_REG_FP; i++) - env->cur_state.regs[i].live = REG_LIVE_NONE; - for (i = 0; i < MAX_BPF_STACK / BPF_REG_SIZE; i++) - if (env->cur_state.stack_slot_type[i * BPF_REG_SIZE] == STACK_SPILL) - env->cur_state.spilled_regs[i].live = REG_LIVE_NONE; + cur->regs[i].live = REG_LIVE_NONE; + for (i = 0; i < cur->allocated_stack / BPF_REG_SIZE; i++) + if (cur->stack[i].slot_type[0] == STACK_SPILL) + cur->stack[i].spilled_ptr.live = REG_LIVE_NONE; return 0; } @@ -3752,15 +3880,19 @@ static int ext_analyzer_insn_hook(struct bpf_verifier_env *env, static int do_check(struct bpf_verifier_env *env) { - struct bpf_verifier_state *state = &env->cur_state; + struct bpf_verifier_state *state; struct bpf_insn *insns = env->prog->insnsi; - struct bpf_reg_state *regs = state->regs; + struct bpf_reg_state *regs; int insn_cnt = env->prog->len; int insn_idx, prev_insn_idx = 0; int insn_processed = 0; bool do_print_state = false; - init_reg_state(regs); + state = kzalloc(sizeof(struct bpf_verifier_state), GFP_KERNEL); + if (!state) + return -ENOMEM; + env->cur_state = state; + init_reg_state(state->regs); state->parent = NULL; insn_idx = 0; for (;;) { @@ -3807,7 +3939,7 @@ static int do_check(struct bpf_verifier_env *env) else verbose("\nfrom %d to %d:", prev_insn_idx, insn_idx); - print_verifier_state(&env->cur_state); + print_verifier_state(env->cur_state); do_print_state = false; } @@ -3820,6 +3952,7 @@ static int do_check(struct bpf_verifier_env *env) if (err) return err; + regs = cur_regs(env); env->insn_aux_data[insn_idx].seen = true; if (class == BPF_ALU || class == BPF_ALU64) { err = check_alu_op(env, insn); @@ -3991,8 +4124,10 @@ static int do_check(struct bpf_verifier_env *env) } process_bpf_exit: - insn_idx = pop_stack(env, &prev_insn_idx); - if (insn_idx < 0) { + err = pop_stack(env, &prev_insn_idx, &insn_idx); + if (err < 0) { + if (err != -ENOENT) + return err; break; } else { do_print_state = true; @@ -4633,9 +4768,11 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr) env->allow_ptr_leaks = capable(CAP_SYS_ADMIN); ret = do_check(env); + free_verifier_state(env->cur_state); + env->cur_state = NULL; skip_full_check: - while (pop_stack(env, NULL) >= 0); + while (!pop_stack(env, NULL, NULL)); free_states(env); if (ret == 0) @@ -4741,9 +4878,11 @@ int bpf_analyzer(struct bpf_prog *prog, const struct bpf_ext_analyzer_ops *ops, env->allow_ptr_leaks = capable(CAP_SYS_ADMIN); ret = do_check(env); + free_verifier_state(env->cur_state); + env->cur_state = NULL; skip_full_check: - while (pop_stack(env, NULL) >= 0); + while (!pop_stack(env, NULL, NULL)); free_states(env); mutex_unlock(&bpf_verifier_lock); -- GitLab From 534087e6c3375562635b734345dd7a00ae53ba31 Mon Sep 17 00:00:00 2001 From: Alexei Starovoitov Date: Wed, 3 Apr 2019 18:39:02 +0000 Subject: [PATCH 0156/1121] bpf: fix verifier memory leaks commit 1969db47f8d0e800397abd4ee4e8d27d2b578587 upstream. fix verifier memory leaks Fixes: 638f5b90d460 ("bpf: reduce verifier memory consumption") Signed-off-by: Alexei Starovoitov Signed-off-by: David S. Miller Signed-off-by: Balbir Singh Signed-off-by: Greg Kroah-Hartman --- kernel/bpf/verifier.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 805bc218150d..8293fc2f452a 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -491,10 +491,12 @@ static int realloc_verifier_state(struct bpf_verifier_state *state, int size, return 0; } -static void free_verifier_state(struct bpf_verifier_state *state) +static void free_verifier_state(struct bpf_verifier_state *state, + bool free_self) { kfree(state->stack); - kfree(state); + if (free_self) + kfree(state); } /* copy verifier state from src to dst growing dst stack space @@ -532,6 +534,7 @@ static int pop_stack(struct bpf_verifier_env *env, int *prev_insn_idx, if (prev_insn_idx) *prev_insn_idx = head->prev_insn_idx; elem = head->next; + free_verifier_state(&head->st, false); kfree(head); env->head = elem; env->stack_size--; @@ -549,14 +552,14 @@ static struct bpf_verifier_state *push_stack(struct bpf_verifier_env *env, if (!elem) goto err; - err = copy_verifier_state(&elem->st, cur); - if (err) - return NULL; elem->insn_idx = insn_idx; elem->prev_insn_idx = prev_insn_idx; elem->next = env->head; env->head = elem; env->stack_size++; + err = copy_verifier_state(&elem->st, cur); + if (err) + goto err; if (env->stack_size > BPF_COMPLEXITY_LIMIT_STACK) { verbose("BPF program is too complex\n"); goto err; @@ -3812,7 +3815,7 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx) struct bpf_verifier_state_list *new_sl; struct bpf_verifier_state_list *sl; struct bpf_verifier_state *cur = env->cur_state; - int i; + int i, err; sl = env->explored_states[insn_idx]; if (!sl) @@ -3850,7 +3853,12 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx) return -ENOMEM; /* add new state to the head of linked list */ - copy_verifier_state(&new_sl->state, cur); + err = copy_verifier_state(&new_sl->state, cur); + if (err) { + free_verifier_state(&new_sl->state, false); + kfree(new_sl); + return err; + } new_sl->next = env->explored_states[insn_idx]; env->explored_states[insn_idx] = new_sl; /* connect new state to parentage chain */ @@ -4692,6 +4700,7 @@ static void free_states(struct bpf_verifier_env *env) if (sl) while (sl != STATE_LIST_MARK) { sln = sl->next; + free_verifier_state(&sl->state, false); kfree(sl); sl = sln; } @@ -4768,7 +4777,7 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr) env->allow_ptr_leaks = capable(CAP_SYS_ADMIN); ret = do_check(env); - free_verifier_state(env->cur_state); + free_verifier_state(env->cur_state, true); env->cur_state = NULL; skip_full_check: @@ -4878,7 +4887,7 @@ int bpf_analyzer(struct bpf_prog *prog, const struct bpf_ext_analyzer_ops *ops, env->allow_ptr_leaks = capable(CAP_SYS_ADMIN); ret = do_check(env); - free_verifier_state(env->cur_state); + free_verifier_state(env->cur_state, true); env->cur_state = NULL; skip_full_check: -- GitLab From 86e5dd8cced7b1bffdae6154a1a7826ed8acf1f4 Mon Sep 17 00:00:00 2001 From: Craig Gallek Date: Wed, 3 Apr 2019 18:39:03 +0000 Subject: [PATCH 0157/1121] bpf: fix verifier NULL pointer dereference commit 8c01c4f896aa3404af948880dcb29a2d51c833dc upstream. do_check() can fail early without allocating env->cur_state under memory pressure. Syzkaller found the stack below on the linux-next tree because of this. kasan: CONFIG_KASAN_INLINE enabled kasan: GPF could be caused by NULL-ptr deref or user memory access general protection fault: 0000 [#1] SMP KASAN Dumping ftrace buffer: (ftrace buffer empty) Modules linked in: CPU: 1 PID: 27062 Comm: syz-executor5 Not tainted 4.14.0-rc7+ #106 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 task: ffff8801c2c74700 task.stack: ffff8801c3e28000 RIP: 0010:free_verifier_state kernel/bpf/verifier.c:347 [inline] RIP: 0010:bpf_check+0xcf4/0x19c0 kernel/bpf/verifier.c:4533 RSP: 0018:ffff8801c3e2f5c8 EFLAGS: 00010202 RAX: dffffc0000000000 RBX: 00000000fffffff4 RCX: 0000000000000000 RDX: 0000000000000070 RSI: ffffffff817d5aa9 RDI: 0000000000000380 RBP: ffff8801c3e2f668 R08: 0000000000000000 R09: 1ffff100387c5d9f R10: 00000000218c4e80 R11: ffffffff85b34380 R12: ffff8801c4dc6a28 R13: 0000000000000000 R14: ffff8801c4dc6a00 R15: ffff8801c4dc6a20 FS: 00007f311079b700(0000) GS:ffff8801db300000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00000000004d4a24 CR3: 00000001cbcd0000 CR4: 00000000001406e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: bpf_prog_load+0xcbb/0x18e0 kernel/bpf/syscall.c:1166 SYSC_bpf kernel/bpf/syscall.c:1690 [inline] SyS_bpf+0xae9/0x4620 kernel/bpf/syscall.c:1652 entry_SYSCALL_64_fastpath+0x1f/0xbe RIP: 0033:0x452869 RSP: 002b:00007f311079abe8 EFLAGS: 00000212 ORIG_RAX: 0000000000000141 RAX: ffffffffffffffda RBX: 0000000000758020 RCX: 0000000000452869 RDX: 0000000000000030 RSI: 0000000020168000 RDI: 0000000000000005 RBP: 00007f311079aa20 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000212 R12: 00000000004b7550 R13: 00007f311079ab58 R14: 00000000004b7560 R15: 0000000000000000 Code: df 48 c1 ea 03 80 3c 02 00 0f 85 e6 0b 00 00 4d 8b 6e 20 48 b8 00 00 00 00 00 fc ff df 49 8d bd 80 03 00 00 48 89 fa 48 c1 ea 03 <80> 3c 02 00 0f 85 b6 0b 00 00 49 8b bd 80 03 00 00 e8 d6 0c 26 RIP: free_verifier_state kernel/bpf/verifier.c:347 [inline] RSP: ffff8801c3e2f5c8 RIP: bpf_check+0xcf4/0x19c0 kernel/bpf/verifier.c:4533 RSP: ffff8801c3e2f5c8 ---[ end trace c8d37f339dc64004 ]--- Fixes: 638f5b90d460 ("bpf: reduce verifier memory consumption") Fixes: 1969db47f8d0 ("bpf: fix verifier memory leaks") Signed-off-by: Craig Gallek Acked-by: Alexei Starovoitov Acked-by: Daniel Borkmann Signed-off-by: David S. Miller Signed-off-by: Balbir Singh Signed-off-by: Greg Kroah-Hartman --- kernel/bpf/verifier.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 8293fc2f452a..68ff8ee42ba0 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -4777,8 +4777,10 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr) env->allow_ptr_leaks = capable(CAP_SYS_ADMIN); ret = do_check(env); - free_verifier_state(env->cur_state, true); - env->cur_state = NULL; + if (env->cur_state) { + free_verifier_state(env->cur_state, true); + env->cur_state = NULL; + } skip_full_check: while (!pop_stack(env, NULL, NULL)); @@ -4887,8 +4889,10 @@ int bpf_analyzer(struct bpf_prog *prog, const struct bpf_ext_analyzer_ops *ops, env->allow_ptr_leaks = capable(CAP_SYS_ADMIN); ret = do_check(env); - free_verifier_state(env->cur_state, true); - env->cur_state = NULL; + if (env->cur_state) { + free_verifier_state(env->cur_state, true); + env->cur_state = NULL; + } skip_full_check: while (!pop_stack(env, NULL, NULL)); -- GitLab From 85614894812adb00ddd1eb3e4b18ddb995dd61c1 Mon Sep 17 00:00:00 2001 From: Alexei Starovoitov Date: Wed, 3 Apr 2019 18:39:04 +0000 Subject: [PATCH 0158/1121] bpf: fix stack state printing in verifier log commit 12a3cc8424fe1237aaeb982dec4f0914ddd22f3e upstream. fix incorrect stack state prints in print_verifier_state() Fixes: 638f5b90d460 ("bpf: reduce verifier memory consumption") Signed-off-by: Alexei Starovoitov Acked-by: John Fastabend Acked-by: Daniel Borkmann Signed-off-by: Daniel Borkmann Signed-off-by: Balbir Singh Signed-off-by: Greg Kroah-Hartman --- kernel/bpf/verifier.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 68ff8ee42ba0..84e0338be0ad 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -268,7 +268,7 @@ static void print_verifier_state(struct bpf_verifier_state *state) for (i = 0; i < state->allocated_stack / BPF_REG_SIZE; i++) { if (state->stack[i].slot_type[0] == STACK_SPILL) verbose(" fp%d=%s", - -MAX_BPF_STACK + i * BPF_REG_SIZE, + (-i - 1) * BPF_REG_SIZE, reg_type_str[state->stack[i].spilled_ptr.type]); } verbose("\n"); -- GitLab From 6a42c49482db5ab565a9dabb1642ff64ae0f45b7 Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Wed, 3 Apr 2019 18:39:05 +0000 Subject: [PATCH 0159/1121] bpf: move {prev_,}insn_idx into verifier env commit c08435ec7f2bc8f4109401f696fd55159b4b40cb upstream. Move prev_insn_idx and insn_idx from the do_check() function into the verifier environment, so they can be read inside the various helper functions for handling the instructions. It's easier to put this into the environment rather than changing all call-sites only to pass it along. insn_idx is useful in particular since this later on allows to hold state in env->insn_aux_data[env->insn_idx]. Signed-off-by: Daniel Borkmann Acked-by: Alexei Starovoitov Signed-off-by: Alexei Starovoitov Signed-off-by: Vallish Vaidyeshwara [Backported to 4.14 by sblbir] Signed-off-by: Balbir Singh Signed-off-by: Greg Kroah-Hartman --- include/linux/bpf_verifier.h | 2 ++ kernel/bpf/verifier.c | 64 +++++++++++++++++------------------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h index 0fc3d9afb8bf..3149a01d0f58 100644 --- a/include/linux/bpf_verifier.h +++ b/include/linux/bpf_verifier.h @@ -134,6 +134,8 @@ struct bpf_ext_analyzer_ops { * one verifier_env per bpf_check() call */ struct bpf_verifier_env { + u32 insn_idx; + u32 prev_insn_idx; struct bpf_prog *prog; /* eBPF program being verified */ struct bpf_verifier_stack_elem *head; /* stack of verifier states to be processed */ int stack_size; /* number of states to be processed */ diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 84e0338be0ad..be0edef26465 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -3892,7 +3892,6 @@ static int do_check(struct bpf_verifier_env *env) struct bpf_insn *insns = env->prog->insnsi; struct bpf_reg_state *regs; int insn_cnt = env->prog->len; - int insn_idx, prev_insn_idx = 0; int insn_processed = 0; bool do_print_state = false; @@ -3902,19 +3901,18 @@ static int do_check(struct bpf_verifier_env *env) env->cur_state = state; init_reg_state(state->regs); state->parent = NULL; - insn_idx = 0; for (;;) { struct bpf_insn *insn; u8 class; int err; - if (insn_idx >= insn_cnt) { + if (env->insn_idx >= insn_cnt) { verbose("invalid insn idx %d insn_cnt %d\n", - insn_idx, insn_cnt); + env->insn_idx, insn_cnt); return -EFAULT; } - insn = &insns[insn_idx]; + insn = &insns[env->insn_idx]; class = BPF_CLASS(insn->code); if (++insn_processed > BPF_COMPLEXITY_LIMIT_INSNS) { @@ -3923,7 +3921,7 @@ static int do_check(struct bpf_verifier_env *env) return -E2BIG; } - err = is_state_visited(env, insn_idx); + err = is_state_visited(env, env->insn_idx); if (err < 0) return err; if (err == 1) { @@ -3931,9 +3929,9 @@ static int do_check(struct bpf_verifier_env *env) if (log_level) { if (do_print_state) verbose("\nfrom %d to %d: safe\n", - prev_insn_idx, insn_idx); + env->prev_insn_idx, env->insn_idx); else - verbose("%d: safe\n", insn_idx); + verbose("%d: safe\n", env->insn_idx); } goto process_bpf_exit; } @@ -3943,25 +3941,25 @@ static int do_check(struct bpf_verifier_env *env) if (log_level > 1 || (log_level && do_print_state)) { if (log_level > 1) - verbose("%d:", insn_idx); + verbose("%d:", env->insn_idx); else verbose("\nfrom %d to %d:", - prev_insn_idx, insn_idx); + env->prev_insn_idx, env->insn_idx); print_verifier_state(env->cur_state); do_print_state = false; } if (log_level) { - verbose("%d: ", insn_idx); + verbose("%d: ", env->insn_idx); print_bpf_insn(env, insn); } - err = ext_analyzer_insn_hook(env, insn_idx, prev_insn_idx); + err = ext_analyzer_insn_hook(env, env->insn_idx, env->prev_insn_idx); if (err) return err; regs = cur_regs(env); - env->insn_aux_data[insn_idx].seen = true; + env->insn_aux_data[env->insn_idx].seen = true; if (class == BPF_ALU || class == BPF_ALU64) { err = check_alu_op(env, insn); if (err) @@ -3986,13 +3984,13 @@ static int do_check(struct bpf_verifier_env *env) /* check that memory (src_reg + off) is readable, * the state of dst_reg will be updated by this func */ - err = check_mem_access(env, insn_idx, insn->src_reg, insn->off, - BPF_SIZE(insn->code), BPF_READ, - insn->dst_reg, false); + err = check_mem_access(env, env->insn_idx, insn->src_reg, + insn->off, BPF_SIZE(insn->code), + BPF_READ, insn->dst_reg, false); if (err) return err; - prev_src_type = &env->insn_aux_data[insn_idx].ptr_type; + prev_src_type = &env->insn_aux_data[env->insn_idx].ptr_type; if (*prev_src_type == NOT_INIT) { /* saw a valid insn @@ -4019,10 +4017,10 @@ static int do_check(struct bpf_verifier_env *env) enum bpf_reg_type *prev_dst_type, dst_reg_type; if (BPF_MODE(insn->code) == BPF_XADD) { - err = check_xadd(env, insn_idx, insn); + err = check_xadd(env, env->insn_idx, insn); if (err) return err; - insn_idx++; + env->insn_idx++; continue; } @@ -4038,13 +4036,13 @@ static int do_check(struct bpf_verifier_env *env) dst_reg_type = regs[insn->dst_reg].type; /* check that memory (dst_reg + off) is writeable */ - err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off, - BPF_SIZE(insn->code), BPF_WRITE, - insn->src_reg, false); + err = check_mem_access(env, env->insn_idx, insn->dst_reg, + insn->off, BPF_SIZE(insn->code), + BPF_WRITE, insn->src_reg, false); if (err) return err; - prev_dst_type = &env->insn_aux_data[insn_idx].ptr_type; + prev_dst_type = &env->insn_aux_data[env->insn_idx].ptr_type; if (*prev_dst_type == NOT_INIT) { *prev_dst_type = dst_reg_type; @@ -4073,9 +4071,9 @@ static int do_check(struct bpf_verifier_env *env) } /* check that memory (dst_reg + off) is writeable */ - err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off, - BPF_SIZE(insn->code), BPF_WRITE, - -1, false); + err = check_mem_access(env, env->insn_idx, insn->dst_reg, + insn->off, BPF_SIZE(insn->code), + BPF_WRITE, -1, false); if (err) return err; @@ -4091,7 +4089,7 @@ static int do_check(struct bpf_verifier_env *env) return -EINVAL; } - err = check_call(env, insn->imm, insn_idx); + err = check_call(env, insn->imm, env->insn_idx); if (err) return err; @@ -4104,7 +4102,7 @@ static int do_check(struct bpf_verifier_env *env) return -EINVAL; } - insn_idx += insn->off + 1; + env->insn_idx += insn->off + 1; continue; } else if (opcode == BPF_EXIT) { @@ -4132,7 +4130,7 @@ static int do_check(struct bpf_verifier_env *env) } process_bpf_exit: - err = pop_stack(env, &prev_insn_idx, &insn_idx); + err = pop_stack(env, &env->prev_insn_idx, &env->insn_idx); if (err < 0) { if (err != -ENOENT) return err; @@ -4142,7 +4140,7 @@ static int do_check(struct bpf_verifier_env *env) continue; } } else { - err = check_cond_jmp_op(env, insn, &insn_idx); + err = check_cond_jmp_op(env, insn, &env->insn_idx); if (err) return err; } @@ -4159,8 +4157,8 @@ static int do_check(struct bpf_verifier_env *env) if (err) return err; - insn_idx++; - env->insn_aux_data[insn_idx].seen = true; + env->insn_idx++; + env->insn_aux_data[env->insn_idx].seen = true; } else { verbose("invalid BPF_LD mode\n"); return -EINVAL; @@ -4170,7 +4168,7 @@ static int do_check(struct bpf_verifier_env *env) return -EINVAL; } - insn_idx++; + env->insn_idx++; } verbose("processed %d insns, stack depth %d\n", -- GitLab From ee282977c63d1c195ee0de6df173b0f216d14c28 Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Wed, 3 Apr 2019 18:39:06 +0000 Subject: [PATCH 0160/1121] bpf: move tmp variable into ax register in interpreter commit 144cd91c4c2bced6eb8a7e25e590f6618a11e854 upstream. This change moves the on-stack 64 bit tmp variable in ___bpf_prog_run() into the hidden ax register. The latter is currently only used in JITs for constant blinding as a temporary scratch register, meaning the BPF interpreter will never see the use of ax. Therefore it is safe to use it for the cases where tmp has been used earlier. This is needed to later on allow restricted hidden use of ax in both interpreter and JITs. Signed-off-by: Daniel Borkmann Acked-by: Alexei Starovoitov Signed-off-by: Alexei Starovoitov [backported to 4.14 sblbir] Signed-off-by: Balbir Singh Signed-off-by: Greg Kroah-Hartman --- include/linux/filter.h | 3 ++- kernel/bpf/core.c | 31 ++++++++++++++++--------------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/include/linux/filter.h b/include/linux/filter.h index 56d2cda9931b..f7880c716308 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -53,7 +53,8 @@ struct bpf_prog_aux; * constants. See JIT pre-step in bpf_jit_blind_constants(). */ #define BPF_REG_AX MAX_BPF_REG -#define MAX_BPF_JIT_REG (MAX_BPF_REG + 1) +#define MAX_BPF_EXT_REG (MAX_BPF_REG + 1) +#define MAX_BPF_JIT_REG MAX_BPF_EXT_REG /* unused opcode to mark special call to bpf_tail_call() helper */ #define BPF_TAIL_CALL 0xf0 diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index d203a5d6b726..e59a72c7d092 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -51,6 +51,7 @@ #define DST regs[insn->dst_reg] #define SRC regs[insn->src_reg] #define FP regs[BPF_REG_FP] +#define AX regs[BPF_REG_AX] #define ARG1 regs[BPF_REG_ARG1] #define CTX regs[BPF_REG_CTX] #define IMM insn->imm @@ -939,22 +940,22 @@ static unsigned int ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn, ALU64_MOD_X: if (unlikely(SRC == 0)) return 0; - div64_u64_rem(DST, SRC, &tmp); - DST = tmp; + div64_u64_rem(DST, SRC, &AX); + DST = AX; CONT; ALU_MOD_X: if (unlikely((u32)SRC == 0)) return 0; - tmp = (u32) DST; - DST = do_div(tmp, (u32) SRC); + AX = (u32) DST; + DST = do_div(AX, (u32) SRC); CONT; ALU64_MOD_K: - div64_u64_rem(DST, IMM, &tmp); - DST = tmp; + div64_u64_rem(DST, IMM, &AX); + DST = AX; CONT; ALU_MOD_K: - tmp = (u32) DST; - DST = do_div(tmp, (u32) IMM); + AX = (u32) DST; + DST = do_div(AX, (u32) IMM); CONT; ALU64_DIV_X: if (unlikely(SRC == 0)) @@ -964,17 +965,17 @@ static unsigned int ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn, ALU_DIV_X: if (unlikely((u32)SRC == 0)) return 0; - tmp = (u32) DST; - do_div(tmp, (u32) SRC); - DST = (u32) tmp; + AX = (u32) DST; + do_div(AX, (u32) SRC); + DST = (u32) AX; CONT; ALU64_DIV_K: DST = div64_u64(DST, IMM); CONT; ALU_DIV_K: - tmp = (u32) DST; - do_div(tmp, (u32) IMM); - DST = (u32) tmp; + AX = (u32) DST; + do_div(AX, (u32) IMM); + DST = (u32) AX; CONT; ALU_END_TO_BE: switch (IMM) { @@ -1278,7 +1279,7 @@ STACK_FRAME_NON_STANDARD(___bpf_prog_run); /* jump table */ static unsigned int PROG_NAME(stack_size)(const void *ctx, const struct bpf_insn *insn) \ { \ u64 stack[stack_size / sizeof(u64)]; \ - u64 regs[MAX_BPF_REG]; \ + u64 regs[MAX_BPF_EXT_REG]; \ \ FP = (u64) (unsigned long) &stack[ARRAY_SIZE(stack)]; \ ARG1 = (u64) (unsigned long) ctx; \ -- GitLab From b101cf55c6da31b86ee8144ac0113b7ecfb7c06b Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Wed, 3 Apr 2019 18:39:07 +0000 Subject: [PATCH 0161/1121] bpf: enable access to ax register also from verifier rewrite commit 9b73bfdd08e73231d6a90ae6db4b46b3fbf56c30 upstream. Right now we are using BPF ax register in JIT for constant blinding as well as in interpreter as temporary variable. Verifier will not be able to use it simply because its use will get overridden from the former in bpf_jit_blind_insn(). However, it can be made to work in that blinding will be skipped if there is prior use in either source or destination register on the instruction. Taking constraints of ax into account, the verifier is then open to use it in rewrites under some constraints. Note, ax register already has mappings in every eBPF JIT. Signed-off-by: Daniel Borkmann Acked-by: Alexei Starovoitov Signed-off-by: Alexei Starovoitov [backported to 4.14 sblbir] Signed-off-by: Balbir Singh Signed-off-by: Greg Kroah-Hartman --- include/linux/filter.h | 7 +------ kernel/bpf/core.c | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/include/linux/filter.h b/include/linux/filter.h index f7880c716308..ac2272778f2e 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -46,12 +46,7 @@ struct bpf_prog_aux; #define BPF_REG_X BPF_REG_7 #define BPF_REG_TMP BPF_REG_8 -/* Kernel hidden auxiliary/helper register for hardening step. - * Only used by eBPF JITs. It's nothing more than a temporary - * register that JITs use internally, only that here it's part - * of eBPF instructions that have been rewritten for blinding - * constants. See JIT pre-step in bpf_jit_blind_constants(). - */ +/* Kernel hidden auxiliary/helper register. */ #define BPF_REG_AX MAX_BPF_REG #define MAX_BPF_EXT_REG (MAX_BPF_REG + 1) #define MAX_BPF_JIT_REG MAX_BPF_EXT_REG diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index e59a72c7d092..e46106c6ac39 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -553,6 +553,26 @@ static int bpf_jit_blind_insn(const struct bpf_insn *from, BUILD_BUG_ON(BPF_REG_AX + 1 != MAX_BPF_JIT_REG); BUILD_BUG_ON(MAX_BPF_REG + 1 != MAX_BPF_JIT_REG); + /* Constraints on AX register: + * + * AX register is inaccessible from user space. It is mapped in + * all JITs, and used here for constant blinding rewrites. It is + * typically "stateless" meaning its contents are only valid within + * the executed instruction, but not across several instructions. + * There are a few exceptions however which are further detailed + * below. + * + * Constant blinding is only used by JITs, not in the interpreter. + * The interpreter uses AX in some occasions as a local temporary + * register e.g. in DIV or MOD instructions. + * + * In restricted circumstances, the verifier can also use the AX + * register for rewrites as long as they do not interfere with + * the above cases! + */ + if (from->dst_reg == BPF_REG_AX || from->src_reg == BPF_REG_AX) + goto out; + if (from->imm == 0 && (from->code == (BPF_ALU | BPF_MOV | BPF_K) || from->code == (BPF_ALU64 | BPF_MOV | BPF_K))) { -- GitLab From afb711a6e8d003eead79432c026f6654ae303fcb Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Wed, 3 Apr 2019 18:39:08 +0000 Subject: [PATCH 0162/1121] bpf: restrict map value pointer arithmetic for unprivileged commit 0d6303db7970e6f56ae700fa07e11eb510cda125 upstream. Restrict map value pointer arithmetic for unprivileged users in that arithmetic itself must not go out of bounds as opposed to the actual access later on. Therefore after each adjust_ptr_min_max_vals() with a map value pointer as a destination it will simulate a check_map_access() of 1 byte on the destination and once that fails the program is rejected for unprivileged program loads. We use this later on for masking any pointer arithmetic with the remainder of the map value space. The likelihood of breaking any existing real-world unprivileged eBPF program is very small for this corner case. Signed-off-by: Daniel Borkmann Acked-by: Alexei Starovoitov Signed-off-by: Alexei Starovoitov Signed-off-by: Greg Kroah-Hartman --- kernel/bpf/verifier.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index be0edef26465..096a15a884c9 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -2191,6 +2191,17 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, __update_reg_bounds(dst_reg); __reg_deduce_bounds(dst_reg); __reg_bound_offset(dst_reg); + + /* For unprivileged we require that resulting offset must be in bounds + * in order to be able to sanitize access later on. + */ + if (!env->allow_ptr_leaks && dst_reg->type == PTR_TO_MAP_VALUE && + check_map_access(env, dst, dst_reg->off, 1, false)) { + verbose(env, "R%d pointer arithmetic of map value goes out of range, prohibited for !root\n", + dst); + return -EACCES; + } + return 0; } -- GitLab From ba9d2e0cc870d1a16195c801aa18b33cd70125b9 Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Wed, 3 Apr 2019 18:39:09 +0000 Subject: [PATCH 0163/1121] bpf: restrict stack pointer arithmetic for unprivileged commit e4298d25830a866cc0f427d4bccb858e76715859 upstream. Restrict stack pointer arithmetic for unprivileged users in that arithmetic itself must not go out of bounds as opposed to the actual access later on. Therefore after each adjust_ptr_min_max_vals() with a stack pointer as a destination we simulate a check_stack_access() of 1 byte on the destination and once that fails the program is rejected for unprivileged program loads. This is analog to map value pointer arithmetic and needed for masking later on. Signed-off-by: Daniel Borkmann Acked-by: Alexei Starovoitov Signed-off-by: Alexei Starovoitov [backported to 4.14 sblbir] Signed-off-by: Balbir Singh Signed-off-by: Greg Kroah-Hartman --- kernel/bpf/verifier.c | 62 ++++++++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 096a15a884c9..bc073789b693 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -940,6 +940,31 @@ static int check_stack_read(struct bpf_verifier_state *state, int off, int size, } } +static int check_stack_access(struct bpf_verifier_env *env, + const struct bpf_reg_state *reg, + int off, int size) +{ + /* Stack accesses must be at a fixed offset, so that we + * can determine what type of data were returned. See + * check_stack_read(). + */ + if (!tnum_is_const(reg->var_off)) { + char tn_buf[48]; + + tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off); + verbose("variable stack access var_off=%s off=%d size=%d", + tn_buf, off, size); + return -EACCES; + } + + if (off >= 0 || off < -MAX_BPF_STACK) { + verbose("invalid stack off=%d size=%d\n", off, size); + return -EACCES; + } + + return 0; +} + /* check read/write into map element returned by bpf_map_lookup_elem() */ static int __check_map_access(struct bpf_verifier_env *env, u32 regno, int off, int size) @@ -1322,23 +1347,10 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn } } else if (reg->type == PTR_TO_STACK) { - /* stack accesses must be at a fixed offset, so that we can - * determine what type of data were returned. - * See check_stack_read(). - */ - if (!tnum_is_const(reg->var_off)) { - char tn_buf[48]; - - tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off); - verbose("variable stack access var_off=%s off=%d size=%d", - tn_buf, off, size); - return -EACCES; - } off += reg->var_off.value; - if (off >= 0 || off < -MAX_BPF_STACK) { - verbose("invalid stack off=%d size=%d\n", off, size); - return -EACCES; - } + err = check_stack_access(env, reg, off, size); + if (err) + return err; if (env->prog->aux->stack_depth < -off) env->prog->aux->stack_depth = -off; @@ -2195,11 +2207,19 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, /* For unprivileged we require that resulting offset must be in bounds * in order to be able to sanitize access later on. */ - if (!env->allow_ptr_leaks && dst_reg->type == PTR_TO_MAP_VALUE && - check_map_access(env, dst, dst_reg->off, 1, false)) { - verbose(env, "R%d pointer arithmetic of map value goes out of range, prohibited for !root\n", - dst); - return -EACCES; + if (!env->allow_ptr_leaks) { + if (dst_reg->type == PTR_TO_MAP_VALUE && + check_map_access(env, dst, dst_reg->off, 1)) { + verbose("R%d pointer arithmetic of map value goes out of range, " + "prohibited for !root\n", dst); + return -EACCES; + } else if (dst_reg->type == PTR_TO_STACK && + check_stack_access(env, dst_reg, dst_reg->off + + dst_reg->var_off.value, 1)) { + verbose("R%d stack pointer arithmetic goes out of range, " + "prohibited for !root\n", dst); + return -EACCES; + } } return 0; -- GitLab From 17efa65350c5a251ba7d90a56abc65205a204a03 Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Wed, 3 Apr 2019 18:39:10 +0000 Subject: [PATCH 0164/1121] bpf: restrict unknown scalars of mixed signed bounds for unprivileged commit 9d7eceede769f90b66cfa06ad5b357140d5141ed upstream. For unknown scalars of mixed signed bounds, meaning their smin_value is negative and their smax_value is positive, we need to reject arithmetic with pointer to map value. For unprivileged the goal is to mask every map pointer arithmetic and this cannot reliably be done when it is unknown at verification time whether the scalar value is negative or positive. Given this is a corner case, the likelihood of breaking should be very small. Signed-off-by: Daniel Borkmann Acked-by: Alexei Starovoitov Signed-off-by: Alexei Starovoitov [backported to 4.14 sblbir] Signed-off-by: Balbir Singh Signed-off-by: Greg Kroah-Hartman --- kernel/bpf/verifier.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index bc073789b693..c4b81d15fbc2 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -2014,8 +2014,8 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, smin_ptr = ptr_reg->smin_value, smax_ptr = ptr_reg->smax_value; u64 umin_val = off_reg->umin_value, umax_val = off_reg->umax_value, umin_ptr = ptr_reg->umin_value, umax_ptr = ptr_reg->umax_value; + u32 dst = insn->dst_reg, src = insn->src_reg; u8 opcode = BPF_OP(insn->code); - u32 dst = insn->dst_reg; dst_reg = ®s[dst]; @@ -2189,6 +2189,13 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, verbose("R%d bitwise operator %s on pointer prohibited\n", dst, bpf_alu_string[opcode >> 4]); return -EACCES; + case PTR_TO_MAP_VALUE: + if (!env->allow_ptr_leaks && !known && (smin_val < 0) != (smax_val < 0)) { + verbose("R%d has unknown scalar with mixed signed bounds, pointer arithmetic with it prohibited for !root\n", + off_reg == dst_reg ? dst : src); + return -EACCES; + } + /* fall-through */ default: /* other operators (e.g. MUL,LSH) produce non-pointer results */ if (!env->allow_ptr_leaks) -- GitLab From 4b756d9f7929f035e4e18cfa36124d9ae6b49cdf Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Wed, 3 Apr 2019 18:39:11 +0000 Subject: [PATCH 0165/1121] bpf: fix check_map_access smin_value test when pointer contains offset commit b7137c4eab85c1cf3d46acdde90ce1163b28c873 upstream. In check_map_access() we probe actual bounds through __check_map_access() with offset of reg->smin_value + off for lower bound and offset of reg->umax_value + off for the upper bound. However, even though the reg->smin_value could have a negative value, the final result of the sum with off could be positive when pointer arithmetic with known and unknown scalars is combined. In this case we reject the program with an error such as "R min value is negative, either use unsigned index or do a if (index >=0) check." even though the access itself would be fine. Therefore extend the check to probe whether the actual resulting reg->smin_value + off is less than zero. Signed-off-by: Daniel Borkmann Acked-by: Alexei Starovoitov Signed-off-by: Alexei Starovoitov [backported to 4.14 sblbir] Signed-off-by: Balbir Singh Signed-off-by: Greg Kroah-Hartman --- kernel/bpf/verifier.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index c4b81d15fbc2..6eb24942554c 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -994,13 +994,17 @@ static int check_map_access(struct bpf_verifier_env *env, u32 regno, */ if (log_level) print_verifier_state(state); + /* The minimum value is only important with signed * comparisons where we can't assume the floor of a * value is 0. If we are using signed variables for our * index'es we need to make sure that whatever we use * will have a set floor within our range. */ - if (reg->smin_value < 0) { + if (reg->smin_value < 0 && + (reg->smin_value == S64_MIN || + (off + reg->smin_value != (s64)(s32)(off + reg->smin_value)) || + reg->smin_value + off < 0)) { verbose("R%d min value is negative, either use unsigned index or do a if (index >=0) check.\n", regno); return -EACCES; -- GitLab From ae03b6b1c880a03d4771257336dc3bca156dd51b Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Wed, 3 Apr 2019 18:39:12 +0000 Subject: [PATCH 0166/1121] bpf: prevent out of bounds speculation on pointer arithmetic commit 979d63d50c0c0f7bc537bf821e056cc9fe5abd38 upstream. Jann reported that the original commit back in b2157399cc98 ("bpf: prevent out-of-bounds speculation") was not sufficient to stop CPU from speculating out of bounds memory access: While b2157399cc98 only focussed on masking array map access for unprivileged users for tail calls and data access such that the user provided index gets sanitized from BPF program and syscall side, there is still a more generic form affected from BPF programs that applies to most maps that hold user data in relation to dynamic map access when dealing with unknown scalars or "slow" known scalars as access offset, for example: - Load a map value pointer into R6 - Load an index into R7 - Do a slow computation (e.g. with a memory dependency) that loads a limit into R8 (e.g. load the limit from a map for high latency, then mask it to make the verifier happy) - Exit if R7 >= R8 (mispredicted branch) - Load R0 = R6[R7] - Load R0 = R6[R0] For unknown scalars there are two options in the BPF verifier where we could derive knowledge from in order to guarantee safe access to the memory: i) While /<=/>= variants won't allow to derive any lower or upper bounds from the unknown scalar where it would be safe to add it to the map value pointer, it is possible through ==/!= test however. ii) another option is to transform the unknown scalar into a known scalar, for example, through ALU ops combination such as R &= followed by R |= or any similar combination where the original information from the unknown scalar would be destroyed entirely leaving R with a constant. The initial slow load still precedes the latter ALU ops on that register, so the CPU executes speculatively from that point. Once we have the known scalar, any compare operation would work then. A third option only involving registers with known scalars could be crafted as described in [0] where a CPU port (e.g. Slow Int unit) would be filled with many dependent computations such that the subsequent condition depending on its outcome has to wait for evaluation on its execution port and thereby executing speculatively if the speculated code can be scheduled on a different execution port, or any other form of mistraining as described in [1], for example. Given this is not limited to only unknown scalars, not only map but also stack access is affected since both is accessible for unprivileged users and could potentially be used for out of bounds access under speculation. In order to prevent any of these cases, the verifier is now sanitizing pointer arithmetic on the offset such that any out of bounds speculation would be masked in a way where the pointer arithmetic result in the destination register will stay unchanged, meaning offset masked into zero similar as in array_index_nospec() case. With regards to implementation, there are three options that were considered: i) new insn for sanitation, ii) push/pop insn and sanitation as inlined BPF, iii) reuse of ax register and sanitation as inlined BPF. Option i) has the downside that we end up using from reserved bits in the opcode space, but also that we would require each JIT to emit masking as native arch opcodes meaning mitigation would have slow adoption till everyone implements it eventually which is counter-productive. Option ii) and iii) have both in common that a temporary register is needed in order to implement the sanitation as inlined BPF since we are not allowed to modify the source register. While a push / pop insn in ii) would be useful to have in any case, it requires once again that every JIT needs to implement it first. While possible, amount of changes needed would also be unsuitable for a -stable patch. Therefore, the path which has fewer changes, less BPF instructions for the mitigation and does not require anything to be changed in the JITs is option iii) which this work is pursuing. The ax register is already mapped to a register in all JITs (modulo arm32 where it's mapped to stack as various other BPF registers there) and used in constant blinding for JITs-only so far. It can be reused for verifier rewrites under certain constraints. The interpreter's tmp "register" has therefore been remapped into extending the register set with hidden ax register and reusing that for a number of instructions that needed the prior temporary variable internally (e.g. div, mod). This allows for zero increase in stack space usage in the interpreter, and enables (restricted) generic use in rewrites otherwise as long as such a patchlet does not make use of these instructions. The sanitation mask is dynamic and relative to the offset the map value or stack pointer currently holds. There are various cases that need to be taken under consideration for the masking, e.g. such operation could look as follows: ptr += val or val += ptr or ptr -= val. Thus, the value to be sanitized could reside either in source or in destination register, and the limit is different depending on whether the ALU op is addition or subtraction and depending on the current known and bounded offset. The limit is derived as follows: limit := max_value_size - (smin_value + off). For subtraction: limit := umax_value + off. This holds because we do not allow any pointer arithmetic that would temporarily go out of bounds or would have an unknown value with mixed signed bounds where it is unclear at verification time whether the actual runtime value would be either negative or positive. For example, we have a derived map pointer value with constant offset and bounded one, so limit based on smin_value works because the verifier requires that statically analyzed arithmetic on the pointer must be in bounds, and thus it checks if resulting smin_value + off and umax_value + off is still within map value bounds at time of arithmetic in addition to time of access. Similarly, for the case of stack access we derive the limit as follows: MAX_BPF_STACK + off for subtraction and -off for the case of addition where off := ptr_reg->off + ptr_reg->var_off.value. Subtraction is a special case for the masking which can be in form of ptr += -val, ptr -= -val, or ptr -= val. In the first two cases where we know that the value is negative, we need to temporarily negate the value in order to do the sanitation on a positive value where we later swap the ALU op, and restore original source register if the value was in source. The sanitation of pointer arithmetic alone is still not fully sufficient as is, since a scenario like the following could happen ... PTR += 0x1000 (e.g. K-based imm) PTR -= BIG_NUMBER_WITH_SLOW_COMPARISON PTR += 0x1000 PTR -= BIG_NUMBER_WITH_SLOW_COMPARISON [...] ... which under speculation could end up as ... PTR += 0x1000 PTR -= 0 [ truncated by mitigation ] PTR += 0x1000 PTR -= 0 [ truncated by mitigation ] [...] ... and therefore still access out of bounds. To prevent such case, the verifier is also analyzing safety for potential out of bounds access under speculative execution. Meaning, it is also simulating pointer access under truncation. We therefore "branch off" and push the current verification state after the ALU operation with known 0 to the verification stack for later analysis. Given the current path analysis succeeded it is likely that the one under speculation can be pruned. In any case, it is also subject to existing complexity limits and therefore anything beyond this point will be rejected. In terms of pruning, it needs to be ensured that the verification state from speculative execution simulation must never prune a non-speculative execution path, therefore, we mark verifier state accordingly at the time of push_stack(). If verifier detects out of bounds access under speculative execution from one of the possible paths that includes a truncation, it will reject such program. Given we mask every reg-based pointer arithmetic for unprivileged programs, we've been looking into how it could affect real-world programs in terms of size increase. As the majority of programs are targeted for privileged-only use case, we've unconditionally enabled masking (with its alu restrictions on top of it) for privileged programs for the sake of testing in order to check i) whether they get rejected in its current form, and ii) by how much the number of instructions and size will increase. We've tested this by using Katran, Cilium and test_l4lb from the kernel selftests. For Katran we've evaluated balancer_kern.o, Cilium bpf_lxc.o and an older test object bpf_lxc_opt_-DUNKNOWN.o and l4lb we've used test_l4lb.o as well as test_l4lb_noinline.o. We found that none of the programs got rejected by the verifier with this change, and that impact is rather minimal to none. balancer_kern.o had 13,904 bytes (1,738 insns) xlated and 7,797 bytes JITed before and after the change. Most complex program in bpf_lxc.o had 30,544 bytes (3,817 insns) xlated and 18,538 bytes JITed before and after and none of the other tail call programs in bpf_lxc.o had any changes either. For the older bpf_lxc_opt_-DUNKNOWN.o object we found a small increase from 20,616 bytes (2,576 insns) and 12,536 bytes JITed before to 20,664 bytes (2,582 insns) and 12,558 bytes JITed after the change. Other programs from that object file had similar small increase. Both test_l4lb.o had no change and remained at 6,544 bytes (817 insns) xlated and 3,401 bytes JITed and for test_l4lb_noinline.o constant at 5,080 bytes (634 insns) xlated and 3,313 bytes JITed. This can be explained in that LLVM typically optimizes stack based pointer arithmetic by using K-based operations and that use of dynamic map access is not overly frequent. However, in future we may decide to optimize the algorithm further under known guarantees from branch and value speculation. Latter seems also unclear in terms of prediction heuristics that today's CPUs apply as well as whether there could be collisions in e.g. the predictor's Value History/Pattern Table for triggering out of bounds access, thus masking is performed unconditionally at this point but could be subject to relaxation later on. We were generally also brainstorming various other approaches for mitigation, but the blocker was always lack of available registers at runtime and/or overhead for runtime tracking of limits belonging to a specific pointer. Thus, we found this to be minimally intrusive under given constraints. With that in place, a simple example with sanitized access on unprivileged load at post-verification time looks as follows: # bpftool prog dump xlated id 282 [...] 28: (79) r1 = *(u64 *)(r7 +0) 29: (79) r2 = *(u64 *)(r7 +8) 30: (57) r1 &= 15 31: (79) r3 = *(u64 *)(r0 +4608) 32: (57) r3 &= 1 33: (47) r3 |= 1 34: (2d) if r2 > r3 goto pc+19 35: (b4) (u32) r11 = (u32) 20479 | 36: (1f) r11 -= r2 | Dynamic sanitation for pointer 37: (4f) r11 |= r2 | arithmetic with registers 38: (87) r11 = -r11 | containing bounded or known 39: (c7) r11 s>>= 63 | scalars in order to prevent 40: (5f) r11 &= r2 | out of bounds speculation. 41: (0f) r4 += r11 | 42: (71) r4 = *(u8 *)(r4 +0) 43: (6f) r4 <<= r1 [...] For the case where the scalar sits in the destination register as opposed to the source register, the following code is emitted for the above example: [...] 16: (b4) (u32) r11 = (u32) 20479 17: (1f) r11 -= r2 18: (4f) r11 |= r2 19: (87) r11 = -r11 20: (c7) r11 s>>= 63 21: (5f) r2 &= r11 22: (0f) r2 += r0 23: (61) r0 = *(u32 *)(r2 +0) [...] JIT blinding example with non-conflicting use of r10: [...] d5: je 0x0000000000000106 _ d7: mov 0x0(%rax),%edi | da: mov $0xf153246,%r10d | Index load from map value and e0: xor $0xf153259,%r10 | (const blinded) mask with 0x1f. e7: and %r10,%rdi |_ ea: mov $0x2f,%r10d | f0: sub %rdi,%r10 | Sanitized addition. Both use r10 f3: or %rdi,%r10 | but do not interfere with each f6: neg %r10 | other. (Neither do these instructions f9: sar $0x3f,%r10 | interfere with the use of ax as temp fd: and %r10,%rdi | in interpreter.) 100: add %rax,%rdi |_ 103: mov 0x0(%rdi),%eax [...] Tested that it fixes Jann's reproducer, and also checked that test_verifier and test_progs suite with interpreter, JIT and JIT with hardening enabled on x86-64 and arm64 runs successfully. [0] Speculose: Analyzing the Security Implications of Speculative Execution in CPUs, Giorgi Maisuradze and Christian Rossow, https://arxiv.org/pdf/1801.04084.pdf [1] A Systematic Evaluation of Transient Execution Attacks and Defenses, Claudio Canella, Jo Van Bulck, Michael Schwarz, Moritz Lipp, Benjamin von Berg, Philipp Ortner, Frank Piessens, Dmitry Evtyushkin, Daniel Gruss, https://arxiv.org/pdf/1811.05441.pdf Fixes: b2157399cc98 ("bpf: prevent out-of-bounds speculation") Reported-by: Jann Horn Signed-off-by: Daniel Borkmann Acked-by: Alexei Starovoitov Signed-off-by: Alexei Starovoitov Signed-off-by: Vallish Vaidyeshwara [some checkpatch cleanups and backported to 4.14 by sblbir] Signed-off-by: Balbir Singh Signed-off-by: Greg Kroah-Hartman --- include/linux/bpf_verifier.h | 10 ++ kernel/bpf/verifier.c | 184 +++++++++++++++++++++++++++++++++-- 2 files changed, 188 insertions(+), 6 deletions(-) diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h index 3149a01d0f58..10d85378e690 100644 --- a/include/linux/bpf_verifier.h +++ b/include/linux/bpf_verifier.h @@ -104,6 +104,7 @@ struct bpf_verifier_state { struct bpf_verifier_state *parent; int allocated_stack; struct bpf_stack_state *stack; + bool speculative; }; /* linked list of verifier states used to prune search */ @@ -112,14 +113,23 @@ struct bpf_verifier_state_list { struct bpf_verifier_state_list *next; }; +/* Possible states for alu_state member. */ +#define BPF_ALU_SANITIZE_SRC 1U +#define BPF_ALU_SANITIZE_DST 2U +#define BPF_ALU_NEG_VALUE (1U << 2) +#define BPF_ALU_SANITIZE (BPF_ALU_SANITIZE_SRC | \ + BPF_ALU_SANITIZE_DST) + struct bpf_insn_aux_data { union { enum bpf_reg_type ptr_type; /* pointer type for load/store insns */ struct bpf_map *map_ptr; /* pointer for call insn into lookup_elem */ + u32 alu_limit; /* limit for add/sub register with pointer */ }; int ctx_field_size; /* the ctx field size for load insn, maybe 0 */ int sanitize_stack_off; /* stack slot to be cleared */ bool seen; /* this insn was processed by the verifier */ + u8 alu_state; /* used in combination with alu_limit */ }; #define MAX_USED_MAPS 64 /* max number of maps accessed by one eBPF program */ diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 6eb24942554c..dc4b0607f2c5 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -542,7 +542,8 @@ static int pop_stack(struct bpf_verifier_env *env, int *prev_insn_idx, } static struct bpf_verifier_state *push_stack(struct bpf_verifier_env *env, - int insn_idx, int prev_insn_idx) + int insn_idx, int prev_insn_idx, + bool speculative) { struct bpf_verifier_stack_elem *elem; struct bpf_verifier_state *cur = env->cur_state; @@ -555,6 +556,7 @@ static struct bpf_verifier_state *push_stack(struct bpf_verifier_env *env, elem->insn_idx = insn_idx; elem->prev_insn_idx = prev_insn_idx; elem->next = env->head; + elem->st.speculative |= speculative; env->head = elem; env->stack_size++; err = copy_verifier_state(&elem->st, cur); @@ -2002,6 +2004,102 @@ static bool check_reg_sane_offset(struct bpf_verifier_env *env, return true; } +static struct bpf_insn_aux_data *cur_aux(struct bpf_verifier_env *env) +{ + return &env->insn_aux_data[env->insn_idx]; +} + +static int retrieve_ptr_limit(const struct bpf_reg_state *ptr_reg, + u32 *ptr_limit, u8 opcode, bool off_is_neg) +{ + bool mask_to_left = (opcode == BPF_ADD && off_is_neg) || + (opcode == BPF_SUB && !off_is_neg); + u32 off; + + switch (ptr_reg->type) { + case PTR_TO_STACK: + off = ptr_reg->off + ptr_reg->var_off.value; + if (mask_to_left) + *ptr_limit = MAX_BPF_STACK + off; + else + *ptr_limit = -off; + return 0; + case PTR_TO_MAP_VALUE: + if (mask_to_left) { + *ptr_limit = ptr_reg->umax_value + ptr_reg->off; + } else { + off = ptr_reg->smin_value + ptr_reg->off; + *ptr_limit = ptr_reg->map_ptr->value_size - off; + } + return 0; + default: + return -EINVAL; + } +} + +static int sanitize_ptr_alu(struct bpf_verifier_env *env, + struct bpf_insn *insn, + const struct bpf_reg_state *ptr_reg, + struct bpf_reg_state *dst_reg, + bool off_is_neg) +{ + struct bpf_verifier_state *vstate = env->cur_state; + struct bpf_insn_aux_data *aux = cur_aux(env); + bool ptr_is_dst_reg = ptr_reg == dst_reg; + u8 opcode = BPF_OP(insn->code); + u32 alu_state, alu_limit; + struct bpf_reg_state tmp; + bool ret; + + if (env->allow_ptr_leaks || BPF_SRC(insn->code) == BPF_K) + return 0; + + /* We already marked aux for masking from non-speculative + * paths, thus we got here in the first place. We only care + * to explore bad access from here. + */ + if (vstate->speculative) + goto do_sim; + + alu_state = off_is_neg ? BPF_ALU_NEG_VALUE : 0; + alu_state |= ptr_is_dst_reg ? + BPF_ALU_SANITIZE_SRC : BPF_ALU_SANITIZE_DST; + + if (retrieve_ptr_limit(ptr_reg, &alu_limit, opcode, off_is_neg)) + return 0; + + /* If we arrived here from different branches with different + * limits to sanitize, then this won't work. + */ + if (aux->alu_state && + (aux->alu_state != alu_state || + aux->alu_limit != alu_limit)) + return -EACCES; + + /* Corresponding fixup done in fixup_bpf_calls(). */ + aux->alu_state = alu_state; + aux->alu_limit = alu_limit; + +do_sim: + /* Simulate and find potential out-of-bounds access under + * speculative execution from truncation as a result of + * masking when off was not within expected range. If off + * sits in dst, then we temporarily need to move ptr there + * to simulate dst (== 0) +/-= ptr. Needed, for example, + * for cases where we use K-based arithmetic in one direction + * and truncated reg-based in the other in order to explore + * bad access. + */ + if (!ptr_is_dst_reg) { + tmp = *dst_reg; + *dst_reg = *ptr_reg; + } + ret = push_stack(env, env->insn_idx + 1, env->insn_idx, true); + if (!ptr_is_dst_reg) + *dst_reg = tmp; + return !ret ? -EFAULT : 0; +} + /* Handles arithmetic on a pointer and a scalar: computes new min/max and var_off. * Caller should also handle BPF_MOV case separately. * If we return -EACCES, caller may want to try again treating pointer as a @@ -2020,6 +2118,7 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, umin_ptr = ptr_reg->umin_value, umax_ptr = ptr_reg->umax_value; u32 dst = insn->dst_reg, src = insn->src_reg; u8 opcode = BPF_OP(insn->code); + int ret; dst_reg = ®s[dst]; @@ -2071,6 +2170,11 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, switch (opcode) { case BPF_ADD: + ret = sanitize_ptr_alu(env, insn, ptr_reg, dst_reg, smin_val < 0); + if (ret < 0) { + verbose("R%d tried to add from different maps or paths\n", dst); + return ret; + } /* We can take a fixed offset as long as it doesn't overflow * the s32 'off' field */ @@ -2121,6 +2225,11 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, } break; case BPF_SUB: + ret = sanitize_ptr_alu(env, insn, ptr_reg, dst_reg, smin_val < 0); + if (ret < 0) { + verbose("R%d tried to sub from different maps or paths\n", dst); + return ret; + } if (dst_reg == off_reg) { /* scalar -= pointer. Creates an unknown scalar */ if (!env->allow_ptr_leaks) @@ -3132,7 +3241,8 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env, } } - other_branch = push_stack(env, *insn_idx + insn->off + 1, *insn_idx); + other_branch = push_stack(env, *insn_idx + insn->off + 1, *insn_idx, + false); if (!other_branch) return -EFAULT; @@ -3767,6 +3877,12 @@ static bool states_equal(struct bpf_verifier_env *env, bool ret = false; int i; + /* Verification state from speculative execution simulation + * must never prune a non-speculative execution one. + */ + if (old->speculative && !cur->speculative) + return false; + idmap = kcalloc(ID_MAP_SIZE, sizeof(struct idpair), GFP_KERNEL); /* If we failed to allocate the idmap, just say it's not safe */ if (!idmap) @@ -3970,8 +4086,10 @@ static int do_check(struct bpf_verifier_env *env) /* found equivalent state, can prune the search */ if (log_level) { if (do_print_state) - verbose("\nfrom %d to %d: safe\n", - env->prev_insn_idx, env->insn_idx); + verbose("\nfrom %d to %d%s: safe\n", + env->prev_insn_idx, env->insn_idx, + env->cur_state->speculative ? + " (speculative execution)" : ""); else verbose("%d: safe\n", env->insn_idx); } @@ -3985,8 +4103,10 @@ static int do_check(struct bpf_verifier_env *env) if (log_level > 1) verbose("%d:", env->insn_idx); else - verbose("\nfrom %d to %d:", - env->prev_insn_idx, env->insn_idx); + verbose("\nfrom %d to %d%s:", + env->prev_insn_idx, env->insn_idx, + env->cur_state->speculative ? + " (speculative execution)" : ""); print_verifier_state(env->cur_state); do_print_state = false; } @@ -4585,6 +4705,7 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env) struct bpf_prog *new_prog; struct bpf_map *map_ptr; int i, cnt, delta = 0; + struct bpf_insn_aux_data *aux; for (i = 0; i < insn_cnt; i++, insn++) { if (insn->code == (BPF_ALU | BPF_MOD | BPF_X) || @@ -4605,6 +4726,57 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env) continue; } + if (insn->code == (BPF_ALU64 | BPF_ADD | BPF_X) || + insn->code == (BPF_ALU64 | BPF_SUB | BPF_X)) { + const u8 code_add = BPF_ALU64 | BPF_ADD | BPF_X; + const u8 code_sub = BPF_ALU64 | BPF_SUB | BPF_X; + struct bpf_insn insn_buf[16]; + struct bpf_insn *patch = &insn_buf[0]; + bool issrc, isneg; + u32 off_reg; + + aux = &env->insn_aux_data[i + delta]; + if (!aux->alu_state) + continue; + + isneg = aux->alu_state & BPF_ALU_NEG_VALUE; + issrc = (aux->alu_state & BPF_ALU_SANITIZE) == + BPF_ALU_SANITIZE_SRC; + + off_reg = issrc ? insn->src_reg : insn->dst_reg; + if (isneg) + *patch++ = BPF_ALU64_IMM(BPF_MUL, off_reg, -1); + *patch++ = BPF_MOV32_IMM(BPF_REG_AX, aux->alu_limit - 1); + *patch++ = BPF_ALU64_REG(BPF_SUB, BPF_REG_AX, off_reg); + *patch++ = BPF_ALU64_REG(BPF_OR, BPF_REG_AX, off_reg); + *patch++ = BPF_ALU64_IMM(BPF_NEG, BPF_REG_AX, 0); + *patch++ = BPF_ALU64_IMM(BPF_ARSH, BPF_REG_AX, 63); + if (issrc) { + *patch++ = BPF_ALU64_REG(BPF_AND, BPF_REG_AX, + off_reg); + insn->src_reg = BPF_REG_AX; + } else { + *patch++ = BPF_ALU64_REG(BPF_AND, off_reg, + BPF_REG_AX); + } + if (isneg) + insn->code = insn->code == code_add ? + code_sub : code_add; + *patch++ = *insn; + if (issrc && isneg) + *patch++ = BPF_ALU64_IMM(BPF_MUL, off_reg, -1); + cnt = patch - insn_buf; + + new_prog = bpf_patch_insn_data(env, i + delta, insn_buf, cnt); + if (!new_prog) + return -ENOMEM; + + delta += cnt - 1; + env->prog = prog = new_prog; + insn = new_prog->insnsi + i + delta; + continue; + } + if (insn->code != (BPF_JMP | BPF_CALL)) continue; -- GitLab From 6588a490bfe1b879f11b5e74724ef53a33b68641 Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Wed, 3 Apr 2019 18:39:13 +0000 Subject: [PATCH 0167/1121] bpf: fix sanitation of alu op with pointer / scalar type from different paths commit d3bd7413e0ca40b60cf60d4003246d067cafdeda upstream. While 979d63d50c0c ("bpf: prevent out of bounds speculation on pointer arithmetic") took care of rejecting alu op on pointer when e.g. pointer came from two different map values with different map properties such as value size, Jann reported that a case was not covered yet when a given alu op is used in both "ptr_reg += reg" and "numeric_reg += reg" from different branches where we would incorrectly try to sanitize based on the pointer's limit. Catch this corner case and reject the program instead. Fixes: 979d63d50c0c ("bpf: prevent out of bounds speculation on pointer arithmetic") Reported-by: Jann Horn Signed-off-by: Daniel Borkmann Acked-by: Alexei Starovoitov Signed-off-by: Alexei Starovoitov Signed-off-by: Vallish Vaidyeshwara Signed-off-by: Balbir Singh Signed-off-by: Greg Kroah-Hartman --- include/linux/bpf_verifier.h | 1 + kernel/bpf/verifier.c | 61 ++++++++++++++++++++++++++++-------- 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h index 10d85378e690..d8b3240cfe6e 100644 --- a/include/linux/bpf_verifier.h +++ b/include/linux/bpf_verifier.h @@ -117,6 +117,7 @@ struct bpf_verifier_state_list { #define BPF_ALU_SANITIZE_SRC 1U #define BPF_ALU_SANITIZE_DST 2U #define BPF_ALU_NEG_VALUE (1U << 2) +#define BPF_ALU_NON_POINTER (1U << 3) #define BPF_ALU_SANITIZE (BPF_ALU_SANITIZE_SRC | \ BPF_ALU_SANITIZE_DST) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index dc4b0607f2c5..ec949a4a7d89 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -2037,6 +2037,40 @@ static int retrieve_ptr_limit(const struct bpf_reg_state *ptr_reg, } } +static bool can_skip_alu_sanitation(const struct bpf_verifier_env *env, + const struct bpf_insn *insn) +{ + return env->allow_ptr_leaks || BPF_SRC(insn->code) == BPF_K; +} + +static int update_alu_sanitation_state(struct bpf_insn_aux_data *aux, + u32 alu_state, u32 alu_limit) +{ + /* If we arrived here from different branches with different + * state or limits to sanitize, then this won't work. + */ + if (aux->alu_state && + (aux->alu_state != alu_state || + aux->alu_limit != alu_limit)) + return -EACCES; + + /* Corresponding fixup done in fixup_bpf_calls(). */ + aux->alu_state = alu_state; + aux->alu_limit = alu_limit; + return 0; +} + +static int sanitize_val_alu(struct bpf_verifier_env *env, + struct bpf_insn *insn) +{ + struct bpf_insn_aux_data *aux = cur_aux(env); + + if (can_skip_alu_sanitation(env, insn)) + return 0; + + return update_alu_sanitation_state(aux, BPF_ALU_NON_POINTER, 0); +} + static int sanitize_ptr_alu(struct bpf_verifier_env *env, struct bpf_insn *insn, const struct bpf_reg_state *ptr_reg, @@ -2051,7 +2085,7 @@ static int sanitize_ptr_alu(struct bpf_verifier_env *env, struct bpf_reg_state tmp; bool ret; - if (env->allow_ptr_leaks || BPF_SRC(insn->code) == BPF_K) + if (can_skip_alu_sanitation(env, insn)) return 0; /* We already marked aux for masking from non-speculative @@ -2067,19 +2101,8 @@ static int sanitize_ptr_alu(struct bpf_verifier_env *env, if (retrieve_ptr_limit(ptr_reg, &alu_limit, opcode, off_is_neg)) return 0; - - /* If we arrived here from different branches with different - * limits to sanitize, then this won't work. - */ - if (aux->alu_state && - (aux->alu_state != alu_state || - aux->alu_limit != alu_limit)) + if (update_alu_sanitation_state(aux, alu_state, alu_limit)) return -EACCES; - - /* Corresponding fixup done in fixup_bpf_calls(). */ - aux->alu_state = alu_state; - aux->alu_limit = alu_limit; - do_sim: /* Simulate and find potential out-of-bounds access under * speculative execution from truncation as a result of @@ -2360,6 +2383,8 @@ static int adjust_scalar_min_max_vals(struct bpf_verifier_env *env, s64 smin_val, smax_val; u64 umin_val, umax_val; u64 insn_bitness = (BPF_CLASS(insn->code) == BPF_ALU64) ? 64 : 32; + u32 dst = insn->dst_reg; + int ret; if (insn_bitness == 32) { /* Relevant for 32-bit RSH: Information can propagate towards @@ -2394,6 +2419,11 @@ static int adjust_scalar_min_max_vals(struct bpf_verifier_env *env, switch (opcode) { case BPF_ADD: + ret = sanitize_val_alu(env, insn); + if (ret < 0) { + verbose("R%d tried to add from different pointers or scalars\n", dst); + return ret; + } if (signed_add_overflows(dst_reg->smin_value, smin_val) || signed_add_overflows(dst_reg->smax_value, smax_val)) { dst_reg->smin_value = S64_MIN; @@ -2413,6 +2443,11 @@ static int adjust_scalar_min_max_vals(struct bpf_verifier_env *env, dst_reg->var_off = tnum_add(dst_reg->var_off, src_reg.var_off); break; case BPF_SUB: + ret = sanitize_val_alu(env, insn); + if (ret < 0) { + verbose("R%d tried to sub from different pointers or scalars\n", dst); + return ret; + } if (signed_sub_overflows(dst_reg->smin_value, smax_val) || signed_sub_overflows(dst_reg->smax_value, smin_val)) { /* Overflow possible, we know nothing */ -- GitLab From 0ed998d17cd421da18334745af7aee246abe4c70 Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Wed, 3 Apr 2019 18:39:14 +0000 Subject: [PATCH 0168/1121] bpf: fix inner map masking to prevent oob under speculation commit 9d5564ddcf2a0f5ba3fa1c3a1f8a1b59ad309553 upstream. During review I noticed that inner meta map setup for map in map is buggy in that it does not propagate all needed data from the reference map which the verifier is later accessing. In particular one such case is index masking to prevent out of bounds access under speculative execution due to missing the map's unpriv_array/index_mask field propagation. Fix this such that the verifier is generating the correct code for inlined lookups in case of unpriviledged use. Before patch (test_verifier's 'map in map access' dump): # bpftool prog dump xla id 3 0: (62) *(u32 *)(r10 -4) = 0 1: (bf) r2 = r10 2: (07) r2 += -4 3: (18) r1 = map[id:4] 5: (07) r1 += 272 | 6: (61) r0 = *(u32 *)(r2 +0) | 7: (35) if r0 >= 0x1 goto pc+6 | Inlined map in map lookup 8: (54) (u32) r0 &= (u32) 0 | with index masking for 9: (67) r0 <<= 3 | map->unpriv_array. 10: (0f) r0 += r1 | 11: (79) r0 = *(u64 *)(r0 +0) | 12: (15) if r0 == 0x0 goto pc+1 | 13: (05) goto pc+1 | 14: (b7) r0 = 0 | 15: (15) if r0 == 0x0 goto pc+11 16: (62) *(u32 *)(r10 -4) = 0 17: (bf) r2 = r10 18: (07) r2 += -4 19: (bf) r1 = r0 20: (07) r1 += 272 | 21: (61) r0 = *(u32 *)(r2 +0) | Index masking missing (!) 22: (35) if r0 >= 0x1 goto pc+3 | for inner map despite 23: (67) r0 <<= 3 | map->unpriv_array set. 24: (0f) r0 += r1 | 25: (05) goto pc+1 | 26: (b7) r0 = 0 | 27: (b7) r0 = 0 28: (95) exit After patch: # bpftool prog dump xla id 1 0: (62) *(u32 *)(r10 -4) = 0 1: (bf) r2 = r10 2: (07) r2 += -4 3: (18) r1 = map[id:2] 5: (07) r1 += 272 | 6: (61) r0 = *(u32 *)(r2 +0) | 7: (35) if r0 >= 0x1 goto pc+6 | Same inlined map in map lookup 8: (54) (u32) r0 &= (u32) 0 | with index masking due to 9: (67) r0 <<= 3 | map->unpriv_array. 10: (0f) r0 += r1 | 11: (79) r0 = *(u64 *)(r0 +0) | 12: (15) if r0 == 0x0 goto pc+1 | 13: (05) goto pc+1 | 14: (b7) r0 = 0 | 15: (15) if r0 == 0x0 goto pc+12 16: (62) *(u32 *)(r10 -4) = 0 17: (bf) r2 = r10 18: (07) r2 += -4 19: (bf) r1 = r0 20: (07) r1 += 272 | 21: (61) r0 = *(u32 *)(r2 +0) | 22: (35) if r0 >= 0x1 goto pc+4 | Now fixed inlined inner map 23: (54) (u32) r0 &= (u32) 0 | lookup with proper index masking 24: (67) r0 <<= 3 | for map->unpriv_array. 25: (0f) r0 += r1 | 26: (05) goto pc+1 | 27: (b7) r0 = 0 | 28: (b7) r0 = 0 29: (95) exit Fixes: b2157399cc98 ("bpf: prevent out-of-bounds speculation") Signed-off-by: Daniel Borkmann Acked-by: Martin KaFai Lau Signed-off-by: Alexei Starovoitov Signed-off-by: Vallish Vaidyeshwara Signed-off-by: Balbir Singh Signed-off-by: Greg Kroah-Hartman --- kernel/bpf/map_in_map.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/kernel/bpf/map_in_map.c b/kernel/bpf/map_in_map.c index 1da574612bea..c0c494b7647b 100644 --- a/kernel/bpf/map_in_map.c +++ b/kernel/bpf/map_in_map.c @@ -12,6 +12,7 @@ struct bpf_map *bpf_map_meta_alloc(int inner_map_ufd) { struct bpf_map *inner_map, *inner_map_meta; + u32 inner_map_meta_size; struct fd f; f = fdget(inner_map_ufd); @@ -34,7 +35,12 @@ struct bpf_map *bpf_map_meta_alloc(int inner_map_ufd) return ERR_PTR(-EINVAL); } - inner_map_meta = kzalloc(sizeof(*inner_map_meta), GFP_USER); + inner_map_meta_size = sizeof(*inner_map_meta); + /* In some cases verifier needs to access beyond just base map. */ + if (inner_map->ops == &array_map_ops) + inner_map_meta_size = sizeof(struct bpf_array); + + inner_map_meta = kzalloc(inner_map_meta_size, GFP_USER); if (!inner_map_meta) { fdput(f); return ERR_PTR(-ENOMEM); @@ -44,9 +50,16 @@ struct bpf_map *bpf_map_meta_alloc(int inner_map_ufd) inner_map_meta->key_size = inner_map->key_size; inner_map_meta->value_size = inner_map->value_size; inner_map_meta->map_flags = inner_map->map_flags; - inner_map_meta->ops = inner_map->ops; inner_map_meta->max_entries = inner_map->max_entries; + /* Misc members not needed in bpf_map_meta_equal() check. */ + inner_map_meta->ops = inner_map->ops; + if (inner_map->ops == &array_map_ops) { + inner_map_meta->unpriv_array = inner_map->unpriv_array; + container_of(inner_map_meta, struct bpf_array, map)->index_mask = + container_of(inner_map, struct bpf_array, map)->index_mask; + } + fdput(f); return inner_map_meta; } -- GitLab From 12462c88e6e281cd136ae7c93e85fadfcf20722f Mon Sep 17 00:00:00 2001 From: Xu Yu Date: Wed, 3 Apr 2019 18:39:15 +0000 Subject: [PATCH 0169/1121] bpf: do not restore dst_reg when cur_state is freed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 0803278b0b4d8eeb2b461fb698785df65a725d9e upstream. Syzkaller hit 'KASAN: use-after-free Write in sanitize_ptr_alu' bug. Call trace: dump_stack+0xbf/0x12e print_address_description+0x6a/0x280 kasan_report+0x237/0x360 sanitize_ptr_alu+0x85a/0x8d0 adjust_ptr_min_max_vals+0x8f2/0x1ca0 adjust_reg_min_max_vals+0x8ed/0x22e0 do_check+0x1ca6/0x5d00 bpf_check+0x9ca/0x2570 bpf_prog_load+0xc91/0x1030 __se_sys_bpf+0x61e/0x1f00 do_syscall_64+0xc8/0x550 entry_SYSCALL_64_after_hwframe+0x49/0xbe Fault injection trace:  kfree+0xea/0x290  free_func_state+0x4a/0x60  free_verifier_state+0x61/0xe0  push_stack+0x216/0x2f0 <- inject failslab  sanitize_ptr_alu+0x2b1/0x8d0  adjust_ptr_min_max_vals+0x8f2/0x1ca0  adjust_reg_min_max_vals+0x8ed/0x22e0  do_check+0x1ca6/0x5d00  bpf_check+0x9ca/0x2570  bpf_prog_load+0xc91/0x1030  __se_sys_bpf+0x61e/0x1f00  do_syscall_64+0xc8/0x550  entry_SYSCALL_64_after_hwframe+0x49/0xbe When kzalloc() fails in push_stack(), free_verifier_state() will free current verifier state. As push_stack() returns, dst_reg was restored if ptr_is_dst_reg is false. However, as member of the cur_state, dst_reg is also freed, and error occurs when dereferencing dst_reg. Simply fix it by testing ret of push_stack() before restoring dst_reg. Fixes: 979d63d50c0c ("bpf: prevent out of bounds speculation on pointer arithmetic") Signed-off-by: Xu Yu Signed-off-by: Daniel Borkmann Signed-off-by: Greg Kroah-Hartman --- kernel/bpf/verifier.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index ec949a4a7d89..87b1293f20d6 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -2118,7 +2118,7 @@ static int sanitize_ptr_alu(struct bpf_verifier_env *env, *dst_reg = *ptr_reg; } ret = push_stack(env, env->insn_idx + 1, env->insn_idx, true); - if (!ptr_is_dst_reg) + if (!ptr_is_dst_reg && ret) *dst_reg = tmp; return !ret ? -EFAULT : 0; } -- GitLab From a042c21a2341979614a2b48d1ec46de5301d3f78 Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Wed, 3 Apr 2019 18:39:16 +0000 Subject: [PATCH 0170/1121] bpf: fix sanitation rewrite in case of non-pointers commit 3612af783cf52c74a031a2f11b82247b2599d3cd upstream. Marek reported that he saw an issue with the below snippet in that timing measurements where off when loaded as unpriv while results were reasonable when loaded as privileged: [...] uint64_t a = bpf_ktime_get_ns(); uint64_t b = bpf_ktime_get_ns(); uint64_t delta = b - a; if ((int64_t)delta > 0) { [...] Turns out there is a bug where a corner case is missing in the fix d3bd7413e0ca ("bpf: fix sanitation of alu op with pointer / scalar type from different paths"), namely fixup_bpf_calls() only checks whether aux has a non-zero alu_state, but it also needs to test for the case of BPF_ALU_NON_POINTER since in both occasions we need to skip the masking rewrite (as there is nothing to mask). Fixes: d3bd7413e0ca ("bpf: fix sanitation of alu op with pointer / scalar type from different paths") Reported-by: Marek Majkowski Reported-by: Arthur Fabre Signed-off-by: Daniel Borkmann Link: https://lore.kernel.org/netdev/CAJPywTJqP34cK20iLM5YmUMz9KXQOdu1-+BZrGMAGgLuBWz7fg@mail.gmail.com/T/ Acked-by: Song Liu Signed-off-by: Alexei Starovoitov Signed-off-by: Balbir Singh Signed-off-by: Greg Kroah-Hartman --- kernel/bpf/verifier.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 87b1293f20d6..a4875ff0bab1 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -4771,7 +4771,8 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env) u32 off_reg; aux = &env->insn_aux_data[i + delta]; - if (!aux->alu_state) + if (!aux->alu_state || + aux->alu_state == BPF_ALU_NON_POINTER) continue; isneg = aux->alu_state & BPF_ALU_NEG_VALUE; -- GitLab From 03f11a51a196a9aadc20a70a73825a811a726218 Mon Sep 17 00:00:00 2001 From: Balbir Singh Date: Wed, 3 Apr 2019 18:39:17 +0000 Subject: [PATCH 0171/1121] bpf: Fix selftests are changes for CVE 2019-7308 The changes to fix the CVE 2019-7308 make the bpf verifier stricter with respect to operations that were allowed earlier in unprivileged mode. Fixup the test cases so that the error messages now correctly reflect pointer arithmetic going out of range for tests. Signed-off-by: Balbir Singh Signed-off-by: Greg Kroah-Hartman --- tools/testing/selftests/bpf/test_verifier.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c index a0591d06c61b..913539aea645 100644 --- a/tools/testing/selftests/bpf/test_verifier.c +++ b/tools/testing/selftests/bpf/test_verifier.c @@ -1860,6 +1860,7 @@ static struct bpf_test tests[] = { }, .result = REJECT, .errstr = "invalid stack off=-79992 size=8", + .errstr_unpriv = "R1 stack pointer arithmetic goes out of range", }, { "PTR_TO_STACK store/load - out of bounds high", @@ -2243,6 +2244,8 @@ static struct bpf_test tests[] = { BPF_EXIT_INSN(), }, .result = ACCEPT, + .result_unpriv = REJECT, + .errstr_unpriv = "R1 stack pointer arithmetic goes out of range", }, { "unpriv: cmp of stack pointer", @@ -7013,6 +7016,7 @@ static struct bpf_test tests[] = { }, .fixup_map1 = { 3 }, .errstr = "pointer offset 1073741822", + .errstr_unpriv = "R0 pointer arithmetic of map value goes out of range", .result = REJECT }, { @@ -7034,6 +7038,7 @@ static struct bpf_test tests[] = { }, .fixup_map1 = { 3 }, .errstr = "pointer offset -1073741822", + .errstr_unpriv = "R0 pointer arithmetic of map value goes out of range", .result = REJECT }, { @@ -7203,6 +7208,7 @@ static struct bpf_test tests[] = { BPF_EXIT_INSN() }, .errstr = "fp pointer offset 1073741822", + .errstr_unpriv = "R1 stack pointer arithmetic goes out of range", .result = REJECT }, { -- GitLab From 5661213956662f592979925eab1e4dfff955ba05 Mon Sep 17 00:00:00 2001 From: Lars Persson Date: Mon, 15 Apr 2019 09:49:47 +0200 Subject: [PATCH 0172/1121] net: stmmac: Set dma ring length before enabling the DMA This was fixed in upstream by commit 7d9e6c5afab6 ("net: stmmac: Integrate XGMAC into main driver flow") that is a new feature commit. We found a race condition in the DMA init sequence that hits if the PHY already has link up during stmmac_hw_setup. Since the ring length was programmed after enabling the RX path, we might receive a packet before the correct ring length is programmed. When that happened we could not get reliable interrupts for DMA RX and the MTL complained about RX FIFO overrun. Signed-off-by: Lars Persson Cc: stable@vger.kernel.org # 4.14.x Cc: Giuseppe Cavallaro Cc: Alexandre Torgue Cc: Jose Abreu Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 4a9dbee6f054..f2429ec07b57 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -2536,9 +2536,6 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp) netdev_warn(priv->dev, "%s: failed debugFS registration\n", __func__); #endif - /* Start the ball rolling... */ - stmmac_start_all_dma(priv); - priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS; if ((priv->use_riwt) && (priv->hw->dma->rx_watchdog)) { @@ -2558,6 +2555,9 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp) priv->hw->dma->enable_tso(priv->ioaddr, 1, chan); } + /* Start the ball rolling... */ + stmmac_start_all_dma(priv); + return 0; } -- GitLab From 1e4bc57ecf60a1240e4cee2c048dedd1a10d4e32 Mon Sep 17 00:00:00 2001 From: Konstantin Khlebnikov Date: Tue, 9 Apr 2019 20:05:43 +0300 Subject: [PATCH 0173/1121] mm: hide incomplete nr_indirectly_reclaimable in sysfs In upstream branch this fixed by commit b29940c1abd7 ("mm: rename and change semantics of nr_indirectly_reclaimable_bytes"). This fixes /sys/devices/system/node/node*/vmstat format: ... nr_dirtied 6613155 nr_written 5796802 11089216 ... Cc: # 4.19.y Fixes: 7aaf77272358 ("mm: don't show nr_indirectly_reclaimable in /proc/vmstat") Signed-off-by: Konstantin Khlebnikov Cc: Roman Gushchin Cc: Vlastimil Babka Signed-off-by: Greg Kroah-Hartman --- drivers/base/node.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/base/node.c b/drivers/base/node.c index ee090ab9171c..5c39f14d15a5 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -197,11 +197,16 @@ static ssize_t node_read_vmstat(struct device *dev, sum_zone_numa_state(nid, i)); #endif - for (i = 0; i < NR_VM_NODE_STAT_ITEMS; i++) + for (i = 0; i < NR_VM_NODE_STAT_ITEMS; i++) { + /* Skip hidden vmstat items. */ + if (*vmstat_text[i + NR_VM_ZONE_STAT_ITEMS + + NR_VM_NUMA_STAT_ITEMS] == '\0') + continue; n += sprintf(buf+n, "%s %lu\n", vmstat_text[i + NR_VM_ZONE_STAT_ITEMS + NR_VM_NUMA_STAT_ITEMS], node_page_state(pgdat, i)); + } return n; } -- GitLab From 76da4272779ab127acdaa9f4aa799cd7e90a8b3f Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 6 Mar 2019 11:52:36 +0100 Subject: [PATCH 0174/1121] appletalk: Fix compile regression [ Upstream commit 27da0d2ef998e222a876c0cec72aa7829a626266 ] A bugfix just broke compilation of appletalk when CONFIG_SYSCTL is disabled: In file included from net/appletalk/ddp.c:65: net/appletalk/ddp.c: In function 'atalk_init': include/linux/atalk.h:164:34: error: expected expression before 'do' #define atalk_register_sysctl() do { } while(0) ^~ net/appletalk/ddp.c:1934:7: note: in expansion of macro 'atalk_register_sysctl' rc = atalk_register_sysctl(); This is easier to avoid by using conventional inline functions as stubs rather than macros. The header already has inline functions for other purposes, so I'm changing over all the macros for consistency. Fixes: 6377f787aeb9 ("appletalk: Fix use-after-free in atalk_proc_exit") Signed-off-by: Arnd Bergmann Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- include/linux/atalk.h | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/include/linux/atalk.h b/include/linux/atalk.h index 212eb8c7fed6..03885e63f92b 100644 --- a/include/linux/atalk.h +++ b/include/linux/atalk.h @@ -154,16 +154,26 @@ extern int sysctl_aarp_resolve_time; extern int atalk_register_sysctl(void); extern void atalk_unregister_sysctl(void); #else -#define atalk_register_sysctl() do { } while(0) -#define atalk_unregister_sysctl() do { } while(0) +static inline int atalk_register_sysctl(void) +{ + return 0; +} +static inline void atalk_unregister_sysctl(void) +{ +} #endif #ifdef CONFIG_PROC_FS extern int atalk_proc_init(void); extern void atalk_proc_exit(void); #else -#define atalk_proc_init() ({ 0; }) -#define atalk_proc_exit() do { } while(0) +static inline int atalk_proc_init(void) +{ + return 0; +} +static inline void atalk_proc_exit(void) +{ +} #endif /* CONFIG_PROC_FS */ #endif /* __LINUX_ATALK_H__ */ -- GitLab From 68d7a45eec101bc1550294c0e675a490c047b2e5 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 20 Apr 2019 09:15:10 +0200 Subject: [PATCH 0175/1121] Linux 4.14.113 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 94673d2a6a27..fcfef30ca9a6 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 4 PATCHLEVEL = 14 -SUBLEVEL = 112 +SUBLEVEL = 113 EXTRAVERSION = NAME = Petit Gorille -- GitLab From ffa22221c473de4515597913892b620e674c059b Mon Sep 17 00:00:00 2001 From: Alistair Strachan Date: Fri, 19 Apr 2019 18:00:50 -0700 Subject: [PATCH 0176/1121] ANDROID: cuttlefish_defconfig: Enable CONFIG_XFRM_STATISTICS Bug: 120439617 Change-Id: Icc7203b504864997dee8b42470c47037c6b87576 Signed-off-by: Alistair Strachan --- arch/arm64/configs/cuttlefish_defconfig | 1 + arch/x86/configs/x86_64_cuttlefish_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig index 6f1beae135b0..2c161483bd4a 100644 --- a/arch/arm64/configs/cuttlefish_defconfig +++ b/arch/arm64/configs/cuttlefish_defconfig @@ -81,6 +81,7 @@ CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM_USER=y CONFIG_XFRM_INTERFACE=y +CONFIG_XFRM_STATISTICS=y CONFIG_NET_KEY=y CONFIG_INET=y CONFIG_IP_MULTICAST=y diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig index 99e766f8dac3..2960fa16be1b 100644 --- a/arch/x86/configs/x86_64_cuttlefish_defconfig +++ b/arch/x86/configs/x86_64_cuttlefish_defconfig @@ -82,6 +82,7 @@ CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM_USER=y CONFIG_XFRM_INTERFACE=y +CONFIG_XFRM_STATISTICS=y CONFIG_NET_KEY=y CONFIG_INET=y CONFIG_IP_MULTICAST=y -- GitLab From a1b3ec23f8884a77cd2def23ace3904d1e2d8788 Mon Sep 17 00:00:00 2001 From: Sabrina Dubroca Date: Fri, 12 Apr 2019 15:04:10 +0200 Subject: [PATCH 0177/1121] bonding: fix event handling for stacked bonds [ Upstream commit 92480b3977fd3884649d404cbbaf839b70035699 ] When a bond is enslaved to another bond, bond_netdev_event() only handles the event as if the bond is a master, and skips treating the bond as a slave. This leads to a refcount leak on the slave, since we don't remove the adjacency to its master and the master holds a reference on the slave. Reproducer: ip link add bondL type bond ip link add bondU type bond ip link set bondL master bondU ip link del bondL No "Fixes:" tag, this code is older than git history. Signed-off-by: Sabrina Dubroca Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/bonding/bond_main.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 99e60bb5fe07..1edd4ff5382c 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -3169,8 +3169,12 @@ static int bond_netdev_event(struct notifier_block *this, return NOTIFY_DONE; if (event_dev->flags & IFF_MASTER) { + int ret; + netdev_dbg(event_dev, "IFF_MASTER\n"); - return bond_master_netdev_event(event, event_dev); + ret = bond_master_netdev_event(event, event_dev); + if (ret != NOTIFY_DONE) + return ret; } if (event_dev->flags & IFF_SLAVE) { -- GitLab From 9fac50c39253b6bef74c2cfc2244a93c4d5a0896 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Mon, 15 Apr 2019 15:57:23 -0500 Subject: [PATCH 0178/1121] net: atm: Fix potential Spectre v1 vulnerabilities [ Upstream commit 899537b73557aafbdd11050b501cf54b4f5c45af ] arg is controlled by user-space, hence leading to a potential exploitation of the Spectre variant 1 vulnerability. This issue was detected with the help of Smatch: net/atm/lec.c:715 lec_mcast_attach() warn: potential spectre issue 'dev_lec' [r] (local cap) Fix this by sanitizing arg before using it to index dev_lec. Notice that given that speculation windows are large, the policy is to kill the speculation on the first load and not worry if it can be completed with a dependent load/store [1]. [1] https://lore.kernel.org/lkml/20180423164740.GY17484@dhcp22.suse.cz/ Signed-off-by: Gustavo A. R. Silva Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/atm/lec.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/net/atm/lec.c b/net/atm/lec.c index 9f2365694ad4..85ce89c8a35c 100644 --- a/net/atm/lec.c +++ b/net/atm/lec.c @@ -710,7 +710,10 @@ static int lec_vcc_attach(struct atm_vcc *vcc, void __user *arg) static int lec_mcast_attach(struct atm_vcc *vcc, int arg) { - if (arg < 0 || arg >= MAX_LEC_ITF || !dev_lec[arg]) + if (arg < 0 || arg >= MAX_LEC_ITF) + return -EINVAL; + arg = array_index_nospec(arg, MAX_LEC_ITF); + if (!dev_lec[arg]) return -EINVAL; vcc->proto_data = dev_lec[arg]; return lec_mcast_make(netdev_priv(dev_lec[arg]), vcc); @@ -728,6 +731,7 @@ static int lecd_attach(struct atm_vcc *vcc, int arg) i = arg; if (arg >= MAX_LEC_ITF) return -EINVAL; + i = array_index_nospec(arg, MAX_LEC_ITF); if (!dev_lec[i]) { int size; -- GitLab From a1a9b69e2605db1edea34bb3a6051cf845b26bc1 Mon Sep 17 00:00:00 2001 From: Nikolay Aleksandrov Date: Thu, 11 Apr 2019 13:56:39 +0300 Subject: [PATCH 0179/1121] net: bridge: fix per-port af_packet sockets [ Upstream commit 3b2e2904deb314cc77a2192f506f2fd44e3d10d0 ] When the commit below was introduced it changed two visible things: - the skb was no longer passed through the protocol handlers with the original device - the skb was passed up the stack with skb->dev = bridge The first change broke af_packet sockets on bridge ports. For example we use them for hostapd which listens for ETH_P_PAE packets on the ports. We discussed two possible fixes: - create a clone and pass it through NF_HOOK(), act on the original skb based on the result - somehow signal to the caller from the okfn() that it was called, meaning the skb is ok to be passed, which this patch is trying to implement via returning 1 from the bridge link-local okfn() Note that we rely on the fact that NF_QUEUE/STOLEN would return 0 and drop/error would return < 0 thus the okfn() is called only when the return was 1, so we signal to the caller that it was called by preserving the return value from nf_hook(). Fixes: 8626c56c8279 ("bridge: fix potential use-after-free when hook returns QUEUE or STOLEN verdict") Signed-off-by: Nikolay Aleksandrov Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/bridge/br_input.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 7637f58c1226..10fa84056cb5 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c @@ -236,13 +236,10 @@ static void __br_handle_local_finish(struct sk_buff *skb) /* note: already called with rcu_read_lock */ static int br_handle_local_finish(struct net *net, struct sock *sk, struct sk_buff *skb) { - struct net_bridge_port *p = br_port_get_rcu(skb->dev); - __br_handle_local_finish(skb); - BR_INPUT_SKB_CB(skb)->brdev = p->br->dev; - br_pass_frame_up(skb); - return 0; + /* return 1 to signal the okfn() was called so it's ok to use the skb */ + return 1; } /* @@ -318,10 +315,18 @@ rx_handler_result_t br_handle_frame(struct sk_buff **pskb) goto forward; } - /* Deliver packet to local host only */ - NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, dev_net(skb->dev), - NULL, skb, skb->dev, NULL, br_handle_local_finish); - return RX_HANDLER_CONSUMED; + /* The else clause should be hit when nf_hook(): + * - returns < 0 (drop/error) + * - returns = 0 (stolen/nf_queue) + * Thus return 1 from the okfn() to signal the skb is ok to pass + */ + if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, + dev_net(skb->dev), NULL, skb, skb->dev, NULL, + br_handle_local_finish) == 1) { + return RX_HANDLER_PASS; + } else { + return RX_HANDLER_CONSUMED; + } } forward: -- GitLab From c1e7e01e2edb90678e26f100fae0dc50024d139b Mon Sep 17 00:00:00 2001 From: Nikolay Aleksandrov Date: Thu, 11 Apr 2019 15:08:25 +0300 Subject: [PATCH 0180/1121] net: bridge: multicast: use rcu to access port list from br_multicast_start_querier [ Upstream commit c5b493ce192bd7a4e7bd073b5685aad121eeef82 ] br_multicast_start_querier() walks over the port list but it can be called from a timer with only multicast_lock held which doesn't protect the port list, so use RCU to walk over it. Fixes: c83b8fab06fc ("bridge: Restart queries when last querier expires") Signed-off-by: Nikolay Aleksandrov Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/bridge/br_multicast.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 8dc5c8d69bcd..e83048cb53ce 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -2119,7 +2119,8 @@ static void br_multicast_start_querier(struct net_bridge *br, __br_multicast_open(br, query); - list_for_each_entry(port, &br->port_list, list) { + rcu_read_lock(); + list_for_each_entry_rcu(port, &br->port_list, list) { if (port->state == BR_STATE_DISABLED || port->state == BR_STATE_BLOCKING) continue; @@ -2131,6 +2132,7 @@ static void br_multicast_start_querier(struct net_bridge *br, br_multicast_enable(&port->ip6_own_query); #endif } + rcu_read_unlock(); } int br_multicast_toggle(struct net_bridge *br, unsigned long val) -- GitLab From 8835f1c7d0fb0faf6df93c1715f13b9ef04a9e99 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Tue, 9 Apr 2019 11:47:20 +0200 Subject: [PATCH 0181/1121] net: fou: do not use guehdr after iptunnel_pull_offloads in gue_udp_recv [ Upstream commit 988dc4a9a3b66be75b30405a5494faf0dc7cffb6 ] gue tunnels run iptunnel_pull_offloads on received skbs. This can determine a possible use-after-free accessing guehdr pointer since the packet will be 'uncloned' running pskb_expand_head if it is a cloned gso skb (e.g if the packet has been sent though a veth device) Fixes: a09a4c8dd1ec ("tunnels: Remove encapsulation offloads on decap") Signed-off-by: Lorenzo Bianconi Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/ipv4/fou.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/ipv4/fou.c b/net/ipv4/fou.c index c9ec1603666b..665f11d7388e 100644 --- a/net/ipv4/fou.c +++ b/net/ipv4/fou.c @@ -120,6 +120,7 @@ static int gue_udp_recv(struct sock *sk, struct sk_buff *skb) struct guehdr *guehdr; void *data; u16 doffset = 0; + u8 proto_ctype; if (!fou) return 1; @@ -211,13 +212,14 @@ static int gue_udp_recv(struct sock *sk, struct sk_buff *skb) if (unlikely(guehdr->control)) return gue_control_message(skb, guehdr); + proto_ctype = guehdr->proto_ctype; __skb_pull(skb, sizeof(struct udphdr) + hdrlen); skb_reset_transport_header(skb); if (iptunnel_pull_offloads(skb)) goto drop; - return -guehdr->proto_ctype; + return -proto_ctype; drop: kfree_skb(skb); -- GitLab From 07b1747f11af7cb3ed0903cd8bf3b5a382452ec4 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 16 Apr 2019 10:55:20 -0700 Subject: [PATCH 0182/1121] tcp: tcp_grow_window() needs to respect tcp_space() [ Upstream commit 50ce163a72d817a99e8974222dcf2886d5deb1ae ] For some reason, tcp_grow_window() correctly tests if enough room is present before attempting to increase tp->rcv_ssthresh, but does not prevent it to grow past tcp_space() This is causing hard to debug issues, like failing the (__tcp_select_window(sk) >= tp->rcv_wnd) test in __tcp_ack_snd_check(), causing ACK delays and possibly slow flows. Depending on tcp_rmem[2], MTU, skb->len/skb->truesize ratio, we can see the problem happening on "netperf -t TCP_RR -- -r 2000,2000" after about 60 round trips, when the active side no longer sends immediate acks. This bug predates git history. Signed-off-by: Eric Dumazet Acked-by: Soheil Hassas Yeganeh Acked-by: Neal Cardwell Acked-by: Wei Wang Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/ipv4/tcp_input.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index c8227e07d574..657d33e2ff6a 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -389,11 +389,12 @@ static int __tcp_grow_window(const struct sock *sk, const struct sk_buff *skb) static void tcp_grow_window(struct sock *sk, const struct sk_buff *skb) { struct tcp_sock *tp = tcp_sk(sk); + int room; + + room = min_t(int, tp->window_clamp, tcp_space(sk)) - tp->rcv_ssthresh; /* Check #1 */ - if (tp->rcv_ssthresh < tp->window_clamp && - (int)tp->rcv_ssthresh < tcp_space(sk) && - !tcp_under_memory_pressure(sk)) { + if (room > 0 && !tcp_under_memory_pressure(sk)) { int incr; /* Check #2. Increase window, if skb with such overhead @@ -406,8 +407,7 @@ static void tcp_grow_window(struct sock *sk, const struct sk_buff *skb) if (incr) { incr = max_t(int, incr, 2 * skb->len); - tp->rcv_ssthresh = min(tp->rcv_ssthresh + incr, - tp->window_clamp); + tp->rcv_ssthresh += min(room, incr); inet_csk(sk)->icsk_ack.quick |= 1; } } -- GitLab From b205097fae230acfe7a928e7f4875148568667bd Mon Sep 17 00:00:00 2001 From: Hangbin Liu Date: Mon, 8 Apr 2019 16:45:17 +0800 Subject: [PATCH 0183/1121] team: set slave to promisc if team is already in promisc mode [ Upstream commit 43c2adb9df7ddd6560fd3546d925b42cef92daa0 ] After adding a team interface to bridge, the team interface will enter promisc mode. Then if we add a new slave to team0, the slave will keep promisc off. Fix it by setting slave to promisc on if team master is already in promisc mode, also do the same for allmulti. v2: add promisc and allmulti checking when delete ports Fixes: 3d249d4ca7d0 ("net: introduce ethernet teaming device") Signed-off-by: Hangbin Liu Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/team/team.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index bb96153f496e..fea141e71705 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -1245,6 +1245,23 @@ static int team_port_add(struct team *team, struct net_device *port_dev) goto err_option_port_add; } + /* set promiscuity level to new slave */ + if (dev->flags & IFF_PROMISC) { + err = dev_set_promiscuity(port_dev, 1); + if (err) + goto err_set_slave_promisc; + } + + /* set allmulti level to new slave */ + if (dev->flags & IFF_ALLMULTI) { + err = dev_set_allmulti(port_dev, 1); + if (err) { + if (dev->flags & IFF_PROMISC) + dev_set_promiscuity(port_dev, -1); + goto err_set_slave_promisc; + } + } + netif_addr_lock_bh(dev); dev_uc_sync_multiple(port_dev, dev); dev_mc_sync_multiple(port_dev, dev); @@ -1261,6 +1278,9 @@ static int team_port_add(struct team *team, struct net_device *port_dev) return 0; +err_set_slave_promisc: + __team_option_inst_del_port(team, port); + err_option_port_add: team_upper_dev_unlink(team, port); @@ -1306,6 +1326,12 @@ static int team_port_del(struct team *team, struct net_device *port_dev) team_port_disable(team, port); list_del_rcu(&port->list); + + if (dev->flags & IFF_PROMISC) + dev_set_promiscuity(port_dev, -1); + if (dev->flags & IFF_ALLMULTI) + dev_set_allmulti(port_dev, -1); + team_upper_dev_unlink(team, port); netdev_rx_handler_unregister(port_dev); team_port_disable_netpoll(port); -- GitLab From f052bafe5476347fe9ae0665c4d2297ad1301e38 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Tue, 9 Apr 2019 12:10:25 +0800 Subject: [PATCH 0184/1121] vhost: reject zero size iova range [ Upstream commit 813dbeb656d6c90266f251d8bd2b02d445afa63f ] We used to accept zero size iova range which will lead a infinite loop in translate_desc(). Fixing this by failing the request in this case. Reported-by: syzbot+d21e6e297322a900c128@syzkaller.appspotmail.com Fixes: 6b1e6cc7 ("vhost: new device IOTLB API") Signed-off-by: Jason Wang Acked-by: Michael S. Tsirkin Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/vhost/vhost.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index d7c22ae5c368..0e93ac888a5f 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -918,8 +918,12 @@ static int vhost_new_umem_range(struct vhost_umem *umem, u64 start, u64 size, u64 end, u64 userspace_addr, int perm) { - struct vhost_umem_node *tmp, *node = kmalloc(sizeof(*node), GFP_ATOMIC); + struct vhost_umem_node *tmp, *node; + if (!size) + return -EFAULT; + + node = kmalloc(sizeof(*node), GFP_ATOMIC); if (!node) return -ENOMEM; -- GitLab From 3d988fcddbe7b8673a231958bd2fba61b5a7ced9 Mon Sep 17 00:00:00 2001 From: Stephen Suryaputra Date: Fri, 12 Apr 2019 16:19:27 -0400 Subject: [PATCH 0185/1121] ipv4: recompile ip options in ipv4_link_failure [ Upstream commit ed0de45a1008991fdaa27a0152befcb74d126a8b ] Recompile IP options since IPCB may not be valid anymore when ipv4_link_failure is called from arp_error_report. Refer to the commit 3da1ed7ac398 ("net: avoid use IPCB in cipso_v4_error") and the commit before that (9ef6b42ad6fd) for a similar issue. Signed-off-by: Stephen Suryaputra Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/ipv4/route.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index a1bf87711bfa..9af1c0d4dea9 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1195,8 +1195,16 @@ static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie) static void ipv4_link_failure(struct sk_buff *skb) { struct rtable *rt; + struct ip_options opt; - icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0); + /* Recompile ip options since IPCB may not be valid anymore. + */ + memset(&opt, 0, sizeof(opt)); + opt.optlen = ip_hdr(skb)->ihl*4 - sizeof(struct iphdr); + if (__ip_options_compile(dev_net(skb->dev), &opt, skb, NULL)) + return; + + __icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0, &opt); rt = skb_rtable(skb); if (rt) -- GitLab From 0a7e8300b7f4cf72a6f1c0c2799d92149465c414 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sat, 13 Apr 2019 17:32:21 -0700 Subject: [PATCH 0186/1121] ipv4: ensure rcu_read_lock() in ipv4_link_failure() [ Upstream commit c543cb4a5f07e09237ec0fc2c60c9f131b2c79ad ] fib_compute_spec_dst() needs to be called under rcu protection. syzbot reported : WARNING: suspicious RCU usage 5.1.0-rc4+ #165 Not tainted include/linux/inetdevice.h:220 suspicious rcu_dereference_check() usage! other info that might help us debug this: rcu_scheduler_active = 2, debug_locks = 1 1 lock held by swapper/0/0: #0: 0000000051b67925 ((&n->timer)){+.-.}, at: lockdep_copy_map include/linux/lockdep.h:170 [inline] #0: 0000000051b67925 ((&n->timer)){+.-.}, at: call_timer_fn+0xda/0x720 kernel/time/timer.c:1315 stack backtrace: CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.1.0-rc4+ #165 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x172/0x1f0 lib/dump_stack.c:113 lockdep_rcu_suspicious+0x153/0x15d kernel/locking/lockdep.c:5162 __in_dev_get_rcu include/linux/inetdevice.h:220 [inline] fib_compute_spec_dst+0xbbd/0x1030 net/ipv4/fib_frontend.c:294 spec_dst_fill net/ipv4/ip_options.c:245 [inline] __ip_options_compile+0x15a7/0x1a10 net/ipv4/ip_options.c:343 ipv4_link_failure+0x172/0x400 net/ipv4/route.c:1195 dst_link_failure include/net/dst.h:427 [inline] arp_error_report+0xd1/0x1c0 net/ipv4/arp.c:297 neigh_invalidate+0x24b/0x570 net/core/neighbour.c:995 neigh_timer_handler+0xc35/0xf30 net/core/neighbour.c:1081 call_timer_fn+0x190/0x720 kernel/time/timer.c:1325 expire_timers kernel/time/timer.c:1362 [inline] __run_timers kernel/time/timer.c:1681 [inline] __run_timers kernel/time/timer.c:1649 [inline] run_timer_softirq+0x652/0x1700 kernel/time/timer.c:1694 __do_softirq+0x266/0x95a kernel/softirq.c:293 invoke_softirq kernel/softirq.c:374 [inline] irq_exit+0x180/0x1d0 kernel/softirq.c:414 exiting_irq arch/x86/include/asm/apic.h:536 [inline] smp_apic_timer_interrupt+0x14a/0x570 arch/x86/kernel/apic/apic.c:1062 apic_timer_interrupt+0xf/0x20 arch/x86/entry/entry_64.S:807 Fixes: ed0de45a1008 ("ipv4: recompile ip options in ipv4_link_failure") Signed-off-by: Eric Dumazet Reported-by: syzbot Cc: Stephen Suryaputra Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/ipv4/route.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 9af1c0d4dea9..c64f062d6323 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1194,14 +1194,20 @@ static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie) static void ipv4_link_failure(struct sk_buff *skb) { - struct rtable *rt; struct ip_options opt; + struct rtable *rt; + int res; /* Recompile ip options since IPCB may not be valid anymore. */ memset(&opt, 0, sizeof(opt)); opt.optlen = ip_hdr(skb)->ihl*4 - sizeof(struct iphdr); - if (__ip_options_compile(dev_net(skb->dev), &opt, skb, NULL)) + + rcu_read_lock(); + res = __ip_options_compile(dev_net(skb->dev), &opt, skb, NULL); + rcu_read_unlock(); + + if (res) return; __icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0, &opt); -- GitLab From 6d5d30e03309fc22a48fc522b2e3f3c02c130092 Mon Sep 17 00:00:00 2001 From: Matteo Croce Date: Thu, 11 Apr 2019 12:26:32 +0200 Subject: [PATCH 0187/1121] net: thunderx: raise XDP MTU to 1508 [ Upstream commit 5ee15c101f29e0093ffb5448773ccbc786eb313b ] The thunderx driver splits frames bigger than 1530 bytes to multiple pages, making impossible to run an eBPF program on it. This leads to a maximum MTU of 1508 if QinQ is in use. The thunderx driver forbids to load an eBPF program if the MTU is higher than 1500 bytes. Raise the limit to 1508 so it is possible to use L2 protocols which need some more headroom. Fixes: 05c773f52b96e ("net: thunderx: Add basic XDP support") Signed-off-by: Matteo Croce Acked-by: Jesper Dangaard Brouer Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/cavium/thunder/nicvf_main.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c index 59b62b49ad48..bbe8add918b7 100644 --- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c +++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c @@ -29,6 +29,13 @@ #define DRV_NAME "thunder-nicvf" #define DRV_VERSION "1.0" +/* NOTE: Packets bigger than 1530 are split across multiple pages and XDP needs + * the buffer to be contiguous. Allow XDP to be set up only if we don't exceed + * this value, keeping headroom for the 14 byte Ethernet header and two + * VLAN tags (for QinQ) + */ +#define MAX_XDP_MTU (1530 - ETH_HLEN - VLAN_HLEN * 2) + /* Supported devices */ static const struct pci_device_id nicvf_id_table[] = { { PCI_DEVICE_SUB(PCI_VENDOR_ID_CAVIUM, @@ -1702,8 +1709,10 @@ static int nicvf_xdp_setup(struct nicvf *nic, struct bpf_prog *prog) bool bpf_attached = false; int ret = 0; - /* For now just support only the usual MTU sized frames */ - if (prog && (dev->mtu > 1500)) { + /* For now just support only the usual MTU sized frames, + * plus some headroom for VLAN, QinQ. + */ + if (prog && dev->mtu > MAX_XDP_MTU) { netdev_warn(dev, "Jumbo frames not yet supported with XDP, current MTU %d.\n", dev->mtu); return -EOPNOTSUPP; -- GitLab From 4a692bc1d5fa706d9170404c34b3efa190ebf039 Mon Sep 17 00:00:00 2001 From: Matteo Croce Date: Thu, 11 Apr 2019 12:26:33 +0200 Subject: [PATCH 0188/1121] net: thunderx: don't allow jumbo frames with XDP [ Upstream commit 1f227d16083b2e280b7dde4ca78883d75593f2fd ] The thunderx driver forbids to load an eBPF program if the MTU is too high, but this can be circumvented by loading the eBPF, then raising the MTU. Fix this by limiting the MTU if an eBPF program is already loaded. Fixes: 05c773f52b96e ("net: thunderx: Add basic XDP support") Signed-off-by: Matteo Croce Acked-by: Jesper Dangaard Brouer Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/cavium/thunder/nicvf_main.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c index bbe8add918b7..98734a37b6f6 100644 --- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c +++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c @@ -1461,6 +1461,15 @@ static int nicvf_change_mtu(struct net_device *netdev, int new_mtu) struct nicvf *nic = netdev_priv(netdev); int orig_mtu = netdev->mtu; + /* For now just support only the usual MTU sized frames, + * plus some headroom for VLAN, QinQ. + */ + if (nic->xdp_prog && new_mtu > MAX_XDP_MTU) { + netdev_warn(netdev, "Jumbo frames not yet supported with XDP, current MTU %d.\n", + netdev->mtu); + return -EINVAL; + } + netdev->mtu = new_mtu; if (!netif_running(netdev)) -- GitLab From 53fc31a4853e30d6e8f142b824f724da27ff3e40 Mon Sep 17 00:00:00 2001 From: Aurelien Aptel Date: Fri, 29 Mar 2019 10:49:12 +0100 Subject: [PATCH 0189/1121] CIFS: keep FileInfo handle live during oplock break commit b98749cac4a695f084a5ff076f4510b23e353ecd upstream. In the oplock break handler, writing pending changes from pages puts the FileInfo handle. If the refcount reaches zero it closes the handle and waits for any oplock break handler to return, thus causing a deadlock. To prevent this situation: * We add a wait flag to cifsFileInfo_put() to decide whether we should wait for running/pending oplock break handlers * We keep an additionnal reference of the SMB FileInfo handle so that for the rest of the handler putting the handle won't close it. - The ref is bumped everytime we queue the handler via the cifs_queue_oplock_break() helper. - The ref is decremented at the end of the handler This bug was triggered by xfstest 464. Also important fix to address the various reports of oops in smb2_push_mandatory_locks Signed-off-by: Aurelien Aptel Signed-off-by: Steve French Reviewed-by: Pavel Shilovsky CC: Stable Signed-off-by: Greg Kroah-Hartman --- fs/cifs/cifsglob.h | 2 ++ fs/cifs/file.c | 30 +++++++++++++++++++++++++----- fs/cifs/misc.c | 25 +++++++++++++++++++++++-- fs/cifs/smb2misc.c | 6 +++--- 4 files changed, 53 insertions(+), 10 deletions(-) diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index f29cdb1cdeb7..7b7ab10a9db1 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -1189,6 +1189,7 @@ cifsFileInfo_get_locked(struct cifsFileInfo *cifs_file) } struct cifsFileInfo *cifsFileInfo_get(struct cifsFileInfo *cifs_file); +void _cifsFileInfo_put(struct cifsFileInfo *cifs_file, bool wait_oplock_hdlr); void cifsFileInfo_put(struct cifsFileInfo *cifs_file); #define CIFS_CACHE_READ_FLG 1 @@ -1693,6 +1694,7 @@ GLOBAL_EXTERN spinlock_t gidsidlock; #endif /* CONFIG_CIFS_ACL */ void cifs_oplock_break(struct work_struct *work); +void cifs_queue_oplock_break(struct cifsFileInfo *cfile); extern const struct slow_work_ops cifs_oplock_break_ops; extern struct workqueue_struct *cifsiod_wq; diff --git a/fs/cifs/file.c b/fs/cifs/file.c index cd69c1e9750f..48ea9dfd5f02 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -358,12 +358,30 @@ cifsFileInfo_get(struct cifsFileInfo *cifs_file) return cifs_file; } -/* - * Release a reference on the file private data. This may involve closing - * the filehandle out on the server. Must be called without holding - * tcon->open_file_lock and cifs_file->file_info_lock. +/** + * cifsFileInfo_put - release a reference of file priv data + * + * Always potentially wait for oplock handler. See _cifsFileInfo_put(). */ void cifsFileInfo_put(struct cifsFileInfo *cifs_file) +{ + _cifsFileInfo_put(cifs_file, true); +} + +/** + * _cifsFileInfo_put - release a reference of file priv data + * + * This may involve closing the filehandle @cifs_file out on the + * server. Must be called without holding tcon->open_file_lock and + * cifs_file->file_info_lock. + * + * If @wait_for_oplock_handler is true and we are releasing the last + * reference, wait for any running oplock break handler of the file + * and cancel any pending one. If calling this function from the + * oplock break handler, you need to pass false. + * + */ +void _cifsFileInfo_put(struct cifsFileInfo *cifs_file, bool wait_oplock_handler) { struct inode *inode = d_inode(cifs_file->dentry); struct cifs_tcon *tcon = tlink_tcon(cifs_file->tlink); @@ -411,7 +429,8 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file) spin_unlock(&tcon->open_file_lock); - oplock_break_cancelled = cancel_work_sync(&cifs_file->oplock_break); + oplock_break_cancelled = wait_oplock_handler ? + cancel_work_sync(&cifs_file->oplock_break) : false; if (!tcon->need_reconnect && !cifs_file->invalidHandle) { struct TCP_Server_Info *server = tcon->ses->server; @@ -4136,6 +4155,7 @@ void cifs_oplock_break(struct work_struct *work) cinode); cifs_dbg(FYI, "Oplock release rc = %d\n", rc); } + _cifsFileInfo_put(cfile, false /* do not wait for ourself */); cifs_done_oplock_break(cinode); } diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index bcab30d4a6c7..76f1649ab444 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -486,8 +486,7 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv) CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, &pCifsInode->flags); - queue_work(cifsoplockd_wq, - &netfile->oplock_break); + cifs_queue_oplock_break(netfile); netfile->oplock_break_cancelled = false; spin_unlock(&tcon->open_file_lock); @@ -584,6 +583,28 @@ void cifs_put_writer(struct cifsInodeInfo *cinode) spin_unlock(&cinode->writers_lock); } +/** + * cifs_queue_oplock_break - queue the oplock break handler for cfile + * + * This function is called from the demultiplex thread when it + * receives an oplock break for @cfile. + * + * Assumes the tcon->open_file_lock is held. + * Assumes cfile->file_info_lock is NOT held. + */ +void cifs_queue_oplock_break(struct cifsFileInfo *cfile) +{ + /* + * Bump the handle refcount now while we hold the + * open_file_lock to enforce the validity of it for the oplock + * break handler. The matching put is done at the end of the + * handler. + */ + cifsFileInfo_get(cfile); + + queue_work(cifsoplockd_wq, &cfile->oplock_break); +} + void cifs_done_oplock_break(struct cifsInodeInfo *cinode) { clear_bit(CIFS_INODE_PENDING_OPLOCK_BREAK, &cinode->flags); diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c index a97a0e0b1a74..31f01f09d25a 100644 --- a/fs/cifs/smb2misc.c +++ b/fs/cifs/smb2misc.c @@ -517,7 +517,7 @@ smb2_tcon_has_lease(struct cifs_tcon *tcon, struct smb2_lease_break *rsp, clear_bit(CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, &cinode->flags); - queue_work(cifsoplockd_wq, &cfile->oplock_break); + cifs_queue_oplock_break(cfile); kfree(lw); return true; } @@ -661,8 +661,8 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server) CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, &cinode->flags); spin_unlock(&cfile->file_info_lock); - queue_work(cifsoplockd_wq, - &cfile->oplock_break); + + cifs_queue_oplock_break(cfile); spin_unlock(&tcon->open_file_lock); spin_unlock(&cifs_tcp_ses_lock); -- GitLab From bc1919400960a50e50ff55b0fde97342e4be621b Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 2 Apr 2019 08:10:47 -0700 Subject: [PATCH 0190/1121] KVM: x86: Don't clear EFER during SMM transitions for 32-bit vCPU commit 8f4dc2e77cdfaf7e644ef29693fa229db29ee1de upstream. Neither AMD nor Intel CPUs have an EFER field in the legacy SMRAM save state area, i.e. don't save/restore EFER across SMM transitions. KVM somewhat models this, e.g. doesn't clear EFER on entry to SMM if the guest doesn't support long mode. But during RSM, KVM unconditionally clears EFER so that it can get back to pure 32-bit mode in order to start loading CRs with their actual non-SMM values. Clear EFER only when it will be written when loading the non-SMM state so as to preserve bits that can theoretically be set on 32-bit vCPUs, e.g. KVM always emulates EFER_SCE. And because CR4.PAE is cleared only to play nice with EFER, wrap that code in the long mode check as well. Note, this may result in a compiler warning about cr4 being consumed uninitialized. Re-read CR4 even though it's technically unnecessary, as doing so allows for more readable code and RSM emulation is not a performance critical path. Fixes: 660a5d517aaab ("KVM: x86: save/load state on SMM switch") Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson Signed-off-by: Paolo Bonzini Signed-off-by: Greg Kroah-Hartman --- arch/x86/kvm/emulate.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 5f758568fc44..2bcadfc5b2f0 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2588,15 +2588,13 @@ static int em_rsm(struct x86_emulate_ctxt *ctxt) * CR0/CR3/CR4/EFER. It's all a bit more complicated if the vCPU * supports long mode. */ - cr4 = ctxt->ops->get_cr(ctxt, 4); if (emulator_has_longmode(ctxt)) { struct desc_struct cs_desc; /* Zero CR4.PCIDE before CR0.PG. */ - if (cr4 & X86_CR4_PCIDE) { + cr4 = ctxt->ops->get_cr(ctxt, 4); + if (cr4 & X86_CR4_PCIDE) ctxt->ops->set_cr(ctxt, 4, cr4 & ~X86_CR4_PCIDE); - cr4 &= ~X86_CR4_PCIDE; - } /* A 32-bit code segment is required to clear EFER.LMA. */ memset(&cs_desc, 0, sizeof(cs_desc)); @@ -2610,13 +2608,16 @@ static int em_rsm(struct x86_emulate_ctxt *ctxt) if (cr0 & X86_CR0_PE) ctxt->ops->set_cr(ctxt, 0, cr0 & ~(X86_CR0_PG | X86_CR0_PE)); - /* Now clear CR4.PAE (which must be done before clearing EFER.LME). */ - if (cr4 & X86_CR4_PAE) - ctxt->ops->set_cr(ctxt, 4, cr4 & ~X86_CR4_PAE); + if (emulator_has_longmode(ctxt)) { + /* Clear CR4.PAE before clearing EFER.LME. */ + cr4 = ctxt->ops->get_cr(ctxt, 4); + if (cr4 & X86_CR4_PAE) + ctxt->ops->set_cr(ctxt, 4, cr4 & ~X86_CR4_PAE); - /* And finally go back to 32-bit mode. */ - efer = 0; - ctxt->ops->set_msr(ctxt, MSR_EFER, efer); + /* And finally go back to 32-bit mode. */ + efer = 0; + ctxt->ops->set_msr(ctxt, MSR_EFER, efer); + } smbase = ctxt->ops->get_smbase(ctxt); if (emulator_has_longmode(ctxt)) -- GitLab From 8091c2ae4a1949f0f2cb8b48a6ccaf383661a76b Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Wed, 3 Apr 2019 16:06:42 +0200 Subject: [PATCH 0191/1121] KVM: x86: svm: make sure NMI is injected after nmi_singlestep commit 99c221796a810055974b54c02e8f53297e48d146 upstream. I noticed that apic test from kvm-unit-tests always hangs on my EPYC 7401P, the hanging test nmi-after-sti is trying to deliver 30000 NMIs and tracing shows that we're sometimes able to deliver a few but never all. When we're trying to inject an NMI we may fail to do so immediately for various reasons, however, we still need to inject it so enable_nmi_window() arms nmi_singlestep mode. #DB occurs as expected, but we're not checking for pending NMIs before entering the guest and unless there's a different event to process, the NMI will never get delivered. Make KVM_REQ_EVENT request on the vCPU from db_interception() to make sure pending NMIs are checked and possibly injected. Signed-off-by: Vitaly Kuznetsov Cc: stable@vger.kernel.org Signed-off-by: Paolo Bonzini Signed-off-by: Greg Kroah-Hartman --- arch/x86/kvm/svm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index c387047e926a..3a57816ea498 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -2211,6 +2211,7 @@ static int pf_interception(struct vcpu_svm *svm) static int db_interception(struct vcpu_svm *svm) { struct kvm_run *kvm_run = svm->vcpu.run; + struct kvm_vcpu *vcpu = &svm->vcpu; if (!(svm->vcpu.guest_debug & (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP)) && @@ -2221,6 +2222,8 @@ static int db_interception(struct vcpu_svm *svm) if (svm->nmi_singlestep) { disable_nmi_singlestep(svm); + /* Make sure we check for pending NMIs upon entry */ + kvm_make_request(KVM_REQ_EVENT, vcpu); } if (svm->vcpu.guest_debug & -- GitLab From b69e4d5f1ab43ea3c5e41ac841606eaffdc61402 Mon Sep 17 00:00:00 2001 From: Leonard Pollak Date: Wed, 13 Feb 2019 11:19:52 +0100 Subject: [PATCH 0192/1121] Staging: iio: meter: fixed typo commit 0a8a29be499cbb67df79370aaf5109085509feb8 upstream. This patch fixes an obvious typo, which will cause erroneously returning the Peak Voltage instead of the Peak Current. Signed-off-by: Leonard Pollak Cc: Acked-by: Michael Hennerich Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/meter/ade7854.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/iio/meter/ade7854.c b/drivers/staging/iio/meter/ade7854.c index 70612da64a8b..7ae774ef9da3 100644 --- a/drivers/staging/iio/meter/ade7854.c +++ b/drivers/staging/iio/meter/ade7854.c @@ -269,7 +269,7 @@ static IIO_DEV_ATTR_VPEAK(0644, static IIO_DEV_ATTR_IPEAK(0644, ade7854_read_32bit, ade7854_write_32bit, - ADE7854_VPEAK); + ADE7854_IPEAK); static IIO_DEV_ATTR_APHCAL(0644, ade7854_read_16bit, ade7854_write_16bit, -- GitLab From 63aafa6501a5640032107fe9647818a930b18222 Mon Sep 17 00:00:00 2001 From: Mircea Caprioru Date: Wed, 20 Feb 2019 13:08:20 +0200 Subject: [PATCH 0193/1121] staging: iio: ad7192: Fix ad7193 channel address commit 7ce0f216221856a17fc4934b39284678a5fef2e9 upstream. This patch fixes the differential channels addresses for the ad7193. Signed-off-by: Mircea Caprioru Cc: Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/ad7192.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index 31a195d1bf05..f58c80327ba5 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c @@ -109,10 +109,10 @@ #define AD7192_CH_AIN3 BIT(6) /* AIN3 - AINCOM */ #define AD7192_CH_AIN4 BIT(7) /* AIN4 - AINCOM */ -#define AD7193_CH_AIN1P_AIN2M 0x000 /* AIN1(+) - AIN2(-) */ -#define AD7193_CH_AIN3P_AIN4M 0x001 /* AIN3(+) - AIN4(-) */ -#define AD7193_CH_AIN5P_AIN6M 0x002 /* AIN5(+) - AIN6(-) */ -#define AD7193_CH_AIN7P_AIN8M 0x004 /* AIN7(+) - AIN8(-) */ +#define AD7193_CH_AIN1P_AIN2M 0x001 /* AIN1(+) - AIN2(-) */ +#define AD7193_CH_AIN3P_AIN4M 0x002 /* AIN3(+) - AIN4(-) */ +#define AD7193_CH_AIN5P_AIN6M 0x004 /* AIN5(+) - AIN6(-) */ +#define AD7193_CH_AIN7P_AIN8M 0x008 /* AIN7(+) - AIN8(-) */ #define AD7193_CH_TEMP 0x100 /* Temp senseor */ #define AD7193_CH_AIN2P_AIN2M 0x200 /* AIN2(+) - AIN2(-) */ #define AD7193_CH_AIN1 0x401 /* AIN1 - AINCOM */ -- GitLab From b7ad00c028ab8ab238cc72906b8fdb6ed3c874ea Mon Sep 17 00:00:00 2001 From: Sergey Larin Date: Sat, 2 Mar 2019 19:54:55 +0300 Subject: [PATCH 0194/1121] iio: gyro: mpu3050: fix chip ID reading commit 409a51e0a4a5f908763191fae2c29008632eb712 upstream. According to the datasheet, the last bit of CHIP_ID register controls I2C bus, and the first one is unused. Handle this correctly. Note that there are chips out there that have a value such that the id check currently fails. Signed-off-by: Sergey Larin Reviewed-by: Linus Walleij Cc: Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/gyro/mpu3050-core.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/iio/gyro/mpu3050-core.c b/drivers/iio/gyro/mpu3050-core.c index e0d241a9aa30..a7be4670bf8f 100644 --- a/drivers/iio/gyro/mpu3050-core.c +++ b/drivers/iio/gyro/mpu3050-core.c @@ -29,7 +29,8 @@ #include "mpu3050.h" -#define MPU3050_CHIP_ID 0x69 +#define MPU3050_CHIP_ID 0x68 +#define MPU3050_CHIP_ID_MASK 0x7E /* * Register map: anything suffixed *_H is a big-endian high byte and always @@ -1178,8 +1179,9 @@ int mpu3050_common_probe(struct device *dev, goto err_power_down; } - if (val != MPU3050_CHIP_ID) { - dev_err(dev, "unsupported chip id %02x\n", (u8)val); + if ((val & MPU3050_CHIP_ID_MASK) != MPU3050_CHIP_ID) { + dev_err(dev, "unsupported chip id %02x\n", + (u8)(val & MPU3050_CHIP_ID_MASK)); ret = -ENODEV; goto err_power_down; } -- GitLab From f245ce44d58e88c74d37d73b23ac9617789038d2 Mon Sep 17 00:00:00 2001 From: Mike Looijmans Date: Wed, 13 Feb 2019 08:41:47 +0100 Subject: [PATCH 0195/1121] iio/gyro/bmg160: Use millidegrees for temperature scale commit 40a7198a4a01037003c7ca714f0d048a61e729ac upstream. Standard unit for temperature is millidegrees Celcius, whereas this driver was reporting in degrees. Fix the scale factor in the driver. Signed-off-by: Mike Looijmans Cc: Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/gyro/bmg160_core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/gyro/bmg160_core.c b/drivers/iio/gyro/bmg160_core.c index 821919dd245b..b5a5517e3ce1 100644 --- a/drivers/iio/gyro/bmg160_core.c +++ b/drivers/iio/gyro/bmg160_core.c @@ -583,11 +583,10 @@ static int bmg160_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: return bmg160_get_filter(data, val); case IIO_CHAN_INFO_SCALE: - *val = 0; switch (chan->type) { case IIO_TEMP: - *val2 = 500000; - return IIO_VAL_INT_PLUS_MICRO; + *val = 500; + return IIO_VAL_INT; case IIO_ANGL_VEL: { int i; @@ -595,6 +594,7 @@ static int bmg160_read_raw(struct iio_dev *indio_dev, for (i = 0; i < ARRAY_SIZE(bmg160_scale_table); ++i) { if (bmg160_scale_table[i].dps_range == data->dps_range) { + *val = 0; *val2 = bmg160_scale_table[i].scale; return IIO_VAL_INT_PLUS_MICRO; } -- GitLab From 0336305753a66205f0b74ab9c7236cd436238870 Mon Sep 17 00:00:00 2001 From: Gwendal Grignou Date: Wed, 13 Mar 2019 12:40:02 +0100 Subject: [PATCH 0196/1121] iio: cros_ec: Fix the maths for gyro scale calculation commit 3d02d7082e5823598090530c3988a35f69689943 upstream. Calculation did not use IIO_DEGREE_TO_RAD and implemented a variant to avoid precision loss as we aim a nano value. The offset added to avoid rounding error, though, doesn't give us a close result to the expected value. E.g. For 1000dps, the result should be: (1000 * pi ) / 180 >> 15 ~= 0.000532632218 But with current calculation we get $ cat scale 0.000547890 Fix the calculation by just doing the maths involved for a nano value val * pi * 10e12 / (180 * 2^15) so we get a closer result. $ cat scale 0.000532632 Fixes: c14dca07a31d ("iio: cros_ec_sensors: add ChromeOS EC Contiguous Sensors driver") Signed-off-by: Gwendal Grignou Signed-off-by: Enric Balletbo i Serra Cc: Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c index 38e8783e4b05..287fbe08264d 100644 --- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c +++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c @@ -104,9 +104,10 @@ static int cros_ec_sensors_read(struct iio_dev *indio_dev, * Do not use IIO_DEGREE_TO_RAD to avoid precision * loss. Round to the nearest integer. */ - *val = div_s64(val64 * 314159 + 9000000ULL, 1000); - *val2 = 18000 << (CROS_EC_SENSOR_BITS - 1); - ret = IIO_VAL_FRACTIONAL; + *val = 0; + *val2 = div_s64(val64 * 3141592653ULL, + 180 << (CROS_EC_SENSOR_BITS - 1)); + ret = IIO_VAL_INT_PLUS_NANO; break; case MOTIONSENSE_TYPE_MAG: /* -- GitLab From ad0f65cd55b88f2e4d49968f9d5aba26fe3e8c1c Mon Sep 17 00:00:00 2001 From: Dragos Bogdan Date: Tue, 19 Mar 2019 12:47:00 +0200 Subject: [PATCH 0197/1121] iio: ad_sigma_delta: select channel when reading register commit fccfb9ce70ed4ea7a145f77b86de62e38178517f upstream. The desired channel has to be selected in order to correctly fill the buffer with the corresponding data. The `ad_sd_write_reg()` already does this, but for the `ad_sd_read_reg_raw()` this was omitted. Fixes: af3008485ea03 ("iio:adc: Add common code for ADI Sigma Delta devices") Signed-off-by: Dragos Bogdan Signed-off-by: Alexandru Ardelean Cc: Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/adc/ad_sigma_delta.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c index 22c4c17cd996..a1d072ecb717 100644 --- a/drivers/iio/adc/ad_sigma_delta.c +++ b/drivers/iio/adc/ad_sigma_delta.c @@ -121,6 +121,7 @@ static int ad_sd_read_reg_raw(struct ad_sigma_delta *sigma_delta, if (sigma_delta->info->has_registers) { data[0] = reg << sigma_delta->info->addr_shift; data[0] |= sigma_delta->info->read_mask; + data[0] |= sigma_delta->comm; spi_message_add_tail(&t[0], &m); } spi_message_add_tail(&t[1], &m); -- GitLab From 8ba5d597593acc318e426d7931d32719039b5138 Mon Sep 17 00:00:00 2001 From: Jean-Francois Dagenais Date: Wed, 6 Mar 2019 15:56:06 -0500 Subject: [PATCH 0198/1121] iio: dac: mcp4725: add missing powerdown bits in store eeprom commit 06003531502d06bc89d32528f6ec96bf978790f9 upstream. When issuing the write DAC register and write eeprom command, the two powerdown bits (PD0 and PD1) are assumed by the chip to be present in the bytes sent. Leaving them at 0 implies "powerdown disabled" which is a different state that the current one. By adding the current state of the powerdown in the i2c write, the chip will correctly power-on exactly like as it is at the moment of store_eeprom call. This is documented in MCP4725's datasheet, FIGURE 6-2: "Write Commands for DAC Input Register and EEPROM" and MCP4726's datasheet, FIGURE 6-3: "Write All Memory Command". Signed-off-by: Jean-Francois Dagenais Acked-by: Peter Meerwald-Stadler Cc: Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/dac/mcp4725.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/iio/dac/mcp4725.c b/drivers/iio/dac/mcp4725.c index 6ab1f23e5a79..fe3e42defb33 100644 --- a/drivers/iio/dac/mcp4725.c +++ b/drivers/iio/dac/mcp4725.c @@ -98,6 +98,7 @@ static ssize_t mcp4725_store_eeprom(struct device *dev, inoutbuf[0] = 0x60; /* write EEPROM */ inoutbuf[0] |= data->ref_mode << 3; + inoutbuf[0] |= data->powerdown ? ((data->powerdown_mode + 1) << 1) : 0; inoutbuf[1] = data->dac_value >> 4; inoutbuf[2] = (data->dac_value & 0xf) << 4; -- GitLab From 1ae7297b737d39fe42cec4de3151e54aefec3666 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 20 Feb 2019 17:11:32 +0200 Subject: [PATCH 0199/1121] iio: Fix scan mask selection commit 20ea39ef9f2f911bd01c69519e7d69cfec79fde3 upstream. The trialmask is expected to have all bits set to 0 after allocation. Currently kmalloc_array() is used which does not zero the memory and so random bits are set. This results in random channels being enabled when they shouldn't. Replace kmalloc_array() with kcalloc() which has the same interface but zeros the memory. Note the fix is actually required earlier than the below fixes tag, but will require a manual backport due to move from kmalloc to kmalloc_array. Signed-off-by: Lars-Peter Clausen Signed-off-by: Alexandru Ardelean Fixes commit 057ac1acdfc4 ("iio: Use kmalloc_array() in iio_scan_mask_set()"). Cc: Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/industrialio-buffer.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 78482d456c3b..d50125766093 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -320,9 +320,8 @@ static int iio_scan_mask_set(struct iio_dev *indio_dev, const unsigned long *mask; unsigned long *trialmask; - trialmask = kmalloc_array(BITS_TO_LONGS(indio_dev->masklength), - sizeof(*trialmask), - GFP_KERNEL); + trialmask = kcalloc(BITS_TO_LONGS(indio_dev->masklength), + sizeof(*trialmask), GFP_KERNEL); if (trialmask == NULL) return -ENOMEM; if (!indio_dev->masklength) { -- GitLab From fe400daf26deaf94cb182fec48b80079d305097e Mon Sep 17 00:00:00 2001 From: Georg Ottinger Date: Wed, 30 Jan 2019 14:42:02 +0100 Subject: [PATCH 0200/1121] iio: adc: at91: disable adc channel interrupt in timeout case commit 09c6bdee51183a575bf7546890c8c137a75a2b44 upstream. Having a brief look at at91_adc_read_raw() it is obvious that in the case of a timeout the setting of AT91_ADC_CHDR and AT91_ADC_IDR registers is omitted. If 2 different channels are queried we can end up with a situation where two interrupts are enabled, but only one interrupt is cleared in the interrupt handler. Resulting in a interrupt loop and a system hang. Signed-off-by: Georg Ottinger Acked-by: Ludovic Desroches Cc: Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/adc/at91_adc.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index cd686179aa92..492f6c8ba735 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -705,23 +705,29 @@ static int at91_adc_read_raw(struct iio_dev *idev, ret = wait_event_interruptible_timeout(st->wq_data_avail, st->done, msecs_to_jiffies(1000)); - if (ret == 0) - ret = -ETIMEDOUT; - if (ret < 0) { - mutex_unlock(&st->lock); - return ret; - } - - *val = st->last_value; + /* Disable interrupts, regardless if adc conversion was + * successful or not + */ at91_adc_writel(st, AT91_ADC_CHDR, AT91_ADC_CH(chan->channel)); at91_adc_writel(st, AT91_ADC_IDR, BIT(chan->channel)); - st->last_value = 0; - st->done = false; + if (ret > 0) { + /* a valid conversion took place */ + *val = st->last_value; + st->last_value = 0; + st->done = false; + ret = IIO_VAL_INT; + } else if (ret == 0) { + /* conversion timeout */ + dev_err(&idev->dev, "ADC Channel %d timeout.\n", + chan->channel); + ret = -ETIMEDOUT; + } + mutex_unlock(&st->lock); - return IIO_VAL_INT; + return ret; case IIO_CHAN_INFO_SCALE: *val = st->vref_mv; -- GitLab From 0386fd65c2db218972a1965471d9c0428a4f5aba Mon Sep 17 00:00:00 2001 From: Fabrice Gasnier Date: Mon, 25 Mar 2019 14:01:23 +0100 Subject: [PATCH 0201/1121] iio: core: fix a possible circular locking dependency commit 7f75591fc5a123929a29636834d1bcb8b5c9fee3 upstream. This fixes a possible circular locking dependency detected warning seen with: - CONFIG_PROVE_LOCKING=y - consumer/provider IIO devices (ex: "voltage-divider" consumer of "adc") When using the IIO consumer interface, e.g. iio_channel_get(), the consumer device will likely call iio_read_channel_raw() or similar that rely on 'info_exist_lock' mutex. typically: ... mutex_lock(&chan->indio_dev->info_exist_lock); if (chan->indio_dev->info == NULL) { ret = -ENODEV; goto err_unlock; } ret = do_some_ops() err_unlock: mutex_unlock(&chan->indio_dev->info_exist_lock); return ret; ... Same mutex is also hold in iio_device_unregister(). The following deadlock warning happens when: - the consumer device has called an API like iio_read_channel_raw() at least once. - the consumer driver is unregistered, removed (unbind from sysfs) ====================================================== WARNING: possible circular locking dependency detected 4.19.24 #577 Not tainted ------------------------------------------------------ sh/372 is trying to acquire lock: (kn->count#30){++++}, at: kernfs_remove_by_name_ns+0x3c/0x84 but task is already holding lock: (&dev->info_exist_lock){+.+.}, at: iio_device_unregister+0x18/0x60 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #1 (&dev->info_exist_lock){+.+.}: __mutex_lock+0x70/0xa3c mutex_lock_nested+0x1c/0x24 iio_read_channel_raw+0x1c/0x60 iio_read_channel_info+0xa8/0xb0 dev_attr_show+0x1c/0x48 sysfs_kf_seq_show+0x84/0xec seq_read+0x154/0x528 __vfs_read+0x2c/0x15c vfs_read+0x8c/0x110 ksys_read+0x4c/0xac ret_fast_syscall+0x0/0x28 0xbedefb60 -> #0 (kn->count#30){++++}: lock_acquire+0xd8/0x268 __kernfs_remove+0x288/0x374 kernfs_remove_by_name_ns+0x3c/0x84 remove_files+0x34/0x78 sysfs_remove_group+0x40/0x9c sysfs_remove_groups+0x24/0x34 device_remove_attrs+0x38/0x64 device_del+0x11c/0x360 cdev_device_del+0x14/0x2c iio_device_unregister+0x24/0x60 release_nodes+0x1bc/0x200 device_release_driver_internal+0x1a0/0x230 unbind_store+0x80/0x130 kernfs_fop_write+0x100/0x1e4 __vfs_write+0x2c/0x160 vfs_write+0xa4/0x17c ksys_write+0x4c/0xac ret_fast_syscall+0x0/0x28 0xbe906840 other info that might help us debug this: Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(&dev->info_exist_lock); lock(kn->count#30); lock(&dev->info_exist_lock); lock(kn->count#30); *** DEADLOCK *** ... cdev_device_del() can be called without holding the lock. It should be safe as info_exist_lock prevents kernelspace consumers to use the exported routines during/after provider removal. cdev_device_del() is for userspace. Help to reproduce: See example: Documentation/devicetree/bindings/iio/afe/voltage-divider.txt sysv { compatible = "voltage-divider"; io-channels = <&adc 0>; output-ohms = <22>; full-ohms = <222>; }; First, go to iio:deviceX for the "voltage-divider", do one read: $ cd /sys/bus/iio/devices/iio:deviceX $ cat in_voltage0_raw Then, unbind the consumer driver. It triggers above deadlock warning. $ cd /sys/bus/platform/drivers/iio-rescale/ $ echo sysv > unbind Note I don't actually expect stable will pick this up all the way back into IIO being in staging, but if's probably valid that far back. Signed-off-by: Fabrice Gasnier Fixes: ac917a81117c ("staging:iio:core set the iio_dev.info pointer to null on unregister") Cc: Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/industrialio-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index e565fd4fc414..97b7266ee0ff 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -1741,10 +1741,10 @@ EXPORT_SYMBOL(iio_device_register); **/ void iio_device_unregister(struct iio_dev *indio_dev) { - mutex_lock(&indio_dev->info_exist_lock); - cdev_device_del(&indio_dev->chrdev, &indio_dev->dev); + mutex_lock(&indio_dev->info_exist_lock); + iio_device_unregister_debugfs(indio_dev); iio_disable_all_buffers(indio_dev); -- GitLab From de970d4efc3bfb944d4c835bed5b73b8f96a10c5 Mon Sep 17 00:00:00 2001 From: "he, bo" Date: Wed, 6 Mar 2019 10:32:20 +0800 Subject: [PATCH 0202/1121] io: accel: kxcjk1013: restore the range after resume. commit fe2d3df639a7940a125a33d6460529b9689c5406 upstream. On some laptops, kxcjk1013 is powered off when system enters S3. We need restore the range regiter during resume. Otherwise, the sensor doesn't work properly after S3. Signed-off-by: he, bo Signed-off-by: Chen, Hu Reviewed-by: Hans de Goede Cc: Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/accel/kxcjk-1013.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c index 784636800361..780f886ccbfe 100644 --- a/drivers/iio/accel/kxcjk-1013.c +++ b/drivers/iio/accel/kxcjk-1013.c @@ -1340,6 +1340,8 @@ static int kxcjk1013_resume(struct device *dev) mutex_lock(&data->mutex); ret = kxcjk1013_set_mode(data, OPERATION); + if (ret == 0) + ret = kxcjk1013_set_range(data, data->range); mutex_unlock(&data->mutex); return ret; -- GitLab From 586f669a2f06818d0c509b17dbd5ab8e216c3ba0 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 15 Apr 2019 12:10:14 +0100 Subject: [PATCH 0203/1121] staging: comedi: vmk80xx: Fix use of uninitialized semaphore commit 08b7c2f9208f0e2a32159e4e7a4831b7adb10a3e upstream. If `vmk80xx_auto_attach()` returns an error, the core comedi module code will call `vmk80xx_detach()` to clean up. If `vmk80xx_auto_attach()` successfully allocated the comedi device private data, `vmk80xx_detach()` assumes that a `struct semaphore limit_sem` contained in the private data has been initialized and uses it. Unfortunately, there are a couple of places where `vmk80xx_auto_attach()` can return an error after allocating the device private data but before initializing the semaphore, so this assumption is invalid. Fix it by initializing the semaphore just after allocating the private data in `vmk80xx_auto_attach()` before any other errors can be returned. I believe this was the cause of the following syzbot crash report : usb 1-1: config 0 has no interface number 0 usb 1-1: New USB device found, idVendor=10cf, idProduct=8068, bcdDevice=e6.8d usb 1-1: New USB device strings: Mfr=0, Product=0, SerialNumber=0 usb 1-1: config 0 descriptor?? vmk80xx 1-1:0.117: driver 'vmk80xx' failed to auto-configure device. INFO: trying to register non-static key. the code is fine but needs lockdep annotation. turning off the locking correctness validator. CPU: 0 PID: 12 Comm: kworker/0:1 Not tainted 5.1.0-rc4-319354-g9a33b36 #3 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Workqueue: usb_hub_wq hub_event Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0xe8/0x16e lib/dump_stack.c:113 assign_lock_key kernel/locking/lockdep.c:786 [inline] register_lock_class+0x11b8/0x1250 kernel/locking/lockdep.c:1095 __lock_acquire+0xfb/0x37c0 kernel/locking/lockdep.c:3582 lock_acquire+0x10d/0x2f0 kernel/locking/lockdep.c:4211 __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline] _raw_spin_lock_irqsave+0x44/0x60 kernel/locking/spinlock.c:152 down+0x12/0x80 kernel/locking/semaphore.c:58 vmk80xx_detach+0x59/0x100 drivers/staging/comedi/drivers/vmk80xx.c:829 comedi_device_detach+0xed/0x800 drivers/staging/comedi/drivers.c:204 comedi_device_cleanup.part.0+0x68/0x140 drivers/staging/comedi/comedi_fops.c:156 comedi_device_cleanup drivers/staging/comedi/comedi_fops.c:187 [inline] comedi_free_board_dev.part.0+0x16/0x90 drivers/staging/comedi/comedi_fops.c:190 comedi_free_board_dev drivers/staging/comedi/comedi_fops.c:189 [inline] comedi_release_hardware_device+0x111/0x140 drivers/staging/comedi/comedi_fops.c:2880 comedi_auto_config.cold+0x124/0x1b0 drivers/staging/comedi/drivers.c:1068 usb_probe_interface+0x31d/0x820 drivers/usb/core/driver.c:361 really_probe+0x2da/0xb10 drivers/base/dd.c:509 driver_probe_device+0x21d/0x350 drivers/base/dd.c:671 __device_attach_driver+0x1d8/0x290 drivers/base/dd.c:778 bus_for_each_drv+0x163/0x1e0 drivers/base/bus.c:454 __device_attach+0x223/0x3a0 drivers/base/dd.c:844 bus_probe_device+0x1f1/0x2a0 drivers/base/bus.c:514 device_add+0xad2/0x16e0 drivers/base/core.c:2106 usb_set_configuration+0xdf7/0x1740 drivers/usb/core/message.c:2021 generic_probe+0xa2/0xda drivers/usb/core/generic.c:210 usb_probe_device+0xc0/0x150 drivers/usb/core/driver.c:266 really_probe+0x2da/0xb10 drivers/base/dd.c:509 driver_probe_device+0x21d/0x350 drivers/base/dd.c:671 __device_attach_driver+0x1d8/0x290 drivers/base/dd.c:778 bus_for_each_drv+0x163/0x1e0 drivers/base/bus.c:454 __device_attach+0x223/0x3a0 drivers/base/dd.c:844 bus_probe_device+0x1f1/0x2a0 drivers/base/bus.c:514 device_add+0xad2/0x16e0 drivers/base/core.c:2106 usb_new_device.cold+0x537/0xccf drivers/usb/core/hub.c:2534 hub_port_connect drivers/usb/core/hub.c:5089 [inline] hub_port_connect_change drivers/usb/core/hub.c:5204 [inline] port_event drivers/usb/core/hub.c:5350 [inline] hub_event+0x138e/0x3b00 drivers/usb/core/hub.c:5432 process_one_work+0x90f/0x1580 kernel/workqueue.c:2269 worker_thread+0x9b/0xe20 kernel/workqueue.c:2415 kthread+0x313/0x420 kernel/kthread.c:253 ret_from_fork+0x3a/0x50 arch/x86/entry/entry_64.S:352 Reported-by: syzbot+54c2f58f15fe6876b6ad@syzkaller.appspotmail.com Signed-off-by: Ian Abbott Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/vmk80xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c index a004aed0147a..ff6f69ffcd62 100644 --- a/drivers/staging/comedi/drivers/vmk80xx.c +++ b/drivers/staging/comedi/drivers/vmk80xx.c @@ -809,6 +809,8 @@ static int vmk80xx_auto_attach(struct comedi_device *dev, devpriv->model = board->model; + sema_init(&devpriv->limit_sem, 8); + ret = vmk80xx_find_usb_endpoints(dev); if (ret) return ret; @@ -817,8 +819,6 @@ static int vmk80xx_auto_attach(struct comedi_device *dev, if (ret) return ret; - sema_init(&devpriv->limit_sem, 8); - usb_set_intfdata(intf, devpriv); if (devpriv->model == VMK8055_MODEL) -- GitLab From 9de6de262c33c8700a2af6209ba732595eb0f94e Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 15 Apr 2019 12:52:30 +0100 Subject: [PATCH 0204/1121] staging: comedi: vmk80xx: Fix possible double-free of ->usb_rx_buf commit 663d294b4768bfd89e529e069bffa544a830b5bf upstream. `vmk80xx_alloc_usb_buffers()` is called from `vmk80xx_auto_attach()` to allocate RX and TX buffers for USB transfers. It allocates `devpriv->usb_rx_buf` followed by `devpriv->usb_tx_buf`. If the allocation of `devpriv->usb_tx_buf` fails, it frees `devpriv->usb_rx_buf`, leaving the pointer set dangling, and returns an error. Later, `vmk80xx_detach()` will be called from the core comedi module code to clean up. `vmk80xx_detach()` also frees both `devpriv->usb_rx_buf` and `devpriv->usb_tx_buf`, but `devpriv->usb_rx_buf` may have already been freed, leading to a double-free error. Fix it by removing the call to `kfree(devpriv->usb_rx_buf)` from `vmk80xx_alloc_usb_buffers()`, relying on `vmk80xx_detach()` to free the memory. Signed-off-by: Ian Abbott Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/vmk80xx.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c index ff6f69ffcd62..1800eb3ae017 100644 --- a/drivers/staging/comedi/drivers/vmk80xx.c +++ b/drivers/staging/comedi/drivers/vmk80xx.c @@ -691,10 +691,8 @@ static int vmk80xx_alloc_usb_buffers(struct comedi_device *dev) size = usb_endpoint_maxp(devpriv->ep_tx); devpriv->usb_tx_buf = kzalloc(size, GFP_KERNEL); - if (!devpriv->usb_tx_buf) { - kfree(devpriv->usb_rx_buf); + if (!devpriv->usb_tx_buf) return -ENOMEM; - } return 0; } -- GitLab From 72cd1a3275cfc4a57d4e0799237666def6fc2510 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 15 Apr 2019 12:43:01 +0100 Subject: [PATCH 0205/1121] staging: comedi: ni_usb6501: Fix use of uninitialized mutex commit 660cf4ce9d0f3497cc7456eaa6d74c8b71d6282c upstream. If `ni6501_auto_attach()` returns an error, the core comedi module code will call `ni6501_detach()` to clean up. If `ni6501_auto_attach()` successfully allocated the comedi device private data, `ni6501_detach()` assumes that a `struct mutex mut` contained in the private data has been initialized and uses it. Unfortunately, there are a couple of places where `ni6501_auto_attach()` can return an error after allocating the device private data but before initializing the mutex, so this assumption is invalid. Fix it by initializing the mutex just after allocating the private data in `ni6501_auto_attach()` before any other errors can be retturned. Also move the call to `usb_set_intfdata()` just to keep the code a bit neater (either position for the call is fine). I believe this was the cause of the following syzbot crash report : usb 1-1: New USB device strings: Mfr=0, Product=0, SerialNumber=0 usb 1-1: config 0 descriptor?? usb 1-1: string descriptor 0 read error: -71 comedi comedi0: Wrong number of endpoints ni6501 1-1:0.233: driver 'ni6501' failed to auto-configure device. INFO: trying to register non-static key. the code is fine but needs lockdep annotation. turning off the locking correctness validator. CPU: 0 PID: 585 Comm: kworker/0:3 Not tainted 5.1.0-rc4-319354-g9a33b36 #3 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Workqueue: usb_hub_wq hub_event Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0xe8/0x16e lib/dump_stack.c:113 assign_lock_key kernel/locking/lockdep.c:786 [inline] register_lock_class+0x11b8/0x1250 kernel/locking/lockdep.c:1095 __lock_acquire+0xfb/0x37c0 kernel/locking/lockdep.c:3582 lock_acquire+0x10d/0x2f0 kernel/locking/lockdep.c:4211 __mutex_lock_common kernel/locking/mutex.c:925 [inline] __mutex_lock+0xfe/0x12b0 kernel/locking/mutex.c:1072 ni6501_detach+0x5b/0x110 drivers/staging/comedi/drivers/ni_usb6501.c:567 comedi_device_detach+0xed/0x800 drivers/staging/comedi/drivers.c:204 comedi_device_cleanup.part.0+0x68/0x140 drivers/staging/comedi/comedi_fops.c:156 comedi_device_cleanup drivers/staging/comedi/comedi_fops.c:187 [inline] comedi_free_board_dev.part.0+0x16/0x90 drivers/staging/comedi/comedi_fops.c:190 comedi_free_board_dev drivers/staging/comedi/comedi_fops.c:189 [inline] comedi_release_hardware_device+0x111/0x140 drivers/staging/comedi/comedi_fops.c:2880 comedi_auto_config.cold+0x124/0x1b0 drivers/staging/comedi/drivers.c:1068 usb_probe_interface+0x31d/0x820 drivers/usb/core/driver.c:361 really_probe+0x2da/0xb10 drivers/base/dd.c:509 driver_probe_device+0x21d/0x350 drivers/base/dd.c:671 __device_attach_driver+0x1d8/0x290 drivers/base/dd.c:778 bus_for_each_drv+0x163/0x1e0 drivers/base/bus.c:454 __device_attach+0x223/0x3a0 drivers/base/dd.c:844 bus_probe_device+0x1f1/0x2a0 drivers/base/bus.c:514 device_add+0xad2/0x16e0 drivers/base/core.c:2106 usb_set_configuration+0xdf7/0x1740 drivers/usb/core/message.c:2021 generic_probe+0xa2/0xda drivers/usb/core/generic.c:210 usb_probe_device+0xc0/0x150 drivers/usb/core/driver.c:266 really_probe+0x2da/0xb10 drivers/base/dd.c:509 driver_probe_device+0x21d/0x350 drivers/base/dd.c:671 __device_attach_driver+0x1d8/0x290 drivers/base/dd.c:778 bus_for_each_drv+0x163/0x1e0 drivers/base/bus.c:454 __device_attach+0x223/0x3a0 drivers/base/dd.c:844 bus_probe_device+0x1f1/0x2a0 drivers/base/bus.c:514 device_add+0xad2/0x16e0 drivers/base/core.c:2106 usb_new_device.cold+0x537/0xccf drivers/usb/core/hub.c:2534 hub_port_connect drivers/usb/core/hub.c:5089 [inline] hub_port_connect_change drivers/usb/core/hub.c:5204 [inline] port_event drivers/usb/core/hub.c:5350 [inline] hub_event+0x138e/0x3b00 drivers/usb/core/hub.c:5432 process_one_work+0x90f/0x1580 kernel/workqueue.c:2269 worker_thread+0x9b/0xe20 kernel/workqueue.c:2415 kthread+0x313/0x420 kernel/kthread.c:253 ret_from_fork+0x3a/0x50 arch/x86/entry/entry_64.S:352 Reported-by: syzbot+cf4f2b6c24aff0a3edf6@syzkaller.appspotmail.com Signed-off-by: Ian Abbott Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_usb6501.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_usb6501.c b/drivers/staging/comedi/drivers/ni_usb6501.c index 9a0a96329a55..9b33e53a3329 100644 --- a/drivers/staging/comedi/drivers/ni_usb6501.c +++ b/drivers/staging/comedi/drivers/ni_usb6501.c @@ -527,6 +527,9 @@ static int ni6501_auto_attach(struct comedi_device *dev, if (!devpriv) return -ENOMEM; + mutex_init(&devpriv->mut); + usb_set_intfdata(intf, devpriv); + ret = ni6501_find_endpoints(dev); if (ret) return ret; @@ -535,9 +538,6 @@ static int ni6501_auto_attach(struct comedi_device *dev, if (ret) return ret; - mutex_init(&devpriv->mut); - usb_set_intfdata(intf, devpriv); - ret = comedi_alloc_subdevices(dev, 2); if (ret) return ret; -- GitLab From 9ae4c50f5e5284808370b47e22a2d0f7dcb38e34 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 15 Apr 2019 12:43:02 +0100 Subject: [PATCH 0206/1121] staging: comedi: ni_usb6501: Fix possible double-free of ->usb_rx_buf commit af4b54a2e5ba18259ff9aac445bf546dd60d037e upstream. `ni6501_alloc_usb_buffers()` is called from `ni6501_auto_attach()` to allocate RX and TX buffers for USB transfers. It allocates `devpriv->usb_rx_buf` followed by `devpriv->usb_tx_buf`. If the allocation of `devpriv->usb_tx_buf` fails, it frees `devpriv->usb_rx_buf`, leaving the pointer set dangling, and returns an error. Later, `ni6501_detach()` will be called from the core comedi module code to clean up. `ni6501_detach()` also frees both `devpriv->usb_rx_buf` and `devpriv->usb_tx_buf`, but `devpriv->usb_rx_buf` may have already beed freed, leading to a double-free error. Fix it bu removing the call to `kfree(devpriv->usb_rx_buf)` from `ni6501_alloc_usb_buffers()`, relying on `ni6501_detach()` to free the memory. Signed-off-by: Ian Abbott Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_usb6501.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_usb6501.c b/drivers/staging/comedi/drivers/ni_usb6501.c index 9b33e53a3329..009c5277387b 100644 --- a/drivers/staging/comedi/drivers/ni_usb6501.c +++ b/drivers/staging/comedi/drivers/ni_usb6501.c @@ -472,10 +472,8 @@ static int ni6501_alloc_usb_buffers(struct comedi_device *dev) size = usb_endpoint_maxp(devpriv->ep_tx); devpriv->usb_tx_buf = kzalloc(size, GFP_KERNEL); - if (!devpriv->usb_tx_buf) { - kfree(devpriv->usb_rx_buf); + if (!devpriv->usb_tx_buf) return -ENOMEM; - } return 0; } -- GitLab From cfb5fb042ee1c8dbfbce53016f331c97c4f29411 Mon Sep 17 00:00:00 2001 From: Hui Wang Date: Wed, 17 Apr 2019 16:10:32 +0800 Subject: [PATCH 0207/1121] ALSA: hda/realtek - add two more pin configuration sets to quirk table commit b26e36b7ef36a8a3a147b1609b2505f8a4ecf511 upstream. We have two Dell laptops which have the codec 10ec0236 and 10ec0256 respectively, the headset mic on them can't work, need to apply the quirk of ALC255_FIXUP_DELL1_MIC_NO_PRESENCE. So adding their pin configurations in the pin quirk table. Cc: Signed-off-by: Hui Wang Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/pci/hda/patch_realtek.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 9637d0bbdeb5..b9e720cb6f02 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6743,6 +6743,8 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { {0x12, 0x90a60140}, {0x14, 0x90170150}, {0x21, 0x02211020}), + SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, + {0x21, 0x02211020}), SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, {0x14, 0x90170110}, {0x21, 0x02211020}), @@ -6853,6 +6855,10 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { {0x21, 0x0221101f}), SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, ALC256_STANDARD_PINS), + SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, + {0x14, 0x90170110}, + {0x1b, 0x01011020}, + {0x21, 0x0221101f}), SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC, {0x14, 0x90170110}, {0x1b, 0x90a70130}, -- GitLab From d11a33e9ba584bb6f5cc74df9d74b26156ba9bb2 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 16 Apr 2019 17:06:33 +0200 Subject: [PATCH 0208/1121] ALSA: core: Fix card races between register and disconnect commit 2a3f7221acddfe1caa9ff09b3a8158c39b2fdeac upstream. There is a small race window in the card disconnection code that allows the registration of another card with the very same card id. This leads to a warning in procfs creation as caught by syzkaller. The problem is that we delete snd_cards and snd_cards_lock entries at the very beginning of the disconnection procedure. This makes the slot available to be assigned for another card object while the disconnection procedure is being processed. Then it becomes possible to issue a procfs registration with the existing file name although we check the conflict beforehand. The fix is simply to move the snd_cards and snd_cards_lock clearances at the end of the disconnection procedure. The references to these entries are merely either from the global proc files like /proc/asound/cards or from the card registration / disconnection, so it should be fine to shift at the very end. Reported-by: syzbot+48df349490c36f9f54ab@syzkaller.appspotmail.com Cc: Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/core/init.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/sound/core/init.c b/sound/core/init.c index 32ebe2f6bc59..dcb9199f5e4f 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -406,14 +406,7 @@ int snd_card_disconnect(struct snd_card *card) card->shutdown = 1; spin_unlock(&card->files_lock); - /* phase 1: disable fops (user space) operations for ALSA API */ - mutex_lock(&snd_card_mutex); - snd_cards[card->number] = NULL; - clear_bit(card->number, snd_cards_lock); - mutex_unlock(&snd_card_mutex); - - /* phase 2: replace file->f_op with special dummy operations */ - + /* replace file->f_op with special dummy operations */ spin_lock(&card->files_lock); list_for_each_entry(mfile, &card->files_list, list) { /* it's critical part, use endless loop */ @@ -429,7 +422,7 @@ int snd_card_disconnect(struct snd_card *card) } spin_unlock(&card->files_lock); - /* phase 3: notify all connected devices about disconnection */ + /* notify all connected devices about disconnection */ /* at this point, they cannot respond to any calls except release() */ #if IS_ENABLED(CONFIG_SND_MIXER_OSS) @@ -445,6 +438,13 @@ int snd_card_disconnect(struct snd_card *card) device_del(&card->card_dev); card->registered = false; } + + /* disable fops (user space) operations for ALSA API */ + mutex_lock(&snd_card_mutex); + snd_cards[card->number] = NULL; + clear_bit(card->number, snd_cards_lock); + mutex_unlock(&snd_card_mutex); + #ifdef CONFIG_PM wake_up(&card->power_sleep); #endif -- GitLab From 49c67980e52ba3bfc7675c777d4896e9ea741efe Mon Sep 17 00:00:00 2001 From: Jaesoo Lee Date: Tue, 9 Apr 2019 17:02:22 -0700 Subject: [PATCH 0209/1121] scsi: core: set result when the command cannot be dispatched commit be549d49115422f846b6d96ee8fd7173a5f7ceb0 upstream. When SCSI blk-mq is enabled, there is a bug in handling errors in scsi_queue_rq. Specifically, the bug is not setting result field of scsi_request correctly when the dispatch of the command has been failed. Since the upper layer code including the sg_io ioctl expects to receive any error status from result field of scsi_request, the error is silently ignored and this could cause data corruptions for some applications. Fixes: d285203cf647 ("scsi: add support for a blk-mq based I/O path.") Cc: Signed-off-by: Jaesoo Lee Reviewed-by: Hannes Reinecke Reviewed-by: Bart Van Assche Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/scsi_lib.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 37d366696d21..c89f0e129f58 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -2050,8 +2050,12 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx, blk_mq_delay_run_hw_queue(hctx, SCSI_QUEUE_DELAY); break; default: + if (unlikely(!scsi_device_online(sdev))) + scsi_req(req)->result = DID_NO_CONNECT << 16; + else + scsi_req(req)->result = DID_ERROR << 16; /* - * Make sure to release all allocated ressources when + * Make sure to release all allocated resources when * we hit an error, as we will never see this command * again. */ -- GitLab From bc6b83db8f5ae658f1db0855bcc03c8366b9084e Mon Sep 17 00:00:00 2001 From: Saurav Kashyap Date: Thu, 18 Apr 2019 03:40:12 -0700 Subject: [PATCH 0210/1121] Revert "scsi: fcoe: clear FC_RP_STARTED flags when receiving a LOGO" commit 0228034d8e5915b98c33db35a98f5e909e848ae9 upstream. This patch clears FC_RP_STARTED flag during logoff, because of this re-login(flogi) didn't happen to the switch. This reverts commit 1550ec458e0cf1a40a170ab1f4c46e3f52860f65. Fixes: 1550ec458e0c ("scsi: fcoe: clear FC_RP_STARTED flags when receiving a LOGO") Cc: # v4.18+ Signed-off-by: Saurav Kashyap Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/libfc/fc_rport.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c index 89b1f1af2fd4..31d31aad3de1 100644 --- a/drivers/scsi/libfc/fc_rport.c +++ b/drivers/scsi/libfc/fc_rport.c @@ -2164,7 +2164,6 @@ static void fc_rport_recv_logo_req(struct fc_lport *lport, struct fc_frame *fp) FC_RPORT_DBG(rdata, "Received LOGO request while in state %s\n", fc_rport_state(rdata)); - rdata->flags &= ~FC_RP_STARTED; fc_rport_enter_delete(rdata, RPORT_EV_STOP); mutex_unlock(&rdata->rp_mutex); kref_put(&rdata->kref, fc_rport_destroy); -- GitLab From c197e4693aca226675ffdce69ee5638842fbdfe6 Mon Sep 17 00:00:00 2001 From: "Suthikulpanit, Suravee" Date: Wed, 20 Mar 2019 08:12:28 +0000 Subject: [PATCH 0211/1121] Revert "svm: Fix AVIC incomplete IPI emulation" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 4a58038b9e420276157785afa0a0bbb4b9bc2265 upstream. This reverts commit bb218fbcfaaa3b115d4cd7a43c0ca164f3a96e57. As Oren Twaig pointed out the old discussion: https://patchwork.kernel.org/patch/8292231/ that the change coud potentially cause an extra IPI to be sent to the destination vcpu because the AVIC hardware already set the IRR bit before the incomplete IPI #VMEXIT with id=1 (target vcpu is not running). Since writting to ICR and ICR2 will also set the IRR. If something triggers the destination vcpu to get scheduled before the emulation finishes, then this could result in an additional IPI. Also, the issue mentioned in the commit bb218fbcfaaa was misdiagnosed. Cc: Radim Krčmáƙ Cc: Paolo Bonzini Reported-by: Oren Twaig Signed-off-by: Suravee Suthikulpanit Cc: stable@vger.kernel.org Signed-off-by: Paolo Bonzini Signed-off-by: Greg Kroah-Hartman --- arch/x86/kvm/svm.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 3a57816ea498..1296e44fd969 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -4017,14 +4017,25 @@ static int avic_incomplete_ipi_interception(struct vcpu_svm *svm) kvm_lapic_reg_write(apic, APIC_ICR, icrl); break; case AVIC_IPI_FAILURE_TARGET_NOT_RUNNING: { + int i; + struct kvm_vcpu *vcpu; + struct kvm *kvm = svm->vcpu.kvm; struct kvm_lapic *apic = svm->vcpu.arch.apic; /* - * Update ICR high and low, then emulate sending IPI, - * which is handled when writing APIC_ICR. + * At this point, we expect that the AVIC HW has already + * set the appropriate IRR bits on the valid target + * vcpus. So, we just need to kick the appropriate vcpu. */ - kvm_lapic_reg_write(apic, APIC_ICR2, icrh); - kvm_lapic_reg_write(apic, APIC_ICR, icrl); + kvm_for_each_vcpu(i, vcpu, kvm) { + bool m = kvm_apic_match_dest(vcpu, apic, + icrl & KVM_APIC_SHORT_MASK, + GET_APIC_DEST_FIELD(icrh), + icrl & KVM_APIC_DEST_MASK); + + if (m && !avic_vcpu_is_running(vcpu)) + kvm_vcpu_wake_up(vcpu); + } break; } case AVIC_IPI_FAILURE_INVALID_TARGET: -- GitLab From bb461ad8e6e0653fc6bd0f26d9173bab0aec235b Mon Sep 17 00:00:00 2001 From: Andrea Arcangeli Date: Thu, 18 Apr 2019 17:50:52 -0700 Subject: [PATCH 0212/1121] coredump: fix race condition between mmget_not_zero()/get_task_mm() and core dumping commit 04f5866e41fb70690e28397487d8bd8eea7d712a upstream. The core dumping code has always run without holding the mmap_sem for writing, despite that is the only way to ensure that the entire vma layout will not change from under it. Only using some signal serialization on the processes belonging to the mm is not nearly enough. This was pointed out earlier. For example in Hugh's post from Jul 2017: https://lkml.kernel.org/r/alpine.LSU.2.11.1707191716030.2055@eggly.anvils "Not strictly relevant here, but a related note: I was very surprised to discover, only quite recently, how handle_mm_fault() may be called without down_read(mmap_sem) - when core dumping. That seems a misguided optimization to me, which would also be nice to correct" In particular because the growsdown and growsup can move the vm_start/vm_end the various loops the core dump does around the vma will not be consistent if page faults can happen concurrently. Pretty much all users calling mmget_not_zero()/get_task_mm() and then taking the mmap_sem had the potential to introduce unexpected side effects in the core dumping code. Adding mmap_sem for writing around the ->core_dump invocation is a viable long term fix, but it requires removing all copy user and page faults and to replace them with get_dump_page() for all binary formats which is not suitable as a short term fix. For the time being this solution manually covers the places that can confuse the core dump either by altering the vma layout or the vma flags while it runs. Once ->core_dump runs under mmap_sem for writing the function mmget_still_valid() can be dropped. Allowing mmap_sem protected sections to run in parallel with the coredump provides some minor parallelism advantage to the swapoff code (which seems to be safe enough by never mangling any vma field and can keep doing swapins in parallel to the core dumping) and to some other corner case. In order to facilitate the backporting I added "Fixes: 86039bd3b4e6" however the side effect of this same race condition in /proc/pid/mem should be reproducible since before 2.6.12-rc2 so I couldn't add any other "Fixes:" because there's no hash beyond the git genesis commit. Because find_extend_vma() is the only location outside of the process context that could modify the "mm" structures under mmap_sem for reading, by adding the mmget_still_valid() check to it, all other cases that take the mmap_sem for reading don't need the new check after mmget_not_zero()/get_task_mm(). The expand_stack() in page fault context also doesn't need the new check, because all tasks under core dumping are frozen. Link: http://lkml.kernel.org/r/20190325224949.11068-1-aarcange@redhat.com Fixes: 86039bd3b4e6 ("userfaultfd: add new syscall to provide memory externalization") Signed-off-by: Andrea Arcangeli Reported-by: Jann Horn Suggested-by: Oleg Nesterov Acked-by: Peter Xu Reviewed-by: Mike Rapoport Reviewed-by: Oleg Nesterov Reviewed-by: Jann Horn Acked-by: Jason Gunthorpe Acked-by: Michal Hocko Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- fs/proc/task_mmu.c | 18 ++++++++++++++++++ fs/userfaultfd.c | 9 +++++++++ include/linux/sched/mm.h | 21 +++++++++++++++++++++ mm/mmap.c | 7 ++++++- 4 files changed, 54 insertions(+), 1 deletion(-) diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 5e63c459dc61..309d24118f9a 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -1160,6 +1160,24 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf, count = -EINTR; goto out_mm; } + /* + * Avoid to modify vma->vm_flags + * without locked ops while the + * coredump reads the vm_flags. + */ + if (!mmget_still_valid(mm)) { + /* + * Silently return "count" + * like if get_task_mm() + * failed. FIXME: should this + * function have returned + * -ESRCH if get_task_mm() + * failed like if + * get_proc_task() fails? + */ + up_write(&mm->mmap_sem); + goto out_mm; + } for (vma = mm->mmap; vma; vma = vma->vm_next) { vma->vm_flags &= ~VM_SOFTDIRTY; vma_set_page_prot(vma); diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c index 5f10052d2671..7a908d683258 100644 --- a/fs/userfaultfd.c +++ b/fs/userfaultfd.c @@ -627,6 +627,8 @@ static void userfaultfd_event_wait_completion(struct userfaultfd_ctx *ctx, /* the various vma->vm_userfaultfd_ctx still points to it */ down_write(&mm->mmap_sem); + /* no task can run (and in turn coredump) yet */ + VM_WARN_ON(!mmget_still_valid(mm)); for (vma = mm->mmap; vma; vma = vma->vm_next) if (vma->vm_userfaultfd_ctx.ctx == release_new_ctx) { vma->vm_userfaultfd_ctx = NULL_VM_UFFD_CTX; @@ -867,6 +869,8 @@ static int userfaultfd_release(struct inode *inode, struct file *file) * taking the mmap_sem for writing. */ down_write(&mm->mmap_sem); + if (!mmget_still_valid(mm)) + goto skip_mm; prev = NULL; for (vma = mm->mmap; vma; vma = vma->vm_next) { cond_resched(); @@ -889,6 +893,7 @@ static int userfaultfd_release(struct inode *inode, struct file *file) vma->vm_flags = new_flags; vma->vm_userfaultfd_ctx = NULL_VM_UFFD_CTX; } +skip_mm: up_write(&mm->mmap_sem); mmput(mm); wakeup: @@ -1327,6 +1332,8 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx, goto out; down_write(&mm->mmap_sem); + if (!mmget_still_valid(mm)) + goto out_unlock; vma = find_vma_prev(mm, start, &prev); if (!vma) goto out_unlock; @@ -1514,6 +1521,8 @@ static int userfaultfd_unregister(struct userfaultfd_ctx *ctx, goto out; down_write(&mm->mmap_sem); + if (!mmget_still_valid(mm)) + goto out_unlock; vma = find_vma_prev(mm, start, &prev); if (!vma) goto out_unlock; diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h index 3d49b91b674d..ef4ae0a545fe 100644 --- a/include/linux/sched/mm.h +++ b/include/linux/sched/mm.h @@ -57,6 +57,27 @@ static inline void mmdrop_async(struct mm_struct *mm) } } +/* + * This has to be called after a get_task_mm()/mmget_not_zero() + * followed by taking the mmap_sem for writing before modifying the + * vmas or anything the coredump pretends not to change from under it. + * + * NOTE: find_extend_vma() called from GUP context is the only place + * that can modify the "mm" (notably the vm_start/end) under mmap_sem + * for reading and outside the context of the process, so it is also + * the only case that holds the mmap_sem for reading that must call + * this function. Generally if the mmap_sem is hold for reading + * there's no need of this check after get_task_mm()/mmget_not_zero(). + * + * This function can be obsoleted and the check can be removed, after + * the coredump code will hold the mmap_sem for writing before + * invoking the ->core_dump methods. + */ +static inline bool mmget_still_valid(struct mm_struct *mm) +{ + return likely(!mm->core_state); +} + /** * mmget() - Pin the address space associated with a &struct mm_struct. * @mm: The address space to pin. diff --git a/mm/mmap.c b/mm/mmap.c index 00dab291e61d..59fd53b41c9c 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -2448,7 +2449,8 @@ find_extend_vma(struct mm_struct *mm, unsigned long addr) vma = find_vma_prev(mm, addr, &prev); if (vma && (vma->vm_start <= addr)) return vma; - if (!prev || expand_stack(prev, addr)) + /* don't alter vm_end if the coredump is running */ + if (!prev || !mmget_still_valid(mm) || expand_stack(prev, addr)) return NULL; if (prev->vm_flags & VM_LOCKED) populate_vma_page_range(prev, addr, prev->vm_end, NULL); @@ -2474,6 +2476,9 @@ find_extend_vma(struct mm_struct *mm, unsigned long addr) return vma; if (!(vma->vm_flags & VM_GROWSDOWN)) return NULL; + /* don't alter vm_start if the coredump is running */ + if (!mmget_still_valid(mm)) + return NULL; start = vma->vm_start; if (expand_stack(vma, addr)) return NULL; -- GitLab From 4de25ac0e2d22198395ae6f2ddd133fb824ea9e5 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sun, 31 Mar 2019 13:04:11 -0700 Subject: [PATCH 0213/1121] crypto: x86/poly1305 - fix overflow during partial reduction commit 678cce4019d746da6c680c48ba9e6d417803e127 upstream. The x86_64 implementation of Poly1305 produces the wrong result on some inputs because poly1305_4block_avx2() incorrectly assumes that when partially reducing the accumulator, the bits carried from limb 'd4' to limb 'h0' fit in a 32-bit integer. This is true for poly1305-generic which processes only one block at a time. However, it's not true for the AVX2 implementation, which processes 4 blocks at a time and therefore can produce intermediate limbs about 4x larger. Fix it by making the relevant calculations use 64-bit arithmetic rather than 32-bit. Note that most of the carries already used 64-bit arithmetic, but the d4 -> h0 carry was different for some reason. To be safe I also made the same change to the corresponding SSE2 code, though that only operates on 1 or 2 blocks at a time. I don't think it's really needed for poly1305_block_sse2(), but it doesn't hurt because it's already x86_64 code. It *might* be needed for poly1305_2block_sse2(), but overflows aren't easy to reproduce there. This bug was originally detected by my patches that improve testmgr to fuzz algorithms against their generic implementation. But also add a test vector which reproduces it directly (in the AVX2 case). Fixes: b1ccc8f4b631 ("crypto: poly1305 - Add a four block AVX2 variant for x86_64") Fixes: c70f4abef07a ("crypto: poly1305 - Add a SSE2 SIMD variant for x86_64") Cc: # v4.3+ Cc: Martin Willi Cc: Jason A. Donenfeld Signed-off-by: Eric Biggers Reviewed-by: Martin Willi Signed-off-by: Herbert Xu Signed-off-by: Greg Kroah-Hartman --- arch/x86/crypto/poly1305-avx2-x86_64.S | 14 +++++--- arch/x86/crypto/poly1305-sse2-x86_64.S | 22 ++++++++----- crypto/testmgr.h | 44 +++++++++++++++++++++++++- 3 files changed, 67 insertions(+), 13 deletions(-) diff --git a/arch/x86/crypto/poly1305-avx2-x86_64.S b/arch/x86/crypto/poly1305-avx2-x86_64.S index 3b6e70d085da..8457cdd47f75 100644 --- a/arch/x86/crypto/poly1305-avx2-x86_64.S +++ b/arch/x86/crypto/poly1305-avx2-x86_64.S @@ -323,6 +323,12 @@ ENTRY(poly1305_4block_avx2) vpaddq t2,t1,t1 vmovq t1x,d4 + # Now do a partial reduction mod (2^130)-5, carrying h0 -> h1 -> h2 -> + # h3 -> h4 -> h0 -> h1 to get h0,h2,h3,h4 < 2^26 and h1 < 2^26 + a small + # amount. Careful: we must not assume the carry bits 'd0 >> 26', + # 'd1 >> 26', 'd2 >> 26', 'd3 >> 26', and '(d4 >> 26) * 5' fit in 32-bit + # integers. It's true in a single-block implementation, but not here. + # d1 += d0 >> 26 mov d0,%rax shr $26,%rax @@ -361,16 +367,16 @@ ENTRY(poly1305_4block_avx2) # h0 += (d4 >> 26) * 5 mov d4,%rax shr $26,%rax - lea (%eax,%eax,4),%eax - add %eax,%ebx + lea (%rax,%rax,4),%rax + add %rax,%rbx # h4 = d4 & 0x3ffffff mov d4,%rax and $0x3ffffff,%eax mov %eax,h4 # h1 += h0 >> 26 - mov %ebx,%eax - shr $26,%eax + mov %rbx,%rax + shr $26,%rax add %eax,h1 # h0 = h0 & 0x3ffffff andl $0x3ffffff,%ebx diff --git a/arch/x86/crypto/poly1305-sse2-x86_64.S b/arch/x86/crypto/poly1305-sse2-x86_64.S index c88c670cb5fc..5851c7418fb7 100644 --- a/arch/x86/crypto/poly1305-sse2-x86_64.S +++ b/arch/x86/crypto/poly1305-sse2-x86_64.S @@ -253,16 +253,16 @@ ENTRY(poly1305_block_sse2) # h0 += (d4 >> 26) * 5 mov d4,%rax shr $26,%rax - lea (%eax,%eax,4),%eax - add %eax,%ebx + lea (%rax,%rax,4),%rax + add %rax,%rbx # h4 = d4 & 0x3ffffff mov d4,%rax and $0x3ffffff,%eax mov %eax,h4 # h1 += h0 >> 26 - mov %ebx,%eax - shr $26,%eax + mov %rbx,%rax + shr $26,%rax add %eax,h1 # h0 = h0 & 0x3ffffff andl $0x3ffffff,%ebx @@ -520,6 +520,12 @@ ENTRY(poly1305_2block_sse2) paddq t2,t1 movq t1,d4 + # Now do a partial reduction mod (2^130)-5, carrying h0 -> h1 -> h2 -> + # h3 -> h4 -> h0 -> h1 to get h0,h2,h3,h4 < 2^26 and h1 < 2^26 + a small + # amount. Careful: we must not assume the carry bits 'd0 >> 26', + # 'd1 >> 26', 'd2 >> 26', 'd3 >> 26', and '(d4 >> 26) * 5' fit in 32-bit + # integers. It's true in a single-block implementation, but not here. + # d1 += d0 >> 26 mov d0,%rax shr $26,%rax @@ -558,16 +564,16 @@ ENTRY(poly1305_2block_sse2) # h0 += (d4 >> 26) * 5 mov d4,%rax shr $26,%rax - lea (%eax,%eax,4),%eax - add %eax,%ebx + lea (%rax,%rax,4),%rax + add %rax,%rbx # h4 = d4 & 0x3ffffff mov d4,%rax and $0x3ffffff,%eax mov %eax,h4 # h1 += h0 >> 26 - mov %ebx,%eax - shr $26,%eax + mov %rbx,%rax + shr $26,%rax add %eax,h1 # h0 = h0 & 0x3ffffff andl $0x3ffffff,%ebx diff --git a/crypto/testmgr.h b/crypto/testmgr.h index fbc0fab5e79e..12835f072614 100644 --- a/crypto/testmgr.h +++ b/crypto/testmgr.h @@ -4660,7 +4660,49 @@ static const struct hash_testvec poly1305_tv_template[] = { .psize = 80, .digest = "\x13\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00", - }, + }, { /* Regression test for overflow in AVX2 implementation */ + .plaintext = "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff", + .psize = 300, + .digest = "\xfb\x5e\x96\xd8\x61\xd5\xc7\xc8" + "\x78\xe5\x87\xcc\x2d\x5a\x22\xe1", + } }; /* -- GitLab From 1f2b61e4657950b96722a5a6c6dd535347d55e8a Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Wed, 17 Apr 2019 00:21:21 -0700 Subject: [PATCH 0214/1121] arm64: futex: Restore oldval initialization to work around buggy compilers commit ff8acf929014b7f87315588e0daf8597c8aa9d1c upstream. Commit 045afc24124d ("arm64: futex: Fix FUTEX_WAKE_OP atomic ops with non-zero result value") removed oldval's zero initialization in arch_futex_atomic_op_inuser because it is not necessary. Unfortunately, Android's arm64 GCC 4.9.4 [1] does not agree: ../kernel/futex.c: In function 'do_futex': ../kernel/futex.c:1658:17: warning: 'oldval' may be used uninitialized in this function [-Wmaybe-uninitialized] return oldval == cmparg; ^ In file included from ../kernel/futex.c:73:0: ../arch/arm64/include/asm/futex.h:53:6: note: 'oldval' was declared here int oldval, ret, tmp; ^ GCC fails to follow that when ret is non-zero, futex_atomic_op_inuser returns right away, avoiding the uninitialized use that it claims. Restoring the zero initialization works around this issue. [1]: https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/ Cc: stable@vger.kernel.org Fixes: 045afc24124d ("arm64: futex: Fix FUTEX_WAKE_OP atomic ops with non-zero result value") Reviewed-by: Greg Kroah-Hartman Signed-off-by: Nathan Chancellor Signed-off-by: Catalin Marinas Signed-off-by: Greg Kroah-Hartman --- arch/arm64/include/asm/futex.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/futex.h b/arch/arm64/include/asm/futex.h index b447b4db423a..fd1e722f3821 100644 --- a/arch/arm64/include/asm/futex.h +++ b/arch/arm64/include/asm/futex.h @@ -50,7 +50,7 @@ do { \ static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *_uaddr) { - int oldval, ret, tmp; + int oldval = 0, ret, tmp; u32 __user *uaddr = __uaccess_mask_ptr(_uaddr); pagefault_disable(); -- GitLab From 877e9c51c96cd5ad92b45e36447e275374efc7af Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Sun, 24 Feb 2019 01:49:52 +0900 Subject: [PATCH 0215/1121] x86/kprobes: Verify stack frame on kretprobe commit 3ff9c075cc767b3060bdac12da72fc94dd7da1b8 upstream. Verify the stack frame pointer on kretprobe trampoline handler, If the stack frame pointer does not match, it skips the wrong entry and tries to find correct one. This can happen if user puts the kretprobe on the function which can be used in the path of ftrace user-function call. Such functions should not be probed, so this adds a warning message that reports which function should be blacklisted. Tested-by: Andrea Righi Signed-off-by: Masami Hiramatsu Acked-by: Steven Rostedt Cc: Linus Torvalds Cc: Mathieu Desnoyers Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/155094059185.6137.15527904013362842072.stgit@devbox Signed-off-by: Ingo Molnar Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/kprobes/core.c | 26 ++++++++++++++++++++++++++ include/linux/kprobes.h | 1 + 2 files changed, 27 insertions(+) diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index 65452d555f05..56cf6c263254 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c @@ -553,6 +553,7 @@ void arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs) unsigned long *sara = stack_addr(regs); ri->ret_addr = (kprobe_opcode_t *) *sara; + ri->fp = sara; /* Replace the return addr with trampoline addr */ *sara = (unsigned long) &kretprobe_trampoline; @@ -754,15 +755,21 @@ __visible __used void *trampoline_handler(struct pt_regs *regs) unsigned long flags, orig_ret_address = 0; unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline; kprobe_opcode_t *correct_ret_addr = NULL; + void *frame_pointer; + bool skipped = false; INIT_HLIST_HEAD(&empty_rp); kretprobe_hash_lock(current, &head, &flags); /* fixup registers */ #ifdef CONFIG_X86_64 regs->cs = __KERNEL_CS; + /* On x86-64, we use pt_regs->sp for return address holder. */ + frame_pointer = ®s->sp; #else regs->cs = __KERNEL_CS | get_kernel_rpl(); regs->gs = 0; + /* On x86-32, we use pt_regs->flags for return address holder. */ + frame_pointer = ®s->flags; #endif regs->ip = trampoline_address; regs->orig_ax = ~0UL; @@ -784,8 +791,25 @@ __visible __used void *trampoline_handler(struct pt_regs *regs) if (ri->task != current) /* another task is sharing our hash bucket */ continue; + /* + * Return probes must be pushed on this hash list correct + * order (same as return order) so that it can be poped + * correctly. However, if we find it is pushed it incorrect + * order, this means we find a function which should not be + * probed, because the wrong order entry is pushed on the + * path of processing other kretprobe itself. + */ + if (ri->fp != frame_pointer) { + if (!skipped) + pr_warn("kretprobe is stacked incorrectly. Trying to fixup.\n"); + skipped = true; + continue; + } orig_ret_address = (unsigned long)ri->ret_addr; + if (skipped) + pr_warn("%ps must be blacklisted because of incorrect kretprobe order\n", + ri->rp->kp.addr); if (orig_ret_address != trampoline_address) /* @@ -803,6 +827,8 @@ __visible __used void *trampoline_handler(struct pt_regs *regs) if (ri->task != current) /* another task is sharing our hash bucket */ continue; + if (ri->fp != frame_pointer) + continue; orig_ret_address = (unsigned long)ri->ret_addr; if (ri->rp && ri->rp->handler) { diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h index bd2684700b74..520702b82134 100644 --- a/include/linux/kprobes.h +++ b/include/linux/kprobes.h @@ -198,6 +198,7 @@ struct kretprobe_instance { struct kretprobe *rp; kprobe_opcode_t *ret_addr; struct task_struct *task; + void *fp; char data[0]; }; -- GitLab From 18a0a7c1f9d5150dd6da3adf93e2275717f6c6d6 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Sun, 24 Feb 2019 01:50:20 +0900 Subject: [PATCH 0216/1121] kprobes: Mark ftrace mcount handler functions nokprobe commit fabe38ab6b2bd9418350284c63825f13b8a6abba upstream. Mark ftrace mcount handler functions nokprobe since probing on these functions with kretprobe pushes return address incorrectly on kretprobe shadow stack. Reported-by: Francis Deslauriers Tested-by: Andrea Righi Signed-off-by: Masami Hiramatsu Acked-by: Steven Rostedt Acked-by: Steven Rostedt (VMware) Cc: Linus Torvalds Cc: Mathieu Desnoyers Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/155094062044.6137.6419622920568680640.stgit@devbox Signed-off-by: Ingo Molnar Signed-off-by: Greg Kroah-Hartman --- kernel/trace/ftrace.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 9937d7cf2a64..3e92852c8b23 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -33,6 +33,7 @@ #include #include #include +#include #include @@ -6035,7 +6036,7 @@ void ftrace_reset_array_ops(struct trace_array *tr) tr->ops->func = ftrace_stub; } -static inline void +static nokprobe_inline void __ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip, struct ftrace_ops *ignored, struct pt_regs *regs) { @@ -6098,11 +6099,13 @@ static void ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip, { __ftrace_ops_list_func(ip, parent_ip, NULL, regs); } +NOKPROBE_SYMBOL(ftrace_ops_list_func); #else static void ftrace_ops_no_ops(unsigned long ip, unsigned long parent_ip) { __ftrace_ops_list_func(ip, parent_ip, NULL, NULL); } +NOKPROBE_SYMBOL(ftrace_ops_no_ops); #endif /* @@ -6132,6 +6135,7 @@ static void ftrace_ops_assist_func(unsigned long ip, unsigned long parent_ip, preempt_enable_notrace(); trace_clear_recursion(bit); } +NOKPROBE_SYMBOL(ftrace_ops_assist_func); /** * ftrace_ops_get_func - get the function a trampoline should call -- GitLab From 5e8002fb22201466d27022c03a5911b30034ff7a Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Mon, 15 Apr 2019 15:01:25 +0900 Subject: [PATCH 0217/1121] kprobes: Fix error check when reusing optimized probes commit 5f843ed415581cfad4ef8fefe31c138a8346ca8a upstream. The following commit introduced a bug in one of our error paths: 819319fc9346 ("kprobes: Return error if we fail to reuse kprobe instead of BUG_ON()") it missed to handle the return value of kprobe_optready() as error-value. In reality, the kprobe_optready() returns a bool result, so "true" case must be passed instead of 0. This causes some errors on kprobe boot-time selftests on ARM: [ ] Beginning kprobe tests... [ ] Probe ARM code [ ] kprobe [ ] kretprobe [ ] ARM instruction simulation [ ] Check decoding tables [ ] Run test cases [ ] FAIL: test_case_handler not run [ ] FAIL: Test andge r10, r11, r14, asr r7 [ ] FAIL: Scenario 11 ... [ ] FAIL: Scenario 7 [ ] Total instruction simulation tests=1631, pass=1433 fail=198 [ ] kprobe tests failed This can happen if an optimized probe is unregistered and next kprobe is registered on same address until the previous probe is not reclaimed. If this happens, a hidden aggregated probe may be kept in memory, and no new kprobe can probe same address. Also, in that case register_kprobe() will return "1" instead of minus error value, which can mislead caller logic. Signed-off-by: Masami Hiramatsu Cc: Anil S Keshavamurthy Cc: David S . Miller Cc: Linus Torvalds Cc: Naveen N . Rao Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: stable@vger.kernel.org # v5.0+ Fixes: 819319fc9346 ("kprobes: Return error if we fail to reuse kprobe instead of BUG_ON()") Link: http://lkml.kernel.org/r/155530808559.32517.539898325433642204.stgit@devnote2 Signed-off-by: Ingo Molnar Signed-off-by: Greg Kroah-Hartman --- kernel/kprobes.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 5cbad4fb9107..ec11bb986a8b 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -703,7 +703,6 @@ static void unoptimize_kprobe(struct kprobe *p, bool force) static int reuse_unused_kprobe(struct kprobe *ap) { struct optimized_kprobe *op; - int ret; BUG_ON(!kprobe_unused(ap)); /* @@ -717,9 +716,8 @@ static int reuse_unused_kprobe(struct kprobe *ap) /* Enable the probe again */ ap->flags &= ~KPROBE_FLAG_DISABLED; /* Optimize it again (remove from op->list) */ - ret = kprobe_optready(ap); - if (ret) - return ret; + if (!kprobe_optready(ap)) + return -EINVAL; optimize_kprobe(ap); return 0; -- GitLab From 8a80544c5e6f50e7796380381f285488af47287f Mon Sep 17 00:00:00 2001 From: Vijayakumar Durai Date: Wed, 27 Mar 2019 11:03:17 +0100 Subject: [PATCH 0218/1121] rt2x00: do not increment sequence number while re-transmitting commit 746ba11f170603bf1eaade817553a6c2e9135bbe upstream. Currently rt2x00 devices retransmit the management frames with incremented sequence number if hardware is assigning the sequence. This is HW bug fixed already for non-QOS data frames, but it should be fixed for management frames except beacon. Without fix retransmitted frames have wrong SN: AlphaNet_e8:fb:36 Vivotek_52:31:51 Authentication, SN=1648, FN=0, Flags=........C Frame is not being retransmitted 1648 1 AlphaNet_e8:fb:36 Vivotek_52:31:51 Authentication, SN=1649, FN=0, Flags=....R...C Frame is being retransmitted 1649 1 AlphaNet_e8:fb:36 Vivotek_52:31:51 Authentication, SN=1650, FN=0, Flags=....R...C Frame is being retransmitted 1650 1 With the fix SN stays correctly the same: 88:6a:e3:e8:f9:a2 8c:f5:a3:88:76:87 Authentication, SN=1450, FN=0, Flags=........C 88:6a:e3:e8:f9:a2 8c:f5:a3:88:76:87 Authentication, SN=1450, FN=0, Flags=....R...C 88:6a:e3:e8:f9:a2 8c:f5:a3:88:76:87 Authentication, SN=1450, FN=0, Flags=....R...C Cc: stable@vger.kernel.org Signed-off-by: Vijayakumar Durai [sgruszka: simplify code, change comments and changelog] Signed-off-by: Stanislaw Gruszka Signed-off-by: Kalle Valo Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ralink/rt2x00/rt2x00.h | 1 - drivers/net/wireless/ralink/rt2x00/rt2x00mac.c | 10 ---------- drivers/net/wireless/ralink/rt2x00/rt2x00queue.c | 15 +++++++++------ 3 files changed, 9 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00.h b/drivers/net/wireless/ralink/rt2x00/rt2x00.h index 1f38c338ca7a..2a25996d058d 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h @@ -672,7 +672,6 @@ enum rt2x00_state_flags { CONFIG_CHANNEL_HT40, CONFIG_POWERSAVING, CONFIG_HT_DISABLED, - CONFIG_QOS_DISABLED, CONFIG_MONITORING, /* diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c b/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c index 6fe0c6abe0d6..84728c281f46 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c @@ -670,18 +670,8 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, rt2x00dev->intf_associated--; rt2x00leds_led_assoc(rt2x00dev, !!rt2x00dev->intf_associated); - - clear_bit(CONFIG_QOS_DISABLED, &rt2x00dev->flags); } - /* - * Check for access point which do not support 802.11e . We have to - * generate data frames sequence number in S/W for such AP, because - * of H/W bug. - */ - if (changes & BSS_CHANGED_QOS && !bss_conf->qos) - set_bit(CONFIG_QOS_DISABLED, &rt2x00dev->flags); - /* * When the erp information has changed, we should perform * additional configuration steps. For all other changes we are done. diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c index e1660b92b20c..1b0f2da8a10d 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c @@ -200,15 +200,18 @@ static void rt2x00queue_create_tx_descriptor_seq(struct rt2x00_dev *rt2x00dev, if (!rt2x00_has_cap_flag(rt2x00dev, REQUIRE_SW_SEQNO)) { /* * rt2800 has a H/W (or F/W) bug, device incorrectly increase - * seqno on retransmited data (non-QOS) frames. To workaround - * the problem let's generate seqno in software if QOS is - * disabled. + * seqno on retransmitted data (non-QOS) and management frames. + * To workaround the problem let's generate seqno in software. + * Except for beacons which are transmitted periodically by H/W + * hence hardware has to assign seqno for them. */ - if (test_bit(CONFIG_QOS_DISABLED, &rt2x00dev->flags)) - __clear_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags); - else + if (ieee80211_is_beacon(hdr->frame_control)) { + __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags); /* H/W will generate sequence number */ return; + } + + __clear_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags); } /* -- GitLab From 5efba8d96466b824aa9d205fe6eabcec2c6aa960 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 1 Mar 2019 14:48:37 +0100 Subject: [PATCH 0219/1121] mac80211: do not call driver wake_tx_queue op during reconfig commit 4856bfd230985e43e84c26473c91028ff0a533bd upstream. There are several scenarios in which mac80211 can call drv_wake_tx_queue after ieee80211_restart_hw has been called and has not yet completed. Driver private structs are considered uninitialized until mac80211 has uploaded the vifs, stations and keys again, so using private tx queue data during that time is not safe. The driver can also not rely on drv_reconfig_complete to figure out when it is safe to accept drv_wake_tx_queue calls again, because it is only called after all tx queues are woken again. To fix this, bail out early in drv_wake_tx_queue if local->in_reconfig is set. Cc: stable@vger.kernel.org Signed-off-by: Felix Fietkau Signed-off-by: Johannes Berg Signed-off-by: Greg Kroah-Hartman --- net/mac80211/driver-ops.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 4d82fe7d627c..284276b3e0b4 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -1164,6 +1164,9 @@ static inline void drv_wake_tx_queue(struct ieee80211_local *local, { struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->txq.vif); + if (local->in_reconfig) + return; + if (!check_sdata_in_driver(sdata)) return; -- GitLab From 59809557e84e22d1ae75703a237b020a4acc9508 Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Thu, 21 Mar 2019 21:15:22 +0000 Subject: [PATCH 0220/1121] perf/x86/amd: Add event map for AMD Family 17h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 3fe3331bb285700ab2253dbb07f8e478fcea2f1b upstream. Family 17h differs from prior families by: - Does not support an L2 cache miss event - It has re-enumerated PMC counters for: - L2 cache references - front & back end stalled cycles So we add a new amd_f17h_perfmon_event_map[] so that the generic perf event names will resolve to the correct h/w events on family 17h and above processors. Reference sections 2.1.13.3.3 (stalls) and 2.1.13.3.6 (L2): https://www.amd.com/system/files/TechDocs/54945_PPR_Family_17h_Models_00h-0Fh.pdf Signed-off-by: Kim Phillips Cc: # v4.9+ Cc: Alexander Shishkin Cc: Arnaldo Carvalho de Melo Cc: Borislav Petkov Cc: H. Peter Anvin Cc: Janakarajan Natarajan Cc: Jiri Olsa Cc: Linus Torvalds Cc: Martin LiĆĄka Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Pu Wen Cc: Suravee Suthikulpanit Cc: Thomas Gleixner Cc: linux-kernel@vger.kernel.org Fixes: e40ed1542dd7 ("perf/x86: Add perf support for AMD family-17h processors") [ Improved the formatting a bit. ] Signed-off-by: Ingo Molnar Signed-off-by: Greg Kroah-Hartman --- arch/x86/events/amd/core.c | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c index 3e5dd85b019a..263af6312329 100644 --- a/arch/x86/events/amd/core.c +++ b/arch/x86/events/amd/core.c @@ -117,22 +117,39 @@ static __initconst const u64 amd_hw_cache_event_ids }; /* - * AMD Performance Monitor K7 and later. + * AMD Performance Monitor K7 and later, up to and including Family 16h: */ static const u64 amd_perfmon_event_map[PERF_COUNT_HW_MAX] = { - [PERF_COUNT_HW_CPU_CYCLES] = 0x0076, - [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0, - [PERF_COUNT_HW_CACHE_REFERENCES] = 0x077d, - [PERF_COUNT_HW_CACHE_MISSES] = 0x077e, - [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c2, - [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c3, - [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x00d0, /* "Decoder empty" event */ - [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = 0x00d1, /* "Dispatch stalls" event */ + [PERF_COUNT_HW_CPU_CYCLES] = 0x0076, + [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0, + [PERF_COUNT_HW_CACHE_REFERENCES] = 0x077d, + [PERF_COUNT_HW_CACHE_MISSES] = 0x077e, + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c2, + [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c3, + [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x00d0, /* "Decoder empty" event */ + [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = 0x00d1, /* "Dispatch stalls" event */ +}; + +/* + * AMD Performance Monitor Family 17h and later: + */ +static const u64 amd_f17h_perfmon_event_map[PERF_COUNT_HW_MAX] = +{ + [PERF_COUNT_HW_CPU_CYCLES] = 0x0076, + [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0, + [PERF_COUNT_HW_CACHE_REFERENCES] = 0xff60, + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c2, + [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c3, + [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x0287, + [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = 0x0187, }; static u64 amd_pmu_event_map(int hw_event) { + if (boot_cpu_data.x86 >= 0x17) + return amd_f17h_perfmon_event_map[hw_event]; + return amd_perfmon_event_map[hw_event]; } -- GitLab From 607d291cfc7b5df5df5194fe8a32d22ec1960aa4 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Fri, 29 Mar 2019 17:47:43 -0700 Subject: [PATCH 0221/1121] x86/cpu/bugs: Use __initconst for 'const' init data commit 1de7edbb59c8f1b46071f66c5c97b8a59569eb51 upstream. Some of the recently added const tables use __initdata which causes section attribute conflicts. Use __initconst instead. Fixes: fa1202ef2243 ("x86/speculation: Add command line control") Signed-off-by: Andi Kleen Signed-off-by: Thomas Gleixner Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/20190330004743.29541-9-andi@firstfloor.org Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/cpu/bugs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index ec7aedba3d74..5567705e0601 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -271,7 +271,7 @@ static const struct { const char *option; enum spectre_v2_user_cmd cmd; bool secure; -} v2_user_options[] __initdata = { +} v2_user_options[] __initconst = { { "auto", SPECTRE_V2_USER_CMD_AUTO, false }, { "off", SPECTRE_V2_USER_CMD_NONE, false }, { "on", SPECTRE_V2_USER_CMD_FORCE, true }, @@ -406,7 +406,7 @@ static const struct { const char *option; enum spectre_v2_mitigation_cmd cmd; bool secure; -} mitigation_options[] __initdata = { +} mitigation_options[] __initconst = { { "off", SPECTRE_V2_CMD_NONE, false }, { "on", SPECTRE_V2_CMD_FORCE, true }, { "retpoline", SPECTRE_V2_CMD_RETPOLINE, false }, @@ -642,7 +642,7 @@ static const char * const ssb_strings[] = { static const struct { const char *option; enum ssb_mitigation_cmd cmd; -} ssb_mitigation_options[] __initdata = { +} ssb_mitigation_options[] __initconst = { { "auto", SPEC_STORE_BYPASS_CMD_AUTO }, /* Platform decides */ { "on", SPEC_STORE_BYPASS_CMD_ON }, /* Disable Speculative Store Bypass */ { "off", SPEC_STORE_BYPASS_CMD_NONE }, /* Don't touch Speculative Store Bypass */ -- GitLab From 55e7e51f750b91adbce9784cd0283f79b6d07af3 Mon Sep 17 00:00:00 2001 From: Kan Liang Date: Tue, 2 Apr 2019 12:44:58 -0700 Subject: [PATCH 0222/1121] perf/x86: Fix incorrect PEBS_REGS commit 9d5dcc93a6ddfc78124f006ccd3637ce070ef2fc upstream. PEBS_REGS used as mask for the supported registers for large PEBS. However, the mask cannot filter the sample_regs_user/sample_regs_intr correctly. (1ULL << PERF_REG_X86_*) should be used to replace PERF_REG_X86_*, which is only the index. Rename PEBS_REGS to PEBS_GP_REGS, because the mask is only for general purpose registers. Signed-off-by: Kan Liang Signed-off-by: Peter Zijlstra (Intel) Cc: Cc: Alexander Shishkin Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Vince Weaver Cc: acme@kernel.org Cc: jolsa@kernel.org Fixes: 2fe1bc1f501d ("perf/x86: Enable free running PEBS for REGS_USER/INTR") Link: https://lkml.kernel.org/r/20190402194509.2832-2-kan.liang@linux.intel.com [ Renamed it to PEBS_GP_REGS - as 'GPRS' is used elsewhere ;-) ] Signed-off-by: Ingo Molnar Signed-off-by: Greg Kroah-Hartman --- arch/x86/events/intel/core.c | 2 +- arch/x86/events/perf_event.h | 38 ++++++++++++++++++------------------ 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index dc8f8b3e6cec..99d45660242e 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -3001,7 +3001,7 @@ static unsigned long intel_pmu_free_running_flags(struct perf_event *event) flags &= ~PERF_SAMPLE_TIME; if (!event->attr.exclude_kernel) flags &= ~PERF_SAMPLE_REGS_USER; - if (event->attr.sample_regs_user & ~PEBS_REGS) + if (event->attr.sample_regs_user & ~PEBS_GP_REGS) flags &= ~(PERF_SAMPLE_REGS_USER | PERF_SAMPLE_REGS_INTR); return flags; } diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h index 84b3841c131d..bfe16631fd1d 100644 --- a/arch/x86/events/perf_event.h +++ b/arch/x86/events/perf_event.h @@ -95,25 +95,25 @@ struct amd_nb { PERF_SAMPLE_TRANSACTION | PERF_SAMPLE_PHYS_ADDR | \ PERF_SAMPLE_REGS_INTR | PERF_SAMPLE_REGS_USER) -#define PEBS_REGS \ - (PERF_REG_X86_AX | \ - PERF_REG_X86_BX | \ - PERF_REG_X86_CX | \ - PERF_REG_X86_DX | \ - PERF_REG_X86_DI | \ - PERF_REG_X86_SI | \ - PERF_REG_X86_SP | \ - PERF_REG_X86_BP | \ - PERF_REG_X86_IP | \ - PERF_REG_X86_FLAGS | \ - PERF_REG_X86_R8 | \ - PERF_REG_X86_R9 | \ - PERF_REG_X86_R10 | \ - PERF_REG_X86_R11 | \ - PERF_REG_X86_R12 | \ - PERF_REG_X86_R13 | \ - PERF_REG_X86_R14 | \ - PERF_REG_X86_R15) +#define PEBS_GP_REGS \ + ((1ULL << PERF_REG_X86_AX) | \ + (1ULL << PERF_REG_X86_BX) | \ + (1ULL << PERF_REG_X86_CX) | \ + (1ULL << PERF_REG_X86_DX) | \ + (1ULL << PERF_REG_X86_DI) | \ + (1ULL << PERF_REG_X86_SI) | \ + (1ULL << PERF_REG_X86_SP) | \ + (1ULL << PERF_REG_X86_BP) | \ + (1ULL << PERF_REG_X86_IP) | \ + (1ULL << PERF_REG_X86_FLAGS) | \ + (1ULL << PERF_REG_X86_R8) | \ + (1ULL << PERF_REG_X86_R9) | \ + (1ULL << PERF_REG_X86_R10) | \ + (1ULL << PERF_REG_X86_R11) | \ + (1ULL << PERF_REG_X86_R12) | \ + (1ULL << PERF_REG_X86_R13) | \ + (1ULL << PERF_REG_X86_R14) | \ + (1ULL << PERF_REG_X86_R15)) /* * Per register state. -- GitLab From 3b921dc46fe13fa20d7bc83df3eaa7511bb2717e Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 14 Apr 2019 19:51:06 +0200 Subject: [PATCH 0223/1121] x86/speculation: Prevent deadlock on ssb_state::lock commit 2f5fb19341883bb6e37da351bc3700489d8506a7 upstream. Mikhail reported a lockdep splat related to the AMD specific ssb_state lock: CPU0 CPU1 lock(&st->lock); local_irq_disable(); lock(&(&sighand->siglock)->rlock); lock(&st->lock); lock(&(&sighand->siglock)->rlock); *** DEADLOCK *** The connection between sighand->siglock and st->lock comes through seccomp, which takes st->lock while holding sighand->siglock. Make sure interrupts are disabled when __speculation_ctrl_update() is invoked via prctl() -> speculation_ctrl_update(). Add a lockdep assert to catch future offenders. Fixes: 1f50ddb4f418 ("x86/speculation: Handle HT correctly on AMD") Reported-by: Mikhail Gavrilov Signed-off-by: Thomas Gleixner Tested-by: Mikhail Gavrilov Cc: Thomas Lendacky Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/alpine.DEB.2.21.1904141948200.4917@nanos.tec.linutronix.de Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/process.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index a98d1cdd6299..d2ef967bfafb 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -465,10 +465,12 @@ static unsigned long speculation_ctrl_update_tif(struct task_struct *tsk) void speculation_ctrl_update(unsigned long tif) { + unsigned long flags; + /* Forced update. Make sure all relevant TIF flags are different */ - preempt_disable(); + local_irq_save(flags); __speculation_ctrl_update(~tif, tif); - preempt_enable(); + local_irq_restore(flags); } /* Called from seccomp/prctl update */ -- GitLab From 4cec35e8e251eb953869c199c2a33e841e422fc4 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Thu, 19 Apr 2018 18:41:55 +0200 Subject: [PATCH 0224/1121] crypto: crypto4xx - properly set IV after de- and encrypt [ Upstream commit fc340115ffb8235c1bbd200c28855e6373d0dd1a ] This patch fixes cts(cbc(aes)) test when cbc-aes-ppc4xx is used. alg: skcipher: Test 1 failed (invalid result) on encryption for cts(cbc-aes-ppc4xx) 00000000: 4b 10 75 fc 2f 14 1b 6a 27 35 37 33 d1 b7 70 05 00000010: 97 alg: skcipher: Failed to load transform for cts(cbc(aes)): -2 The CTS cipher mode expect the IV (req->iv) of skcipher_request to contain the last ciphertext block after the {en,de}crypt operation is complete. Fix this issue for the AMCC Crypto4xx hardware engine. The tcrypt test case for cts(cbc(aes)) is now correctly passed. name : cts(cbc(aes)) driver : cts(cbc-aes-ppc4xx) module : cts priority : 300 refcnt : 1 selftest : passed internal : no type : skcipher async : yes blocksize : 16 min keysize : 16 max keysize : 32 ivsize : 16 chunksize : 16 walksize : 16 Signed-off-by: Christian Lamparter Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/amcc/crypto4xx_alg.c | 3 ++- drivers/crypto/amcc/crypto4xx_core.c | 9 +++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/crypto/amcc/crypto4xx_alg.c b/drivers/crypto/amcc/crypto4xx_alg.c index 4afca3968773..e3b8bebfdd30 100644 --- a/drivers/crypto/amcc/crypto4xx_alg.c +++ b/drivers/crypto/amcc/crypto4xx_alg.c @@ -138,7 +138,8 @@ static int crypto4xx_setkey_aes(struct crypto_ablkcipher *cipher, sa = (struct dynamic_sa_ctl *) ctx->sa_in; ctx->hash_final = 0; - set_dynamic_sa_command_0(sa, SA_NOT_SAVE_HASH, SA_NOT_SAVE_IV, + set_dynamic_sa_command_0(sa, SA_NOT_SAVE_HASH, (cm == CRYPTO_MODE_CBC ? + SA_SAVE_IV : SA_NOT_SAVE_IV), SA_LOAD_HASH_FROM_SA, SA_LOAD_IV_FROM_STATE, SA_NO_HEADER_PROC, SA_HASH_ALG_NULL, SA_CIPHER_ALG_AES, SA_PAD_TYPE_ZERO, diff --git a/drivers/crypto/amcc/crypto4xx_core.c b/drivers/crypto/amcc/crypto4xx_core.c index 3f9eee7e555f..8d4d8db244e9 100644 --- a/drivers/crypto/amcc/crypto4xx_core.c +++ b/drivers/crypto/amcc/crypto4xx_core.c @@ -645,6 +645,15 @@ static u32 crypto4xx_ablkcipher_done(struct crypto4xx_device *dev, addr = dma_map_page(dev->core_dev->device, sg_page(dst), dst->offset, dst->length, DMA_FROM_DEVICE); } + + if (pd_uinfo->sa_va->sa_command_0.bf.save_iv == SA_SAVE_IV) { + struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req); + + crypto4xx_memcpy_from_le32((u32 *)req->iv, + pd_uinfo->sr_va->save_iv, + crypto_skcipher_ivsize(skcipher)); + } + crypto4xx_ret_sg_desc(dev, pd_uinfo); if (ablk_req->base.complete != NULL) ablk_req->base.complete(&ablk_req->base, 0); -- GitLab From f83cf258b928b94a908d88e692f14ef459f927db Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Thu, 15 Nov 2018 15:53:41 +0200 Subject: [PATCH 0225/1121] mmc: sdhci: Fix data command CRC error handling [ Upstream commit 4bf780996669280171c9cd58196512849b93434e ] Existing data command CRC error handling is non-standard and does not work with some Intel host controllers. Specifically, the assumption that the host controller will continue operating normally after the error interrupt, is not valid. Change the driver to handle the error in the same manner as a data CRC error, taking care to ensure that the data line reset is done for single or multi-block transfers, and it is done before unmapping DMA. Signed-off-by: Adrian Hunter Signed-off-by: Ulf Hansson Signed-off-by: Sasha Levin --- drivers/mmc/host/sdhci.c | 40 +++++++++++++++------------------------- 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 0edcc2763f3c..2d59b0389567 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1002,8 +1002,7 @@ static bool sdhci_needs_reset(struct sdhci_host *host, struct mmc_request *mrq) return (!(host->flags & SDHCI_DEVICE_DEAD) && ((mrq->cmd && mrq->cmd->error) || (mrq->sbc && mrq->sbc->error) || - (mrq->data && ((mrq->data->error && !mrq->data->stop) || - (mrq->data->stop && mrq->data->stop->error))) || + (mrq->data && mrq->data->stop && mrq->data->stop->error) || (host->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST))); } @@ -1055,6 +1054,16 @@ static void sdhci_finish_data(struct sdhci_host *host) host->data = NULL; host->data_cmd = NULL; + /* + * The controller needs a reset of internal state machines upon error + * conditions. + */ + if (data->error) { + if (!host->cmd || host->cmd == data_cmd) + sdhci_do_reset(host, SDHCI_RESET_CMD); + sdhci_do_reset(host, SDHCI_RESET_DATA); + } + if ((host->flags & (SDHCI_REQ_USE_DMA | SDHCI_USE_ADMA)) == (SDHCI_REQ_USE_DMA | SDHCI_USE_ADMA)) sdhci_adma_table_post(host, data); @@ -1079,17 +1088,6 @@ static void sdhci_finish_data(struct sdhci_host *host) if (data->stop && (data->error || !data->mrq->sbc)) { - - /* - * The controller needs a reset of internal state machines - * upon error conditions. - */ - if (data->error) { - if (!host->cmd || host->cmd == data_cmd) - sdhci_do_reset(host, SDHCI_RESET_CMD); - sdhci_do_reset(host, SDHCI_RESET_DATA); - } - /* * 'cap_cmd_during_tfr' request must not use the command line * after mmc_command_done() has been called. It is upper layer's @@ -2560,7 +2558,7 @@ static void sdhci_timeout_data_timer(unsigned long data) * * \*****************************************************************************/ -static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask) +static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask, u32 *intmask_p) { if (!host->cmd) { /* @@ -2583,20 +2581,12 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask) else host->cmd->error = -EILSEQ; - /* - * If this command initiates a data phase and a response - * CRC error is signalled, the card can start transferring - * data - the card may have received the command without - * error. We must not terminate the mmc_request early. - * - * If the card did not receive the command or returned an - * error which prevented it sending data, the data phase - * will time out. - */ + /* Treat data command CRC error the same as data CRC error */ if (host->cmd->data && (intmask & (SDHCI_INT_CRC | SDHCI_INT_TIMEOUT)) == SDHCI_INT_CRC) { host->cmd = NULL; + *intmask_p |= SDHCI_INT_DATA_CRC; return; } @@ -2824,7 +2814,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) } if (intmask & SDHCI_INT_CMD_MASK) - sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK); + sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK, &intmask); if (intmask & SDHCI_INT_DATA_MASK) sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK); -- GitLab From 45fd8679ea86bffb352132a1df4917c3d11375aa Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Thu, 15 Nov 2018 15:53:42 +0200 Subject: [PATCH 0226/1121] mmc: sdhci: Rename SDHCI_ACMD12_ERR and SDHCI_INT_ACMD12ERR [ Upstream commit 869f8a69bb3a4aec4eb914a330d4ba53a9eed495 ] The SDHCI_ACMD12_ERR register is used for auto-CMD23 and auto-CMD12 errors, as is the SDHCI_INT_ACMD12ERR interrupt bit. Rename them to SDHCI_AUTO_CMD_STATUS and SDHCI_INT_AUTO_CMD_ERR respectively. Signed-off-by: Adrian Hunter Signed-off-by: Ulf Hansson Signed-off-by: Sasha Levin --- drivers/mmc/host/sdhci-esdhc-imx.c | 12 ++++++------ drivers/mmc/host/sdhci.c | 4 ++-- drivers/mmc/host/sdhci.h | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index ff5c4ad37a3a..8c0b80a54e4d 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -425,7 +425,7 @@ static u16 esdhc_readw_le(struct sdhci_host *host, int reg) val = readl(host->ioaddr + ESDHC_MIX_CTRL); else if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) /* the std tuning bits is in ACMD12_ERR for imx6sl */ - val = readl(host->ioaddr + SDHCI_ACMD12_ERR); + val = readl(host->ioaddr + SDHCI_AUTO_CMD_STATUS); } if (val & ESDHC_MIX_CTRL_EXE_TUNE) @@ -490,7 +490,7 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg) } writel(new_val , host->ioaddr + ESDHC_MIX_CTRL); } else if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) { - u32 v = readl(host->ioaddr + SDHCI_ACMD12_ERR); + u32 v = readl(host->ioaddr + SDHCI_AUTO_CMD_STATUS); u32 m = readl(host->ioaddr + ESDHC_MIX_CTRL); if (val & SDHCI_CTRL_TUNED_CLK) { v |= ESDHC_MIX_CTRL_SMPCLK_SEL; @@ -508,7 +508,7 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg) v &= ~ESDHC_MIX_CTRL_EXE_TUNE; } - writel(v, host->ioaddr + SDHCI_ACMD12_ERR); + writel(v, host->ioaddr + SDHCI_AUTO_CMD_STATUS); writel(m, host->ioaddr + ESDHC_MIX_CTRL); } return; @@ -937,9 +937,9 @@ static void esdhc_reset_tuning(struct sdhci_host *host) writel(ctrl, host->ioaddr + ESDHC_MIX_CTRL); writel(0, host->ioaddr + ESDHC_TUNE_CTRL_STATUS); } else if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) { - ctrl = readl(host->ioaddr + SDHCI_ACMD12_ERR); + ctrl = readl(host->ioaddr + SDHCI_AUTO_CMD_STATUS); ctrl &= ~ESDHC_MIX_CTRL_SMPCLK_SEL; - writel(ctrl, host->ioaddr + SDHCI_ACMD12_ERR); + writel(ctrl, host->ioaddr + SDHCI_AUTO_CMD_STATUS); } } } @@ -1303,7 +1303,7 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev) /* clear tuning bits in case ROM has set it already */ writel(0x0, host->ioaddr + ESDHC_MIX_CTRL); - writel(0x0, host->ioaddr + SDHCI_ACMD12_ERR); + writel(0x0, host->ioaddr + SDHCI_AUTO_CMD_STATUS); writel(0x0, host->ioaddr + ESDHC_TUNE_CTRL_STATUS); } diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 2d59b0389567..8abbe40a9a05 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -82,8 +82,8 @@ void sdhci_dumpregs(struct sdhci_host *host) SDHCI_DUMP("Int enab: 0x%08x | Sig enab: 0x%08x\n", sdhci_readl(host, SDHCI_INT_ENABLE), sdhci_readl(host, SDHCI_SIGNAL_ENABLE)); - SDHCI_DUMP("AC12 err: 0x%08x | Slot int: 0x%08x\n", - sdhci_readw(host, SDHCI_ACMD12_ERR), + SDHCI_DUMP("ACmd stat: 0x%08x | Slot int: 0x%08x\n", + sdhci_readw(host, SDHCI_AUTO_CMD_STATUS), sdhci_readw(host, SDHCI_SLOT_INT_STATUS)); SDHCI_DUMP("Caps: 0x%08x | Caps_1: 0x%08x\n", sdhci_readl(host, SDHCI_CAPABILITIES), diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 1d7d61e25dbf..860b2c729e68 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -144,7 +144,7 @@ #define SDHCI_INT_DATA_CRC 0x00200000 #define SDHCI_INT_DATA_END_BIT 0x00400000 #define SDHCI_INT_BUS_POWER 0x00800000 -#define SDHCI_INT_ACMD12ERR 0x01000000 +#define SDHCI_INT_AUTO_CMD_ERR 0x01000000 #define SDHCI_INT_ADMA_ERROR 0x02000000 #define SDHCI_INT_NORMAL_MASK 0x00007FFF @@ -166,7 +166,7 @@ #define SDHCI_CQE_INT_MASK (SDHCI_CQE_INT_ERR_MASK | SDHCI_INT_CQE) -#define SDHCI_ACMD12_ERR 0x3C +#define SDHCI_AUTO_CMD_STATUS 0x3C #define SDHCI_HOST_CONTROL2 0x3E #define SDHCI_CTRL_UHS_MASK 0x0007 -- GitLab From c728ffc5150c0e7b6c895f281a3d37c1bef52a10 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Thu, 15 Nov 2018 15:53:43 +0200 Subject: [PATCH 0227/1121] mmc: sdhci: Handle auto-command errors [ Upstream commit af849c86109d79222e549826068bbf4e7f9a2472 ] If the host controller supports auto-commands then enable the auto-command error interrupt and handle it. In the case of auto-CMD23, the error is treated the same as manual CMD23 error. In the case of auto-CMD12, commands-during-transfer are not permitted, so the error handling is treated the same as a data error. Signed-off-by: Adrian Hunter Signed-off-by: Ulf Hansson Signed-off-by: Sasha Levin --- drivers/mmc/host/sdhci.c | 35 +++++++++++++++++++++++++++++++++++ drivers/mmc/host/sdhci.h | 7 ++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 8abbe40a9a05..9540fda7fc6b 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -790,6 +790,11 @@ static void sdhci_set_transfer_irqs(struct sdhci_host *host) else host->ier = (host->ier & ~dma_irqs) | pio_irqs; + if (host->flags & (SDHCI_AUTO_CMD23 | SDHCI_AUTO_CMD12)) + host->ier |= SDHCI_INT_AUTO_CMD_ERR; + else + host->ier &= ~SDHCI_INT_AUTO_CMD_ERR; + sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); } @@ -2560,6 +2565,21 @@ static void sdhci_timeout_data_timer(unsigned long data) static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask, u32 *intmask_p) { + /* Handle auto-CMD12 error */ + if (intmask & SDHCI_INT_AUTO_CMD_ERR && host->data_cmd) { + struct mmc_request *mrq = host->data_cmd->mrq; + u16 auto_cmd_status = sdhci_readw(host, SDHCI_AUTO_CMD_STATUS); + int data_err_bit = (auto_cmd_status & SDHCI_AUTO_CMD_TIMEOUT) ? + SDHCI_INT_DATA_TIMEOUT : + SDHCI_INT_DATA_CRC; + + /* Treat auto-CMD12 error the same as data error */ + if (!mrq->sbc && (host->flags & SDHCI_AUTO_CMD12)) { + *intmask_p |= data_err_bit; + return; + } + } + if (!host->cmd) { /* * SDHCI recovers from errors by resetting the cmd and data @@ -2594,6 +2614,21 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask, u32 *intmask_p) return; } + /* Handle auto-CMD23 error */ + if (intmask & SDHCI_INT_AUTO_CMD_ERR) { + struct mmc_request *mrq = host->cmd->mrq; + u16 auto_cmd_status = sdhci_readw(host, SDHCI_AUTO_CMD_STATUS); + int err = (auto_cmd_status & SDHCI_AUTO_CMD_TIMEOUT) ? + -ETIMEDOUT : + -EILSEQ; + + if (mrq->sbc && (host->flags & SDHCI_AUTO_CMD23)) { + mrq->sbc->error = err; + sdhci_finish_mrq(host, mrq); + return; + } + } + if (intmask & SDHCI_INT_RESPONSE) sdhci_finish_command(host); } diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 860b2c729e68..c0d5458c36d4 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -151,7 +151,8 @@ #define SDHCI_INT_ERROR_MASK 0xFFFF8000 #define SDHCI_INT_CMD_MASK (SDHCI_INT_RESPONSE | SDHCI_INT_TIMEOUT | \ - SDHCI_INT_CRC | SDHCI_INT_END_BIT | SDHCI_INT_INDEX) + SDHCI_INT_CRC | SDHCI_INT_END_BIT | SDHCI_INT_INDEX | \ + SDHCI_INT_AUTO_CMD_ERR) #define SDHCI_INT_DATA_MASK (SDHCI_INT_DATA_END | SDHCI_INT_DMA_END | \ SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | \ SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \ @@ -167,6 +168,10 @@ #define SDHCI_CQE_INT_MASK (SDHCI_CQE_INT_ERR_MASK | SDHCI_INT_CQE) #define SDHCI_AUTO_CMD_STATUS 0x3C +#define SDHCI_AUTO_CMD_TIMEOUT 0x00000002 +#define SDHCI_AUTO_CMD_CRC 0x00000004 +#define SDHCI_AUTO_CMD_END_BIT 0x00000008 +#define SDHCI_AUTO_CMD_INDEX 0x00000010 #define SDHCI_HOST_CONTROL2 0x3E #define SDHCI_CTRL_UHS_MASK 0x0007 -- GitLab From 1a7fe5cb7a04ebc00cc282bb227bb8b78f52138b Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 22 Nov 2018 13:28:41 +0900 Subject: [PATCH 0228/1121] modpost: file2alias: go back to simple devtable lookup commit ec91e78d378cc5d4b43805a1227d8e04e5dfa17d upstream. Commit e49ce14150c6 ("modpost: use linker section to generate table.") was not so cool as we had expected first; it ended up with ugly section hacks when commit dd2a3acaecd7 ("mod/file2alias: make modpost compile on darwin again") came in. Given a certain degree of unknowledge about the link stage of host programs, I really want to see simple, stupid table lookup so that this works in the same way regardless of the underlying executable format. Signed-off-by: Masahiro Yamada Acked-by: Mathieu Malaterre [nc: Omit rpmsg, sdw, tbsvc, and typec as they do not exist here] Signed-off-by: Nathan Chancellor Signed-off-by: Sasha Levin --- scripts/mod/file2alias.c | 136 +++++++++++++-------------------------- 1 file changed, 45 insertions(+), 91 deletions(-) diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 29d6699d5a06..6e3ae94cf123 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -50,46 +50,6 @@ struct devtable { void *function; }; -#define ___cat(a,b) a ## b -#define __cat(a,b) ___cat(a,b) - -/* we need some special handling for this host tool running eventually on - * Darwin. The Mach-O section handling is a bit different than ELF section - * handling. The differnces in detail are: - * a) we have segments which have sections - * b) we need a API call to get the respective section symbols */ -#if defined(__MACH__) -#include - -#define INIT_SECTION(name) do { \ - unsigned long name ## _len; \ - char *__cat(pstart_,name) = getsectdata("__TEXT", \ - #name, &__cat(name,_len)); \ - char *__cat(pstop_,name) = __cat(pstart_,name) + \ - __cat(name, _len); \ - __cat(__start_,name) = (void *)__cat(pstart_,name); \ - __cat(__stop_,name) = (void *)__cat(pstop_,name); \ - } while (0) -#define SECTION(name) __attribute__((section("__TEXT, " #name))) - -struct devtable **__start___devtable, **__stop___devtable; -#else -#define INIT_SECTION(name) /* no-op for ELF */ -#define SECTION(name) __attribute__((section(#name))) - -/* We construct a table of pointers in an ELF section (pointers generally - * go unpadded by gcc). ld creates boundary syms for us. */ -extern struct devtable *__start___devtable[], *__stop___devtable[]; -#endif /* __MACH__ */ - -#if !defined(__used) -# if __GNUC__ == 3 && __GNUC_MINOR__ < 3 -# define __used __attribute__((__unused__)) -# else -# define __used __attribute__((__used__)) -# endif -#endif - /* Define a variable f that holds the value of field f of struct devid * based at address m. */ @@ -102,16 +62,6 @@ extern struct devtable *__start___devtable[], *__stop___devtable[]; #define DEF_FIELD_ADDR(m, devid, f) \ typeof(((struct devid *)0)->f) *f = ((m) + OFF_##devid##_##f) -/* Add a table entry. We test function type matches while we're here. */ -#define ADD_TO_DEVTABLE(device_id, type, function) \ - static struct devtable __cat(devtable,__LINE__) = { \ - device_id + 0*sizeof((function)((const char *)NULL, \ - (void *)NULL, \ - (char *)NULL)), \ - SIZE_##type, (function) }; \ - static struct devtable *SECTION(__devtable) __used \ - __cat(devtable_ptr,__LINE__) = &__cat(devtable,__LINE__) - #define ADD(str, sep, cond, field) \ do { \ strcat(str, sep); \ @@ -431,7 +381,6 @@ static int do_hid_entry(const char *filename, return 1; } -ADD_TO_DEVTABLE("hid", hid_device_id, do_hid_entry); /* Looks like: ieee1394:venNmoNspNverN */ static int do_ieee1394_entry(const char *filename, @@ -456,7 +405,6 @@ static int do_ieee1394_entry(const char *filename, add_wildcard(alias); return 1; } -ADD_TO_DEVTABLE("ieee1394", ieee1394_device_id, do_ieee1394_entry); /* Looks like: pci:vNdNsvNsdNbcNscNiN. */ static int do_pci_entry(const char *filename, @@ -500,7 +448,6 @@ static int do_pci_entry(const char *filename, add_wildcard(alias); return 1; } -ADD_TO_DEVTABLE("pci", pci_device_id, do_pci_entry); /* looks like: "ccw:tNmNdtNdmN" */ static int do_ccw_entry(const char *filename, @@ -524,7 +471,6 @@ static int do_ccw_entry(const char *filename, add_wildcard(alias); return 1; } -ADD_TO_DEVTABLE("ccw", ccw_device_id, do_ccw_entry); /* looks like: "ap:tN" */ static int do_ap_entry(const char *filename, @@ -535,7 +481,6 @@ static int do_ap_entry(const char *filename, sprintf(alias, "ap:t%02X*", dev_type); return 1; } -ADD_TO_DEVTABLE("ap", ap_device_id, do_ap_entry); /* looks like: "css:tN" */ static int do_css_entry(const char *filename, @@ -546,7 +491,6 @@ static int do_css_entry(const char *filename, sprintf(alias, "css:t%01X", type); return 1; } -ADD_TO_DEVTABLE("css", css_device_id, do_css_entry); /* Looks like: "serio:tyNprNidNexN" */ static int do_serio_entry(const char *filename, @@ -566,7 +510,6 @@ static int do_serio_entry(const char *filename, add_wildcard(alias); return 1; } -ADD_TO_DEVTABLE("serio", serio_device_id, do_serio_entry); /* looks like: "acpi:ACPI0003" or "acpi:PNP0C0B" or "acpi:LNXVIDEO" or * "acpi:bbsspp" (bb=base-class, ss=sub-class, pp=prog-if) @@ -604,7 +547,6 @@ static int do_acpi_entry(const char *filename, } return 1; } -ADD_TO_DEVTABLE("acpi", acpi_device_id, do_acpi_entry); /* looks like: "pnp:dD" */ static void do_pnp_device_entry(void *symval, unsigned long size, @@ -725,7 +667,6 @@ static int do_pcmcia_entry(const char *filename, add_wildcard(alias); return 1; } -ADD_TO_DEVTABLE("pcmcia", pcmcia_device_id, do_pcmcia_entry); static int do_vio_entry(const char *filename, void *symval, char *alias) @@ -745,7 +686,6 @@ static int do_vio_entry(const char *filename, void *symval, add_wildcard(alias); return 1; } -ADD_TO_DEVTABLE("vio", vio_device_id, do_vio_entry); #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) @@ -818,7 +758,6 @@ static int do_input_entry(const char *filename, void *symval, do_input(alias, *swbit, 0, INPUT_DEVICE_ID_SW_MAX); return 1; } -ADD_TO_DEVTABLE("input", input_device_id, do_input_entry); static int do_eisa_entry(const char *filename, void *symval, char *alias) @@ -830,7 +769,6 @@ static int do_eisa_entry(const char *filename, void *symval, strcat(alias, "*"); return 1; } -ADD_TO_DEVTABLE("eisa", eisa_device_id, do_eisa_entry); /* Looks like: parisc:tNhvNrevNsvN */ static int do_parisc_entry(const char *filename, void *symval, @@ -850,7 +788,6 @@ static int do_parisc_entry(const char *filename, void *symval, add_wildcard(alias); return 1; } -ADD_TO_DEVTABLE("parisc", parisc_device_id, do_parisc_entry); /* Looks like: sdio:cNvNdN. */ static int do_sdio_entry(const char *filename, @@ -867,7 +804,6 @@ static int do_sdio_entry(const char *filename, add_wildcard(alias); return 1; } -ADD_TO_DEVTABLE("sdio", sdio_device_id, do_sdio_entry); /* Looks like: ssb:vNidNrevN. */ static int do_ssb_entry(const char *filename, @@ -884,7 +820,6 @@ static int do_ssb_entry(const char *filename, add_wildcard(alias); return 1; } -ADD_TO_DEVTABLE("ssb", ssb_device_id, do_ssb_entry); /* Looks like: bcma:mNidNrevNclN. */ static int do_bcma_entry(const char *filename, @@ -903,7 +838,6 @@ static int do_bcma_entry(const char *filename, add_wildcard(alias); return 1; } -ADD_TO_DEVTABLE("bcma", bcma_device_id, do_bcma_entry); /* Looks like: virtio:dNvN */ static int do_virtio_entry(const char *filename, void *symval, @@ -919,7 +853,6 @@ static int do_virtio_entry(const char *filename, void *symval, add_wildcard(alias); return 1; } -ADD_TO_DEVTABLE("virtio", virtio_device_id, do_virtio_entry); /* * Looks like: vmbus:guid @@ -942,7 +875,6 @@ static int do_vmbus_entry(const char *filename, void *symval, return 1; } -ADD_TO_DEVTABLE("vmbus", hv_vmbus_device_id, do_vmbus_entry); /* Looks like: i2c:S */ static int do_i2c_entry(const char *filename, void *symval, @@ -953,7 +885,6 @@ static int do_i2c_entry(const char *filename, void *symval, return 1; } -ADD_TO_DEVTABLE("i2c", i2c_device_id, do_i2c_entry); /* Looks like: spi:S */ static int do_spi_entry(const char *filename, void *symval, @@ -964,7 +895,6 @@ static int do_spi_entry(const char *filename, void *symval, return 1; } -ADD_TO_DEVTABLE("spi", spi_device_id, do_spi_entry); static const struct dmifield { const char *prefix; @@ -1019,7 +949,6 @@ static int do_dmi_entry(const char *filename, void *symval, strcat(alias, ":"); return 1; } -ADD_TO_DEVTABLE("dmi", dmi_system_id, do_dmi_entry); static int do_platform_entry(const char *filename, void *symval, char *alias) @@ -1028,7 +957,6 @@ static int do_platform_entry(const char *filename, sprintf(alias, PLATFORM_MODULE_PREFIX "%s", *name); return 1; } -ADD_TO_DEVTABLE("platform", platform_device_id, do_platform_entry); static int do_mdio_entry(const char *filename, void *symval, char *alias) @@ -1053,7 +981,6 @@ static int do_mdio_entry(const char *filename, return 1; } -ADD_TO_DEVTABLE("mdio", mdio_device_id, do_mdio_entry); /* Looks like: zorro:iN. */ static int do_zorro_entry(const char *filename, void *symval, @@ -1064,7 +991,6 @@ static int do_zorro_entry(const char *filename, void *symval, ADD(alias, "i", id != ZORRO_WILDCARD, id); return 1; } -ADD_TO_DEVTABLE("zorro", zorro_device_id, do_zorro_entry); /* looks like: "pnp:dD" */ static int do_isapnp_entry(const char *filename, @@ -1080,7 +1006,6 @@ static int do_isapnp_entry(const char *filename, (function >> 12) & 0x0f, (function >> 8) & 0x0f); return 1; } -ADD_TO_DEVTABLE("isapnp", isapnp_device_id, do_isapnp_entry); /* Looks like: "ipack:fNvNdN". */ static int do_ipack_entry(const char *filename, @@ -1096,7 +1021,6 @@ static int do_ipack_entry(const char *filename, add_wildcard(alias); return 1; } -ADD_TO_DEVTABLE("ipack", ipack_device_id, do_ipack_entry); /* * Append a match expression for a single masked hex digit. @@ -1167,7 +1091,6 @@ static int do_amba_entry(const char *filename, return 1; } -ADD_TO_DEVTABLE("amba", amba_id, do_amba_entry); /* * looks like: "mipscdmm:tN" @@ -1183,7 +1106,6 @@ static int do_mips_cdmm_entry(const char *filename, sprintf(alias, "mipscdmm:t%02X*", type); return 1; } -ADD_TO_DEVTABLE("mipscdmm", mips_cdmm_device_id, do_mips_cdmm_entry); /* LOOKS like cpu:type:x86,venVVVVfamFFFFmodMMMM:feature:*,FEAT,* * All fields are numbers. It would be nicer to use strings for vendor @@ -1208,7 +1130,6 @@ static int do_x86cpu_entry(const char *filename, void *symval, sprintf(alias + strlen(alias), "%04X*", feature); return 1; } -ADD_TO_DEVTABLE("x86cpu", x86_cpu_id, do_x86cpu_entry); /* LOOKS like cpu:type:*:feature:*FEAT* */ static int do_cpu_entry(const char *filename, void *symval, char *alias) @@ -1218,7 +1139,6 @@ static int do_cpu_entry(const char *filename, void *symval, char *alias) sprintf(alias, "cpu:type:*:feature:*%04X*", feature); return 1; } -ADD_TO_DEVTABLE("cpu", cpu_feature, do_cpu_entry); /* Looks like: mei:S:uuid:N:* */ static int do_mei_entry(const char *filename, void *symval, @@ -1237,7 +1157,6 @@ static int do_mei_entry(const char *filename, void *symval, return 1; } -ADD_TO_DEVTABLE("mei", mei_cl_device_id, do_mei_entry); /* Looks like: rapidio:vNdNavNadN */ static int do_rio_entry(const char *filename, @@ -1257,7 +1176,6 @@ static int do_rio_entry(const char *filename, add_wildcard(alias); return 1; } -ADD_TO_DEVTABLE("rapidio", rio_device_id, do_rio_entry); /* Looks like: ulpi:vNpN */ static int do_ulpi_entry(const char *filename, void *symval, @@ -1270,7 +1188,6 @@ static int do_ulpi_entry(const char *filename, void *symval, return 1; } -ADD_TO_DEVTABLE("ulpi", ulpi_device_id, do_ulpi_entry); /* Looks like: hdaudio:vNrNaN */ static int do_hda_entry(const char *filename, void *symval, char *alias) @@ -1287,7 +1204,6 @@ static int do_hda_entry(const char *filename, void *symval, char *alias) add_wildcard(alias); return 1; } -ADD_TO_DEVTABLE("hdaudio", hda_device_id, do_hda_entry); /* Looks like: fsl-mc:vNdN */ static int do_fsl_mc_entry(const char *filename, void *symval, @@ -1299,7 +1215,6 @@ static int do_fsl_mc_entry(const char *filename, void *symval, sprintf(alias, "fsl-mc:v%08Xd%s", vendor, *obj_type); return 1; } -ADD_TO_DEVTABLE("fslmc", fsl_mc_device_id, do_fsl_mc_entry); /* Does namelen bytes of name exactly match the symbol? */ static bool sym_is(const char *name, unsigned namelen, const char *symbol) @@ -1332,6 +1247,44 @@ static void do_table(void *symval, unsigned long size, } } +static const struct devtable devtable[] = { + {"hid", SIZE_hid_device_id, do_hid_entry}, + {"ieee1394", SIZE_ieee1394_device_id, do_ieee1394_entry}, + {"pci", SIZE_pci_device_id, do_pci_entry}, + {"ccw", SIZE_ccw_device_id, do_ccw_entry}, + {"ap", SIZE_ap_device_id, do_ap_entry}, + {"css", SIZE_css_device_id, do_css_entry}, + {"serio", SIZE_serio_device_id, do_serio_entry}, + {"acpi", SIZE_acpi_device_id, do_acpi_entry}, + {"pcmcia", SIZE_pcmcia_device_id, do_pcmcia_entry}, + {"vio", SIZE_vio_device_id, do_vio_entry}, + {"input", SIZE_input_device_id, do_input_entry}, + {"eisa", SIZE_eisa_device_id, do_eisa_entry}, + {"parisc", SIZE_parisc_device_id, do_parisc_entry}, + {"sdio", SIZE_sdio_device_id, do_sdio_entry}, + {"ssb", SIZE_ssb_device_id, do_ssb_entry}, + {"bcma", SIZE_bcma_device_id, do_bcma_entry}, + {"virtio", SIZE_virtio_device_id, do_virtio_entry}, + {"vmbus", SIZE_hv_vmbus_device_id, do_vmbus_entry}, + {"i2c", SIZE_i2c_device_id, do_i2c_entry}, + {"spi", SIZE_spi_device_id, do_spi_entry}, + {"dmi", SIZE_dmi_system_id, do_dmi_entry}, + {"platform", SIZE_platform_device_id, do_platform_entry}, + {"mdio", SIZE_mdio_device_id, do_mdio_entry}, + {"zorro", SIZE_zorro_device_id, do_zorro_entry}, + {"isapnp", SIZE_isapnp_device_id, do_isapnp_entry}, + {"ipack", SIZE_ipack_device_id, do_ipack_entry}, + {"amba", SIZE_amba_id, do_amba_entry}, + {"mipscdmm", SIZE_mips_cdmm_device_id, do_mips_cdmm_entry}, + {"x86cpu", SIZE_x86_cpu_id, do_x86cpu_entry}, + {"cpu", SIZE_cpu_feature, do_cpu_entry}, + {"mei", SIZE_mei_cl_device_id, do_mei_entry}, + {"rapidio", SIZE_rio_device_id, do_rio_entry}, + {"ulpi", SIZE_ulpi_device_id, do_ulpi_entry}, + {"hdaudio", SIZE_hda_device_id, do_hda_entry}, + {"fslmc", SIZE_fsl_mc_device_id, do_fsl_mc_entry}, +}; + /* Create MODULE_ALIAS() statements. * At this time, we cannot write the actual output C source yet, * so we write into the mod->dev_table_buf buffer. */ @@ -1386,13 +1339,14 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, else if (sym_is(name, namelen, "pnp_card")) do_pnp_card_entries(symval, sym->st_size, mod); else { - struct devtable **p; - INIT_SECTION(__devtable); + int i; + + for (i = 0; i < ARRAY_SIZE(devtable); i++) { + const struct devtable *p = &devtable[i]; - for (p = __start___devtable; p < __stop___devtable; p++) { - if (sym_is(name, namelen, (*p)->device_id)) { - do_table(symval, sym->st_size, (*p)->id_size, - (*p)->device_id, (*p)->function, mod); + if (sym_is(name, namelen, p->device_id)) { + do_table(symval, sym->st_size, p->id_size, + p->device_id, p->function, mod); break; } } -- GitLab From 10bd1c7ad3894bb9bf2a6d2f3669b5b674f1e59e Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 22 Nov 2018 13:28:42 +0900 Subject: [PATCH 0229/1121] modpost: file2alias: check prototype of handler commit f880eea68fe593342fa6e09be9bb661f3c297aec upstream. Use specific prototype instead of an opaque pointer so that the compiler can catch function prototype mismatch. Signed-off-by: Masahiro Yamada Reviewed-by: Mathieu Malaterre Signed-off-by: Nathan Chancellor Signed-off-by: Sasha Levin --- scripts/mod/file2alias.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 6e3ae94cf123..55b4c0dc2b93 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -47,7 +47,7 @@ typedef struct { struct devtable { const char *device_id; /* name of table, __mod___*_device_table. */ unsigned long id_size; - void *function; + int (*do_entry)(const char *filename, void *symval, char *alias); }; /* Define a variable f that holds the value of field f of struct devid @@ -1228,12 +1228,11 @@ static bool sym_is(const char *name, unsigned namelen, const char *symbol) static void do_table(void *symval, unsigned long size, unsigned long id_size, const char *device_id, - void *function, + int (*do_entry)(const char *filename, void *symval, char *alias), struct module *mod) { unsigned int i; char alias[500]; - int (*do_entry)(const char *, void *entry, char *alias) = function; device_id_check(mod->name, device_id, size, id_size, symval); /* Leave last one: it's the terminator. */ @@ -1346,7 +1345,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, if (sym_is(name, namelen, p->device_id)) { do_table(symval, sym->st_size, p->id_size, - p->device_id, p->function, mod); + p->device_id, p->do_entry, mod); break; } } -- GitLab From 00a22235025c6d12ee5d67cf50698ea93181b0b6 Mon Sep 17 00:00:00 2001 From: Jarkko Sakkinen Date: Fri, 8 Feb 2019 18:30:59 +0200 Subject: [PATCH 0230/1121] tpm/tpm_i2c_atmel: Return -E2BIG when the transfer is incomplete [ Upstream commit 442601e87a4769a8daba4976ec3afa5222ca211d ] Return -E2BIG when the transfer is incomplete. The upper layer does not retry, so not doing that is incorrect behaviour. Cc: stable@vger.kernel.org Fixes: a2871c62e186 ("tpm: Add support for Atmel I2C TPMs") Signed-off-by: Jarkko Sakkinen Reviewed-by: Stefan Berger Reviewed-by: Jerry Snitselaar Signed-off-by: Sasha Levin --- drivers/char/tpm/tpm_i2c_atmel.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/char/tpm/tpm_i2c_atmel.c b/drivers/char/tpm/tpm_i2c_atmel.c index 32a8e27c5382..cc4e642d3180 100644 --- a/drivers/char/tpm/tpm_i2c_atmel.c +++ b/drivers/char/tpm/tpm_i2c_atmel.c @@ -69,6 +69,10 @@ static int i2c_atmel_send(struct tpm_chip *chip, u8 *buf, size_t len) if (status < 0) return status; + /* The upper layer does not support incomplete sends. */ + if (status != len) + return -E2BIG; + return 0; } -- GitLab From a885a0ff776680ab6cb79cf891a81da9a2c18371 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 23 Apr 2019 10:48:21 -0700 Subject: [PATCH 0231/1121] ipv6: frags: fix a lockdep false positive [ Upstream commit 415787d7799f4fccbe8d49cb0b8e5811be6b0389 ] lockdep does not know that the locks used by IPv4 defrag and IPv6 reassembly units are of different classes. It complains because of following chains : 1) sch_direct_xmit() (lock txq->_xmit_lock) dev_hard_start_xmit() xmit_one() dev_queue_xmit_nit() packet_rcv_fanout() ip_check_defrag() ip_defrag() spin_lock() (lock frag queue spinlock) 2) ip6_input_finish() ipv6_frag_rcv() (lock frag queue spinlock) ip6_frag_queue() icmpv6_param_prob() (lock txq->_xmit_lock at some point) We could add lockdep annotations, but we also can make sure IPv6 calls icmpv6_param_prob() only after the release of the frag queue spinlock, since this naturally makes frag queue spinlock a leaf in lock hierarchy. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/ipv6/reassembly.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index 2a8c680b67cd..f75e9e711c31 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c @@ -170,7 +170,8 @@ fq_find(struct net *net, __be32 id, const struct ipv6hdr *hdr, int iif) } static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, - struct frag_hdr *fhdr, int nhoff) + struct frag_hdr *fhdr, int nhoff, + u32 *prob_offset) { struct sk_buff *prev, *next; struct net_device *dev; @@ -186,11 +187,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, ((u8 *)(fhdr + 1) - (u8 *)(ipv6_hdr(skb) + 1))); if ((unsigned int)end > IPV6_MAXPLEN) { - __IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), - IPSTATS_MIB_INHDRERRORS); - icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, - ((u8 *)&fhdr->frag_off - - skb_network_header(skb))); + *prob_offset = (u8 *)&fhdr->frag_off - skb_network_header(skb); return -1; } @@ -221,10 +218,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, /* RFC2460 says always send parameter problem in * this case. -DaveM */ - __IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), - IPSTATS_MIB_INHDRERRORS); - icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, - offsetof(struct ipv6hdr, payload_len)); + *prob_offset = offsetof(struct ipv6hdr, payload_len); return -1; } if (end > fq->q.len) { @@ -536,15 +530,22 @@ static int ipv6_frag_rcv(struct sk_buff *skb) iif = skb->dev ? skb->dev->ifindex : 0; fq = fq_find(net, fhdr->identification, hdr, iif); if (fq) { + u32 prob_offset = 0; int ret; spin_lock(&fq->q.lock); fq->iif = iif; - ret = ip6_frag_queue(fq, skb, fhdr, IP6CB(skb)->nhoff); + ret = ip6_frag_queue(fq, skb, fhdr, IP6CB(skb)->nhoff, + &prob_offset); spin_unlock(&fq->q.lock); inet_frag_put(&fq->q); + if (prob_offset) { + __IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), + IPSTATS_MIB_INHDRERRORS); + icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, prob_offset); + } return ret; } -- GitLab From ccfa73daf762f3adac3f6c0e2f09c3c74548775f Mon Sep 17 00:00:00 2001 From: Peter Oskolkov Date: Tue, 23 Apr 2019 10:48:22 -0700 Subject: [PATCH 0232/1121] net: IP defrag: encapsulate rbtree defrag code into callable functions [ Upstream commit c23f35d19db3b36ffb9e04b08f1d91565d15f84f ] This is a refactoring patch: without changing runtime behavior, it moves rbtree-related code from IPv4-specific files/functions into .h/.c defrag files shared with IPv6 defragmentation code. v2: make handling of overlapping packets match upstream. Signed-off-by: Peter Oskolkov Cc: Eric Dumazet Cc: Florian Westphal Cc: Tom Herbert Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- include/net/inet_frag.h | 16 ++- net/ipv4/inet_fragment.c | 293 +++++++++++++++++++++++++++++++++++++ net/ipv4/ip_fragment.c | 302 +++++---------------------------------- 3 files changed, 342 insertions(+), 269 deletions(-) diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h index 335cf7851f12..008f64823c41 100644 --- a/include/net/inet_frag.h +++ b/include/net/inet_frag.h @@ -77,8 +77,8 @@ struct inet_frag_queue { struct timer_list timer; spinlock_t lock; refcount_t refcnt; - struct sk_buff *fragments; /* Used in IPv6. */ - struct rb_root rb_fragments; /* Used in IPv4. */ + struct sk_buff *fragments; /* used in 6lopwpan IPv6. */ + struct rb_root rb_fragments; /* Used in IPv4/IPv6. */ struct sk_buff *fragments_tail; struct sk_buff *last_run_head; ktime_t stamp; @@ -153,4 +153,16 @@ static inline void add_frag_mem_limit(struct netns_frags *nf, long val) extern const u8 ip_frag_ecn_table[16]; +/* Return values of inet_frag_queue_insert() */ +#define IPFRAG_OK 0 +#define IPFRAG_DUP 1 +#define IPFRAG_OVERLAP 2 +int inet_frag_queue_insert(struct inet_frag_queue *q, struct sk_buff *skb, + int offset, int end); +void *inet_frag_reasm_prepare(struct inet_frag_queue *q, struct sk_buff *skb, + struct sk_buff *parent); +void inet_frag_reasm_finish(struct inet_frag_queue *q, struct sk_buff *head, + void *reasm_data); +struct sk_buff *inet_frag_pull_head(struct inet_frag_queue *q); + #endif diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c index 6ffee9d2b0e5..481cded81b2d 100644 --- a/net/ipv4/inet_fragment.c +++ b/net/ipv4/inet_fragment.c @@ -24,6 +24,62 @@ #include #include #include +#include +#include + +/* Use skb->cb to track consecutive/adjacent fragments coming at + * the end of the queue. Nodes in the rb-tree queue will + * contain "runs" of one or more adjacent fragments. + * + * Invariants: + * - next_frag is NULL at the tail of a "run"; + * - the head of a "run" has the sum of all fragment lengths in frag_run_len. + */ +struct ipfrag_skb_cb { + union { + struct inet_skb_parm h4; + struct inet6_skb_parm h6; + }; + struct sk_buff *next_frag; + int frag_run_len; +}; + +#define FRAG_CB(skb) ((struct ipfrag_skb_cb *)((skb)->cb)) + +static void fragcb_clear(struct sk_buff *skb) +{ + RB_CLEAR_NODE(&skb->rbnode); + FRAG_CB(skb)->next_frag = NULL; + FRAG_CB(skb)->frag_run_len = skb->len; +} + +/* Append skb to the last "run". */ +static void fragrun_append_to_last(struct inet_frag_queue *q, + struct sk_buff *skb) +{ + fragcb_clear(skb); + + FRAG_CB(q->last_run_head)->frag_run_len += skb->len; + FRAG_CB(q->fragments_tail)->next_frag = skb; + q->fragments_tail = skb; +} + +/* Create a new "run" with the skb. */ +static void fragrun_create(struct inet_frag_queue *q, struct sk_buff *skb) +{ + BUILD_BUG_ON(sizeof(struct ipfrag_skb_cb) > sizeof(skb->cb)); + fragcb_clear(skb); + + if (q->last_run_head) + rb_link_node(&skb->rbnode, &q->last_run_head->rbnode, + &q->last_run_head->rbnode.rb_right); + else + rb_link_node(&skb->rbnode, NULL, &q->rb_fragments.rb_node); + rb_insert_color(&skb->rbnode, &q->rb_fragments); + + q->fragments_tail = skb; + q->last_run_head = skb; +} /* Given the OR values of all fragments, apply RFC 3168 5.3 requirements * Value : 0xff if frame should be dropped. @@ -122,6 +178,28 @@ static void inet_frag_destroy_rcu(struct rcu_head *head) kmem_cache_free(f->frags_cachep, q); } +unsigned int inet_frag_rbtree_purge(struct rb_root *root) +{ + struct rb_node *p = rb_first(root); + unsigned int sum = 0; + + while (p) { + struct sk_buff *skb = rb_entry(p, struct sk_buff, rbnode); + + p = rb_next(p); + rb_erase(&skb->rbnode, root); + while (skb) { + struct sk_buff *next = FRAG_CB(skb)->next_frag; + + sum += skb->truesize; + kfree_skb(skb); + skb = next; + } + } + return sum; +} +EXPORT_SYMBOL(inet_frag_rbtree_purge); + void inet_frag_destroy(struct inet_frag_queue *q) { struct sk_buff *fp; @@ -224,3 +302,218 @@ struct inet_frag_queue *inet_frag_find(struct netns_frags *nf, void *key) return fq; } EXPORT_SYMBOL(inet_frag_find); + +int inet_frag_queue_insert(struct inet_frag_queue *q, struct sk_buff *skb, + int offset, int end) +{ + struct sk_buff *last = q->fragments_tail; + + /* RFC5722, Section 4, amended by Errata ID : 3089 + * When reassembling an IPv6 datagram, if + * one or more its constituent fragments is determined to be an + * overlapping fragment, the entire datagram (and any constituent + * fragments) MUST be silently discarded. + * + * Duplicates, however, should be ignored (i.e. skb dropped, but the + * queue/fragments kept for later reassembly). + */ + if (!last) + fragrun_create(q, skb); /* First fragment. */ + else if (last->ip_defrag_offset + last->len < end) { + /* This is the common case: skb goes to the end. */ + /* Detect and discard overlaps. */ + if (offset < last->ip_defrag_offset + last->len) + return IPFRAG_OVERLAP; + if (offset == last->ip_defrag_offset + last->len) + fragrun_append_to_last(q, skb); + else + fragrun_create(q, skb); + } else { + /* Binary search. Note that skb can become the first fragment, + * but not the last (covered above). + */ + struct rb_node **rbn, *parent; + + rbn = &q->rb_fragments.rb_node; + do { + struct sk_buff *curr; + int curr_run_end; + + parent = *rbn; + curr = rb_to_skb(parent); + curr_run_end = curr->ip_defrag_offset + + FRAG_CB(curr)->frag_run_len; + if (end <= curr->ip_defrag_offset) + rbn = &parent->rb_left; + else if (offset >= curr_run_end) + rbn = &parent->rb_right; + else if (offset >= curr->ip_defrag_offset && + end <= curr_run_end) + return IPFRAG_DUP; + else + return IPFRAG_OVERLAP; + } while (*rbn); + /* Here we have parent properly set, and rbn pointing to + * one of its NULL left/right children. Insert skb. + */ + fragcb_clear(skb); + rb_link_node(&skb->rbnode, parent, rbn); + rb_insert_color(&skb->rbnode, &q->rb_fragments); + } + + skb->ip_defrag_offset = offset; + + return IPFRAG_OK; +} +EXPORT_SYMBOL(inet_frag_queue_insert); + +void *inet_frag_reasm_prepare(struct inet_frag_queue *q, struct sk_buff *skb, + struct sk_buff *parent) +{ + struct sk_buff *fp, *head = skb_rb_first(&q->rb_fragments); + struct sk_buff **nextp; + int delta; + + if (head != skb) { + fp = skb_clone(skb, GFP_ATOMIC); + if (!fp) + return NULL; + FRAG_CB(fp)->next_frag = FRAG_CB(skb)->next_frag; + if (RB_EMPTY_NODE(&skb->rbnode)) + FRAG_CB(parent)->next_frag = fp; + else + rb_replace_node(&skb->rbnode, &fp->rbnode, + &q->rb_fragments); + if (q->fragments_tail == skb) + q->fragments_tail = fp; + skb_morph(skb, head); + FRAG_CB(skb)->next_frag = FRAG_CB(head)->next_frag; + rb_replace_node(&head->rbnode, &skb->rbnode, + &q->rb_fragments); + consume_skb(head); + head = skb; + } + WARN_ON(head->ip_defrag_offset != 0); + + delta = -head->truesize; + + /* Head of list must not be cloned. */ + if (skb_unclone(head, GFP_ATOMIC)) + return NULL; + + delta += head->truesize; + if (delta) + add_frag_mem_limit(q->net, delta); + + /* If the first fragment is fragmented itself, we split + * it to two chunks: the first with data and paged part + * and the second, holding only fragments. + */ + if (skb_has_frag_list(head)) { + struct sk_buff *clone; + int i, plen = 0; + + clone = alloc_skb(0, GFP_ATOMIC); + if (!clone) + return NULL; + skb_shinfo(clone)->frag_list = skb_shinfo(head)->frag_list; + skb_frag_list_init(head); + for (i = 0; i < skb_shinfo(head)->nr_frags; i++) + plen += skb_frag_size(&skb_shinfo(head)->frags[i]); + clone->data_len = head->data_len - plen; + clone->len = clone->data_len; + head->truesize += clone->truesize; + clone->csum = 0; + clone->ip_summed = head->ip_summed; + add_frag_mem_limit(q->net, clone->truesize); + skb_shinfo(head)->frag_list = clone; + nextp = &clone->next; + } else { + nextp = &skb_shinfo(head)->frag_list; + } + + return nextp; +} +EXPORT_SYMBOL(inet_frag_reasm_prepare); + +void inet_frag_reasm_finish(struct inet_frag_queue *q, struct sk_buff *head, + void *reasm_data) +{ + struct sk_buff **nextp = (struct sk_buff **)reasm_data; + struct rb_node *rbn; + struct sk_buff *fp; + + skb_push(head, head->data - skb_network_header(head)); + + /* Traverse the tree in order, to build frag_list. */ + fp = FRAG_CB(head)->next_frag; + rbn = rb_next(&head->rbnode); + rb_erase(&head->rbnode, &q->rb_fragments); + while (rbn || fp) { + /* fp points to the next sk_buff in the current run; + * rbn points to the next run. + */ + /* Go through the current run. */ + while (fp) { + *nextp = fp; + nextp = &fp->next; + fp->prev = NULL; + memset(&fp->rbnode, 0, sizeof(fp->rbnode)); + fp->sk = NULL; + head->data_len += fp->len; + head->len += fp->len; + if (head->ip_summed != fp->ip_summed) + head->ip_summed = CHECKSUM_NONE; + else if (head->ip_summed == CHECKSUM_COMPLETE) + head->csum = csum_add(head->csum, fp->csum); + head->truesize += fp->truesize; + fp = FRAG_CB(fp)->next_frag; + } + /* Move to the next run. */ + if (rbn) { + struct rb_node *rbnext = rb_next(rbn); + + fp = rb_to_skb(rbn); + rb_erase(rbn, &q->rb_fragments); + rbn = rbnext; + } + } + sub_frag_mem_limit(q->net, head->truesize); + + *nextp = NULL; + head->next = NULL; + head->prev = NULL; + head->tstamp = q->stamp; +} +EXPORT_SYMBOL(inet_frag_reasm_finish); + +struct sk_buff *inet_frag_pull_head(struct inet_frag_queue *q) +{ + struct sk_buff *head; + + if (q->fragments) { + head = q->fragments; + q->fragments = head->next; + } else { + struct sk_buff *skb; + + head = skb_rb_first(&q->rb_fragments); + if (!head) + return NULL; + skb = FRAG_CB(head)->next_frag; + if (skb) + rb_replace_node(&head->rbnode, &skb->rbnode, + &q->rb_fragments); + else + rb_erase(&head->rbnode, &q->rb_fragments); + memset(&head->rbnode, 0, sizeof(head->rbnode)); + barrier(); + } + if (head == q->fragments_tail) + q->fragments_tail = NULL; + + sub_frag_mem_limit(q->net, head->truesize); + + return head; +} +EXPORT_SYMBOL(inet_frag_pull_head); diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index d95b32af4a0e..5a1d39e32196 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -57,57 +57,6 @@ */ static const char ip_frag_cache_name[] = "ip4-frags"; -/* Use skb->cb to track consecutive/adjacent fragments coming at - * the end of the queue. Nodes in the rb-tree queue will - * contain "runs" of one or more adjacent fragments. - * - * Invariants: - * - next_frag is NULL at the tail of a "run"; - * - the head of a "run" has the sum of all fragment lengths in frag_run_len. - */ -struct ipfrag_skb_cb { - struct inet_skb_parm h; - struct sk_buff *next_frag; - int frag_run_len; -}; - -#define FRAG_CB(skb) ((struct ipfrag_skb_cb *)((skb)->cb)) - -static void ip4_frag_init_run(struct sk_buff *skb) -{ - BUILD_BUG_ON(sizeof(struct ipfrag_skb_cb) > sizeof(skb->cb)); - - FRAG_CB(skb)->next_frag = NULL; - FRAG_CB(skb)->frag_run_len = skb->len; -} - -/* Append skb to the last "run". */ -static void ip4_frag_append_to_last_run(struct inet_frag_queue *q, - struct sk_buff *skb) -{ - RB_CLEAR_NODE(&skb->rbnode); - FRAG_CB(skb)->next_frag = NULL; - - FRAG_CB(q->last_run_head)->frag_run_len += skb->len; - FRAG_CB(q->fragments_tail)->next_frag = skb; - q->fragments_tail = skb; -} - -/* Create a new "run" with the skb. */ -static void ip4_frag_create_run(struct inet_frag_queue *q, struct sk_buff *skb) -{ - if (q->last_run_head) - rb_link_node(&skb->rbnode, &q->last_run_head->rbnode, - &q->last_run_head->rbnode.rb_right); - else - rb_link_node(&skb->rbnode, NULL, &q->rb_fragments.rb_node); - rb_insert_color(&skb->rbnode, &q->rb_fragments); - - ip4_frag_init_run(skb); - q->fragments_tail = skb; - q->last_run_head = skb; -} - /* Describe an entry in the "incomplete datagrams" queue. */ struct ipq { struct inet_frag_queue q; @@ -212,27 +161,9 @@ static void ip_expire(struct timer_list *t) * pull the head out of the tree in order to be able to * deal with head->dev. */ - if (qp->q.fragments) { - head = qp->q.fragments; - qp->q.fragments = head->next; - } else { - head = skb_rb_first(&qp->q.rb_fragments); - if (!head) - goto out; - if (FRAG_CB(head)->next_frag) - rb_replace_node(&head->rbnode, - &FRAG_CB(head)->next_frag->rbnode, - &qp->q.rb_fragments); - else - rb_erase(&head->rbnode, &qp->q.rb_fragments); - memset(&head->rbnode, 0, sizeof(head->rbnode)); - barrier(); - } - if (head == qp->q.fragments_tail) - qp->q.fragments_tail = NULL; - - sub_frag_mem_limit(qp->q.net, head->truesize); - + head = inet_frag_pull_head(&qp->q); + if (!head) + goto out; head->dev = dev_get_by_index_rcu(net, qp->iif); if (!head->dev) goto out; @@ -345,12 +276,10 @@ static int ip_frag_reinit(struct ipq *qp) static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb) { struct net *net = container_of(qp->q.net, struct net, ipv4.frags); - struct rb_node **rbn, *parent; - struct sk_buff *skb1, *prev_tail; - int ihl, end, skb1_run_end; + int ihl, end, flags, offset; + struct sk_buff *prev_tail; struct net_device *dev; unsigned int fragsize; - int flags, offset; int err = -ENOENT; u8 ecn; @@ -382,7 +311,7 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb) */ if (end < qp->q.len || ((qp->q.flags & INET_FRAG_LAST_IN) && end != qp->q.len)) - goto err; + goto discard_qp; qp->q.flags |= INET_FRAG_LAST_IN; qp->q.len = end; } else { @@ -394,82 +323,33 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb) if (end > qp->q.len) { /* Some bits beyond end -> corruption. */ if (qp->q.flags & INET_FRAG_LAST_IN) - goto err; + goto discard_qp; qp->q.len = end; } } if (end == offset) - goto err; + goto discard_qp; err = -ENOMEM; if (!pskb_pull(skb, skb_network_offset(skb) + ihl)) - goto err; + goto discard_qp; err = pskb_trim_rcsum(skb, end - offset); if (err) - goto err; + goto discard_qp; /* Note : skb->rbnode and skb->dev share the same location. */ dev = skb->dev; /* Makes sure compiler wont do silly aliasing games */ barrier(); - /* RFC5722, Section 4, amended by Errata ID : 3089 - * When reassembling an IPv6 datagram, if - * one or more its constituent fragments is determined to be an - * overlapping fragment, the entire datagram (and any constituent - * fragments) MUST be silently discarded. - * - * We do the same here for IPv4 (and increment an snmp counter) but - * we do not want to drop the whole queue in response to a duplicate - * fragment. - */ - - err = -EINVAL; - /* Find out where to put this fragment. */ prev_tail = qp->q.fragments_tail; - if (!prev_tail) - ip4_frag_create_run(&qp->q, skb); /* First fragment. */ - else if (prev_tail->ip_defrag_offset + prev_tail->len < end) { - /* This is the common case: skb goes to the end. */ - /* Detect and discard overlaps. */ - if (offset < prev_tail->ip_defrag_offset + prev_tail->len) - goto discard_qp; - if (offset == prev_tail->ip_defrag_offset + prev_tail->len) - ip4_frag_append_to_last_run(&qp->q, skb); - else - ip4_frag_create_run(&qp->q, skb); - } else { - /* Binary search. Note that skb can become the first fragment, - * but not the last (covered above). - */ - rbn = &qp->q.rb_fragments.rb_node; - do { - parent = *rbn; - skb1 = rb_to_skb(parent); - skb1_run_end = skb1->ip_defrag_offset + - FRAG_CB(skb1)->frag_run_len; - if (end <= skb1->ip_defrag_offset) - rbn = &parent->rb_left; - else if (offset >= skb1_run_end) - rbn = &parent->rb_right; - else if (offset >= skb1->ip_defrag_offset && - end <= skb1_run_end) - goto err; /* No new data, potential duplicate */ - else - goto discard_qp; /* Found an overlap */ - } while (*rbn); - /* Here we have parent properly set, and rbn pointing to - * one of its NULL left/right children. Insert skb. - */ - ip4_frag_init_run(skb); - rb_link_node(&skb->rbnode, parent, rbn); - rb_insert_color(&skb->rbnode, &qp->q.rb_fragments); - } + err = inet_frag_queue_insert(&qp->q, skb, offset, end); + if (err) + goto insert_error; if (dev) qp->iif = dev->ifindex; - skb->ip_defrag_offset = offset; qp->q.stamp = skb->tstamp; qp->q.meat += skb->len; @@ -494,15 +374,24 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb) skb->_skb_refdst = 0UL; err = ip_frag_reasm(qp, skb, prev_tail, dev); skb->_skb_refdst = orefdst; + if (err) + inet_frag_kill(&qp->q); return err; } skb_dst_drop(skb); return -EINPROGRESS; +insert_error: + if (err == IPFRAG_DUP) { + kfree_skb(skb); + return -EINVAL; + } + err = -EINVAL; + __IP_INC_STATS(net, IPSTATS_MIB_REASM_OVERLAPS); discard_qp: inet_frag_kill(&qp->q); - __IP_INC_STATS(net, IPSTATS_MIB_REASM_OVERLAPS); + __IP_INC_STATS(net, IPSTATS_MIB_REASMFAILS); err: kfree_skb(skb); return err; @@ -514,13 +403,8 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *skb, { struct net *net = container_of(qp->q.net, struct net, ipv4.frags); struct iphdr *iph; - struct sk_buff *fp, *head = skb_rb_first(&qp->q.rb_fragments); - struct sk_buff **nextp; /* To build frag_list. */ - struct rb_node *rbn; - int len; - int ihlen; - int delta; - int err; + void *reasm_data; + int len, err; u8 ecn; ipq_kill(qp); @@ -530,117 +414,23 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *skb, err = -EINVAL; goto out_fail; } - /* Make the one we just received the head. */ - if (head != skb) { - fp = skb_clone(skb, GFP_ATOMIC); - if (!fp) - goto out_nomem; - FRAG_CB(fp)->next_frag = FRAG_CB(skb)->next_frag; - if (RB_EMPTY_NODE(&skb->rbnode)) - FRAG_CB(prev_tail)->next_frag = fp; - else - rb_replace_node(&skb->rbnode, &fp->rbnode, - &qp->q.rb_fragments); - if (qp->q.fragments_tail == skb) - qp->q.fragments_tail = fp; - skb_morph(skb, head); - FRAG_CB(skb)->next_frag = FRAG_CB(head)->next_frag; - rb_replace_node(&head->rbnode, &skb->rbnode, - &qp->q.rb_fragments); - consume_skb(head); - head = skb; - } - WARN_ON(head->ip_defrag_offset != 0); - - /* Allocate a new buffer for the datagram. */ - ihlen = ip_hdrlen(head); - len = ihlen + qp->q.len; + /* Make the one we just received the head. */ + reasm_data = inet_frag_reasm_prepare(&qp->q, skb, prev_tail); + if (!reasm_data) + goto out_nomem; + len = ip_hdrlen(skb) + qp->q.len; err = -E2BIG; if (len > 65535) goto out_oversize; - delta = - head->truesize; - - /* Head of list must not be cloned. */ - if (skb_unclone(head, GFP_ATOMIC)) - goto out_nomem; - - delta += head->truesize; - if (delta) - add_frag_mem_limit(qp->q.net, delta); - - /* If the first fragment is fragmented itself, we split - * it to two chunks: the first with data and paged part - * and the second, holding only fragments. */ - if (skb_has_frag_list(head)) { - struct sk_buff *clone; - int i, plen = 0; - - clone = alloc_skb(0, GFP_ATOMIC); - if (!clone) - goto out_nomem; - skb_shinfo(clone)->frag_list = skb_shinfo(head)->frag_list; - skb_frag_list_init(head); - for (i = 0; i < skb_shinfo(head)->nr_frags; i++) - plen += skb_frag_size(&skb_shinfo(head)->frags[i]); - clone->len = clone->data_len = head->data_len - plen; - head->truesize += clone->truesize; - clone->csum = 0; - clone->ip_summed = head->ip_summed; - add_frag_mem_limit(qp->q.net, clone->truesize); - skb_shinfo(head)->frag_list = clone; - nextp = &clone->next; - } else { - nextp = &skb_shinfo(head)->frag_list; - } + inet_frag_reasm_finish(&qp->q, skb, reasm_data); - skb_push(head, head->data - skb_network_header(head)); + skb->dev = dev; + IPCB(skb)->frag_max_size = max(qp->max_df_size, qp->q.max_size); - /* Traverse the tree in order, to build frag_list. */ - fp = FRAG_CB(head)->next_frag; - rbn = rb_next(&head->rbnode); - rb_erase(&head->rbnode, &qp->q.rb_fragments); - while (rbn || fp) { - /* fp points to the next sk_buff in the current run; - * rbn points to the next run. - */ - /* Go through the current run. */ - while (fp) { - *nextp = fp; - nextp = &fp->next; - fp->prev = NULL; - memset(&fp->rbnode, 0, sizeof(fp->rbnode)); - fp->sk = NULL; - head->data_len += fp->len; - head->len += fp->len; - if (head->ip_summed != fp->ip_summed) - head->ip_summed = CHECKSUM_NONE; - else if (head->ip_summed == CHECKSUM_COMPLETE) - head->csum = csum_add(head->csum, fp->csum); - head->truesize += fp->truesize; - fp = FRAG_CB(fp)->next_frag; - } - /* Move to the next run. */ - if (rbn) { - struct rb_node *rbnext = rb_next(rbn); - - fp = rb_to_skb(rbn); - rb_erase(rbn, &qp->q.rb_fragments); - rbn = rbnext; - } - } - sub_frag_mem_limit(qp->q.net, head->truesize); - - *nextp = NULL; - head->next = NULL; - head->prev = NULL; - head->dev = dev; - head->tstamp = qp->q.stamp; - IPCB(head)->frag_max_size = max(qp->max_df_size, qp->q.max_size); - - iph = ip_hdr(head); + iph = ip_hdr(skb); iph->tot_len = htons(len); iph->tos |= ecn; @@ -653,7 +443,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *skb, * from one very small df-fragment and one large non-df frag. */ if (qp->max_df_size == qp->q.max_size) { - IPCB(head)->flags |= IPSKB_FRAG_PMTU; + IPCB(skb)->flags |= IPSKB_FRAG_PMTU; iph->frag_off = htons(IP_DF); } else { iph->frag_off = 0; @@ -751,28 +541,6 @@ struct sk_buff *ip_check_defrag(struct net *net, struct sk_buff *skb, u32 user) } EXPORT_SYMBOL(ip_check_defrag); -unsigned int inet_frag_rbtree_purge(struct rb_root *root) -{ - struct rb_node *p = rb_first(root); - unsigned int sum = 0; - - while (p) { - struct sk_buff *skb = rb_entry(p, struct sk_buff, rbnode); - - p = rb_next(p); - rb_erase(&skb->rbnode, root); - while (skb) { - struct sk_buff *next = FRAG_CB(skb)->next_frag; - - sum += skb->truesize; - kfree_skb(skb); - skb = next; - } - } - return sum; -} -EXPORT_SYMBOL(inet_frag_rbtree_purge); - #ifdef CONFIG_SYSCTL static int dist_min; -- GitLab From 5d827bfe37a5cecd1de33405afde4708657643c5 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Tue, 23 Apr 2019 10:48:23 -0700 Subject: [PATCH 0233/1121] ipv6: remove dependency of nf_defrag_ipv6 on ipv6 module [ Upstream commit 70b095c84326640eeacfd69a411db8fc36e8ab1a ] IPV6=m DEFRAG_IPV6=m CONNTRACK=y yields: net/netfilter/nf_conntrack_proto.o: In function `nf_ct_netns_do_get': net/netfilter/nf_conntrack_proto.c:802: undefined reference to `nf_defrag_ipv6_enable' net/netfilter/nf_conntrack_proto.o:(.rodata+0x640): undefined reference to `nf_conntrack_l4proto_icmpv6' Setting DEFRAG_IPV6=y causes undefined references to ip6_rhash_params ip6_frag_init and ip6_expire_frag_queue so it would be needed to force IPV6=y too. This patch gets rid of the 'followup linker error' by removing the dependency of ipv6.ko symbols from netfilter ipv6 defrag. Shared code is placed into a header, then used from both. Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso Signed-off-by: Sasha Levin --- include/net/ipv6.h | 29 ------ include/net/ipv6_frag.h | 104 ++++++++++++++++++++++ net/ieee802154/6lowpan/reassembly.c | 2 +- net/ipv6/netfilter/nf_conntrack_reasm.c | 17 ++-- net/ipv6/netfilter/nf_defrag_ipv6_hooks.c | 3 +- net/ipv6/reassembly.c | 92 ++----------------- net/openvswitch/conntrack.c | 1 + 7 files changed, 126 insertions(+), 122 deletions(-) create mode 100644 include/net/ipv6_frag.h diff --git a/include/net/ipv6.h b/include/net/ipv6.h index fa87a62e9bd3..6294d20a5f0e 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -512,35 +512,6 @@ static inline bool ipv6_prefix_equal(const struct in6_addr *addr1, } #endif -struct inet_frag_queue; - -enum ip6_defrag_users { - IP6_DEFRAG_LOCAL_DELIVER, - IP6_DEFRAG_CONNTRACK_IN, - __IP6_DEFRAG_CONNTRACK_IN = IP6_DEFRAG_CONNTRACK_IN + USHRT_MAX, - IP6_DEFRAG_CONNTRACK_OUT, - __IP6_DEFRAG_CONNTRACK_OUT = IP6_DEFRAG_CONNTRACK_OUT + USHRT_MAX, - IP6_DEFRAG_CONNTRACK_BRIDGE_IN, - __IP6_DEFRAG_CONNTRACK_BRIDGE_IN = IP6_DEFRAG_CONNTRACK_BRIDGE_IN + USHRT_MAX, -}; - -void ip6_frag_init(struct inet_frag_queue *q, const void *a); -extern const struct rhashtable_params ip6_rhash_params; - -/* - * Equivalent of ipv4 struct ip - */ -struct frag_queue { - struct inet_frag_queue q; - - int iif; - unsigned int csum; - __u16 nhoffset; - u8 ecn; -}; - -void ip6_expire_frag_queue(struct net *net, struct frag_queue *fq); - static inline bool ipv6_addr_any(const struct in6_addr *a) { #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64 diff --git a/include/net/ipv6_frag.h b/include/net/ipv6_frag.h new file mode 100644 index 000000000000..6ced1e6899b6 --- /dev/null +++ b/include/net/ipv6_frag.h @@ -0,0 +1,104 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _IPV6_FRAG_H +#define _IPV6_FRAG_H +#include +#include +#include +#include + +enum ip6_defrag_users { + IP6_DEFRAG_LOCAL_DELIVER, + IP6_DEFRAG_CONNTRACK_IN, + __IP6_DEFRAG_CONNTRACK_IN = IP6_DEFRAG_CONNTRACK_IN + USHRT_MAX, + IP6_DEFRAG_CONNTRACK_OUT, + __IP6_DEFRAG_CONNTRACK_OUT = IP6_DEFRAG_CONNTRACK_OUT + USHRT_MAX, + IP6_DEFRAG_CONNTRACK_BRIDGE_IN, + __IP6_DEFRAG_CONNTRACK_BRIDGE_IN = IP6_DEFRAG_CONNTRACK_BRIDGE_IN + USHRT_MAX, +}; + +/* + * Equivalent of ipv4 struct ip + */ +struct frag_queue { + struct inet_frag_queue q; + + int iif; + __u16 nhoffset; + u8 ecn; +}; + +#if IS_ENABLED(CONFIG_IPV6) +static inline void ip6frag_init(struct inet_frag_queue *q, const void *a) +{ + struct frag_queue *fq = container_of(q, struct frag_queue, q); + const struct frag_v6_compare_key *key = a; + + q->key.v6 = *key; + fq->ecn = 0; +} + +static inline u32 ip6frag_key_hashfn(const void *data, u32 len, u32 seed) +{ + return jhash2(data, + sizeof(struct frag_v6_compare_key) / sizeof(u32), seed); +} + +static inline u32 ip6frag_obj_hashfn(const void *data, u32 len, u32 seed) +{ + const struct inet_frag_queue *fq = data; + + return jhash2((const u32 *)&fq->key.v6, + sizeof(struct frag_v6_compare_key) / sizeof(u32), seed); +} + +static inline int +ip6frag_obj_cmpfn(struct rhashtable_compare_arg *arg, const void *ptr) +{ + const struct frag_v6_compare_key *key = arg->key; + const struct inet_frag_queue *fq = ptr; + + return !!memcmp(&fq->key, key, sizeof(*key)); +} + +static inline void +ip6frag_expire_frag_queue(struct net *net, struct frag_queue *fq) +{ + struct net_device *dev = NULL; + struct sk_buff *head; + + rcu_read_lock(); + spin_lock(&fq->q.lock); + + if (fq->q.flags & INET_FRAG_COMPLETE) + goto out; + + inet_frag_kill(&fq->q); + + dev = dev_get_by_index_rcu(net, fq->iif); + if (!dev) + goto out; + + __IP6_INC_STATS(net, __in6_dev_get(dev), IPSTATS_MIB_REASMFAILS); + __IP6_INC_STATS(net, __in6_dev_get(dev), IPSTATS_MIB_REASMTIMEOUT); + + /* Don't send error if the first segment did not arrive. */ + head = fq->q.fragments; + if (!(fq->q.flags & INET_FRAG_FIRST_IN) || !head) + goto out; + + head->dev = dev; + skb_get(head); + spin_unlock(&fq->q.lock); + + icmpv6_send(head, ICMPV6_TIME_EXCEED, ICMPV6_EXC_FRAGTIME, 0); + kfree_skb(head); + goto out_rcu_unlock; + +out: + spin_unlock(&fq->q.lock); +out_rcu_unlock: + rcu_read_unlock(); + inet_frag_put(&fq->q); +} +#endif +#endif diff --git a/net/ieee802154/6lowpan/reassembly.c b/net/ieee802154/6lowpan/reassembly.c index 2cc224106b69..ec7a5da56129 100644 --- a/net/ieee802154/6lowpan/reassembly.c +++ b/net/ieee802154/6lowpan/reassembly.c @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include "6lowpan_i.h" diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index 237fb04c6716..0568d49b5da4 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -33,9 +33,8 @@ #include #include -#include +#include -#include #include #include #include @@ -159,7 +158,7 @@ static void nf_ct_frag6_expire(struct timer_list *t) fq = container_of(frag, struct frag_queue, q); net = container_of(fq->q.net, struct net, nf_frag.frags); - ip6_expire_frag_queue(net, fq); + ip6frag_expire_frag_queue(net, fq); } /* Creation primitives. */ @@ -641,16 +640,24 @@ static struct pernet_operations nf_ct_net_ops = { .exit = nf_ct_net_exit, }; +static const struct rhashtable_params nfct_rhash_params = { + .head_offset = offsetof(struct inet_frag_queue, node), + .hashfn = ip6frag_key_hashfn, + .obj_hashfn = ip6frag_obj_hashfn, + .obj_cmpfn = ip6frag_obj_cmpfn, + .automatic_shrinking = true, +}; + int nf_ct_frag6_init(void) { int ret = 0; - nf_frags.constructor = ip6_frag_init; + nf_frags.constructor = ip6frag_init; nf_frags.destructor = NULL; nf_frags.qsize = sizeof(struct frag_queue); nf_frags.frag_expire = nf_ct_frag6_expire; nf_frags.frags_cache_name = nf_frags_cache_name; - nf_frags.rhash_params = ip6_rhash_params; + nf_frags.rhash_params = nfct_rhash_params; ret = inet_frags_init(&nf_frags); if (ret) goto out; diff --git a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c index b326da59257f..123bfb13a5d1 100644 --- a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c +++ b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c @@ -14,8 +14,7 @@ #include #include #include -#include -#include +#include #include #include diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index f75e9e711c31..e5ab3b7813d6 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c @@ -57,7 +57,7 @@ #include #include #include -#include +#include #include static const char ip6_frag_cache_name[] = "ip6-frags"; @@ -79,61 +79,6 @@ static struct inet_frags ip6_frags; static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, struct net_device *dev); -void ip6_frag_init(struct inet_frag_queue *q, const void *a) -{ - struct frag_queue *fq = container_of(q, struct frag_queue, q); - const struct frag_v6_compare_key *key = a; - - q->key.v6 = *key; - fq->ecn = 0; -} -EXPORT_SYMBOL(ip6_frag_init); - -void ip6_expire_frag_queue(struct net *net, struct frag_queue *fq) -{ - struct net_device *dev = NULL; - struct sk_buff *head; - - rcu_read_lock(); - spin_lock(&fq->q.lock); - - if (fq->q.flags & INET_FRAG_COMPLETE) - goto out; - - inet_frag_kill(&fq->q); - - dev = dev_get_by_index_rcu(net, fq->iif); - if (!dev) - goto out; - - __IP6_INC_STATS(net, __in6_dev_get(dev), IPSTATS_MIB_REASMFAILS); - __IP6_INC_STATS(net, __in6_dev_get(dev), IPSTATS_MIB_REASMTIMEOUT); - - /* Don't send error if the first segment did not arrive. */ - head = fq->q.fragments; - if (!(fq->q.flags & INET_FRAG_FIRST_IN) || !head) - goto out; - - /* But use as source device on which LAST ARRIVED - * segment was received. And do not use fq->dev - * pointer directly, device might already disappeared. - */ - head->dev = dev; - skb_get(head); - spin_unlock(&fq->q.lock); - - icmpv6_send(head, ICMPV6_TIME_EXCEED, ICMPV6_EXC_FRAGTIME, 0); - kfree_skb(head); - goto out_rcu_unlock; - -out: - spin_unlock(&fq->q.lock); -out_rcu_unlock: - rcu_read_unlock(); - inet_frag_put(&fq->q); -} -EXPORT_SYMBOL(ip6_expire_frag_queue); - static void ip6_frag_expire(struct timer_list *t) { struct inet_frag_queue *frag = from_timer(frag, t, timer); @@ -143,7 +88,7 @@ static void ip6_frag_expire(struct timer_list *t) fq = container_of(frag, struct frag_queue, q); net = container_of(fq->q.net, struct net, ipv6.frags); - ip6_expire_frag_queue(net, fq); + ip6frag_expire_frag_queue(net, fq); } static struct frag_queue * @@ -713,42 +658,19 @@ static struct pernet_operations ip6_frags_ops = { .exit = ipv6_frags_exit_net, }; -static u32 ip6_key_hashfn(const void *data, u32 len, u32 seed) -{ - return jhash2(data, - sizeof(struct frag_v6_compare_key) / sizeof(u32), seed); -} - -static u32 ip6_obj_hashfn(const void *data, u32 len, u32 seed) -{ - const struct inet_frag_queue *fq = data; - - return jhash2((const u32 *)&fq->key.v6, - sizeof(struct frag_v6_compare_key) / sizeof(u32), seed); -} - -static int ip6_obj_cmpfn(struct rhashtable_compare_arg *arg, const void *ptr) -{ - const struct frag_v6_compare_key *key = arg->key; - const struct inet_frag_queue *fq = ptr; - - return !!memcmp(&fq->key, key, sizeof(*key)); -} - -const struct rhashtable_params ip6_rhash_params = { +static const struct rhashtable_params ip6_rhash_params = { .head_offset = offsetof(struct inet_frag_queue, node), - .hashfn = ip6_key_hashfn, - .obj_hashfn = ip6_obj_hashfn, - .obj_cmpfn = ip6_obj_cmpfn, + .hashfn = ip6frag_key_hashfn, + .obj_hashfn = ip6frag_obj_hashfn, + .obj_cmpfn = ip6frag_obj_cmpfn, .automatic_shrinking = true, }; -EXPORT_SYMBOL(ip6_rhash_params); int __init ipv6_frag_init(void) { int ret; - ip6_frags.constructor = ip6_frag_init; + ip6_frags.constructor = ip6frag_init; ip6_frags.destructor = NULL; ip6_frags.qsize = sizeof(struct frag_queue); ip6_frags.frag_expire = ip6_frag_expire; diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c index 285f8797c26a..0171b27a2b81 100644 --- a/net/openvswitch/conntrack.c +++ b/net/openvswitch/conntrack.c @@ -23,6 +23,7 @@ #include #include #include +#include #ifdef CONFIG_NF_NAT_NEEDED #include -- GitLab From 6925083963809d53f1d5ef58c2ef8a3792908166 Mon Sep 17 00:00:00 2001 From: Peter Oskolkov Date: Tue, 23 Apr 2019 10:48:24 -0700 Subject: [PATCH 0234/1121] net: IP6 defrag: use rbtrees for IPv6 defrag [ Upstream commit d4289fcc9b16b89619ee1c54f829e05e56de8b9a ] Currently, IPv6 defragmentation code drops non-last fragments that are smaller than 1280 bytes: see commit 0ed4229b08c1 ("ipv6: defrag: drop non-last frags smaller than min mtu") This behavior is not specified in IPv6 RFCs and appears to break compatibility with some IPv6 implemenations, as reported here: https://www.spinics.net/lists/netdev/msg543846.html This patch re-uses common IP defragmentation queueing and reassembly code in IPv6, removing the 1280 byte restriction. v2: change handling of overlaps to match that of upstream. Signed-off-by: Peter Oskolkov Reported-by: Tom Herbert Cc: Eric Dumazet Cc: Florian Westphal Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- include/net/ipv6_frag.h | 11 +- net/ipv6/reassembly.c | 249 +++++++++++----------------------------- 2 files changed, 77 insertions(+), 183 deletions(-) diff --git a/include/net/ipv6_frag.h b/include/net/ipv6_frag.h index 6ced1e6899b6..28aa9b30aece 100644 --- a/include/net/ipv6_frag.h +++ b/include/net/ipv6_frag.h @@ -82,8 +82,15 @@ ip6frag_expire_frag_queue(struct net *net, struct frag_queue *fq) __IP6_INC_STATS(net, __in6_dev_get(dev), IPSTATS_MIB_REASMTIMEOUT); /* Don't send error if the first segment did not arrive. */ - head = fq->q.fragments; - if (!(fq->q.flags & INET_FRAG_FIRST_IN) || !head) + if (!(fq->q.flags & INET_FRAG_FIRST_IN)) + goto out; + + /* sk_buff::dev and sk_buff::rbnode are unionized. So we + * pull the head out of the tree in order to be able to + * deal with head->dev. + */ + head = inet_frag_pull_head(&fq->q); + if (!head) goto out; head->dev = dev; diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index e5ab3b7813d6..fe797b29ca89 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c @@ -62,13 +62,6 @@ static const char ip6_frag_cache_name[] = "ip6-frags"; -struct ip6frag_skb_cb { - struct inet6_skb_parm h; - int offset; -}; - -#define FRAG6_CB(skb) ((struct ip6frag_skb_cb *)((skb)->cb)) - static u8 ip6_frag_ecn(const struct ipv6hdr *ipv6h) { return 1 << (ipv6_get_dsfield(ipv6h) & INET_ECN_MASK); @@ -76,8 +69,8 @@ static u8 ip6_frag_ecn(const struct ipv6hdr *ipv6h) static struct inet_frags ip6_frags; -static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, - struct net_device *dev); +static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *skb, + struct sk_buff *prev_tail, struct net_device *dev); static void ip6_frag_expire(struct timer_list *t) { @@ -118,21 +111,26 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, struct frag_hdr *fhdr, int nhoff, u32 *prob_offset) { - struct sk_buff *prev, *next; - struct net_device *dev; - int offset, end, fragsize; struct net *net = dev_net(skb_dst(skb)->dev); + int offset, end, fragsize; + struct sk_buff *prev_tail; + struct net_device *dev; + int err = -ENOENT; u8 ecn; if (fq->q.flags & INET_FRAG_COMPLETE) goto err; + err = -EINVAL; offset = ntohs(fhdr->frag_off) & ~0x7; end = offset + (ntohs(ipv6_hdr(skb)->payload_len) - ((u8 *)(fhdr + 1) - (u8 *)(ipv6_hdr(skb) + 1))); if ((unsigned int)end > IPV6_MAXPLEN) { *prob_offset = (u8 *)&fhdr->frag_off - skb_network_header(skb); + /* note that if prob_offset is set, the skb is freed elsewhere, + * we do not free it here. + */ return -1; } @@ -152,7 +150,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, */ if (end < fq->q.len || ((fq->q.flags & INET_FRAG_LAST_IN) && end != fq->q.len)) - goto err; + goto discard_fq; fq->q.flags |= INET_FRAG_LAST_IN; fq->q.len = end; } else { @@ -169,70 +167,36 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, if (end > fq->q.len) { /* Some bits beyond end -> corruption. */ if (fq->q.flags & INET_FRAG_LAST_IN) - goto err; + goto discard_fq; fq->q.len = end; } } if (end == offset) - goto err; + goto discard_fq; + err = -ENOMEM; /* Point into the IP datagram 'data' part. */ if (!pskb_pull(skb, (u8 *) (fhdr + 1) - skb->data)) - goto err; - - if (pskb_trim_rcsum(skb, end - offset)) - goto err; - - /* Find out which fragments are in front and at the back of us - * in the chain of fragments so far. We must know where to put - * this fragment, right? - */ - prev = fq->q.fragments_tail; - if (!prev || FRAG6_CB(prev)->offset < offset) { - next = NULL; - goto found; - } - prev = NULL; - for (next = fq->q.fragments; next != NULL; next = next->next) { - if (FRAG6_CB(next)->offset >= offset) - break; /* bingo! */ - prev = next; - } - -found: - /* RFC5722, Section 4, amended by Errata ID : 3089 - * When reassembling an IPv6 datagram, if - * one or more its constituent fragments is determined to be an - * overlapping fragment, the entire datagram (and any constituent - * fragments) MUST be silently discarded. - */ - - /* Check for overlap with preceding fragment. */ - if (prev && - (FRAG6_CB(prev)->offset + prev->len) > offset) goto discard_fq; - /* Look for overlap with succeeding segment. */ - if (next && FRAG6_CB(next)->offset < end) + err = pskb_trim_rcsum(skb, end - offset); + if (err) goto discard_fq; - FRAG6_CB(skb)->offset = offset; + /* Note : skb->rbnode and skb->dev share the same location. */ + dev = skb->dev; + /* Makes sure compiler wont do silly aliasing games */ + barrier(); - /* Insert this fragment in the chain of fragments. */ - skb->next = next; - if (!next) - fq->q.fragments_tail = skb; - if (prev) - prev->next = skb; - else - fq->q.fragments = skb; + prev_tail = fq->q.fragments_tail; + err = inet_frag_queue_insert(&fq->q, skb, offset, end); + if (err) + goto insert_error; - dev = skb->dev; - if (dev) { + if (dev) fq->iif = dev->ifindex; - skb->dev = NULL; - } + fq->q.stamp = skb->tstamp; fq->q.meat += skb->len; fq->ecn |= ecn; @@ -252,44 +216,48 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, if (fq->q.flags == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) && fq->q.meat == fq->q.len) { - int res; unsigned long orefdst = skb->_skb_refdst; skb->_skb_refdst = 0UL; - res = ip6_frag_reasm(fq, prev, dev); + err = ip6_frag_reasm(fq, skb, prev_tail, dev); skb->_skb_refdst = orefdst; - return res; + return err; } skb_dst_drop(skb); - return -1; + return -EINPROGRESS; +insert_error: + if (err == IPFRAG_DUP) { + kfree_skb(skb); + return -EINVAL; + } + err = -EINVAL; + __IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), + IPSTATS_MIB_REASM_OVERLAPS); discard_fq: inet_frag_kill(&fq->q); -err: __IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_REASMFAILS); +err: kfree_skb(skb); - return -1; + return err; } /* * Check if this packet is complete. - * Returns NULL on failure by any reason, and pointer - * to current nexthdr field in reassembled frame. * * It is called with locked fq, and caller must check that * queue is eligible for reassembly i.e. it is not COMPLETE, * the last and the first frames arrived and all the bits are here. */ -static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, - struct net_device *dev) +static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *skb, + struct sk_buff *prev_tail, struct net_device *dev) { struct net *net = container_of(fq->q.net, struct net, ipv6.frags); - struct sk_buff *fp, *head = fq->q.fragments; - int payload_len, delta; unsigned int nhoff; - int sum_truesize; + void *reasm_data; + int payload_len; u8 ecn; inet_frag_kill(&fq->q); @@ -298,120 +266,40 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, if (unlikely(ecn == 0xff)) goto out_fail; - /* Make the one we just received the head. */ - if (prev) { - head = prev->next; - fp = skb_clone(head, GFP_ATOMIC); - - if (!fp) - goto out_oom; - - fp->next = head->next; - if (!fp->next) - fq->q.fragments_tail = fp; - prev->next = fp; - - skb_morph(head, fq->q.fragments); - head->next = fq->q.fragments->next; - - consume_skb(fq->q.fragments); - fq->q.fragments = head; - } - - WARN_ON(head == NULL); - WARN_ON(FRAG6_CB(head)->offset != 0); + reasm_data = inet_frag_reasm_prepare(&fq->q, skb, prev_tail); + if (!reasm_data) + goto out_oom; - /* Unfragmented part is taken from the first segment. */ - payload_len = ((head->data - skb_network_header(head)) - + payload_len = ((skb->data - skb_network_header(skb)) - sizeof(struct ipv6hdr) + fq->q.len - sizeof(struct frag_hdr)); if (payload_len > IPV6_MAXPLEN) goto out_oversize; - delta = - head->truesize; - - /* Head of list must not be cloned. */ - if (skb_unclone(head, GFP_ATOMIC)) - goto out_oom; - - delta += head->truesize; - if (delta) - add_frag_mem_limit(fq->q.net, delta); - - /* If the first fragment is fragmented itself, we split - * it to two chunks: the first with data and paged part - * and the second, holding only fragments. */ - if (skb_has_frag_list(head)) { - struct sk_buff *clone; - int i, plen = 0; - - clone = alloc_skb(0, GFP_ATOMIC); - if (!clone) - goto out_oom; - clone->next = head->next; - head->next = clone; - skb_shinfo(clone)->frag_list = skb_shinfo(head)->frag_list; - skb_frag_list_init(head); - for (i = 0; i < skb_shinfo(head)->nr_frags; i++) - plen += skb_frag_size(&skb_shinfo(head)->frags[i]); - clone->len = clone->data_len = head->data_len - plen; - head->data_len -= clone->len; - head->len -= clone->len; - clone->csum = 0; - clone->ip_summed = head->ip_summed; - add_frag_mem_limit(fq->q.net, clone->truesize); - } - /* We have to remove fragment header from datagram and to relocate * header in order to calculate ICV correctly. */ nhoff = fq->nhoffset; - skb_network_header(head)[nhoff] = skb_transport_header(head)[0]; - memmove(head->head + sizeof(struct frag_hdr), head->head, - (head->data - head->head) - sizeof(struct frag_hdr)); - if (skb_mac_header_was_set(head)) - head->mac_header += sizeof(struct frag_hdr); - head->network_header += sizeof(struct frag_hdr); - - skb_reset_transport_header(head); - skb_push(head, head->data - skb_network_header(head)); - - sum_truesize = head->truesize; - for (fp = head->next; fp;) { - bool headstolen; - int delta; - struct sk_buff *next = fp->next; - - sum_truesize += fp->truesize; - if (head->ip_summed != fp->ip_summed) - head->ip_summed = CHECKSUM_NONE; - else if (head->ip_summed == CHECKSUM_COMPLETE) - head->csum = csum_add(head->csum, fp->csum); - - if (skb_try_coalesce(head, fp, &headstolen, &delta)) { - kfree_skb_partial(fp, headstolen); - } else { - if (!skb_shinfo(head)->frag_list) - skb_shinfo(head)->frag_list = fp; - head->data_len += fp->len; - head->len += fp->len; - head->truesize += fp->truesize; - } - fp = next; - } - sub_frag_mem_limit(fq->q.net, sum_truesize); + skb_network_header(skb)[nhoff] = skb_transport_header(skb)[0]; + memmove(skb->head + sizeof(struct frag_hdr), skb->head, + (skb->data - skb->head) - sizeof(struct frag_hdr)); + if (skb_mac_header_was_set(skb)) + skb->mac_header += sizeof(struct frag_hdr); + skb->network_header += sizeof(struct frag_hdr); + + skb_reset_transport_header(skb); + + inet_frag_reasm_finish(&fq->q, skb, reasm_data); - head->next = NULL; - head->dev = dev; - head->tstamp = fq->q.stamp; - ipv6_hdr(head)->payload_len = htons(payload_len); - ipv6_change_dsfield(ipv6_hdr(head), 0xff, ecn); - IP6CB(head)->nhoff = nhoff; - IP6CB(head)->flags |= IP6SKB_FRAGMENTED; - IP6CB(head)->frag_max_size = fq->q.max_size; + skb->dev = dev; + ipv6_hdr(skb)->payload_len = htons(payload_len); + ipv6_change_dsfield(ipv6_hdr(skb), 0xff, ecn); + IP6CB(skb)->nhoff = nhoff; + IP6CB(skb)->flags |= IP6SKB_FRAGMENTED; + IP6CB(skb)->frag_max_size = fq->q.max_size; /* Yes, and fold redundant checksum back. 8) */ - skb_postpush_rcsum(head, skb_network_header(head), - skb_network_header_len(head)); + skb_postpush_rcsum(skb, skb_network_header(skb), + skb_network_header_len(skb)); rcu_read_lock(); __IP6_INC_STATS(net, __in6_dev_get(dev), IPSTATS_MIB_REASMOKS); @@ -419,6 +307,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, fq->q.fragments = NULL; fq->q.rb_fragments = RB_ROOT; fq->q.fragments_tail = NULL; + fq->q.last_run_head = NULL; return 1; out_oversize: @@ -430,6 +319,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, rcu_read_lock(); __IP6_INC_STATS(net, __in6_dev_get(dev), IPSTATS_MIB_REASMFAILS); rcu_read_unlock(); + inet_frag_kill(&fq->q); return -1; } @@ -468,10 +358,6 @@ static int ipv6_frag_rcv(struct sk_buff *skb) return 1; } - if (skb->len - skb_network_offset(skb) < IPV6_MIN_MTU && - fhdr->frag_off & htons(IP6_MF)) - goto fail_hdr; - iif = skb->dev ? skb->dev->ifindex : 0; fq = fq_find(net, fhdr->identification, hdr, iif); if (fq) { @@ -489,6 +375,7 @@ static int ipv6_frag_rcv(struct sk_buff *skb) if (prob_offset) { __IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_INHDRERRORS); + /* icmpv6_param_prob() calls kfree_skb(skb) */ icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, prob_offset); } return ret; -- GitLab From 74cec2565b14c3bd6d1c77d5e3ef9eaffab70404 Mon Sep 17 00:00:00 2001 From: Peter Oskolkov Date: Tue, 23 Apr 2019 10:48:25 -0700 Subject: [PATCH 0235/1121] net: IP6 defrag: use rbtrees in nf_conntrack_reasm.c [ Upstream commit 997dd96471641e147cb2c33ad54284000d0f5e35 ] Currently, IPv6 defragmentation code drops non-last fragments that are smaller than 1280 bytes: see commit 0ed4229b08c1 ("ipv6: defrag: drop non-last frags smaller than min mtu") This behavior is not specified in IPv6 RFCs and appears to break compatibility with some IPv6 implemenations, as reported here: https://www.spinics.net/lists/netdev/msg543846.html This patch re-uses common IP defragmentation queueing and reassembly code in IP6 defragmentation in nf_conntrack, removing the 1280 byte restriction. Signed-off-by: Peter Oskolkov Reported-by: Tom Herbert Cc: Eric Dumazet Cc: Florian Westphal Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/ipv6/netfilter/nf_conntrack_reasm.c | 262 +++++++----------------- 1 file changed, 72 insertions(+), 190 deletions(-) diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index 0568d49b5da4..cb1b4772dac0 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -51,14 +51,6 @@ static const char nf_frags_cache_name[] = "nf-frags"; -struct nf_ct_frag6_skb_cb -{ - struct inet6_skb_parm h; - int offset; -}; - -#define NFCT_FRAG6_CB(skb) ((struct nf_ct_frag6_skb_cb *)((skb)->cb)) - static struct inet_frags nf_frags; #ifdef CONFIG_SYSCTL @@ -144,6 +136,9 @@ static void __net_exit nf_ct_frags6_sysctl_unregister(struct net *net) } #endif +static int nf_ct_frag6_reasm(struct frag_queue *fq, struct sk_buff *skb, + struct sk_buff *prev_tail, struct net_device *dev); + static inline u8 ip6_frag_ecn(const struct ipv6hdr *ipv6h) { return 1 << (ipv6_get_dsfield(ipv6h) & INET_ECN_MASK); @@ -185,9 +180,10 @@ static struct frag_queue *fq_find(struct net *net, __be32 id, u32 user, static int nf_ct_frag6_queue(struct frag_queue *fq, struct sk_buff *skb, const struct frag_hdr *fhdr, int nhoff) { - struct sk_buff *prev, *next; unsigned int payload_len; - int offset, end; + struct net_device *dev; + struct sk_buff *prev; + int offset, end, err; u8 ecn; if (fq->q.flags & INET_FRAG_COMPLETE) { @@ -262,55 +258,19 @@ static int nf_ct_frag6_queue(struct frag_queue *fq, struct sk_buff *skb, goto err; } - /* Find out which fragments are in front and at the back of us - * in the chain of fragments so far. We must know where to put - * this fragment, right? - */ + /* Note : skb->rbnode and skb->dev share the same location. */ + dev = skb->dev; + /* Makes sure compiler wont do silly aliasing games */ + barrier(); + prev = fq->q.fragments_tail; - if (!prev || NFCT_FRAG6_CB(prev)->offset < offset) { - next = NULL; - goto found; - } - prev = NULL; - for (next = fq->q.fragments; next != NULL; next = next->next) { - if (NFCT_FRAG6_CB(next)->offset >= offset) - break; /* bingo! */ - prev = next; - } + err = inet_frag_queue_insert(&fq->q, skb, offset, end); + if (err) + goto insert_error; -found: - /* RFC5722, Section 4: - * When reassembling an IPv6 datagram, if - * one or more its constituent fragments is determined to be an - * overlapping fragment, the entire datagram (and any constituent - * fragments, including those not yet received) MUST be silently - * discarded. - */ + if (dev) + fq->iif = dev->ifindex; - /* Check for overlap with preceding fragment. */ - if (prev && - (NFCT_FRAG6_CB(prev)->offset + prev->len) > offset) - goto discard_fq; - - /* Look for overlap with succeeding segment. */ - if (next && NFCT_FRAG6_CB(next)->offset < end) - goto discard_fq; - - NFCT_FRAG6_CB(skb)->offset = offset; - - /* Insert this fragment in the chain of fragments. */ - skb->next = next; - if (!next) - fq->q.fragments_tail = skb; - if (prev) - prev->next = skb; - else - fq->q.fragments = skb; - - if (skb->dev) { - fq->iif = skb->dev->ifindex; - skb->dev = NULL; - } fq->q.stamp = skb->tstamp; fq->q.meat += skb->len; fq->ecn |= ecn; @@ -326,11 +286,25 @@ static int nf_ct_frag6_queue(struct frag_queue *fq, struct sk_buff *skb, fq->q.flags |= INET_FRAG_FIRST_IN; } - return 0; + if (fq->q.flags == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) && + fq->q.meat == fq->q.len) { + unsigned long orefdst = skb->_skb_refdst; -discard_fq: + skb->_skb_refdst = 0UL; + err = nf_ct_frag6_reasm(fq, skb, prev, dev); + skb->_skb_refdst = orefdst; + return err; + } + + skb_dst_drop(skb); + return -EINPROGRESS; + +insert_error: + if (err == IPFRAG_DUP) + goto err; inet_frag_kill(&fq->q); err: + skb_dst_drop(skb); return -EINVAL; } @@ -340,147 +314,67 @@ static int nf_ct_frag6_queue(struct frag_queue *fq, struct sk_buff *skb, * It is called with locked fq, and caller must check that * queue is eligible for reassembly i.e. it is not COMPLETE, * the last and the first frames arrived and all the bits are here. - * - * returns true if *prev skb has been transformed into the reassembled - * skb, false otherwise. */ -static bool -nf_ct_frag6_reasm(struct frag_queue *fq, struct sk_buff *prev, struct net_device *dev) +static int nf_ct_frag6_reasm(struct frag_queue *fq, struct sk_buff *skb, + struct sk_buff *prev_tail, struct net_device *dev) { - struct sk_buff *fp, *head = fq->q.fragments; - int payload_len, delta; + void *reasm_data; + int payload_len; u8 ecn; inet_frag_kill(&fq->q); - WARN_ON(head == NULL); - WARN_ON(NFCT_FRAG6_CB(head)->offset != 0); - ecn = ip_frag_ecn_table[fq->ecn]; if (unlikely(ecn == 0xff)) - return false; + goto err; + + reasm_data = inet_frag_reasm_prepare(&fq->q, skb, prev_tail); + if (!reasm_data) + goto err; - /* Unfragmented part is taken from the first segment. */ - payload_len = ((head->data - skb_network_header(head)) - + payload_len = ((skb->data - skb_network_header(skb)) - sizeof(struct ipv6hdr) + fq->q.len - sizeof(struct frag_hdr)); if (payload_len > IPV6_MAXPLEN) { net_dbg_ratelimited("nf_ct_frag6_reasm: payload len = %d\n", payload_len); - return false; - } - - delta = - head->truesize; - - /* Head of list must not be cloned. */ - if (skb_unclone(head, GFP_ATOMIC)) - return false; - - delta += head->truesize; - if (delta) - add_frag_mem_limit(fq->q.net, delta); - - /* If the first fragment is fragmented itself, we split - * it to two chunks: the first with data and paged part - * and the second, holding only fragments. */ - if (skb_has_frag_list(head)) { - struct sk_buff *clone; - int i, plen = 0; - - clone = alloc_skb(0, GFP_ATOMIC); - if (clone == NULL) - return false; - - clone->next = head->next; - head->next = clone; - skb_shinfo(clone)->frag_list = skb_shinfo(head)->frag_list; - skb_frag_list_init(head); - for (i = 0; i < skb_shinfo(head)->nr_frags; i++) - plen += skb_frag_size(&skb_shinfo(head)->frags[i]); - clone->len = clone->data_len = head->data_len - plen; - head->data_len -= clone->len; - head->len -= clone->len; - clone->csum = 0; - clone->ip_summed = head->ip_summed; - - add_frag_mem_limit(fq->q.net, clone->truesize); - } - - /* morph head into last received skb: prev. - * - * This allows callers of ipv6 conntrack defrag to continue - * to use the last skb(frag) passed into the reasm engine. - * The last skb frag 'silently' turns into the full reassembled skb. - * - * Since prev is also part of q->fragments we have to clone it first. - */ - if (head != prev) { - struct sk_buff *iter; - - fp = skb_clone(prev, GFP_ATOMIC); - if (!fp) - return false; - - fp->next = prev->next; - - iter = head; - while (iter) { - if (iter->next == prev) { - iter->next = fp; - break; - } - iter = iter->next; - } - - skb_morph(prev, head); - prev->next = head->next; - consume_skb(head); - head = prev; + goto err; } /* We have to remove fragment header from datagram and to relocate * header in order to calculate ICV correctly. */ - skb_network_header(head)[fq->nhoffset] = skb_transport_header(head)[0]; - memmove(head->head + sizeof(struct frag_hdr), head->head, - (head->data - head->head) - sizeof(struct frag_hdr)); - head->mac_header += sizeof(struct frag_hdr); - head->network_header += sizeof(struct frag_hdr); - - skb_shinfo(head)->frag_list = head->next; - skb_reset_transport_header(head); - skb_push(head, head->data - skb_network_header(head)); - - for (fp = head->next; fp; fp = fp->next) { - head->data_len += fp->len; - head->len += fp->len; - if (head->ip_summed != fp->ip_summed) - head->ip_summed = CHECKSUM_NONE; - else if (head->ip_summed == CHECKSUM_COMPLETE) - head->csum = csum_add(head->csum, fp->csum); - head->truesize += fp->truesize; - fp->sk = NULL; - } - sub_frag_mem_limit(fq->q.net, head->truesize); + skb_network_header(skb)[fq->nhoffset] = skb_transport_header(skb)[0]; + memmove(skb->head + sizeof(struct frag_hdr), skb->head, + (skb->data - skb->head) - sizeof(struct frag_hdr)); + skb->mac_header += sizeof(struct frag_hdr); + skb->network_header += sizeof(struct frag_hdr); + + skb_reset_transport_header(skb); + + inet_frag_reasm_finish(&fq->q, skb, reasm_data); - head->ignore_df = 1; - head->next = NULL; - head->dev = dev; - head->tstamp = fq->q.stamp; - ipv6_hdr(head)->payload_len = htons(payload_len); - ipv6_change_dsfield(ipv6_hdr(head), 0xff, ecn); - IP6CB(head)->frag_max_size = sizeof(struct ipv6hdr) + fq->q.max_size; + skb->ignore_df = 1; + skb->dev = dev; + ipv6_hdr(skb)->payload_len = htons(payload_len); + ipv6_change_dsfield(ipv6_hdr(skb), 0xff, ecn); + IP6CB(skb)->frag_max_size = sizeof(struct ipv6hdr) + fq->q.max_size; /* Yes, and fold redundant checksum back. 8) */ - if (head->ip_summed == CHECKSUM_COMPLETE) - head->csum = csum_partial(skb_network_header(head), - skb_network_header_len(head), - head->csum); + if (skb->ip_summed == CHECKSUM_COMPLETE) + skb->csum = csum_partial(skb_network_header(skb), + skb_network_header_len(skb), + skb->csum); fq->q.fragments = NULL; fq->q.rb_fragments = RB_ROOT; fq->q.fragments_tail = NULL; + fq->q.last_run_head = NULL; - return true; + return 0; + +err: + inet_frag_kill(&fq->q); + return -EINVAL; } /* @@ -549,7 +443,6 @@ find_prev_fhdr(struct sk_buff *skb, u8 *prevhdrp, int *prevhoff, int *fhoff) int nf_ct_frag6_gather(struct net *net, struct sk_buff *skb, u32 user) { u16 savethdr = skb->transport_header; - struct net_device *dev = skb->dev; int fhoff, nhoff, ret; struct frag_hdr *fhdr; struct frag_queue *fq; @@ -572,10 +465,6 @@ int nf_ct_frag6_gather(struct net *net, struct sk_buff *skb, u32 user) hdr = ipv6_hdr(skb); fhdr = (struct frag_hdr *)skb_transport_header(skb); - if (skb->len - skb_network_offset(skb) < IPV6_MIN_MTU && - fhdr->frag_off & htons(IP6_MF)) - return -EINVAL; - skb_orphan(skb); fq = fq_find(net, fhdr->identification, user, hdr, skb->dev ? skb->dev->ifindex : 0); @@ -587,24 +476,17 @@ int nf_ct_frag6_gather(struct net *net, struct sk_buff *skb, u32 user) spin_lock_bh(&fq->q.lock); ret = nf_ct_frag6_queue(fq, skb, fhdr, nhoff); - if (ret < 0) { - if (ret == -EPROTO) { - skb->transport_header = savethdr; - ret = 0; - } - goto out_unlock; + if (ret == -EPROTO) { + skb->transport_header = savethdr; + ret = 0; } /* after queue has assumed skb ownership, only 0 or -EINPROGRESS * must be returned. */ - ret = -EINPROGRESS; - if (fq->q.flags == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) && - fq->q.meat == fq->q.len && - nf_ct_frag6_reasm(fq, skb, dev)) - ret = 0; + if (ret) + ret = -EINPROGRESS; -out_unlock: spin_unlock_bh(&fq->q.lock); inet_frag_put(&fq->q); return ret; -- GitLab From 56714d4517b45acfb3747980fda39e018deb756a Mon Sep 17 00:00:00 2001 From: Matthias Kaehlcke Date: Tue, 23 Apr 2019 12:04:22 -0700 Subject: [PATCH 0236/1121] Revert "kbuild: use -Oz instead of -Os when using clang" commit a75bb4eb9e565b9f5115e2e8c07377ce32cbe69a upstream. The clang option -Oz enables *aggressive* optimization for size, which doesn't necessarily result in smaller images, but can have negative impact on performance. Switch back to the less aggressive -Os. This reverts commit 6748cb3c299de1ffbe56733647b01dbcc398c419. Suggested-by: Peter Zijlstra Signed-off-by: Matthias Kaehlcke Reviewed-by: Nick Desaulniers Signed-off-by: Masahiro Yamada Signed-off-by: Nathan Chancellor Signed-off-by: Sasha Levin --- Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Makefile b/Makefile index fcfef30ca9a6..d36e66ff60aa 100644 --- a/Makefile +++ b/Makefile @@ -653,8 +653,7 @@ KBUILD_CFLAGS += $(call cc-disable-warning, int-in-bool-context) KBUILD_CFLAGS += $(call cc-disable-warning, attribute-alias) ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE -KBUILD_CFLAGS += $(call cc-option,-Oz,-Os) -KBUILD_CFLAGS += $(call cc-disable-warning,maybe-uninitialized,) +KBUILD_CFLAGS += -Os $(call cc-disable-warning,maybe-uninitialized,) else ifdef CONFIG_PROFILE_ALL_BRANCHES KBUILD_CFLAGS += -O2 $(call cc-disable-warning,maybe-uninitialized,) -- GitLab From d069fe4844f8d799d771659a745fe91870c93fda Mon Sep 17 00:00:00 2001 From: Phil Auld Date: Tue, 23 Apr 2019 19:51:06 -0400 Subject: [PATCH 0237/1121] sched/fair: Limit sched_cfs_period_timer() loop to avoid hard lockup [ Upstream commit 2e8e19226398db8265a8e675fcc0118b9e80c9e8 ] With extremely short cfs_period_us setting on a parent task group with a large number of children the for loop in sched_cfs_period_timer() can run until the watchdog fires. There is no guarantee that the call to hrtimer_forward_now() will ever return 0. The large number of children can make do_sched_cfs_period_timer() take longer than the period. NMI watchdog: Watchdog detected hard LOCKUP on cpu 24 RIP: 0010:tg_nop+0x0/0x10 walk_tg_tree_from+0x29/0xb0 unthrottle_cfs_rq+0xe0/0x1a0 distribute_cfs_runtime+0xd3/0xf0 sched_cfs_period_timer+0xcb/0x160 ? sched_cfs_slack_timer+0xd0/0xd0 __hrtimer_run_queues+0xfb/0x270 hrtimer_interrupt+0x122/0x270 smp_apic_timer_interrupt+0x6a/0x140 apic_timer_interrupt+0xf/0x20 To prevent this we add protection to the loop that detects when the loop has run too many times and scales the period and quota up, proportionally, so that the timer can complete before then next period expires. This preserves the relative runtime quota while preventing the hard lockup. A warning is issued reporting this state and the new values. Signed-off-by: Phil Auld Signed-off-by: Peter Zijlstra (Intel) Cc: Cc: Anton Blanchard Cc: Ben Segall Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Link: https://lkml.kernel.org/r/20190319130005.25492-1-pauld@redhat.com Signed-off-by: Ingo Molnar Signed-off-by: Sasha Levin --- kernel/sched/fair.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 9829ede00498..a5d163903835 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -4672,12 +4672,15 @@ static enum hrtimer_restart sched_cfs_slack_timer(struct hrtimer *timer) return HRTIMER_NORESTART; } +extern const u64 max_cfs_quota_period; + static enum hrtimer_restart sched_cfs_period_timer(struct hrtimer *timer) { struct cfs_bandwidth *cfs_b = container_of(timer, struct cfs_bandwidth, period_timer); int overrun; int idle = 0; + int count = 0; raw_spin_lock(&cfs_b->lock); for (;;) { @@ -4685,6 +4688,28 @@ static enum hrtimer_restart sched_cfs_period_timer(struct hrtimer *timer) if (!overrun) break; + if (++count > 3) { + u64 new, old = ktime_to_ns(cfs_b->period); + + new = (old * 147) / 128; /* ~115% */ + new = min(new, max_cfs_quota_period); + + cfs_b->period = ns_to_ktime(new); + + /* since max is 1s, this is limited to 1e9^2, which fits in u64 */ + cfs_b->quota *= new; + cfs_b->quota = div64_u64(cfs_b->quota, old); + + pr_warn_ratelimited( + "cfs_period_timer[cpu%d]: period too short, scaling up (new cfs_period_us %lld, cfs_quota_us = %lld)\n", + smp_processor_id(), + div_u64(new, NSEC_PER_USEC), + div_u64(cfs_b->quota, NSEC_PER_USEC)); + + /* reset count so we don't come right back in here */ + count = 0; + } + idle = do_sched_cfs_period_timer(cfs_b, overrun); } if (idle) -- GitLab From 80ef021be19d3cdebe162c73b13d0f249d5bd2f3 Mon Sep 17 00:00:00 2001 From: Jann Horn Date: Tue, 19 Mar 2019 02:36:59 +0100 Subject: [PATCH 0238/1121] device_cgroup: fix RCU imbalance in error case commit 0fcc4c8c044e117ac126ab6df4138ea9a67fa2a9 upstream. When dev_exception_add() returns an error (due to a failed memory allocation), make sure that we move the RCU preemption count back to where it was before we were called. We dropped the RCU read lock inside the loop body, so we can't just "break". sparse complains about this, too: $ make -s C=2 security/device_cgroup.o ./include/linux/rcupdate.h:647:9: warning: context imbalance in 'propagate_exception' - unexpected unlock Fixes: d591fb56618f ("device_cgroup: simplify cgroup tree walk in propagate_exception()") Cc: stable@vger.kernel.org Signed-off-by: Jann Horn Acked-by: Michal Hocko Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- security/device_cgroup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/device_cgroup.c b/security/device_cgroup.c index 5ef7e5240563..ea014df89428 100644 --- a/security/device_cgroup.c +++ b/security/device_cgroup.c @@ -569,7 +569,7 @@ static int propagate_exception(struct dev_cgroup *devcg_root, devcg->behavior == DEVCG_DEFAULT_ALLOW) { rc = dev_exception_add(devcg, ex); if (rc) - break; + return rc; } else { /* * in the other possible cases: -- GitLab From 98ae85677ebfac2fa2243a9c954d96ea58c08e85 Mon Sep 17 00:00:00 2001 From: Konstantin Khlebnikov Date: Thu, 18 Apr 2019 17:50:20 -0700 Subject: [PATCH 0239/1121] mm/vmstat.c: fix /proc/vmstat format for CONFIG_DEBUG_TLBFLUSH=y CONFIG_SMP=n commit e8277b3b52240ec1caad8e6df278863e4bf42eac upstream. Commit 58bc4c34d249 ("mm/vmstat.c: skip NR_TLB_REMOTE_FLUSH* properly") depends on skipping vmstat entries with empty name introduced in 7aaf77272358 ("mm: don't show nr_indirectly_reclaimable in /proc/vmstat") but reverted in b29940c1abd7 ("mm: rename and change semantics of nr_indirectly_reclaimable_bytes"). So skipping no longer works and /proc/vmstat has misformatted lines " 0". This patch simply shows debug counters "nr_tlb_remote_*" for UP. Link: http://lkml.kernel.org/r/155481488468.467.4295519102880913454.stgit@buzz Fixes: 58bc4c34d249 ("mm/vmstat.c: skip NR_TLB_REMOTE_FLUSH* properly") Signed-off-by: Konstantin Khlebnikov Acked-by: Vlastimil Babka Cc: Roman Gushchin Cc: Jann Horn Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- mm/vmstat.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/mm/vmstat.c b/mm/vmstat.c index 6389e876c7a7..28c45c26f901 100644 --- a/mm/vmstat.c +++ b/mm/vmstat.c @@ -1201,13 +1201,8 @@ const char * const vmstat_text[] = { #endif #endif /* CONFIG_MEMORY_BALLOON */ #ifdef CONFIG_DEBUG_TLBFLUSH -#ifdef CONFIG_SMP "nr_tlb_remote_flush", "nr_tlb_remote_flush_received", -#else - "", /* nr_tlb_remote_flush */ - "", /* nr_tlb_remote_flush_received */ -#endif /* CONFIG_SMP */ "nr_tlb_local_flush_all", "nr_tlb_local_flush_one", #endif /* CONFIG_DEBUG_TLBFLUSH */ -- GitLab From 216f6570d18bcd06975205b8af1708ea10a1baf6 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 16 Apr 2019 15:25:00 +0200 Subject: [PATCH 0240/1121] ALSA: info: Fix racy addition/deletion of nodes commit 8c2f870890fd28e023b0fcf49dcee333f2c8bad7 upstream. The ALSA proc helper manages the child nodes in a linked list, but its addition and deletion is done without any lock. This leads to a corruption if they are operated concurrently. Usually this isn't a problem because the proc entries are added sequentially in the driver probe procedure itself. But the card registrations are done often asynchronously, and the crash could be actually reproduced with syzkaller. This patch papers over it by protecting the link addition and deletion with the parent's mutex. There is "access" mutex that is used for the file access, and this can be reused for this purpose as well. Reported-by: syzbot+48df349490c36f9f54ab@syzkaller.appspotmail.com Cc: Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/core/info.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/sound/core/info.c b/sound/core/info.c index bcf6a48cc70d..5fb00437507b 100644 --- a/sound/core/info.c +++ b/sound/core/info.c @@ -722,8 +722,11 @@ snd_info_create_entry(const char *name, struct snd_info_entry *parent) INIT_LIST_HEAD(&entry->children); INIT_LIST_HEAD(&entry->list); entry->parent = parent; - if (parent) + if (parent) { + mutex_lock(&parent->access); list_add_tail(&entry->list, &parent->children); + mutex_unlock(&parent->access); + } return entry; } @@ -805,7 +808,12 @@ void snd_info_free_entry(struct snd_info_entry * entry) list_for_each_entry_safe(p, n, &entry->children, list) snd_info_free_entry(p); - list_del(&entry->list); + p = entry->parent; + if (p) { + mutex_lock(&p->access); + list_del(&entry->list); + mutex_unlock(&p->access); + } kfree(entry->name); if (entry->private_free) entry->private_free(entry); -- GitLab From 47ad82a34560ea70e85d2eb56be0ada03dc4fd35 Mon Sep 17 00:00:00 2001 From: Matteo Croce Date: Mon, 18 Mar 2019 02:32:36 +0100 Subject: [PATCH 0241/1121] percpu: stop printing kernel addresses commit 00206a69ee32f03e6f40837684dcbe475ea02266 upstream. Since commit ad67b74d2469d9b8 ("printk: hash addresses printed with %p"), at boot "____ptrval____" is printed instead of actual addresses: percpu: Embedded 38 pages/cpu @(____ptrval____) s124376 r0 d31272 u524288 Instead of changing the print to "%px", and leaking kernel addresses, just remove the print completely, cfr. e.g. commit 071929dbdd865f77 ("arm64: Stop printing the virtual memory layout"). Signed-off-by: Matteo Croce Signed-off-by: Dennis Zhou Signed-off-by: Greg Kroah-Hartman --- mm/percpu.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mm/percpu.c b/mm/percpu.c index 3074148b7e0d..0c06e2f549a7 100644 --- a/mm/percpu.c +++ b/mm/percpu.c @@ -2507,8 +2507,8 @@ int __init pcpu_embed_first_chunk(size_t reserved_size, size_t dyn_size, ai->groups[group].base_offset = areas[group] - base; } - pr_info("Embedded %zu pages/cpu @%p s%zu r%zu d%zu u%zu\n", - PFN_DOWN(size_sum), base, ai->static_size, ai->reserved_size, + pr_info("Embedded %zu pages/cpu s%zu r%zu d%zu u%zu\n", + PFN_DOWN(size_sum), ai->static_size, ai->reserved_size, ai->dyn_size, ai->unit_size); rc = pcpu_setup_first_chunk(ai, base); @@ -2629,8 +2629,8 @@ int __init pcpu_page_first_chunk(size_t reserved_size, } /* we're ready, commit */ - pr_info("%d %s pages/cpu @%p s%zu r%zu d%zu\n", - unit_pages, psize_str, vm.addr, ai->static_size, + pr_info("%d %s pages/cpu s%zu r%zu d%zu\n", + unit_pages, psize_str, ai->static_size, ai->reserved_size, ai->dyn_size); rc = pcpu_setup_first_chunk(ai, vm.addr); -- GitLab From c5e44540ca312c4bbaafb1950c825a930c9adfdf Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 25 Sep 2018 10:55:59 -0300 Subject: [PATCH 0242/1121] tools include: Adopt linux/bits.h commit ba4aa02b417f08a0bee5e7b8ed70cac788a7c854 upstream. So that we reduce the difference of tools/include/linux/bitops.h to the original kernel file, include/linux/bitops.h, trying to remove the need to define BITS_PER_LONG, to avoid clashes with asm/bitsperlong.h. And the things removed from tools/include/linux/bitops.h are really in linux/bits.h, so that we can have a copy and then tools/perf/check_headers.sh will tell us when new stuff gets added to linux/bits.h so that we can check if it is useful and if any adjustment needs to be done to the tools/{include,arch}/ copies. Cc: Adrian Hunter Cc: Alexander Sverdlin Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-y1sqyydvfzo0bjjoj4zsl562@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Greg Kroah-Hartman --- tools/include/linux/bitops.h | 7 ++----- tools/include/linux/bits.h | 26 ++++++++++++++++++++++++++ tools/perf/check-headers.sh | 1 + 3 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 tools/include/linux/bits.h diff --git a/tools/include/linux/bitops.h b/tools/include/linux/bitops.h index acc704bd3998..0b0ef3abc966 100644 --- a/tools/include/linux/bitops.h +++ b/tools/include/linux/bitops.h @@ -3,8 +3,6 @@ #define _TOOLS_LINUX_BITOPS_H_ #include -#include - #ifndef __WORDSIZE #define __WORDSIZE (__SIZEOF_LONG__ * 8) #endif @@ -12,10 +10,9 @@ #ifndef BITS_PER_LONG # define BITS_PER_LONG __WORDSIZE #endif +#include +#include -#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) -#define BIT_WORD(nr) ((nr) / BITS_PER_LONG) -#define BITS_PER_BYTE 8 #define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) #define BITS_TO_U64(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u64)) #define BITS_TO_U32(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u32)) diff --git a/tools/include/linux/bits.h b/tools/include/linux/bits.h new file mode 100644 index 000000000000..2b7b532c1d51 --- /dev/null +++ b/tools/include/linux/bits.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __LINUX_BITS_H +#define __LINUX_BITS_H +#include + +#define BIT(nr) (1UL << (nr)) +#define BIT_ULL(nr) (1ULL << (nr)) +#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) +#define BIT_WORD(nr) ((nr) / BITS_PER_LONG) +#define BIT_ULL_MASK(nr) (1ULL << ((nr) % BITS_PER_LONG_LONG)) +#define BIT_ULL_WORD(nr) ((nr) / BITS_PER_LONG_LONG) +#define BITS_PER_BYTE 8 + +/* + * Create a contiguous bitmask starting at bit position @l and ending at + * position @h. For example + * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000. + */ +#define GENMASK(h, l) \ + (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h)))) + +#define GENMASK_ULL(h, l) \ + (((~0ULL) - (1ULL << (l)) + 1) & \ + (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h)))) + +#endif /* __LINUX_BITS_H */ diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh index 50cd6228f506..df1dbee8d98d 100755 --- a/tools/perf/check-headers.sh +++ b/tools/perf/check-headers.sh @@ -11,6 +11,7 @@ include/uapi/linux/sched.h include/uapi/linux/stat.h include/uapi/linux/vhost.h include/uapi/sound/asound.h +include/linux/bits.h include/linux/hash.h include/uapi/linux/hw_breakpoint.h arch/x86/include/asm/disabled-features.h -- GitLab From 4fa17fc730ba3b7f0cb69937df919a7a226067be Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 8 Jan 2018 10:41:39 -0800 Subject: [PATCH 0243/1121] iomap: report collisions between directio and buffered writes to userspace commit 5a9d929d6e13278df62bd9e3d3ceae8c87ad1eea upstream. If two programs simultaneously try to write to the same part of a file via direct IO and buffered IO, there's a chance that the post-diowrite pagecache invalidation will fail on the dirty page. When this happens, the dio write succeeded, which means that the page cache is no longer coherent with the disk! Programs are not supposed to mix IO types and this is a clear case of data corruption, so store an EIO which will be reflected to userspace during the next fsync. Replace the WARN_ON with a ratelimited pr_crit so that the developers have /some/ kind of breadcrumb to track down the offending program(s) and file(s) involved. Signed-off-by: Darrick J. Wong Reviewed-by: Liu Bo Signed-off-by: Greg Kroah-Hartman Cc: Zubin Mithra --- fs/direct-io.c | 24 +++++++++++++++++++++++- fs/iomap.c | 12 ++++++++++-- include/linux/fs.h | 1 + 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/fs/direct-io.c b/fs/direct-io.c index 2c90d541f527..30bf22c989de 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c @@ -219,6 +219,27 @@ static inline struct page *dio_get_page(struct dio *dio, return dio->pages[sdio->head]; } +/* + * Warn about a page cache invalidation failure during a direct io write. + */ +void dio_warn_stale_pagecache(struct file *filp) +{ + static DEFINE_RATELIMIT_STATE(_rs, 86400 * HZ, DEFAULT_RATELIMIT_BURST); + char pathname[128]; + struct inode *inode = file_inode(filp); + char *path; + + errseq_set(&inode->i_mapping->wb_err, -EIO); + if (__ratelimit(&_rs)) { + path = file_path(filp, pathname, sizeof(pathname)); + if (IS_ERR(path)) + path = "(unknown)"; + pr_crit("Page cache invalidation failure on direct I/O. Possible data corruption due to collision with buffered I/O!\n"); + pr_crit("File: %s PID: %d Comm: %.20s\n", path, current->pid, + current->comm); + } +} + /** * dio_complete() - called when all DIO BIO I/O has been completed * @offset: the byte offset in the file of the completed operation @@ -290,7 +311,8 @@ static ssize_t dio_complete(struct dio *dio, ssize_t ret, unsigned int flags) err = invalidate_inode_pages2_range(dio->inode->i_mapping, offset >> PAGE_SHIFT, (offset + ret - 1) >> PAGE_SHIFT); - WARN_ON_ONCE(err); + if (err) + dio_warn_stale_pagecache(dio->iocb->ki_filp); } if (!(dio->flags & DIO_SKIP_DIO_COUNT)) diff --git a/fs/iomap.c b/fs/iomap.c index 8f7673a69273..467d98bf7054 100644 --- a/fs/iomap.c +++ b/fs/iomap.c @@ -753,7 +753,8 @@ static ssize_t iomap_dio_complete(struct iomap_dio *dio) err = invalidate_inode_pages2_range(inode->i_mapping, offset >> PAGE_SHIFT, (offset + dio->size - 1) >> PAGE_SHIFT); - WARN_ON_ONCE(err); + if (err) + dio_warn_stale_pagecache(iocb->ki_filp); } inode_dio_end(file_inode(iocb->ki_filp)); @@ -1010,9 +1011,16 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, if (ret) goto out_free_dio; + /* + * Try to invalidate cache pages for the range we're direct + * writing. If this invalidation fails, tough, the write will + * still work, but racing two incompatible write paths is a + * pretty crazy thing to do, so we don't support it 100%. + */ ret = invalidate_inode_pages2_range(mapping, start >> PAGE_SHIFT, end >> PAGE_SHIFT); - WARN_ON_ONCE(ret); + if (ret) + dio_warn_stale_pagecache(iocb->ki_filp); ret = 0; if (iov_iter_rw(iter) == WRITE && !dio->wait_for_completion && diff --git a/include/linux/fs.h b/include/linux/fs.h index f6a577edec67..dafac283b0ff 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2965,6 +2965,7 @@ enum { }; void dio_end_io(struct bio *bio); +void dio_warn_stale_pagecache(struct file *filp); ssize_t __blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, struct block_device *bdev, struct iov_iter *iter, -- GitLab From 2411a27e7475273aa10179d94bb00e958f6fbec5 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Thu, 7 Dec 2017 19:07:02 -0800 Subject: [PATCH 0244/1121] xfs: add the ability to join a held buffer to a defer_ops commit b7b2846fe26f2c0d7f317c874a13d3ecf22670ff upstream. In certain cases, defer_ops callers will lock a buffer and want to hold the lock across transaction rolls. Similar to ijoined inodes, we want to dirty & join the buffer with each transaction roll in defer_finish so that afterwards the caller still owns the buffer lock and we haven't inadvertently pinned the log. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig Signed-off-by: Alex Lyakas Signed-off-by: Greg Kroah-Hartman --- fs/xfs/libxfs/xfs_defer.c | 39 ++++++++++++++++++++++++++++++++++++--- fs/xfs/libxfs/xfs_defer.h | 5 ++++- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c index 072ebfe1d6ae..087fea02c389 100644 --- a/fs/xfs/libxfs/xfs_defer.c +++ b/fs/xfs/libxfs/xfs_defer.c @@ -249,6 +249,10 @@ xfs_defer_trans_roll( for (i = 0; i < XFS_DEFER_OPS_NR_INODES && dop->dop_inodes[i]; i++) xfs_trans_log_inode(*tp, dop->dop_inodes[i], XFS_ILOG_CORE); + /* Hold the (previously bjoin'd) buffer locked across the roll. */ + for (i = 0; i < XFS_DEFER_OPS_NR_BUFS && dop->dop_bufs[i]; i++) + xfs_trans_dirty_buf(*tp, dop->dop_bufs[i]); + trace_xfs_defer_trans_roll((*tp)->t_mountp, dop); /* Roll the transaction. */ @@ -264,6 +268,12 @@ xfs_defer_trans_roll( for (i = 0; i < XFS_DEFER_OPS_NR_INODES && dop->dop_inodes[i]; i++) xfs_trans_ijoin(*tp, dop->dop_inodes[i], 0); + /* Rejoin the buffers and dirty them so the log moves forward. */ + for (i = 0; i < XFS_DEFER_OPS_NR_BUFS && dop->dop_bufs[i]; i++) { + xfs_trans_bjoin(*tp, dop->dop_bufs[i]); + xfs_trans_bhold(*tp, dop->dop_bufs[i]); + } + return error; } @@ -295,6 +305,31 @@ xfs_defer_ijoin( } } + ASSERT(0); + return -EFSCORRUPTED; +} + +/* + * Add this buffer to the deferred op. Each joined buffer is relogged + * each time we roll the transaction. + */ +int +xfs_defer_bjoin( + struct xfs_defer_ops *dop, + struct xfs_buf *bp) +{ + int i; + + for (i = 0; i < XFS_DEFER_OPS_NR_BUFS; i++) { + if (dop->dop_bufs[i] == bp) + return 0; + else if (dop->dop_bufs[i] == NULL) { + dop->dop_bufs[i] = bp; + return 0; + } + } + + ASSERT(0); return -EFSCORRUPTED; } @@ -493,9 +528,7 @@ xfs_defer_init( struct xfs_defer_ops *dop, xfs_fsblock_t *fbp) { - dop->dop_committed = false; - dop->dop_low = false; - memset(&dop->dop_inodes, 0, sizeof(dop->dop_inodes)); + memset(dop, 0, sizeof(struct xfs_defer_ops)); *fbp = NULLFSBLOCK; INIT_LIST_HEAD(&dop->dop_intake); INIT_LIST_HEAD(&dop->dop_pending); diff --git a/fs/xfs/libxfs/xfs_defer.h b/fs/xfs/libxfs/xfs_defer.h index d4f046dd44bd..045beacdd37d 100644 --- a/fs/xfs/libxfs/xfs_defer.h +++ b/fs/xfs/libxfs/xfs_defer.h @@ -59,6 +59,7 @@ enum xfs_defer_ops_type { }; #define XFS_DEFER_OPS_NR_INODES 2 /* join up to two inodes */ +#define XFS_DEFER_OPS_NR_BUFS 2 /* join up to two buffers */ struct xfs_defer_ops { bool dop_committed; /* did any trans commit? */ @@ -66,8 +67,9 @@ struct xfs_defer_ops { struct list_head dop_intake; /* unlogged pending work */ struct list_head dop_pending; /* logged pending work */ - /* relog these inodes with each roll */ + /* relog these with each roll */ struct xfs_inode *dop_inodes[XFS_DEFER_OPS_NR_INODES]; + struct xfs_buf *dop_bufs[XFS_DEFER_OPS_NR_BUFS]; }; void xfs_defer_add(struct xfs_defer_ops *dop, enum xfs_defer_ops_type type, @@ -77,6 +79,7 @@ void xfs_defer_cancel(struct xfs_defer_ops *dop); void xfs_defer_init(struct xfs_defer_ops *dop, xfs_fsblock_t *fbp); bool xfs_defer_has_unfinished_work(struct xfs_defer_ops *dop); int xfs_defer_ijoin(struct xfs_defer_ops *dop, struct xfs_inode *ip); +int xfs_defer_bjoin(struct xfs_defer_ops *dop, struct xfs_buf *bp); /* Description of a deferred type. */ struct xfs_defer_op_type { -- GitLab From 4024e3bde13e46489634cd2734d1518b1d92aef4 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Thu, 7 Dec 2017 19:07:02 -0800 Subject: [PATCH 0245/1121] xfs: hold xfs_buf locked between shortform->leaf conversion and the addition of an attribute commit 6e643cd094de3bd0f97edcc1db0089afa24d909f upstream. The new attribute leaf buffer is not held locked across the transaction roll between the shortform->leaf modification and the addition of the new entry. As a result, the attribute buffer modification being made is not atomic from an operational perspective. Hence the AIL push can grab it in the transient state of "just created" after the initial transaction is rolled, because the buffer has been released. This leads to xfs_attr3_leaf_verify() asserting that hdr.count is zero, treating this as in-memory corruption, and shutting down the filesystem. Darrick ported the original patch to 4.15 and reworked it use the xfs_defer_bjoin helper and hold/join the buffer correctly across the second transaction roll. Signed-off-by: Alex Lyakas Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig Signed-off-by: Alex Lyakas Signed-off-by: Greg Kroah-Hartman --- fs/xfs/libxfs/xfs_attr.c | 20 +++++++++++++++----- fs/xfs/libxfs/xfs_attr_leaf.c | 9 ++++++--- fs/xfs/libxfs/xfs_attr_leaf.h | 3 ++- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index ea66f04f46f7..e4265db08e4b 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -212,6 +212,7 @@ xfs_attr_set( int flags) { struct xfs_mount *mp = dp->i_mount; + struct xfs_buf *leaf_bp = NULL; struct xfs_da_args args; struct xfs_defer_ops dfops; struct xfs_trans_res tres; @@ -327,9 +328,16 @@ xfs_attr_set( * GROT: another possible req'mt for a double-split btree op. */ xfs_defer_init(args.dfops, args.firstblock); - error = xfs_attr_shortform_to_leaf(&args); + error = xfs_attr_shortform_to_leaf(&args, &leaf_bp); if (error) goto out_defer_cancel; + /* + * Prevent the leaf buffer from being unlocked so that a + * concurrent AIL push cannot grab the half-baked leaf + * buffer and run into problems with the write verifier. + */ + xfs_trans_bhold(args.trans, leaf_bp); + xfs_defer_bjoin(args.dfops, leaf_bp); xfs_defer_ijoin(args.dfops, dp); error = xfs_defer_finish(&args.trans, args.dfops); if (error) @@ -337,13 +345,14 @@ xfs_attr_set( /* * Commit the leaf transformation. We'll need another (linked) - * transaction to add the new attribute to the leaf. + * transaction to add the new attribute to the leaf, which + * means that we have to hold & join the leaf buffer here too. */ - error = xfs_trans_roll_inode(&args.trans, dp); if (error) goto out; - + xfs_trans_bjoin(args.trans, leaf_bp); + leaf_bp = NULL; } if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) @@ -374,8 +383,9 @@ xfs_attr_set( out_defer_cancel: xfs_defer_cancel(&dfops); - args.trans = NULL; out: + if (leaf_bp) + xfs_trans_brelse(args.trans, leaf_bp); if (args.trans) xfs_trans_cancel(args.trans); xfs_iunlock(dp, XFS_ILOCK_EXCL); diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index 40e53a4fc0a6..73a541755d5b 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c @@ -739,10 +739,13 @@ xfs_attr_shortform_getvalue(xfs_da_args_t *args) } /* - * Convert from using the shortform to the leaf. + * Convert from using the shortform to the leaf. On success, return the + * buffer so that we can keep it locked until we're totally done with it. */ int -xfs_attr_shortform_to_leaf(xfs_da_args_t *args) +xfs_attr_shortform_to_leaf( + struct xfs_da_args *args, + struct xfs_buf **leaf_bp) { xfs_inode_t *dp; xfs_attr_shortform_t *sf; @@ -821,7 +824,7 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args) sfe = XFS_ATTR_SF_NEXTENTRY(sfe); } error = 0; - + *leaf_bp = bp; out: kmem_free(tmpbuffer); return error; diff --git a/fs/xfs/libxfs/xfs_attr_leaf.h b/fs/xfs/libxfs/xfs_attr_leaf.h index f7dda0c237b0..894124efb421 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.h +++ b/fs/xfs/libxfs/xfs_attr_leaf.h @@ -48,7 +48,8 @@ void xfs_attr_shortform_create(struct xfs_da_args *args); void xfs_attr_shortform_add(struct xfs_da_args *args, int forkoff); int xfs_attr_shortform_lookup(struct xfs_da_args *args); int xfs_attr_shortform_getvalue(struct xfs_da_args *args); -int xfs_attr_shortform_to_leaf(struct xfs_da_args *args); +int xfs_attr_shortform_to_leaf(struct xfs_da_args *args, + struct xfs_buf **leaf_bp); int xfs_attr_shortform_remove(struct xfs_da_args *args); int xfs_attr_shortform_allfit(struct xfs_buf *bp, struct xfs_inode *dp); int xfs_attr_shortform_bytesfit(struct xfs_inode *dp, int bytes); -- GitLab From d6b11409047f4aa9b1fec4e665b5cd42fcf3bbdb Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 27 Oct 2018 09:10:48 -0700 Subject: [PATCH 0246/1121] i2c-hid: properly terminate i2c_hid_dmi_desc_override_table[] array MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit b59dfdaef173677b0b7e10f375226c0a1114fd20 upstream. Commit 9ee3e06610fd ("HID: i2c-hid: override HID descriptors for certain devices") added a new dmi_system_id quirk table to override certain HID report descriptors for some systems that lack them. But the table wasn't properly terminated, causing the dmi matching to walk off into la-la-land, and starting to treat random data as dmi descriptor pointers, causing boot-time oopses if you were at all unlucky. Terminate the array. We really should have some way to just statically check that arrays that should be terminated by an empty entry actually are so. But the HID people really should have caught this themselves, rather than have me deal with an oops during the merge window. Tssk, tssk. Cc: Julian Sax Cc: Benjamin Tissoires Cc: Jiri Kosina Signed-off-by: Linus Torvalds Cc: AmbroĆŸ Bizjak Signed-off-by: Greg Kroah-Hartman --- drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c index 1d645c9ab417..cac262a912c1 100644 --- a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c +++ b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c @@ -337,7 +337,8 @@ static const struct dmi_system_id i2c_hid_dmi_desc_override_table[] = { DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "FlexBook edge11 - M-FBE11"), }, .driver_data = (void *)&sipodev_desc - } + }, + { } /* Terminate list */ }; -- GitLab From 599c8a408f875477624384edd60ce0c821ff7c8a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 25 Apr 2019 10:00:43 +0200 Subject: [PATCH 0247/1121] Revert "locking/lockdep: Add debug_locks check in __lock_downgrade()" This reverts commit 4a195a0bc2e954b91085d5c82eb20c51835ee7b0 which was commit 71492580571467fb7177aade19c18ce7486267f5 upstream. Tetsuo rightly points out that the backport here is incorrect, as it touches the __lock_set_class function instead of the intended __lock_downgrade function. Reported-by: Tetsuo Handa Cc: Waiman Long Cc: Peter Zijlstra (Intel) Cc: Andrew Morton Cc: Linus Torvalds Cc: Paul E. McKenney Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: Will Deacon Cc: Ingo Molnar Cc: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- kernel/locking/lockdep.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index e57be7031cb3..bf694c709b96 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c @@ -3650,9 +3650,6 @@ __lock_set_class(struct lockdep_map *lock, const char *name, unsigned int depth; int i; - if (unlikely(!debug_locks)) - return 0; - depth = curr->lockdep_depth; /* * This function is about (re)setting the class of a held lock, -- GitLab From 62c1af5fb31a72c229d17f812fa1fc37f69d4dbf Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 5 Apr 2019 18:39:38 -0700 Subject: [PATCH 0248/1121] kernel/sysctl.c: fix out-of-bounds access when setting file-max commit 9002b21465fa4d829edfc94a5a441005cffaa972 upstream. Commit 32a5ad9c2285 ("sysctl: handle overflow for file-max") hooked up min/max values for the file-max sysctl parameter via the .extra1 and .extra2 fields in the corresponding struct ctl_table entry. Unfortunately, the minimum value points at the global 'zero' variable, which is an int. This results in a KASAN splat when accessed as a long by proc_doulongvec_minmax on 64-bit architectures: | BUG: KASAN: global-out-of-bounds in __do_proc_doulongvec_minmax+0x5d8/0x6a0 | Read of size 8 at addr ffff2000133d1c20 by task systemd/1 | | CPU: 0 PID: 1 Comm: systemd Not tainted 5.1.0-rc3-00012-g40b114779944 #2 | Hardware name: linux,dummy-virt (DT) | Call trace: | dump_backtrace+0x0/0x228 | show_stack+0x14/0x20 | dump_stack+0xe8/0x124 | print_address_description+0x60/0x258 | kasan_report+0x140/0x1a0 | __asan_report_load8_noabort+0x18/0x20 | __do_proc_doulongvec_minmax+0x5d8/0x6a0 | proc_doulongvec_minmax+0x4c/0x78 | proc_sys_call_handler.isra.19+0x144/0x1d8 | proc_sys_write+0x34/0x58 | __vfs_write+0x54/0xe8 | vfs_write+0x124/0x3c0 | ksys_write+0xbc/0x168 | __arm64_sys_write+0x68/0x98 | el0_svc_common+0x100/0x258 | el0_svc_handler+0x48/0xc0 | el0_svc+0x8/0xc | | The buggy address belongs to the variable: | zero+0x0/0x40 | | Memory state around the buggy address: | ffff2000133d1b00: 00 00 00 00 00 00 00 00 fa fa fa fa 04 fa fa fa | ffff2000133d1b80: fa fa fa fa 04 fa fa fa fa fa fa fa 04 fa fa fa | >ffff2000133d1c00: fa fa fa fa 04 fa fa fa fa fa fa fa 00 00 00 00 | ^ | ffff2000133d1c80: fa fa fa fa 00 fa fa fa fa fa fa fa 00 00 00 00 | ffff2000133d1d00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Fix the splat by introducing a unsigned long 'zero_ul' and using that instead. Link: http://lkml.kernel.org/r/20190403153409.17307-1-will.deacon@arm.com Fixes: 32a5ad9c2285 ("sysctl: handle overflow for file-max") Signed-off-by: Will Deacon Acked-by: Christian Brauner Cc: Kees Cook Cc: Alexey Dobriyan Cc: Matteo Croce Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- kernel/sysctl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 34a3b8a262a9..f13601a616ad 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -124,6 +124,7 @@ static int zero; static int __maybe_unused one = 1; static int __maybe_unused two = 2; static int __maybe_unused four = 4; +static unsigned long zero_ul; static unsigned long one_ul = 1; static unsigned long long_max = LONG_MAX; static int one_hundred = 100; @@ -1682,7 +1683,7 @@ static struct ctl_table fs_table[] = { .maxlen = sizeof(files_stat.max_files), .mode = 0644, .proc_handler = proc_doulongvec_minmax, - .extra1 = &zero, + .extra1 = &zero_ul, .extra2 = &long_max, }, { -- GitLab From fa5941f45d7ed070118b7c209b7f2c3a034293bd Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 27 Apr 2019 09:35:42 +0200 Subject: [PATCH 0249/1121] Linux 4.14.114 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d36e66ff60aa..47a9f9883bdd 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 4 PATCHLEVEL = 14 -SUBLEVEL = 113 +SUBLEVEL = 114 EXTRAVERSION = NAME = Petit Gorille -- GitLab From 1f855871fc65a5dbe875df8bb13e7d018a542d93 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 23 Feb 2018 13:56:53 +0900 Subject: [PATCH 0250/1121] kbuild: simplify ld-option implementation commit 0294e6f4a0006856e1f36b8cd8fa088d9e499e98 upstream. Currently, linker options are tested by the coordination of $(CC) and $(LD) because $(LD) needs some object to link. As commit 86a9df597cdd ("kbuild: fix linker feature test macros when cross compiling with Clang") addressed, we need to make sure $(CC) and $(LD) agree the underlying architecture of the passed object. This could be a bit complex when we combine tools from different groups. For example, we can use clang for $(CC), but we still need to rely on GCC toolchain for $(LD). So, I was searching for a way of standalone testing of linker options. A trick I found is to use '-v'; this not only prints the version string, but also tests if the given option is recognized. If a given option is supported, $ aarch64-linux-gnu-ld -v --fix-cortex-a53-843419 GNU ld (Linaro_Binutils-2017.11) 2.28.2.20170706 $ echo $? 0 If unsupported, $ aarch64-linux-gnu-ld -v --fix-cortex-a53-843419 GNU ld (crosstool-NG linaro-1.13.1-4.7-2013.04-20130415 - Linaro GCC 2013.04) 2.23.1 aarch64-linux-gnu-ld: unrecognized option '--fix-cortex-a53-843419' aarch64-linux-gnu-ld: use the --help option for usage information $ echo $? 1 Gold works likewise. $ aarch64-linux-gnu-ld.gold -v --fix-cortex-a53-843419 GNU gold (Linaro_Binutils-2017.11 2.28.2.20170706) 1.14 masahiro@pug:~/ref/linux$ echo $? 0 $ aarch64-linux-gnu-ld.gold -v --fix-cortex-a53-999999 GNU gold (Linaro_Binutils-2017.11 2.28.2.20170706) 1.14 aarch64-linux-gnu-ld.gold: --fix-cortex-a53-999999: unknown option aarch64-linux-gnu-ld.gold: use the --help option for usage information $ echo $? 1 LLD too. $ ld.lld -v --gc-sections LLD 7.0.0 (http://llvm.org/git/lld.git 4a0e4190e74cea19f8a8dc625ccaebdf8b5d1585) (compatible with GNU linkers) $ echo $? 0 $ ld.lld -v --fix-cortex-a53-843419 LLD 7.0.0 (http://llvm.org/git/lld.git 4a0e4190e74cea19f8a8dc625ccaebdf8b5d1585) (compatible with GNU linkers) $ echo $? 0 $ ld.lld -v --fix-cortex-a53-999999 ld.lld: error: unknown argument: --fix-cortex-a53-999999 LLD 7.0.0 (http://llvm.org/git/lld.git 4a0e4190e74cea19f8a8dc625ccaebdf8b5d1585) (compatible with GNU linkers) $ echo $? 1 Signed-off-by: Masahiro Yamada Tested-by: Nick Desaulniers [nc: try-run-cached was added later, just use try-run, which is the current mainline state] Signed-off-by: Nathan Chancellor Signed-off-by: Greg Kroah-Hartman --- scripts/Kbuild.include | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index a0ad87e869f9..a33fa1a91873 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -165,9 +165,7 @@ cc-ldoption = $(call try-run,\ # ld-option # Usage: LDFLAGS += $(call ld-option, -X) -ld-option = $(call try-run,\ - $(CC) $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) -x c /dev/null -c -o "$$TMPO"; \ - $(LD) $(LDFLAGS) $(1) "$$TMPO" -o "$$TMP",$(1),$(2)) +ld-option = $(call try-run, $(LD) $(LDFLAGS) $(1) -v,$(1),$(2)) # ar-option # Usage: KBUILD_ARFLAGS := $(call ar-option,D) -- GitLab From 0bc43c8776d413d0b22f1d4719b226df36825b37 Mon Sep 17 00:00:00 2001 From: Frank Sorenson Date: Tue, 16 Apr 2019 08:37:27 -0500 Subject: [PATCH 0251/1121] cifs: do not attempt cifs operation on smb2+ rename error commit 652727bbe1b17993636346716ae5867627793647 upstream. A path-based rename returning EBUSY will incorrectly try opening the file with a cifs (NT Create AndX) operation on an smb2+ mount, which causes the server to force a session close. If the mount is smb2+, skip the fallback. Signed-off-by: Frank Sorenson Signed-off-by: Steve French CC: Stable Reviewed-by: Ronnie Sahlberg Signed-off-by: Greg Kroah-Hartman --- fs/cifs/inode.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 6fd4a6a75234..e7192ee7a89c 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -1730,6 +1730,10 @@ cifs_do_rename(const unsigned int xid, struct dentry *from_dentry, if (rc == 0 || rc != -EBUSY) goto do_rename_exit; + /* Don't fall back to using SMB on SMB 2+ mount */ + if (server->vals->protocol_id != 0) + goto do_rename_exit; + /* open-file renames don't work across directories */ if (to_dentry->d_parent != from_dentry->d_parent) goto do_rename_exit; -- GitLab From 5cc7ae880836c5943a773148e7a936728c750430 Mon Sep 17 00:00:00 2001 From: Wenwen Wang Date: Fri, 19 Apr 2019 21:22:59 -0500 Subject: [PATCH 0252/1121] tracing: Fix a memory leak by early error exit in trace_pid_write() commit 91862cc7867bba4ee5c8fcf0ca2f1d30427b6129 upstream. In trace_pid_write(), the buffer for trace parser is allocated through kmalloc() in trace_parser_get_init(). Later on, after the buffer is used, it is then freed through kfree() in trace_parser_put(). However, it is possible that trace_pid_write() is terminated due to unexpected errors, e.g., ENOMEM. In that case, the allocated buffer will not be freed, which is a memory leak bug. To fix this issue, free the allocated buffer when an error is encountered. Link: http://lkml.kernel.org/r/1555726979-15633-1-git-send-email-wang6495@umn.edu Fixes: f4d34a87e9c10 ("tracing: Use pid bitmap instead of a pid array for set_event_pid") Cc: stable@vger.kernel.org Signed-off-by: Wenwen Wang Signed-off-by: Steven Rostedt (VMware) Signed-off-by: Greg Kroah-Hartman --- kernel/trace/trace.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index ffddb5ac255c..1b9736aceecc 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -494,8 +494,10 @@ int trace_pid_write(struct trace_pid_list *filtered_pids, * not modified. */ pid_list = kmalloc(sizeof(*pid_list), GFP_KERNEL); - if (!pid_list) + if (!pid_list) { + trace_parser_put(&parser); return -ENOMEM; + } pid_list->pid_max = READ_ONCE(pid_max); @@ -505,6 +507,7 @@ int trace_pid_write(struct trace_pid_list *filtered_pids, pid_list->pids = vzalloc((pid_list->pid_max + 7) >> 3); if (!pid_list->pids) { + trace_parser_put(&parser); kfree(pid_list); return -ENOMEM; } -- GitLab From aec0d4aad4613ea834b65070aba62ced4ec4e540 Mon Sep 17 00:00:00 2001 From: Jann Horn Date: Thu, 4 Apr 2019 23:59:25 +0200 Subject: [PATCH 0253/1121] tracing: Fix buffer_ref pipe ops commit b987222654f84f7b4ca95b3a55eca784cb30235b upstream. This fixes multiple issues in buffer_pipe_buf_ops: - The ->steal() handler must not return zero unless the pipe buffer has the only reference to the page. But generic_pipe_buf_steal() assumes that every reference to the pipe is tracked by the page's refcount, which isn't true for these buffers - buffer_pipe_buf_get(), which duplicates a buffer, doesn't touch the page's refcount. Fix it by using generic_pipe_buf_nosteal(), which refuses every attempted theft. It should be easy to actually support ->steal, but the only current users of pipe_buf_steal() are the virtio console and FUSE, and they also only use it as an optimization. So it's probably not worth the effort. - The ->get() and ->release() handlers can be invoked concurrently on pipe buffers backed by the same struct buffer_ref. Make them safe against concurrency by using refcount_t. - The pointers stored in ->private were only zeroed out when the last reference to the buffer_ref was dropped. As far as I know, this shouldn't be necessary anyway, but if we do it, let's always do it. Link: http://lkml.kernel.org/r/20190404215925.253531-1-jannh@google.com Cc: Ingo Molnar Cc: Masami Hiramatsu Cc: Al Viro Cc: stable@vger.kernel.org Fixes: 73a757e63114d ("ring-buffer: Return reader page back into existing ring buffer") Signed-off-by: Jann Horn Signed-off-by: Steven Rostedt (VMware) Signed-off-by: Greg Kroah-Hartman --- fs/splice.c | 4 ++-- include/linux/pipe_fs_i.h | 1 + kernel/trace/trace.c | 28 ++++++++++++++-------------- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/fs/splice.c b/fs/splice.c index 00d2f142dcf9..a598d444abe1 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -332,8 +332,8 @@ const struct pipe_buf_operations default_pipe_buf_ops = { .get = generic_pipe_buf_get, }; -static int generic_pipe_buf_nosteal(struct pipe_inode_info *pipe, - struct pipe_buffer *buf) +int generic_pipe_buf_nosteal(struct pipe_inode_info *pipe, + struct pipe_buffer *buf) { return 1; } diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index befdcd304b3d..2dcf6e81b2e2 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h @@ -182,6 +182,7 @@ void free_pipe_info(struct pipe_inode_info *); void generic_pipe_buf_get(struct pipe_inode_info *, struct pipe_buffer *); int generic_pipe_buf_confirm(struct pipe_inode_info *, struct pipe_buffer *); int generic_pipe_buf_steal(struct pipe_inode_info *, struct pipe_buffer *); +int generic_pipe_buf_nosteal(struct pipe_inode_info *, struct pipe_buffer *); void generic_pipe_buf_release(struct pipe_inode_info *, struct pipe_buffer *); void pipe_buf_mark_unmergeable(struct pipe_buffer *buf); diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 1b9736aceecc..591be15404a1 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -6719,19 +6719,23 @@ struct buffer_ref { struct ring_buffer *buffer; void *page; int cpu; - int ref; + refcount_t refcount; }; +static void buffer_ref_release(struct buffer_ref *ref) +{ + if (!refcount_dec_and_test(&ref->refcount)) + return; + ring_buffer_free_read_page(ref->buffer, ref->cpu, ref->page); + kfree(ref); +} + static void buffer_pipe_buf_release(struct pipe_inode_info *pipe, struct pipe_buffer *buf) { struct buffer_ref *ref = (struct buffer_ref *)buf->private; - if (--ref->ref) - return; - - ring_buffer_free_read_page(ref->buffer, ref->cpu, ref->page); - kfree(ref); + buffer_ref_release(ref); buf->private = 0; } @@ -6740,7 +6744,7 @@ static void buffer_pipe_buf_get(struct pipe_inode_info *pipe, { struct buffer_ref *ref = (struct buffer_ref *)buf->private; - ref->ref++; + refcount_inc(&ref->refcount); } /* Pipe buffer operations for a buffer. */ @@ -6748,7 +6752,7 @@ static const struct pipe_buf_operations buffer_pipe_buf_ops = { .can_merge = 0, .confirm = generic_pipe_buf_confirm, .release = buffer_pipe_buf_release, - .steal = generic_pipe_buf_steal, + .steal = generic_pipe_buf_nosteal, .get = buffer_pipe_buf_get, }; @@ -6761,11 +6765,7 @@ static void buffer_spd_release(struct splice_pipe_desc *spd, unsigned int i) struct buffer_ref *ref = (struct buffer_ref *)spd->partial[i].private; - if (--ref->ref) - return; - - ring_buffer_free_read_page(ref->buffer, ref->cpu, ref->page); - kfree(ref); + buffer_ref_release(ref); spd->partial[i].private = 0; } @@ -6820,7 +6820,7 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, break; } - ref->ref = 1; + refcount_set(&ref->refcount, 1); ref->buffer = iter->trace_buffer->buffer; ref->page = ring_buffer_alloc_read_page(ref->buffer, iter->cpu_file); if (IS_ERR(ref->page)) { -- GitLab From 0f2739be115bb3edc70fc67f52b7767cb3490069 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Glisse?= Date: Thu, 25 Apr 2019 22:23:41 -0700 Subject: [PATCH 0254/1121] zram: pass down the bvec we need to read into in the work struct MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit e153abc0739ff77bd89c9ba1688cdb963464af97 upstream. When scheduling work item to read page we need to pass down the proper bvec struct which points to the page to read into. Before this patch it uses a randomly initialized bvec (only if PAGE_SIZE != 4096) which is wrong. Note that without this patch on arch/kernel where PAGE_SIZE != 4096 userspace could read random memory through a zram block device (thought userspace probably would have no control on the address being read). Link: http://lkml.kernel.org/r/20190408183219.26377-1-jglisse@redhat.com Signed-off-by: JĂ©rĂŽme Glisse Reviewed-by: Andrew Morton Reviewed-by: Sergey Senozhatsky Acked-by: Minchan Kim Cc: Nitin Gupta Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/block/zram/zram_drv.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index a46776a84480..133178c9b2cf 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -488,18 +488,18 @@ struct zram_work { struct zram *zram; unsigned long entry; struct bio *bio; + struct bio_vec bvec; }; #if PAGE_SIZE != 4096 static void zram_sync_read(struct work_struct *work) { - struct bio_vec bvec; struct zram_work *zw = container_of(work, struct zram_work, work); struct zram *zram = zw->zram; unsigned long entry = zw->entry; struct bio *bio = zw->bio; - read_from_bdev_async(zram, &bvec, entry, bio); + read_from_bdev_async(zram, &zw->bvec, entry, bio); } /* @@ -512,6 +512,7 @@ static int read_from_bdev_sync(struct zram *zram, struct bio_vec *bvec, { struct zram_work work; + work.bvec = *bvec; work.zram = zram; work.entry = entry; work.bio = bio; -- GitLab From 7a326879fcca3140c350c3a8ba5e0f659242639b Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Thu, 25 Apr 2019 22:23:44 -0700 Subject: [PATCH 0255/1121] lib/Kconfig.debug: fix build error without CONFIG_BLOCK commit ae3d6a323347940f0548bbb4b17f0bb2e9164169 upstream. If CONFIG_TEST_KMOD is set to M, while CONFIG_BLOCK is not set, XFS and BTRFS can not be compiled successly. Link: http://lkml.kernel.org/r/20190410075434.35220-1-yuehaibing@huawei.com Fixes: d9c6a72d6fa2 ("kmod: add test driver to stress test the module loader") Signed-off-by: YueHaibing Reported-by: Hulk Robot Reviewed-by: Kees Cook Cc: Masahiro Yamada Cc: Petr Mladek Cc: Andy Shevchenko Cc: Matthew Wilcox Cc: Joe Lawrence Cc: Robin Murphy Cc: Luis Chamberlain Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- lib/Kconfig.debug | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 62d0e25c054c..131d5871f8c9 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -1884,6 +1884,7 @@ config TEST_KMOD depends on m depends on BLOCK && (64BIT || LBDAF) # for XFS, BTRFS depends on NETDEVICES && NET_CORE && INET # for TUN + depends on BLOCK select TEST_LKM select XFS_FS select TUN -- GitLab From 85946150b26cc532356192f27ee893d6ec753c35 Mon Sep 17 00:00:00 2001 From: Aurelien Jarno Date: Tue, 9 Apr 2019 16:53:55 +0200 Subject: [PATCH 0256/1121] MIPS: scall64-o32: Fix indirect syscall number load MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 79b4a9cf0e2ea8203ce777c8d5cfa86c71eae86e upstream. Commit 4c21b8fd8f14 (MIPS: seccomp: Handle indirect system calls (o32)) added indirect syscall detection for O32 processes running on MIPS64, but it did not work correctly for big endian kernel/processes. The reason is that the syscall number is loaded from ARG1 using the lw instruction while this is a 64-bit value, so zero is loaded instead of the syscall number. Fix the code by using the ld instruction instead. When running a 32-bit processes on a 64 bit CPU, the values are properly sign-extended, so it ensures the value passed to syscall_trace_enter is correct. Recent systemd versions with seccomp enabled whitelist the getpid syscall for their internal processes (e.g. systemd-journald), but call it through syscall(SYS_getpid). This fix therefore allows O32 big endian systems with a 64-bit kernel to run recent systemd versions. Signed-off-by: Aurelien Jarno Cc: # v3.15+ Reviewed-by: Philippe Mathieu-DaudĂ© Signed-off-by: Paul Burton Cc: Ralf Baechle Cc: James Hogan Cc: linux-mips@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- arch/mips/kernel/scall64-o32.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 9ebe3e2403b1..c6b2e484d6c1 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -125,7 +125,7 @@ trace_a_syscall: subu t1, v0, __NR_O32_Linux move a1, v0 bnez t1, 1f /* __NR_syscall at offset 0 */ - lw a1, PT_R4(sp) /* Arg1 for __NR_syscall case */ + ld a1, PT_R4(sp) /* Arg1 for __NR_syscall case */ .set pop 1: jal syscall_trace_enter -- GitLab From 2c7bedd0ca381d05df5472a90154f9f28f2934df Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 23 Apr 2019 22:03:18 +0200 Subject: [PATCH 0257/1121] trace: Fix preempt_enable_no_resched() abuse commit d6097c9e4454adf1f8f2c9547c2fa6060d55d952 upstream. Unless the very next line is schedule(), or implies it, one must not use preempt_enable_no_resched(). It can cause a preemption to go missing and thereby cause arbitrary delays, breaking the PREEMPT=y invariant. Link: http://lkml.kernel.org/r/20190423200318.GY14281@hirez.programming.kicks-ass.net Cc: Waiman Long Cc: Linus Torvalds Cc: Ingo Molnar Cc: Will Deacon Cc: Thomas Gleixner Cc: the arch/x86 maintainers Cc: Davidlohr Bueso Cc: Tim Chen Cc: huang ying Cc: Roman Gushchin Cc: Alexei Starovoitov Cc: Daniel Borkmann Cc: stable@vger.kernel.org Fixes: 2c2d7329d8af ("tracing/ftrace: use preempt_enable_no_resched_notrace in ring_buffer_time_stamp()") Signed-off-by: Peter Zijlstra (Intel) Signed-off-by: Steven Rostedt (VMware) Signed-off-by: Greg Kroah-Hartman --- kernel/trace/ring_buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 5f7f4f07499f..8123a8b53c54 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -700,7 +700,7 @@ u64 ring_buffer_time_stamp(struct ring_buffer *buffer, int cpu) preempt_disable_notrace(); time = rb_time_stamp(buffer); - preempt_enable_no_resched_notrace(); + preempt_enable_notrace(); return time; } -- GitLab From daff434656562c3c8c9328945156ff241448d521 Mon Sep 17 00:00:00 2001 From: Josh Collier Date: Mon, 15 Apr 2019 11:34:22 -0700 Subject: [PATCH 0258/1121] IB/rdmavt: Fix frwr memory registration commit 7c39f7f671d2acc0a1f39ebbbee4303ad499bbfa upstream. Current implementation was not properly handling frwr memory registrations. This was uncovered by commit 27f26cec761das ("xprtrdma: Plant XID in on-the-wire RDMA offset (FRWR)") in which xprtrdma, which is used for NFS over RDMA, started failing as it was the first ULP to modify the ib_mr iova resulting in the NFS server getting REMOTE ACCESS ERROR when attempting to perform RDMA Writes to the client. The fix is to properly capture the true iova, offset, and length in the call to ib_map_mr_sg, and then update the iova when processing the IB_WR_REG_MEM on the send queue. Fixes: a41081aa5936 ("IB/rdmavt: Add support for ib_map_mr_sg") Cc: stable@vger.kernel.org Reviewed-by: Mike Marciniszyn Reviewed-by: Dennis Dalessandro Reviewed-by: Michael J. Ruhl Signed-off-by: Josh Collier Signed-off-by: Dennis Dalessandro Signed-off-by: Jason Gunthorpe Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/sw/rdmavt/mr.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/infiniband/sw/rdmavt/mr.c b/drivers/infiniband/sw/rdmavt/mr.c index 524e6134642e..e7013d2d4f0e 100644 --- a/drivers/infiniband/sw/rdmavt/mr.c +++ b/drivers/infiniband/sw/rdmavt/mr.c @@ -611,11 +611,6 @@ static int rvt_set_page(struct ib_mr *ibmr, u64 addr) if (unlikely(mapped_segs == mr->mr.max_segs)) return -ENOMEM; - if (mr->mr.length == 0) { - mr->mr.user_base = addr; - mr->mr.iova = addr; - } - m = mapped_segs / RVT_SEGSZ; n = mapped_segs % RVT_SEGSZ; mr->mr.map[m]->segs[n].vaddr = (void *)addr; @@ -633,17 +628,24 @@ static int rvt_set_page(struct ib_mr *ibmr, u64 addr) * @sg_nents: number of entries in sg * @sg_offset: offset in bytes into sg * + * Overwrite rvt_mr length with mr length calculated by ib_sg_to_pages. + * * Return: number of sg elements mapped to the memory region */ int rvt_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents, unsigned int *sg_offset) { struct rvt_mr *mr = to_imr(ibmr); + int ret; mr->mr.length = 0; mr->mr.page_shift = PAGE_SHIFT; - return ib_sg_to_pages(ibmr, sg, sg_nents, sg_offset, - rvt_set_page); + ret = ib_sg_to_pages(ibmr, sg, sg_nents, sg_offset, rvt_set_page); + mr->mr.user_base = ibmr->iova; + mr->mr.iova = ibmr->iova; + mr->mr.offset = ibmr->iova - (u64)mr->mr.map[0]->segs[0].vaddr; + mr->mr.length = (size_t)ibmr->length; + return ret; } /** @@ -674,6 +676,7 @@ int rvt_fast_reg_mr(struct rvt_qp *qp, struct ib_mr *ibmr, u32 key, ibmr->rkey = key; mr->mr.lkey = key; mr->mr.access_flags = access; + mr->mr.iova = ibmr->iova; atomic_set(&mr->mr.lkey_invalid, 0); return 0; -- GitLab From e4713de969c4b20a71fd3905af19e8b3904e7425 Mon Sep 17 00:00:00 2001 From: Xie XiuQi Date: Sat, 20 Apr 2019 16:34:16 +0800 Subject: [PATCH 0259/1121] sched/numa: Fix a possible divide-by-zero commit a860fa7b96e1a1c974556327aa1aee852d434c21 upstream. sched_clock_cpu() may not be consistent between CPUs. If a task migrates to another CPU, then se.exec_start is set to that CPU's rq_clock_task() by update_stats_curr_start(). Specifically, the new value might be before the old value due to clock skew. So then if in numa_get_avg_runtime() the expression: 'now - p->last_task_numa_placement' ends up as -1, then the divider '*period + 1' in task_numa_placement() is 0 and things go bang. Similar to update_curr(), check if time goes backwards to avoid this. [ peterz: Wrote new changelog. ] [ mingo: Tweaked the code comment. ] Signed-off-by: Xie XiuQi Signed-off-by: Peter Zijlstra (Intel) Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: cj.chengjian@huawei.com Cc: Link: http://lkml.kernel.org/r/20190425080016.GX11158@hirez.programming.kicks-ass.net Signed-off-by: Ingo Molnar Signed-off-by: Greg Kroah-Hartman --- kernel/sched/fair.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index a5d163903835..af7de1f9906c 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -2026,6 +2026,10 @@ static u64 numa_get_avg_runtime(struct task_struct *p, u64 *period) if (p->last_task_numa_placement) { delta = runtime - p->last_sum_exec_runtime; *period = now - p->last_task_numa_placement; + + /* Avoid time going backwards, prevent potential divide error: */ + if (unlikely((s64)*period < 0)) + *period = 0; } else { delta = p->se.avg.load_sum / p->se.load.weight; *period = LOAD_AVG_MAX; -- GitLab From cc97f988b736c678a921cba87a350e6833489f82 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 15 Apr 2019 12:00:42 -0400 Subject: [PATCH 0260/1121] ceph: only use d_name directly when parent is locked commit 1bcb344086f3ecf8d6705f6d708441baa823beb3 upstream. Ben reported tripping the BUG_ON in create_request_message during some performance testing. Analysis of the vmcore showed that the length of the r_dentry->d_name string changed after we allocated the buffer, but before we encoded it. build_dentry_path returns pointers to d_name in the common case of non-snapped dentries, but this optimization isn't safe unless the parent directory is locked. When it isn't, have the code make a copy of the d_name while holding the d_lock. Cc: stable@vger.kernel.org Reported-by: Ben England Signed-off-by: Jeff Layton Reviewed-by: "Yan, Zheng" Signed-off-by: Ilya Dryomov Signed-off-by: Greg Kroah-Hartman --- fs/ceph/mds_client.c | 61 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 11 deletions(-) diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index a48984dd6426..501805fc142e 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -1863,10 +1863,39 @@ char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *base, return path; } +/* Duplicate the dentry->d_name.name safely */ +static int clone_dentry_name(struct dentry *dentry, const char **ppath, + int *ppathlen) +{ + u32 len; + char *name; + +retry: + len = READ_ONCE(dentry->d_name.len); + name = kmalloc(len + 1, GFP_NOFS); + if (!name) + return -ENOMEM; + + spin_lock(&dentry->d_lock); + if (dentry->d_name.len != len) { + spin_unlock(&dentry->d_lock); + kfree(name); + goto retry; + } + memcpy(name, dentry->d_name.name, len); + spin_unlock(&dentry->d_lock); + + name[len] = '\0'; + *ppath = name; + *ppathlen = len; + return 0; +} + static int build_dentry_path(struct dentry *dentry, struct inode *dir, const char **ppath, int *ppathlen, u64 *pino, - int *pfreepath) + bool *pfreepath, bool parent_locked) { + int ret; char *path; rcu_read_lock(); @@ -1875,8 +1904,15 @@ static int build_dentry_path(struct dentry *dentry, struct inode *dir, if (dir && ceph_snap(dir) == CEPH_NOSNAP) { *pino = ceph_ino(dir); rcu_read_unlock(); - *ppath = dentry->d_name.name; - *ppathlen = dentry->d_name.len; + if (parent_locked) { + *ppath = dentry->d_name.name; + *ppathlen = dentry->d_name.len; + } else { + ret = clone_dentry_name(dentry, ppath, ppathlen); + if (ret) + return ret; + *pfreepath = true; + } return 0; } rcu_read_unlock(); @@ -1884,13 +1920,13 @@ static int build_dentry_path(struct dentry *dentry, struct inode *dir, if (IS_ERR(path)) return PTR_ERR(path); *ppath = path; - *pfreepath = 1; + *pfreepath = true; return 0; } static int build_inode_path(struct inode *inode, const char **ppath, int *ppathlen, u64 *pino, - int *pfreepath) + bool *pfreepath) { struct dentry *dentry; char *path; @@ -1906,7 +1942,7 @@ static int build_inode_path(struct inode *inode, if (IS_ERR(path)) return PTR_ERR(path); *ppath = path; - *pfreepath = 1; + *pfreepath = true; return 0; } @@ -1917,7 +1953,7 @@ static int build_inode_path(struct inode *inode, static int set_request_path_attr(struct inode *rinode, struct dentry *rdentry, struct inode *rdiri, const char *rpath, u64 rino, const char **ppath, int *pathlen, - u64 *ino, int *freepath) + u64 *ino, bool *freepath, bool parent_locked) { int r = 0; @@ -1927,7 +1963,7 @@ static int set_request_path_attr(struct inode *rinode, struct dentry *rdentry, ceph_snap(rinode)); } else if (rdentry) { r = build_dentry_path(rdentry, rdiri, ppath, pathlen, ino, - freepath); + freepath, parent_locked); dout(" dentry %p %llx/%.*s\n", rdentry, *ino, *pathlen, *ppath); } else if (rpath || rino) { @@ -1953,7 +1989,7 @@ static struct ceph_msg *create_request_message(struct ceph_mds_client *mdsc, const char *path2 = NULL; u64 ino1 = 0, ino2 = 0; int pathlen1 = 0, pathlen2 = 0; - int freepath1 = 0, freepath2 = 0; + bool freepath1 = false, freepath2 = false; int len; u16 releases; void *p, *end; @@ -1961,16 +1997,19 @@ static struct ceph_msg *create_request_message(struct ceph_mds_client *mdsc, ret = set_request_path_attr(req->r_inode, req->r_dentry, req->r_parent, req->r_path1, req->r_ino1.ino, - &path1, &pathlen1, &ino1, &freepath1); + &path1, &pathlen1, &ino1, &freepath1, + test_bit(CEPH_MDS_R_PARENT_LOCKED, + &req->r_req_flags)); if (ret < 0) { msg = ERR_PTR(ret); goto out; } + /* If r_old_dentry is set, then assume that its parent is locked */ ret = set_request_path_attr(NULL, req->r_old_dentry, req->r_old_dentry_dir, req->r_path2, req->r_ino2.ino, - &path2, &pathlen2, &ino2, &freepath2); + &path2, &pathlen2, &ino2, &freepath2, true); if (ret < 0) { msg = ERR_PTR(ret); goto out_free1; -- GitLab From 08152ac980c608f5add894b0f34d111f1fe50be4 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Wed, 17 Apr 2019 12:58:28 -0400 Subject: [PATCH 0261/1121] ceph: ensure d_name stability in ceph_dentry_hash() commit 76a495d666e5043ffc315695f8241f5e94a98849 upstream. Take the d_lock here to ensure that d_name doesn't change. Cc: stable@vger.kernel.org Signed-off-by: Jeff Layton Reviewed-by: "Yan, Zheng" Signed-off-by: Ilya Dryomov Signed-off-by: Greg Kroah-Hartman --- fs/ceph/dir.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 8a5266699b67..56e8fc896f6b 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c @@ -1454,6 +1454,7 @@ void ceph_dentry_lru_del(struct dentry *dn) unsigned ceph_dentry_hash(struct inode *dir, struct dentry *dn) { struct ceph_inode_info *dci = ceph_inode(dir); + unsigned hash; switch (dci->i_dir_layout.dl_dir_hash) { case 0: /* for backward compat */ @@ -1461,8 +1462,11 @@ unsigned ceph_dentry_hash(struct inode *dir, struct dentry *dn) return dn->d_name.hash; default: - return ceph_str_hash(dci->i_dir_layout.dl_dir_hash, + spin_lock(&dn->d_lock); + hash = ceph_str_hash(dci->i_dir_layout.dl_dir_hash, dn->d_name.name, dn->d_name.len); + spin_unlock(&dn->d_lock); + return hash; } } -- GitLab From be539bbf3c8619bccc6b74825710f1ff7a8bb068 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Thu, 18 Apr 2019 11:24:57 +0800 Subject: [PATCH 0262/1121] ceph: fix ci->i_head_snapc leak commit 37659182bff1eeaaeadcfc8f853c6d2b6dbc3f47 upstream. We missed two places that i_wrbuffer_ref_head, i_wr_ref, i_dirty_caps and i_flushing_caps may change. When they are all zeros, we should free i_head_snapc. Cc: stable@vger.kernel.org Link: https://tracker.ceph.com/issues/38224 Reported-and-tested-by: Luis Henriques Signed-off-by: "Yan, Zheng" Signed-off-by: Ilya Dryomov Signed-off-by: Greg Kroah-Hartman --- fs/ceph/mds_client.c | 9 +++++++++ fs/ceph/snap.c | 7 ++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 501805fc142e..e1ded4bd6115 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -1219,6 +1219,15 @@ static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap, list_add(&ci->i_prealloc_cap_flush->i_list, &to_remove); ci->i_prealloc_cap_flush = NULL; } + + if (drop && + ci->i_wrbuffer_ref_head == 0 && + ci->i_wr_ref == 0 && + ci->i_dirty_caps == 0 && + ci->i_flushing_caps == 0) { + ceph_put_snap_context(ci->i_head_snapc); + ci->i_head_snapc = NULL; + } } spin_unlock(&ci->i_ceph_lock); while (!list_empty(&to_remove)) { diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c index 9b6207c84b68..a7e763dac038 100644 --- a/fs/ceph/snap.c +++ b/fs/ceph/snap.c @@ -568,7 +568,12 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci) old_snapc = NULL; update_snapc: - if (ci->i_head_snapc) { + if (ci->i_wrbuffer_ref_head == 0 && + ci->i_wr_ref == 0 && + ci->i_dirty_caps == 0 && + ci->i_flushing_caps == 0) { + ci->i_head_snapc = NULL; + } else { ci->i_head_snapc = ceph_get_snap_context(new_snapc); dout(" new snapc is %p\n", new_snapc); } -- GitLab From f08c65298341a0a62e57f66ddee6849f0d0654a9 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 5 Apr 2019 08:54:37 -0700 Subject: [PATCH 0263/1121] nfsd: Don't release the callback slot unless it was actually held commit e6abc8caa6deb14be2a206253f7e1c5e37e9515b upstream. If there are multiple callbacks queued, waiting for the callback slot when the callback gets shut down, then they all currently end up acting as if they hold the slot, and call nfsd4_cb_sequence_done() resulting in interesting side-effects. In addition, the 'retry_nowait' path in nfsd4_cb_sequence_done() causes a loop back to nfsd4_cb_prepare() without first freeing the slot, which causes a deadlock when nfsd41_cb_get_slot() gets called a second time. This patch therefore adds a boolean to track whether or not the callback did pick up the slot, so that it can do the right thing in these 2 cases. Cc: stable@vger.kernel.org Signed-off-by: Trond Myklebust Signed-off-by: J. Bruce Fields Signed-off-by: Greg Kroah-Hartman --- fs/nfsd/nfs4callback.c | 8 +++++++- fs/nfsd/state.h | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index 49b0a9e7ff18..80aeb19b176b 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c @@ -939,8 +939,9 @@ static void nfsd4_cb_prepare(struct rpc_task *task, void *calldata) cb->cb_seq_status = 1; cb->cb_status = 0; if (minorversion) { - if (!nfsd41_cb_get_slot(clp, task)) + if (!cb->cb_holds_slot && !nfsd41_cb_get_slot(clp, task)) return; + cb->cb_holds_slot = true; } rpc_call_start(task); } @@ -967,6 +968,9 @@ static bool nfsd4_cb_sequence_done(struct rpc_task *task, struct nfsd4_callback return true; } + if (!cb->cb_holds_slot) + goto need_restart; + switch (cb->cb_seq_status) { case 0: /* @@ -1004,6 +1008,7 @@ static bool nfsd4_cb_sequence_done(struct rpc_task *task, struct nfsd4_callback cb->cb_seq_status); } + cb->cb_holds_slot = false; clear_bit(0, &clp->cl_cb_slot_busy); rpc_wake_up_next(&clp->cl_cb_waitq); dprintk("%s: freed slot, new seqid=%d\n", __func__, @@ -1211,6 +1216,7 @@ void nfsd4_init_cb(struct nfsd4_callback *cb, struct nfs4_client *clp, cb->cb_seq_status = 1; cb->cb_status = 0; cb->cb_need_restart = false; + cb->cb_holds_slot = false; } void nfsd4_run_cb(struct nfsd4_callback *cb) diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 86aa92d200e1..133d8bf62a5c 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -69,6 +69,7 @@ struct nfsd4_callback { int cb_seq_status; int cb_status; bool cb_need_restart; + bool cb_holds_slot; }; struct nfsd4_callback_ops { -- GitLab From 790899da35fa894c8d916c612aadb9f4e8631ed5 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 5 Apr 2019 11:34:40 +1100 Subject: [PATCH 0264/1121] sunrpc: don't mark uninitialised items as VALID. commit d58431eacb226222430940134d97bfd72f292fcd upstream. A recent commit added a call to cache_fresh_locked() when an expired item was found. The call sets the CACHE_VALID flag, so it is important that the item actually is valid. There are two ways it could be valid: 1/ If ->update has been called to fill in relevant content 2/ if CACHE_NEGATIVE is set, to say that content doesn't exist. An expired item that is waiting for an update will be neither. Setting CACHE_VALID will mean that a subsequent call to cache_put() will be likely to dereference uninitialised pointers. So we must make sure the item is valid, and we already have code to do that in try_to_negate_entry(). This takes the hash lock and so cannot be used directly, so take out the two lines that we need and use them. Now cache_fresh_locked() is certain to be called only on a valid item. Cc: stable@kernel.org # 2.6.35 Fixes: 4ecd55ea0742 ("sunrpc: fix cache_head leak due to queued request") Signed-off-by: NeilBrown Signed-off-by: J. Bruce Fields Signed-off-by: Greg Kroah-Hartman --- net/sunrpc/cache.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index f2cf4edf219b..475b453dc7ae 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c @@ -54,6 +54,7 @@ static void cache_init(struct cache_head *h, struct cache_detail *detail) h->last_refresh = now; } +static inline int cache_is_valid(struct cache_head *h); static void cache_fresh_locked(struct cache_head *head, time_t expiry, struct cache_detail *detail); static void cache_fresh_unlocked(struct cache_head *head, @@ -100,6 +101,8 @@ struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail, if (cache_is_expired(detail, tmp)) { hlist_del_init(&tmp->cache_list); detail->entries --; + if (cache_is_valid(tmp) == -EAGAIN) + set_bit(CACHE_NEGATIVE, &tmp->flags); cache_fresh_locked(tmp, 0, detail); freeme = tmp; break; -- GitLab From 14ce45a0103d0bd086857539ec96a2a0bcda4d48 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Fri, 26 Apr 2019 17:22:01 -0700 Subject: [PATCH 0265/1121] Input: synaptics-rmi4 - write config register values to the right offset commit 3a349763cf11e63534b8f2d302f2d0c790566497 upstream. Currently any changed config register values don't take effect, as the function to write them back is called with the wrong register offset. Fixes: ff8f83708b3e (Input: synaptics-rmi4 - add support for 2D sensors and F11) Signed-off-by: Lucas Stach Reviewed-by: Philipp Zabel Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/rmi4/rmi_f11.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c index bc5e37f30ac1..bb63b8823d62 100644 --- a/drivers/input/rmi4/rmi_f11.c +++ b/drivers/input/rmi4/rmi_f11.c @@ -1239,7 +1239,7 @@ static int rmi_f11_initialize(struct rmi_function *fn) } rc = f11_write_control_regs(fn, &f11->sens_query, - &f11->dev_controls, fn->fd.query_base_addr); + &f11->dev_controls, fn->fd.control_base_addr); if (rc) dev_warn(&fn->dev, "Failed to write control registers\n"); -- GitLab From 73a95f1a41c0bb586b8c62622ebf25aca1582af3 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Wed, 3 Apr 2019 12:36:21 -0600 Subject: [PATCH 0266/1121] vfio/type1: Limit DMA mappings per container commit 492855939bdb59c6f947b0b5b44af9ad82b7e38c upstream. Memory backed DMA mappings are accounted against a user's locked memory limit, including multiple mappings of the same memory. This accounting bounds the number of such mappings that a user can create. However, DMA mappings that are not backed by memory, such as DMA mappings of device MMIO via mmaps, do not make use of page pinning and therefore do not count against the user's locked memory limit. These mappings still consume memory, but the memory is not well associated to the process for the purpose of oom killing a task. To add bounding on this use case, we introduce a limit to the total number of concurrent DMA mappings that a user is allowed to create. This limit is exposed as a tunable module option where the default value of 64K is expected to be well in excess of any reasonable use case (a large virtual machine configuration would typically only make use of tens of concurrent mappings). This fixes CVE-2019-3882. Reviewed-by: Eric Auger Tested-by: Eric Auger Reviewed-by: Peter Xu Reviewed-by: Cornelia Huck Signed-off-by: Alex Williamson Signed-off-by: Greg Kroah-Hartman --- drivers/vfio/vfio_iommu_type1.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c index 50eeb74ddc0a..f77a9b3370b5 100644 --- a/drivers/vfio/vfio_iommu_type1.c +++ b/drivers/vfio/vfio_iommu_type1.c @@ -58,12 +58,18 @@ module_param_named(disable_hugepages, MODULE_PARM_DESC(disable_hugepages, "Disable VFIO IOMMU support for IOMMU hugepages."); +static unsigned int dma_entry_limit __read_mostly = U16_MAX; +module_param_named(dma_entry_limit, dma_entry_limit, uint, 0644); +MODULE_PARM_DESC(dma_entry_limit, + "Maximum number of user DMA mappings per container (65535)."); + struct vfio_iommu { struct list_head domain_list; struct vfio_domain *external_domain; /* domain for external user */ struct mutex lock; struct rb_root dma_list; struct blocking_notifier_head notifier; + unsigned int dma_avail; bool v2; bool nesting; }; @@ -732,6 +738,7 @@ static void vfio_remove_dma(struct vfio_iommu *iommu, struct vfio_dma *dma) vfio_unlink_dma(iommu, dma); put_task_struct(dma->task); kfree(dma); + iommu->dma_avail++; } static unsigned long vfio_pgsize_bitmap(struct vfio_iommu *iommu) @@ -1003,12 +1010,18 @@ static int vfio_dma_do_map(struct vfio_iommu *iommu, goto out_unlock; } + if (!iommu->dma_avail) { + ret = -ENOSPC; + goto out_unlock; + } + dma = kzalloc(sizeof(*dma), GFP_KERNEL); if (!dma) { ret = -ENOMEM; goto out_unlock; } + iommu->dma_avail--; dma->iova = iova; dma->vaddr = vaddr; dma->prot = prot; @@ -1504,6 +1517,7 @@ static void *vfio_iommu_type1_open(unsigned long arg) INIT_LIST_HEAD(&iommu->domain_list); iommu->dma_list = RB_ROOT; + iommu->dma_avail = dma_entry_limit; mutex_init(&iommu->lock); BLOCKING_INIT_NOTIFIER_HEAD(&iommu->notifier); -- GitLab From 5db50e4f36f331d60830a771252aeae5beff01e9 Mon Sep 17 00:00:00 2001 From: Dirk Behme Date: Fri, 12 Apr 2019 07:29:13 +0200 Subject: [PATCH 0267/1121] dmaengine: sh: rcar-dmac: With cyclic DMA residue 0 is valid commit 907bd68a2edc491849e2fdcfe52c4596627bca94 upstream. Having a cyclic DMA, a residue 0 is not an indication of a completed DMA. In case of cyclic DMA make sure that dma_set_residue() is called and with this a residue of 0 is forwarded correctly to the caller. Fixes: 3544d2878817 ("dmaengine: rcar-dmac: use result of updated get_residue in tx_status") Signed-off-by: Dirk Behme Signed-off-by: Achim Dahlhoff Signed-off-by: Hiroyuki Yokoyama Signed-off-by: Yao Lihua Reviewed-by: Yoshihiro Shimoda Reviewed-by: Laurent Pinchart Cc: # v4.8+ Signed-off-by: Vinod Koul Signed-off-by: Greg Kroah-Hartman --- drivers/dma/sh/rcar-dmac.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c index 9d6ce5051d8f..77b126525dac 100644 --- a/drivers/dma/sh/rcar-dmac.c +++ b/drivers/dma/sh/rcar-dmac.c @@ -1332,6 +1332,7 @@ static enum dma_status rcar_dmac_tx_status(struct dma_chan *chan, enum dma_status status; unsigned long flags; unsigned int residue; + bool cyclic; status = dma_cookie_status(chan, cookie, txstate); if (status == DMA_COMPLETE || !txstate) @@ -1339,10 +1340,11 @@ static enum dma_status rcar_dmac_tx_status(struct dma_chan *chan, spin_lock_irqsave(&rchan->lock, flags); residue = rcar_dmac_chan_get_residue(rchan, cookie); + cyclic = rchan->desc.running ? rchan->desc.running->cyclic : false; spin_unlock_irqrestore(&rchan->lock, flags); /* if there's no residue, the cookie is complete */ - if (!residue) + if (!residue && !cyclic) return DMA_COMPLETE; dma_set_residue(txstate, residue); -- GitLab From c433c36e7ed5b0ed33d725138ec130ab2a23c8c6 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Fri, 12 Apr 2019 22:34:18 +0100 Subject: [PATCH 0268/1121] ARM: 8857/1: efi: enable CP15 DMB instructions before cleaning the cache commit e17b1af96b2afc38e684aa2f1033387e2ed10029 upstream. The EFI stub is entered with the caches and MMU enabled by the firmware, and once the stub is ready to hand over to the decompressor, we clean and disable the caches. The cache clean routines use CP15 barrier instructions, which can be disabled via SCTLR. Normally, when using the provided cache handling routines to enable the caches and MMU, this bit is enabled as well. However, but since we entered the stub with the caches already enabled, this routine is not executed before we call the cache clean routines, resulting in undefined instruction exceptions if the firmware never enabled this bit. So set the bit explicitly in the EFI entry code, but do so in a way that guarantees that the resulting code can still run on v6 cores as well (which are guaranteed to have CP15 barriers enabled) Cc: # v4.9+ Acked-by: Marc Zyngier Signed-off-by: Ard Biesheuvel Signed-off-by: Russell King Signed-off-by: Greg Kroah-Hartman --- arch/arm/boot/compressed/head.S | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 5f687ba1eaa7..8ca539bdac35 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -1393,7 +1393,21 @@ ENTRY(efi_stub_entry) @ Preserve return value of efi_entry() in r4 mov r4, r0 - bl cache_clean_flush + + @ our cache maintenance code relies on CP15 barrier instructions + @ but since we arrived here with the MMU and caches configured + @ by UEFI, we must check that the CP15BEN bit is set in SCTLR. + @ Note that this bit is RAO/WI on v6 and earlier, so the ISB in + @ the enable path will be executed on v7+ only. + mrc p15, 0, r1, c1, c0, 0 @ read SCTLR + tst r1, #(1 << 5) @ CP15BEN bit set? + bne 0f + orr r1, r1, #(1 << 5) @ CP15 barrier instructions + mcr p15, 0, r1, c1, c0, 0 @ write SCTLR + ARM( .inst 0xf57ff06f @ v7+ isb ) + THUMB( isb ) + +0: bl cache_clean_flush bl cache_off @ Set parameters for booting zImage according to boot protocol -- GitLab From 8bf63442f9ca4694f4ab28e62e3b9bc84cfffa7d Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Fri, 1 Mar 2019 13:56:11 +0100 Subject: [PATCH 0269/1121] drm/vc4: Fix memory leak during gpu reset. commit d08106796a78a4273e39e1bbdf538dc4334b2635 upstream. __drm_atomic_helper_crtc_destroy_state does not free memory, it only cleans it up. Fix this by calling the functions own destroy function. Fixes: 6d6e50039187 ("drm/vc4: Allocate the right amount of space for boot-time CRTC state.") Cc: Eric Anholt Cc: # v4.6+ Reviewed-by: Eric Anholt Signed-off-by: Maarten Lankhorst Link: https://patchwork.freedesktop.org/patch/msgid/20190301125627.7285-2-maarten.lankhorst@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/vc4/vc4_crtc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index ce1e3b9e14c9..14d0d113849a 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -867,7 +867,7 @@ static void vc4_crtc_reset(struct drm_crtc *crtc) { if (crtc->state) - __drm_atomic_helper_crtc_destroy_state(crtc->state); + vc4_crtc_destroy_state(crtc->state); crtc->state = kzalloc(sizeof(struct vc4_crtc_state), GFP_KERNEL); if (crtc->state) -- GitLab From 261eff5dd5b67d9424f2ac5f1f95e89fbdc50b3b Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 24 Apr 2019 10:47:56 +1000 Subject: [PATCH 0270/1121] Revert "drm/i915/fbdev: Actually configure untiled displays" commit 9fa246256e09dc30820524401cdbeeaadee94025 upstream. This reverts commit d179b88deb3bf6fed4991a31fd6f0f2cad21fab5. This commit is documented to break userspace X.org modesetting driver in certain configurations. The X.org modesetting userspace driver is broken. No fixes are available yet. In order for this patch to be applied it either needs a config option or a workaround developed. This has been reported a few times, saying it's a userspace problem is clearly against the regression rules. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=109806 Signed-off-by: Dave Airlie Cc: # v3.19+ Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/i915/intel_fbdev.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index 14eb8a064562..da2d309574ba 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -326,8 +326,8 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper, bool *enabled, int width, int height) { struct drm_i915_private *dev_priv = to_i915(fb_helper->dev); + unsigned long conn_configured, conn_seq, mask; unsigned int count = min(fb_helper->connector_count, BITS_PER_LONG); - unsigned long conn_configured, conn_seq; int i, j; bool *save_enabled; bool fallback = true, ret = true; @@ -345,9 +345,10 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper, drm_modeset_backoff(&ctx); memcpy(save_enabled, enabled, count); - conn_seq = GENMASK(count - 1, 0); + mask = GENMASK(count - 1, 0); conn_configured = 0; retry: + conn_seq = conn_configured; for (i = 0; i < count; i++) { struct drm_fb_helper_connector *fb_conn; struct drm_connector *connector; @@ -360,8 +361,7 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper, if (conn_configured & BIT(i)) continue; - /* First pass, only consider tiled connectors */ - if (conn_seq == GENMASK(count - 1, 0) && !connector->has_tile) + if (conn_seq == 0 && !connector->has_tile) continue; if (connector->status == connector_status_connected) @@ -465,10 +465,8 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper, conn_configured |= BIT(i); } - if (conn_configured != conn_seq) { /* repeat until no more are found */ - conn_seq = conn_configured; + if ((conn_configured & mask) != mask && conn_configured != conn_seq) goto retry; - } /* * If the BIOS didn't enable everything it could, fall back to have the -- GitLab From c13229b3003e142971a0551fbac74fd6b1c62951 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Wed, 24 Apr 2019 17:06:29 +0200 Subject: [PATCH 0271/1121] drm/vc4: Fix compilation error reported by kbuild test bot commit 462ce5d963f18b71c63f6b7730a35a2ee5273540 upstream. A pointer to crtc was missing, resulting in the following build error: drivers/gpu/drm/vc4/vc4_crtc.c:1045:44: sparse: sparse: incorrect type in argument 1 (different base types) drivers/gpu/drm/vc4/vc4_crtc.c:1045:44: sparse: expected struct drm_crtc *crtc drivers/gpu/drm/vc4/vc4_crtc.c:1045:44: sparse: got struct drm_crtc_state *state drivers/gpu/drm/vc4/vc4_crtc.c:1045:39: sparse: sparse: not enough arguments for function vc4_crtc_destroy_state Signed-off-by: Maarten Lankhorst Reported-by: kbuild test robot Cc: Eric Anholt Link: https://patchwork.freedesktop.org/patch/msgid/2b6ed5e6-81b0-4276-8860-870b54ca3262@linux.intel.com Fixes: d08106796a78 ("drm/vc4: Fix memory leak during gpu reset.") Cc: # v4.6+ Acked-by: Daniel Vetter Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/vc4/vc4_crtc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 14d0d113849a..7747f160c740 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -867,7 +867,7 @@ static void vc4_crtc_reset(struct drm_crtc *crtc) { if (crtc->state) - vc4_crtc_destroy_state(crtc->state); + vc4_crtc_destroy_state(crtc, crtc->state); crtc->state = kzalloc(sizeof(struct vc4_crtc_state), GFP_KERNEL); if (crtc->state) -- GitLab From 277519b646caa25d1afa986bc62091576ceaecdf Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Sat, 12 Jan 2019 03:54:24 +0800 Subject: [PATCH 0272/1121] USB: Add new USB LPM helpers commit 7529b2574a7aaf902f1f8159fbc2a7caa74be559 upstream. Use new helpers to make LPM enabling/disabling more clear. This is a preparation to subsequent patch. Signed-off-by: Kai-Heng Feng Cc: stable # after much soaking Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/driver.c | 12 +++++++++++- drivers/usb/core/hub.c | 12 ++++++------ drivers/usb/core/message.c | 2 +- drivers/usb/core/sysfs.c | 5 ++++- drivers/usb/core/usb.h | 10 ++++++++-- 5 files changed, 30 insertions(+), 11 deletions(-) diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 2f3dbf1c3c2d..7dc99c9b3ad8 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -1891,7 +1891,7 @@ int usb_runtime_idle(struct device *dev) return -EBUSY; } -int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable) +static int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable) { struct usb_hcd *hcd = bus_to_hcd(udev->bus); int ret = -EPERM; @@ -1908,6 +1908,16 @@ int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable) return ret; } +int usb_enable_usb2_hardware_lpm(struct usb_device *udev) +{ + return usb_set_usb2_hardware_lpm(udev, 1); +} + +int usb_disable_usb2_hardware_lpm(struct usb_device *udev) +{ + return usb_set_usb2_hardware_lpm(udev, 0); +} + #endif /* CONFIG_PM */ struct bus_type usb_bus_type = { diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 4a4e666a8e09..9f3a7ca4d72c 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -3175,7 +3175,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) /* disable USB2 hardware LPM */ if (udev->usb2_hw_lpm_enabled == 1) - usb_set_usb2_hardware_lpm(udev, 0); + usb_disable_usb2_hardware_lpm(udev); if (usb_disable_ltm(udev)) { dev_err(&udev->dev, "Failed to disable LTM before suspend\n."); @@ -3214,7 +3214,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) err_ltm: /* Try to enable USB2 hardware LPM again */ if (udev->usb2_hw_lpm_capable == 1) - usb_set_usb2_hardware_lpm(udev, 1); + usb_enable_usb2_hardware_lpm(udev); if (udev->do_remote_wakeup) (void) usb_disable_remote_wakeup(udev); @@ -3498,7 +3498,7 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg) } else { /* Try to enable USB2 hardware LPM */ if (udev->usb2_hw_lpm_capable == 1) - usb_set_usb2_hardware_lpm(udev, 1); + usb_enable_usb2_hardware_lpm(udev); /* Try to enable USB3 LTM */ usb_enable_ltm(udev); @@ -4334,7 +4334,7 @@ static void hub_set_initial_usb2_lpm_policy(struct usb_device *udev) if ((udev->bos->ext_cap->bmAttributes & cpu_to_le32(USB_BESL_SUPPORT)) || connect_type == USB_PORT_CONNECT_TYPE_HARD_WIRED) { udev->usb2_hw_lpm_allowed = 1; - usb_set_usb2_hardware_lpm(udev, 1); + usb_enable_usb2_hardware_lpm(udev); } } @@ -5492,7 +5492,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev) * It will be re-enabled by the enumeration process. */ if (udev->usb2_hw_lpm_enabled == 1) - usb_set_usb2_hardware_lpm(udev, 0); + usb_disable_usb2_hardware_lpm(udev); /* Disable LPM and LTM while we reset the device and reinstall the alt * settings. Device-initiated LPM settings, and system exit latency @@ -5602,7 +5602,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev) done: /* Now that the alt settings are re-installed, enable LTM and LPM. */ - usb_set_usb2_hardware_lpm(udev, 1); + usb_enable_usb2_hardware_lpm(udev); usb_unlocked_enable_lpm(udev); usb_enable_ltm(udev); usb_release_bos_descriptor(udev); diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 833ddd228e3a..f245c654175e 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1183,7 +1183,7 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) } if (dev->usb2_hw_lpm_enabled == 1) - usb_set_usb2_hardware_lpm(dev, 0); + usb_disable_usb2_hardware_lpm(dev); usb_unlocked_disable_lpm(dev); usb_disable_ltm(dev); diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index d930bfda4010..15c19863f7b3 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -508,7 +508,10 @@ static ssize_t usb2_hardware_lpm_store(struct device *dev, if (!ret) { udev->usb2_hw_lpm_allowed = value; - ret = usb_set_usb2_hardware_lpm(udev, value); + if (value) + ret = usb_enable_usb2_hardware_lpm(udev); + else + ret = usb_disable_usb2_hardware_lpm(udev); } usb_unlock_device(udev); diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index dc6949248823..1b5f346d93eb 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -89,7 +89,8 @@ extern int usb_remote_wakeup(struct usb_device *dev); extern int usb_runtime_suspend(struct device *dev); extern int usb_runtime_resume(struct device *dev); extern int usb_runtime_idle(struct device *dev); -extern int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable); +extern int usb_enable_usb2_hardware_lpm(struct usb_device *udev); +extern int usb_disable_usb2_hardware_lpm(struct usb_device *udev); #else @@ -109,7 +110,12 @@ static inline int usb_autoresume_device(struct usb_device *udev) return 0; } -static inline int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable) +static inline int usb_enable_usb2_hardware_lpm(struct usb_device *udev) +{ + return 0; +} + +static inline int usb_disable_usb2_hardware_lpm(struct usb_device *udev) { return 0; } -- GitLab From 0feaa3aeea0914a33a2da33d5e9480d4a17b27e2 Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Sat, 12 Jan 2019 03:54:25 +0800 Subject: [PATCH 0273/1121] USB: Consolidate LPM checks to avoid enabling LPM twice MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit d7a6c0ce8d26412903c7981503bad9e1cc7c45d2 upstream. USB Bluetooth controller QCA ROME (0cf3:e007) sometimes stops working after S3: [ 165.110742] Bluetooth: hci0: using NVM file: qca/nvm_usb_00000302.bin [ 168.432065] Bluetooth: hci0: Failed to send body at 4 of 1953 (-110) After some experiments, I found that disabling LPM can workaround the issue. On some platforms, the USB power is cut during S3, so the driver uses reset-resume to resume the device. During port resume, LPM gets enabled twice, by usb_reset_and_verify_device() and usb_port_resume(). Consolidate all checks into new LPM helpers to make sure LPM only gets enabled once. Fixes: de68bab4fa96 ("usb: Don't enable USB 2.0 Link PM by default.”) Signed-off-by: Kai-Heng Feng Cc: stable # after much soaking Signed-off-by: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/driver.c | 11 ++++++++--- drivers/usb/core/hub.c | 12 ++++-------- drivers/usb/core/message.c | 3 +-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 7dc99c9b3ad8..79d2c0bf7870 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -1896,9 +1896,6 @@ static int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable) struct usb_hcd *hcd = bus_to_hcd(udev->bus); int ret = -EPERM; - if (enable && !udev->usb2_hw_lpm_allowed) - return 0; - if (hcd->driver->set_usb2_hw_lpm) { ret = hcd->driver->set_usb2_hw_lpm(hcd, udev, enable); if (!ret) @@ -1910,11 +1907,19 @@ static int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable) int usb_enable_usb2_hardware_lpm(struct usb_device *udev) { + if (!udev->usb2_hw_lpm_capable || + !udev->usb2_hw_lpm_allowed || + udev->usb2_hw_lpm_enabled) + return 0; + return usb_set_usb2_hardware_lpm(udev, 1); } int usb_disable_usb2_hardware_lpm(struct usb_device *udev) { + if (!udev->usb2_hw_lpm_enabled) + return 0; + return usb_set_usb2_hardware_lpm(udev, 0); } diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 9f3a7ca4d72c..a9541525ea4f 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -3174,8 +3174,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) } /* disable USB2 hardware LPM */ - if (udev->usb2_hw_lpm_enabled == 1) - usb_disable_usb2_hardware_lpm(udev); + usb_disable_usb2_hardware_lpm(udev); if (usb_disable_ltm(udev)) { dev_err(&udev->dev, "Failed to disable LTM before suspend\n."); @@ -3213,8 +3212,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) usb_enable_ltm(udev); err_ltm: /* Try to enable USB2 hardware LPM again */ - if (udev->usb2_hw_lpm_capable == 1) - usb_enable_usb2_hardware_lpm(udev); + usb_enable_usb2_hardware_lpm(udev); if (udev->do_remote_wakeup) (void) usb_disable_remote_wakeup(udev); @@ -3497,8 +3495,7 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg) hub_port_logical_disconnect(hub, port1); } else { /* Try to enable USB2 hardware LPM */ - if (udev->usb2_hw_lpm_capable == 1) - usb_enable_usb2_hardware_lpm(udev); + usb_enable_usb2_hardware_lpm(udev); /* Try to enable USB3 LTM */ usb_enable_ltm(udev); @@ -5491,8 +5488,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev) /* Disable USB2 hardware LPM. * It will be re-enabled by the enumeration process. */ - if (udev->usb2_hw_lpm_enabled == 1) - usb_disable_usb2_hardware_lpm(udev); + usb_disable_usb2_hardware_lpm(udev); /* Disable LPM and LTM while we reset the device and reinstall the alt * settings. Device-initiated LPM settings, and system exit latency diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index f245c654175e..1fe3c5d3be5f 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1182,8 +1182,7 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) dev->actconfig->interface[i] = NULL; } - if (dev->usb2_hw_lpm_enabled == 1) - usb_disable_usb2_hardware_lpm(dev); + usb_disable_usb2_hardware_lpm(dev); usb_unlocked_disable_lpm(dev); usb_disable_ltm(dev); -- GitLab From d9d262229d646ca28d3aaca2b46906d92f9b6c6f Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 21 Feb 2019 11:17:34 -0500 Subject: [PATCH 0274/1121] ext4: fix some error pointer dereferences commit 7159a986b4202343f6cca3bb8079ecace5816fd6 upstream. We can't pass error pointers to brelse(). Fixes: fb265c9cb49e ("ext4: add ext4_sb_bread() to disambiguate ENOMEM cases") Signed-off-by: Dan Carpenter Signed-off-by: Theodore Ts'o Reviewed-by: Jan Kara Signed-off-by: Greg Kroah-Hartman --- fs/ext4/xattr.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 311761a6ef6d..6761e905cab0 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -828,6 +828,7 @@ int ext4_get_inode_usage(struct inode *inode, qsize_t *usage) bh = ext4_sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl, REQ_PRIO); if (IS_ERR(bh)) { ret = PTR_ERR(bh); + bh = NULL; goto out; } @@ -2905,6 +2906,7 @@ int ext4_xattr_delete_inode(handle_t *handle, struct inode *inode, if (error == -EIO) EXT4_ERROR_INODE(inode, "block %llu read error", EXT4_I(inode)->i_file_acl); + bh = NULL; goto cleanup; } error = ext4_xattr_check_block(inode, bh); @@ -3061,6 +3063,7 @@ ext4_xattr_block_cache_find(struct inode *inode, if (IS_ERR(bh)) { if (PTR_ERR(bh) == -ENOMEM) return NULL; + bh = NULL; EXT4_ERROR_INODE(inode, "block %lu read error", (unsigned long)ce->e_value); } else if (ext4_xattr_cmp(header, BHDR(bh)) == 0) { -- GitLab From 0be0231ac9fc72c9877d887d563903ccb9be745f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adalbert=20Laz=C4=83r?= Date: Wed, 6 Mar 2019 12:13:53 +0200 Subject: [PATCH 0275/1121] vsock/virtio: fix kernel panic from virtio_transport_reset_no_sock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 4c404ce23358d5d8fbdeb7a6021a9b33d3c3c167 upstream. Previous to commit 22b5c0b63f32 ("vsock/virtio: fix kernel panic after device hot-unplug"), vsock_core_init() was called from virtio_vsock_probe(). Now, virtio_transport_reset_no_sock() can be called before vsock_core_init() has the chance to run. [Wed Feb 27 14:17:09 2019] BUG: unable to handle kernel NULL pointer dereference at 0000000000000110 [Wed Feb 27 14:17:09 2019] #PF error: [normal kernel read fault] [Wed Feb 27 14:17:09 2019] PGD 0 P4D 0 [Wed Feb 27 14:17:09 2019] Oops: 0000 [#1] SMP PTI [Wed Feb 27 14:17:09 2019] CPU: 3 PID: 59 Comm: kworker/3:1 Not tainted 5.0.0-rc7-390-generic-hvi #390 [Wed Feb 27 14:17:09 2019] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014 [Wed Feb 27 14:17:09 2019] Workqueue: virtio_vsock virtio_transport_rx_work [vmw_vsock_virtio_transport] [Wed Feb 27 14:17:09 2019] RIP: 0010:virtio_transport_reset_no_sock+0x8c/0xc0 [vmw_vsock_virtio_transport_common] [Wed Feb 27 14:17:09 2019] Code: 35 8b 4f 14 48 8b 57 08 31 f6 44 8b 4f 10 44 8b 07 48 8d 7d c8 e8 84 f8 ff ff 48 85 c0 48 89 c3 74 2a e8 f7 31 03 00 48 89 df <48> 8b 80 10 01 00 00 e8 68 fb 69 ed 48 8b 75 f0 65 48 33 34 25 28 [Wed Feb 27 14:17:09 2019] RSP: 0018:ffffb42701ab7d40 EFLAGS: 00010282 [Wed Feb 27 14:17:09 2019] RAX: 0000000000000000 RBX: ffff9d79637ee080 RCX: 0000000000000003 [Wed Feb 27 14:17:09 2019] RDX: 0000000000000001 RSI: 0000000000000002 RDI: ffff9d79637ee080 [Wed Feb 27 14:17:09 2019] RBP: ffffb42701ab7d78 R08: ffff9d796fae70e0 R09: ffff9d796f403500 [Wed Feb 27 14:17:09 2019] R10: ffffb42701ab7d90 R11: 0000000000000000 R12: ffff9d7969d09240 [Wed Feb 27 14:17:09 2019] R13: ffff9d79624e6840 R14: ffff9d7969d09318 R15: ffff9d796d48ff80 [Wed Feb 27 14:17:09 2019] FS: 0000000000000000(0000) GS:ffff9d796fac0000(0000) knlGS:0000000000000000 [Wed Feb 27 14:17:09 2019] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [Wed Feb 27 14:17:09 2019] CR2: 0000000000000110 CR3: 0000000427f22000 CR4: 00000000000006e0 [Wed Feb 27 14:17:09 2019] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [Wed Feb 27 14:17:09 2019] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [Wed Feb 27 14:17:09 2019] Call Trace: [Wed Feb 27 14:17:09 2019] virtio_transport_recv_pkt+0x63/0x820 [vmw_vsock_virtio_transport_common] [Wed Feb 27 14:17:09 2019] ? kfree+0x17e/0x190 [Wed Feb 27 14:17:09 2019] ? detach_buf_split+0x145/0x160 [Wed Feb 27 14:17:09 2019] ? __switch_to_asm+0x40/0x70 [Wed Feb 27 14:17:09 2019] virtio_transport_rx_work+0xa0/0x106 [vmw_vsock_virtio_transport] [Wed Feb 27 14:17:09 2019] NET: Registered protocol family 40 [Wed Feb 27 14:17:09 2019] process_one_work+0x167/0x410 [Wed Feb 27 14:17:09 2019] worker_thread+0x4d/0x460 [Wed Feb 27 14:17:09 2019] kthread+0x105/0x140 [Wed Feb 27 14:17:09 2019] ? rescuer_thread+0x360/0x360 [Wed Feb 27 14:17:09 2019] ? kthread_destroy_worker+0x50/0x50 [Wed Feb 27 14:17:09 2019] ret_from_fork+0x35/0x40 [Wed Feb 27 14:17:09 2019] Modules linked in: vmw_vsock_virtio_transport vmw_vsock_virtio_transport_common input_leds vsock serio_raw i2c_piix4 mac_hid qemu_fw_cfg autofs4 cirrus ttm drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops virtio_net psmouse drm net_failover pata_acpi virtio_blk failover floppy Fixes: 22b5c0b63f32 ("vsock/virtio: fix kernel panic after device hot-unplug") Reported-by: Alexandru Herghelegiu Signed-off-by: Adalbert Lazăr Co-developed-by: Stefan Hajnoczi Reviewed-by: Stefan Hajnoczi Reviewed-by: Stefano Garzarella Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/vmw_vsock/virtio_transport_common.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c index edba7ab97563..40a8731c663b 100644 --- a/net/vmw_vsock/virtio_transport_common.c +++ b/net/vmw_vsock/virtio_transport_common.c @@ -662,6 +662,8 @@ static int virtio_transport_reset(struct vsock_sock *vsk, */ static int virtio_transport_reset_no_sock(struct virtio_vsock_pkt *pkt) { + const struct virtio_transport *t; + struct virtio_vsock_pkt *reply; struct virtio_vsock_pkt_info info = { .op = VIRTIO_VSOCK_OP_RST, .type = le16_to_cpu(pkt->hdr.type), @@ -672,15 +674,21 @@ static int virtio_transport_reset_no_sock(struct virtio_vsock_pkt *pkt) if (le16_to_cpu(pkt->hdr.op) == VIRTIO_VSOCK_OP_RST) return 0; - pkt = virtio_transport_alloc_pkt(&info, 0, - le64_to_cpu(pkt->hdr.dst_cid), - le32_to_cpu(pkt->hdr.dst_port), - le64_to_cpu(pkt->hdr.src_cid), - le32_to_cpu(pkt->hdr.src_port)); - if (!pkt) + reply = virtio_transport_alloc_pkt(&info, 0, + le64_to_cpu(pkt->hdr.dst_cid), + le32_to_cpu(pkt->hdr.dst_port), + le64_to_cpu(pkt->hdr.src_cid), + le32_to_cpu(pkt->hdr.src_port)); + if (!reply) return -ENOMEM; - return virtio_transport_get_ops()->send_pkt(pkt); + t = virtio_transport_get_ops(); + if (!t) { + virtio_transport_free_pkt(reply); + return -ENOTCONN; + } + + return t->send_pkt(reply); } static void virtio_transport_wait_close(struct sock *sk, long timeout) -- GitLab From 7dabc887d133afce32a58c022cb114c53d156e21 Mon Sep 17 00:00:00 2001 From: Xin Long Date: Sun, 31 Mar 2019 22:50:10 +0800 Subject: [PATCH 0276/1121] tipc: handle the err returned from cmd header function commit 2ac695d1d602ce00b12170242f58c3d3a8e36d04 upstream. Syzbot found a crash: BUG: KMSAN: uninit-value in tipc_nl_compat_name_table_dump+0x54f/0xcd0 net/tipc/netlink_compat.c:872 Call Trace: tipc_nl_compat_name_table_dump+0x54f/0xcd0 net/tipc/netlink_compat.c:872 __tipc_nl_compat_dumpit+0x59e/0xda0 net/tipc/netlink_compat.c:215 tipc_nl_compat_dumpit+0x63a/0x820 net/tipc/netlink_compat.c:280 tipc_nl_compat_handle net/tipc/netlink_compat.c:1226 [inline] tipc_nl_compat_recv+0x1b5f/0x2750 net/tipc/netlink_compat.c:1265 genl_family_rcv_msg net/netlink/genetlink.c:601 [inline] genl_rcv_msg+0x185f/0x1a60 net/netlink/genetlink.c:626 netlink_rcv_skb+0x431/0x620 net/netlink/af_netlink.c:2477 genl_rcv+0x63/0x80 net/netlink/genetlink.c:637 netlink_unicast_kernel net/netlink/af_netlink.c:1310 [inline] netlink_unicast+0xf3e/0x1020 net/netlink/af_netlink.c:1336 netlink_sendmsg+0x127f/0x1300 net/netlink/af_netlink.c:1917 sock_sendmsg_nosec net/socket.c:622 [inline] sock_sendmsg net/socket.c:632 [inline] Uninit was created at: __alloc_skb+0x309/0xa20 net/core/skbuff.c:208 alloc_skb include/linux/skbuff.h:1012 [inline] netlink_alloc_large_skb net/netlink/af_netlink.c:1182 [inline] netlink_sendmsg+0xb82/0x1300 net/netlink/af_netlink.c:1892 sock_sendmsg_nosec net/socket.c:622 [inline] sock_sendmsg net/socket.c:632 [inline] It was supposed to be fixed on commit 974cb0e3e7c9 ("tipc: fix uninit-value in tipc_nl_compat_name_table_dump") by checking TLV_GET_DATA_LEN(msg->req) in cmd->header()/tipc_nl_compat_name_table_dump_header(), which is called ahead of tipc_nl_compat_name_table_dump(). However, tipc_nl_compat_dumpit() doesn't handle the error returned from cmd header function. It means even when the check added in that fix fails, it won't stop calling tipc_nl_compat_name_table_dump(), and the issue will be triggered again. So this patch is to add the process for the err returned from cmd header function in tipc_nl_compat_dumpit(). Reported-by: syzbot+3ce8520484b0d4e260a5@syzkaller.appspotmail.com Signed-off-by: Xin Long Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/tipc/netlink_compat.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index 73895daf8943..8fe3da21e712 100644 --- a/net/tipc/netlink_compat.c +++ b/net/tipc/netlink_compat.c @@ -262,8 +262,14 @@ static int tipc_nl_compat_dumpit(struct tipc_nl_compat_cmd_dump *cmd, if (msg->rep_type) tipc_tlv_init(msg->rep, msg->rep_type); - if (cmd->header) - (*cmd->header)(msg); + if (cmd->header) { + err = (*cmd->header)(msg); + if (err) { + kfree_skb(msg->rep); + msg->rep = NULL; + return err; + } + } arg = nlmsg_new(0, GFP_KERNEL); if (!arg) { -- GitLab From da0bbf51bdcb043fad034b6ccabc0775bd5397bc Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 25 Apr 2019 16:13:58 -0700 Subject: [PATCH 0277/1121] slip: make slhc_free() silently accept an error pointer commit baf76f0c58aec435a3a864075b8f6d8ee5d1f17e upstream. This way, slhc_free() accepts what slhc_init() returns, whether that is an error or not. In particular, the pattern in sl_alloc_bufs() is slcomp = slhc_init(16, 16); ... slhc_free(slcomp); for the error handling path, and rather than complicate that code, just make it ok to always free what was returned by the init function. That's what the code used to do before commit 4ab42d78e37a ("ppp, slip: Validate VJ compression slot parameters completely") when slhc_init() just returned NULL for the error case, with no actual indication of the details of the error. Reported-by: syzbot+45474c076a4927533d2e@syzkaller.appspotmail.com Fixes: 4ab42d78e37a ("ppp, slip: Validate VJ compression slot parameters completely") Acked-by: Ben Hutchings Cc: David Miller Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/net/slip/slhc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/slip/slhc.c b/drivers/net/slip/slhc.c index f4e93f5fc204..ea90db3c7705 100644 --- a/drivers/net/slip/slhc.c +++ b/drivers/net/slip/slhc.c @@ -153,7 +153,7 @@ slhc_init(int rslots, int tslots) void slhc_free(struct slcompress *comp) { - if ( comp == NULLSLCOMPR ) + if ( IS_ERR_OR_NULL(comp) ) return; if ( comp->tstate != NULLSLSTATE ) -- GitLab From 01b6f50f90387c1f020bcf3cd684d24e3f0c16c5 Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Fri, 1 Mar 2019 10:09:55 +0200 Subject: [PATCH 0278/1121] intel_th: gth: Fix an off-by-one in output unassigning commit 91d3f8a629849968dc91d6ce54f2d46abf4feb7f upstream. Commit 9ed3f22223c3 ("intel_th: Don't reference unassigned outputs") fixes a NULL dereference for all masters except the last one ("256+"), which keeps the stale pointer after the output driver had been unassigned. Fix the off-by-one. Signed-off-by: Alexander Shishkin Fixes: 9ed3f22223c3 ("intel_th: Don't reference unassigned outputs") Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/intel_th/gth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hwtracing/intel_th/gth.c b/drivers/hwtracing/intel_th/gth.c index bb27a3150563..2a3ae9006c58 100644 --- a/drivers/hwtracing/intel_th/gth.c +++ b/drivers/hwtracing/intel_th/gth.c @@ -624,7 +624,7 @@ static void intel_th_gth_unassign(struct intel_th_device *thdev, othdev->output.port = -1; othdev->output.active = false; gth->output[port].output = NULL; - for (master = 0; master < TH_CONFIGURABLE_MASTERS; master++) + for (master = 0; master <= TH_CONFIGURABLE_MASTERS; master++) if (gth->master[master] == port) gth->master[master] = -1; spin_unlock(>h->gth_lock); -- GitLab From a50d8db5f3ec1cd11d97fffca6ba242cff18f1ea Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Thu, 25 Apr 2019 22:24:05 -0700 Subject: [PATCH 0279/1121] fs/proc/proc_sysctl.c: Fix a NULL pointer dereference commit 89189557b47b35683a27c80ee78aef18248eefb4 upstream. Syzkaller report this: sysctl could not get directory: /net//bridge -12 kasan: CONFIG_KASAN_INLINE enabled kasan: GPF could be caused by NULL-ptr deref or user memory access general protection fault: 0000 [#1] SMP KASAN PTI CPU: 1 PID: 7027 Comm: syz-executor.0 Tainted: G C 5.1.0-rc3+ #8 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1 04/01/2014 RIP: 0010:__write_once_size include/linux/compiler.h:220 [inline] RIP: 0010:__rb_change_child include/linux/rbtree_augmented.h:144 [inline] RIP: 0010:__rb_erase_augmented include/linux/rbtree_augmented.h:186 [inline] RIP: 0010:rb_erase+0x5f4/0x19f0 lib/rbtree.c:459 Code: 00 0f 85 60 13 00 00 48 89 1a 48 83 c4 18 5b 5d 41 5c 41 5d 41 5e 41 5f c3 48 89 f2 48 b8 00 00 00 00 00 fc ff df 48 c1 ea 03 <80> 3c 02 00 0f 85 75 0c 00 00 4d 85 ed 4c 89 2e 74 ce 4c 89 ea 48 RSP: 0018:ffff8881bb507778 EFLAGS: 00010206 RAX: dffffc0000000000 RBX: ffff8881f224b5b8 RCX: ffffffff818f3f6a RDX: 000000000000000a RSI: 0000000000000050 RDI: ffff8881f224b568 RBP: 0000000000000000 R08: ffffed10376a0ef4 R09: ffffed10376a0ef4 R10: 0000000000000001 R11: ffffed10376a0ef4 R12: ffff8881f224b558 R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 FS: 00007f3e7ce13700(0000) GS:ffff8881f7300000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007fd60fbe9398 CR3: 00000001cb55c001 CR4: 00000000007606e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 PKRU: 55555554 Call Trace: erase_entry fs/proc/proc_sysctl.c:178 [inline] erase_header+0xe3/0x160 fs/proc/proc_sysctl.c:207 start_unregistering fs/proc/proc_sysctl.c:331 [inline] drop_sysctl_table+0x558/0x880 fs/proc/proc_sysctl.c:1631 get_subdir fs/proc/proc_sysctl.c:1022 [inline] __register_sysctl_table+0xd65/0x1090 fs/proc/proc_sysctl.c:1335 br_netfilter_init+0x68/0x1000 [br_netfilter] do_one_initcall+0xbc/0x47d init/main.c:901 do_init_module+0x1b5/0x547 kernel/module.c:3456 load_module+0x6405/0x8c10 kernel/module.c:3804 __do_sys_finit_module+0x162/0x190 kernel/module.c:3898 do_syscall_64+0x9f/0x450 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x49/0xbe Modules linked in: br_netfilter(+) backlight comedi(C) hid_sensor_hub max3100 ti_ads8688 udc_core fddi snd_mona leds_gpio rc_streamzap mtd pata_netcell nf_log_common rc_winfast udp_tunnel snd_usbmidi_lib snd_usb_toneport snd_usb_line6 snd_rawmidi snd_seq_device snd_hwdep videobuf2_v4l2 videobuf2_common videodev media videobuf2_vmalloc videobuf2_memops rc_gadmei_rm008z 8250_of smm665 hid_tmff hid_saitek hwmon_vid rc_ati_tv_wonder_hd_600 rc_core pata_pdc202xx_old dn_rtmsg as3722 ad714x_i2c ad714x snd_soc_cs4265 hid_kensington panel_ilitek_ili9322 drm drm_panel_orientation_quirks ipack cdc_phonet usbcore phonet hid_jabra hid extcon_arizona can_dev industrialio_triggered_buffer kfifo_buf industrialio adm1031 i2c_mux_ltc4306 i2c_mux ipmi_msghandler mlxsw_core snd_soc_cs35l34 snd_soc_core snd_pcm_dmaengine snd_pcm snd_timer ac97_bus snd_compress snd soundcore gpio_da9055 uio ecdh_generic mdio_thunder of_mdio fixed_phy libphy mdio_cavium iptable_security iptable_raw iptable_mangle iptable_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 iptable_filter bpfilter ip6_vti ip_vti ip_gre ipip sit tunnel4 ip_tunnel hsr veth netdevsim vxcan batman_adv cfg80211 rfkill chnl_net caif nlmon dummy team bonding vcan bridge stp llc ip6_gre gre ip6_tunnel tunnel6 tun joydev mousedev ppdev tpm kvm_intel kvm irqbypass crct10dif_pclmul crc32_pclmul crc32c_intel ghash_clmulni_intel aesni_intel ide_pci_generic piix aes_x86_64 crypto_simd cryptd ide_core glue_helper input_leds psmouse intel_agp intel_gtt serio_raw ata_generic i2c_piix4 agpgart pata_acpi parport_pc parport floppy rtc_cmos sch_fq_codel ip_tables x_tables sha1_ssse3 sha1_generic ipv6 [last unloaded: br_netfilter] Dumping ftrace buffer: (ftrace buffer empty) ---[ end trace 68741688d5fbfe85 ]--- commit 23da9588037e ("fs/proc/proc_sysctl.c: fix NULL pointer dereference in put_links") forgot to handle start_unregistering() case, while header->parent is NULL, it calls erase_header() and as seen in the above syzkaller call trace, accessing &header->parent->root will trigger a NULL pointer dereference. As that commit explained, there is also no need to call start_unregistering() if header->parent is NULL. Link: http://lkml.kernel.org/r/20190409153622.28112-1-yuehaibing@huawei.com Fixes: 23da9588037e ("fs/proc/proc_sysctl.c: fix NULL pointer dereference in put_links") Fixes: 0e47c99d7fe25 ("sysctl: Replace root_list with links between sysctl_table_sets") Signed-off-by: YueHaibing Reported-by: Hulk Robot Reviewed-by: Kees Cook Cc: Luis Chamberlain Cc: Alexey Dobriyan Cc: Al Viro Cc: "Eric W. Biederman" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- fs/proc/proc_sysctl.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index 8d5422bb9c1a..555698ddb943 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c @@ -1620,9 +1620,11 @@ static void drop_sysctl_table(struct ctl_table_header *header) if (--header->nreg) return; - if (parent) + if (parent) { put_links(header); - start_unregistering(header); + start_unregistering(header); + } + if (!--header->count) kfree_rcu(header, rcu); -- GitLab From 44579653c9ab9bb1be04888f285ba4c20c924217 Mon Sep 17 00:00:00 2001 From: Andrea Claudi Date: Fri, 15 Feb 2019 17:51:48 +0100 Subject: [PATCH 0280/1121] ipvs: fix warning on unused variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit c93a49b9769e435990c82297aa0baa31e1538790 upstream. When CONFIG_IP_VS_IPV6 is not defined, build produced this warning: net/netfilter/ipvs/ip_vs_ctl.c:899:6: warning: unused variable ‘ret’ [-Wunused-variable] int ret = 0; ^~~ Fix this by moving the declaration of 'ret' in the CONFIG_IP_VS_IPV6 section in the same function. While at it, drop its unneeded initialisation. Fixes: 098e13f5b21d ("ipvs: fix dependency on nf_defrag_ipv6") Reported-by: Stefano Brivio Signed-off-by: Andrea Claudi Reviewed-by: Stefano Brivio Signed-off-by: Pablo Neira Ayuso Signed-off-by: Greg Kroah-Hartman --- net/netfilter/ipvs/ip_vs_ctl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index 56dd5ce6274f..6d7608b88f66 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -889,12 +889,13 @@ ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest, { struct ip_vs_dest *dest; unsigned int atype, i; - int ret = 0; EnterFunction(2); #ifdef CONFIG_IP_VS_IPV6 if (udest->af == AF_INET6) { + int ret; + atype = ipv6_addr_type(&udest->addr.in6); if ((!(atype & IPV6_ADDR_UNICAST) || atype & IPV6_ADDR_LINKLOCAL) && -- GitLab From 33c6b9ca70a8b066a613e2a3d0331ae8f82aa31a Mon Sep 17 00:00:00 2001 From: Todd Kjos Date: Thu, 14 Feb 2019 15:22:57 -0800 Subject: [PATCH 0281/1121] binder: fix handling of misaligned binder object commit 26528be6720bb40bc8844e97ee73a37e530e9c5e upstream. Fixes crash found by syzbot: kernel BUG at drivers/android/binder_alloc.c:LINE! (2) Reported-and-tested-by: syzbot+55de1eb4975dec156d8f@syzkaller.appspotmail.com Signed-off-by: Todd Kjos Reviewed-by: Joel Fernandes (Google) Cc: stable # 5.0, 4.19, 4.14 Signed-off-by: Greg Kroah-Hartman --- drivers/android/binder_alloc.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c index b9281f2725a6..e0b0399ff7ec 100644 --- a/drivers/android/binder_alloc.c +++ b/drivers/android/binder_alloc.c @@ -945,14 +945,13 @@ enum lru_status binder_alloc_free_page(struct list_head *item, index = page - alloc->pages; page_addr = (uintptr_t)alloc->buffer + index * PAGE_SIZE; + + mm = alloc->vma_vm_mm; + if (!mmget_not_zero(mm)) + goto err_mmget; + if (!down_write_trylock(&mm->mmap_sem)) + goto err_down_write_mmap_sem_failed; vma = binder_alloc_get_vma(alloc); - if (vma) { - if (!mmget_not_zero(alloc->vma_vm_mm)) - goto err_mmget; - mm = alloc->vma_vm_mm; - if (!down_write_trylock(&mm->mmap_sem)) - goto err_down_write_mmap_sem_failed; - } list_lru_isolate(lru, item); spin_unlock(lock); @@ -965,10 +964,9 @@ enum lru_status binder_alloc_free_page(struct list_head *item, PAGE_SIZE); trace_binder_unmap_user_end(alloc, index); - - up_write(&mm->mmap_sem); - mmput(mm); } + up_write(&mm->mmap_sem); + mmput(mm); trace_binder_unmap_kernel_start(alloc, index); -- GitLab From c22cb4bd1a35fb86ef00547031b975e3235201e8 Mon Sep 17 00:00:00 2001 From: luca abeni Date: Mon, 25 Mar 2019 14:15:30 +0100 Subject: [PATCH 0282/1121] sched/deadline: Correctly handle active 0-lag timers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 1b02cd6a2d7f3e2a6a5262887d2cb2912083e42f upstream. syzbot reported the following warning: [ ] WARNING: CPU: 4 PID: 17089 at kernel/sched/deadline.c:255 task_non_contending+0xae0/0x1950 line 255 of deadline.c is: WARN_ON(hrtimer_active(&dl_se->inactive_timer)); in task_non_contending(). Unfortunately, in some cases (for example, a deadline task continuosly blocking and waking immediately) it can happen that a task blocks (and task_non_contending() is called) while the 0-lag timer is still active. In this case, the safest thing to do is to immediately decrease the running bandwidth of the task, without trying to re-arm the 0-lag timer. Signed-off-by: luca abeni Signed-off-by: Peter Zijlstra (Intel) Acked-by: Juri Lelli Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: chengjian (D) Link: https://lkml.kernel.org/r/20190325131530.34706-1-luca.abeni@santannapisa.it Signed-off-by: Ingo Molnar Signed-off-by: Greg Kroah-Hartman --- kernel/sched/deadline.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c index b2589c7e9439..22770168bff8 100644 --- a/kernel/sched/deadline.c +++ b/kernel/sched/deadline.c @@ -217,7 +217,6 @@ static void task_non_contending(struct task_struct *p) if (dl_se->dl_runtime == 0) return; - WARN_ON(hrtimer_active(&dl_se->inactive_timer)); WARN_ON(dl_se->dl_non_contending); zerolag_time = dl_se->deadline - @@ -234,7 +233,7 @@ static void task_non_contending(struct task_struct *p) * If the "0-lag time" already passed, decrease the active * utilization now, instead of starting a timer */ - if (zerolag_time < 0) { + if ((zerolag_time < 0) || hrtimer_active(&dl_se->inactive_timer)) { if (dl_task(p)) sub_running_bw(dl_se->dl_bw, dl_rq); if (!dl_task(p) || p->state == TASK_DEAD) { -- GitLab From ba4837023eba2b8799d62892f938f86b1a01d218 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Sat, 30 Mar 2019 10:21:07 +0900 Subject: [PATCH 0283/1121] NFS: Forbid setting AF_INET6 to "struct sockaddr_in"->sin_family. commit 7c2bd9a39845bfb6d72ddb55ce737650271f6f96 upstream. syzbot is reporting uninitialized value at rpc_sockaddr2uaddr() [1]. This is because syzbot is setting AF_INET6 to "struct sockaddr_in"->sin_family (which is embedded into user-visible "struct nfs_mount_data" structure) despite nfs23_validate_mount_data() cannot pass sizeof(struct sockaddr_in6) bytes of AF_INET6 address to rpc_sockaddr2uaddr(). Since "struct nfs_mount_data" structure is user-visible, we can't change "struct nfs_mount_data" to use "struct sockaddr_storage". Therefore, assuming that everybody is using AF_INET family when passing address via "struct nfs_mount_data"->addr, reject if its sin_family is not AF_INET. [1] https://syzkaller.appspot.com/bug?id=599993614e7cbbf66bc2656a919ab2a95fb5d75c Reported-by: syzbot Signed-off-by: Tetsuo Handa Signed-off-by: Trond Myklebust Signed-off-by: Greg Kroah-Hartman --- fs/nfs/super.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 77d8d03344c8..f464f8d9060c 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -2044,7 +2044,8 @@ static int nfs23_validate_mount_data(void *options, memcpy(sap, &data->addr, sizeof(data->addr)); args->nfs_server.addrlen = sizeof(data->addr); args->nfs_server.port = ntohs(data->addr.sin_port); - if (!nfs_verify_server_address(sap)) + if (sap->sa_family != AF_INET || + !nfs_verify_server_address(sap)) goto out_no_address; if (!(data->flags & NFS_MOUNT_TCP)) -- GitLab From a8946d9cbd1fc969b094fafaac590d06e46f739c Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Mon, 15 Apr 2019 00:43:00 +0200 Subject: [PATCH 0284/1121] netfilter: ebtables: CONFIG_COMPAT: drop a bogus WARN_ON commit 7caa56f006e9d712b44f27b32520c66420d5cbc6 upstream. It means userspace gave us a ruleset where there is some other data after the ebtables target but before the beginning of the next rule. Fixes: 81e675c227ec ("netfilter: ebtables: add CONFIG_COMPAT support") Reported-by: syzbot+659574e7bcc7f7eb4df7@syzkaller.appspotmail.com Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso Signed-off-by: Greg Kroah-Hartman --- net/bridge/netfilter/ebtables.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 38b3309edba8..b967bd51bf1f 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c @@ -2030,7 +2030,8 @@ static int ebt_size_mwt(struct compat_ebt_entry_mwt *match32, if (match_kern) match_kern->match_size = ret; - if (WARN_ON(type == EBT_COMPAT_TARGET && size_left)) + /* rule should have no remaining data after target */ + if (type == EBT_COMPAT_TARGET && size_left) return -EINVAL; match32 = (struct compat_ebt_entry_mwt *) buf; -- GitLab From 2617f9af19ce93c509ebf3fd3ce26048b8f85216 Mon Sep 17 00:00:00 2001 From: Yue Haibing Date: Thu, 21 Mar 2019 22:42:23 +0800 Subject: [PATCH 0285/1121] fm10k: Fix a potential NULL pointer dereference commit 01ca667133d019edc9f0a1f70a272447c84ec41f upstream. Syzkaller report this: kasan: GPF could be caused by NULL-ptr deref or user memory access general protection fault: 0000 [#1] SMP KASAN PTI CPU: 0 PID: 4378 Comm: syz-executor.0 Tainted: G C 5.0.0+ #5 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1 04/01/2014 RIP: 0010:__lock_acquire+0x95b/0x3200 kernel/locking/lockdep.c:3573 Code: 00 0f 85 28 1e 00 00 48 81 c4 08 01 00 00 5b 5d 41 5c 41 5d 41 5e 41 5f c3 4c 89 ea 48 b8 00 00 00 00 00 fc ff df 48 c1 ea 03 <80> 3c 02 00 0f 85 cc 24 00 00 49 81 7d 00 e0 de 03 a6 41 bc 00 00 RSP: 0018:ffff8881e3c07a40 EFLAGS: 00010002 RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 0000000000000000 RDX: 0000000000000010 RSI: 0000000000000000 RDI: 0000000000000080 RBP: 0000000000000000 R08: 0000000000000001 R09: 0000000000000000 R10: ffff8881e3c07d98 R11: ffff8881c7f21f80 R12: 0000000000000001 R13: 0000000000000080 R14: 0000000000000000 R15: 0000000000000001 FS: 00007fce2252e700(0000) GS:ffff8881f2400000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007fffc7eb0228 CR3: 00000001e5bea002 CR4: 00000000007606f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 PKRU: 55555554 Call Trace: lock_acquire+0xff/0x2c0 kernel/locking/lockdep.c:4211 __mutex_lock_common kernel/locking/mutex.c:925 [inline] __mutex_lock+0xdf/0x1050 kernel/locking/mutex.c:1072 drain_workqueue+0x24/0x3f0 kernel/workqueue.c:2934 destroy_workqueue+0x23/0x630 kernel/workqueue.c:4319 __do_sys_delete_module kernel/module.c:1018 [inline] __se_sys_delete_module kernel/module.c:961 [inline] __x64_sys_delete_module+0x30c/0x480 kernel/module.c:961 do_syscall_64+0x9f/0x450 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x49/0xbe RIP: 0033:0x462e99 Code: f7 d8 64 89 02 b8 ff ff ff ff c3 66 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 bc ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007fce2252dc58 EFLAGS: 00000246 ORIG_RAX: 00000000000000b0 RAX: ffffffffffffffda RBX: 000000000073bf00 RCX: 0000000000462e99 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000020000140 RBP: 0000000000000002 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 00007fce2252e6bc R13: 00000000004bcca9 R14: 00000000006f6b48 R15: 00000000ffffffff If alloc_workqueue fails, it should return -ENOMEM, otherwise may trigger this NULL pointer dereference while unloading drivers. Reported-by: Hulk Robot Fixes: 0a38c17a21a0 ("fm10k: Remove create_workqueue") Signed-off-by: Yue Haibing Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/intel/fm10k/fm10k_main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_main.c b/drivers/net/ethernet/intel/fm10k/fm10k_main.c index 103c0a742d03..fef0bff4a54b 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_main.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_main.c @@ -58,6 +58,8 @@ static int __init fm10k_init_module(void) /* create driver workqueue */ fm10k_workqueue = alloc_workqueue("%s", WQ_MEM_RECLAIM, 0, fm10k_driver_name); + if (!fm10k_workqueue) + return -ENOMEM; fm10k_dbg_init(); -- GitLab From 13af7118da01f6daf6a1aa4cdddc4836952472c3 Mon Sep 17 00:00:00 2001 From: Xin Long Date: Sun, 31 Mar 2019 22:50:08 +0800 Subject: [PATCH 0286/1121] tipc: check bearer name with right length in tipc_nl_compat_bearer_enable commit 6f07e5f06c8712acc423485f657799fc8e11e56c upstream. Syzbot reported the following crash: BUG: KMSAN: uninit-value in memchr+0xce/0x110 lib/string.c:961 memchr+0xce/0x110 lib/string.c:961 string_is_valid net/tipc/netlink_compat.c:176 [inline] tipc_nl_compat_bearer_enable+0x2c4/0x910 net/tipc/netlink_compat.c:401 __tipc_nl_compat_doit net/tipc/netlink_compat.c:321 [inline] tipc_nl_compat_doit+0x3aa/0xaf0 net/tipc/netlink_compat.c:354 tipc_nl_compat_handle net/tipc/netlink_compat.c:1162 [inline] tipc_nl_compat_recv+0x1ae7/0x2750 net/tipc/netlink_compat.c:1265 genl_family_rcv_msg net/netlink/genetlink.c:601 [inline] genl_rcv_msg+0x185f/0x1a60 net/netlink/genetlink.c:626 netlink_rcv_skb+0x431/0x620 net/netlink/af_netlink.c:2477 genl_rcv+0x63/0x80 net/netlink/genetlink.c:637 netlink_unicast_kernel net/netlink/af_netlink.c:1310 [inline] netlink_unicast+0xf3e/0x1020 net/netlink/af_netlink.c:1336 netlink_sendmsg+0x127f/0x1300 net/netlink/af_netlink.c:1917 sock_sendmsg_nosec net/socket.c:622 [inline] sock_sendmsg net/socket.c:632 [inline] Uninit was created at: __alloc_skb+0x309/0xa20 net/core/skbuff.c:208 alloc_skb include/linux/skbuff.h:1012 [inline] netlink_alloc_large_skb net/netlink/af_netlink.c:1182 [inline] netlink_sendmsg+0xb82/0x1300 net/netlink/af_netlink.c:1892 sock_sendmsg_nosec net/socket.c:622 [inline] sock_sendmsg net/socket.c:632 [inline] It was triggered when the bearer name size < TIPC_MAX_BEARER_NAME, it would check with a wrong len/TLV_GET_DATA_LEN(msg->req), which also includes priority and disc_domain length. This patch is to fix it by checking it with a right length: 'TLV_GET_DATA_LEN(msg->req) - offsetof(struct tipc_bearer_config, name)'. Reported-by: syzbot+8b707430713eb46e1e45@syzkaller.appspotmail.com Signed-off-by: Xin Long Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/tipc/netlink_compat.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index 8fe3da21e712..e2db60960f23 100644 --- a/net/tipc/netlink_compat.c +++ b/net/tipc/netlink_compat.c @@ -394,7 +394,12 @@ static int tipc_nl_compat_bearer_enable(struct tipc_nl_compat_cmd_doit *cmd, if (!bearer) return -EMSGSIZE; - len = min_t(int, TLV_GET_DATA_LEN(msg->req), TIPC_MAX_BEARER_NAME); + len = TLV_GET_DATA_LEN(msg->req); + len -= offsetof(struct tipc_bearer_config, name); + if (len <= 0) + return -EINVAL; + + len = min_t(int, len, TIPC_MAX_BEARER_NAME); if (!string_is_valid(b->name, len)) return -EINVAL; -- GitLab From 87e87b655801993eb9cd1aba7418bd2a0a152bd1 Mon Sep 17 00:00:00 2001 From: Xin Long Date: Sun, 31 Mar 2019 22:50:09 +0800 Subject: [PATCH 0287/1121] tipc: check link name with right length in tipc_nl_compat_link_set commit 8c63bf9ab4be8b83bd8c34aacfd2f1d2c8901c8a upstream. A similar issue as fixed by Patch "tipc: check bearer name with right length in tipc_nl_compat_bearer_enable" was also found by syzbot in tipc_nl_compat_link_set(). The length to check with should be 'TLV_GET_DATA_LEN(msg->req) - offsetof(struct tipc_link_config, name)'. Reported-by: syzbot+de00a87b8644a582ae79@syzkaller.appspotmail.com Signed-off-by: Xin Long Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/tipc/netlink_compat.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index e2db60960f23..aa75bc8b158f 100644 --- a/net/tipc/netlink_compat.c +++ b/net/tipc/netlink_compat.c @@ -768,7 +768,12 @@ static int tipc_nl_compat_link_set(struct tipc_nl_compat_cmd_doit *cmd, lc = (struct tipc_link_config *)TLV_DATA(msg->req); - len = min_t(int, TLV_GET_DATA_LEN(msg->req), TIPC_MAX_LINK_NAME); + len = TLV_GET_DATA_LEN(msg->req); + len -= offsetof(struct tipc_link_config, name); + if (len <= 0) + return -EINVAL; + + len = min_t(int, len, TIPC_MAX_LINK_NAME); if (!string_is_valid(lc->name, len)) return -EINVAL; -- GitLab From 8468115ee9f0f4e2c7ce4ef219a515b2a8bec19d Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Wed, 13 Mar 2019 07:56:02 -0400 Subject: [PATCH 0288/1121] dm integrity: change memcmp to strncmp in dm_integrity_ctr commit 0d74e6a3b6421d98eeafbed26f29156d469bc0b5 upstream. If the string opt_string is small, the function memcmp can access bytes that are beyond the terminating nul character. In theory, it could cause segfault, if opt_string were located just below some unmapped memory. Change from memcmp to strncmp so that we don't read bytes beyond the end of the string. Cc: stable@vger.kernel.org # v4.12+ Signed-off-by: Mikulas Patocka Signed-off-by: Mike Snitzer Signed-off-by: Greg Kroah-Hartman --- drivers/md/dm-integrity.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c index 036379a23499..23f0f4eaaa2e 100644 --- a/drivers/md/dm-integrity.c +++ b/drivers/md/dm-integrity.c @@ -2917,17 +2917,17 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned argc, char **argv) goto bad; } ic->sectors_per_block = val >> SECTOR_SHIFT; - } else if (!memcmp(opt_string, "internal_hash:", strlen("internal_hash:"))) { + } else if (!strncmp(opt_string, "internal_hash:", strlen("internal_hash:"))) { r = get_alg_and_key(opt_string, &ic->internal_hash_alg, &ti->error, "Invalid internal_hash argument"); if (r) goto bad; - } else if (!memcmp(opt_string, "journal_crypt:", strlen("journal_crypt:"))) { + } else if (!strncmp(opt_string, "journal_crypt:", strlen("journal_crypt:"))) { r = get_alg_and_key(opt_string, &ic->journal_crypt_alg, &ti->error, "Invalid journal_crypt argument"); if (r) goto bad; - } else if (!memcmp(opt_string, "journal_mac:", strlen("journal_mac:"))) { + } else if (!strncmp(opt_string, "journal_mac:", strlen("journal_mac:"))) { r = get_alg_and_key(opt_string, &ic->journal_mac_alg, &ti->error, "Invalid journal_mac argument"); if (r) -- GitLab From 4c75d3d5104ecb5deafa40108153454b39b4f90b Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Thu, 21 Feb 2019 23:19:41 +0100 Subject: [PATCH 0289/1121] x86, retpolines: Raise limit for generating indirect calls from switch-case MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit ce02ef06fcf7a399a6276adb83f37373d10cbbe1 upstream. From networking side, there are numerous attempts to get rid of indirect calls in fast-path wherever feasible in order to avoid the cost of retpolines, for example, just to name a few: * 283c16a2dfd3 ("indirect call wrappers: helpers to speed-up indirect calls of builtin") * aaa5d90b395a ("net: use indirect call wrappers at GRO network layer") * 028e0a476684 ("net: use indirect call wrappers at GRO transport layer") * 356da6d0cde3 ("dma-mapping: bypass indirect calls for dma-direct") * 09772d92cd5a ("bpf: avoid retpoline for lookup/update/delete calls on maps") * 10870dd89e95 ("netfilter: nf_tables: add direct calls for all builtin expressions") [...] Recent work on XDP from Björn and Magnus additionally found that manually transforming the XDP return code switch statement with more than 5 cases into if-else combination would result in a considerable speedup in XDP layer due to avoidance of indirect calls in CONFIG_RETPOLINE enabled builds. On i40e driver with XDP prog attached, a 20-26% speedup has been observed [0]. Aside from XDP, there are many other places later in the networking stack's critical path with similar switch-case processing. Rather than fixing every XDP-enabled driver and locations in stack by hand, it would be good to instead raise the limit where gcc would emit expensive indirect calls from the switch under retpolines and stick with the default as-is in case of !retpoline configured kernels. This would also have the advantage that for archs where this is not necessary, we let compiler select the underlying target optimization for these constructs and avoid potential slow-downs by if-else hand-rewrite. In case of gcc, this setting is controlled by case-values-threshold which has an architecture global default that selects 4 or 5 (latter if target does not have a case insn that compares the bounds) where some arch back ends like arm64 or s390 override it with their own target hooks, for example, in gcc commit db7a90aa0de5 ("S/390: Disable prediction of indirect branches") the threshold pretty much disables jump tables by limit of 20 under retpoline builds. Comparing gcc's and clang's default code generation on x86-64 under O2 level with retpoline build results in the following outcome for 5 switch cases: * gcc with -mindirect-branch=thunk-inline -mindirect-branch-register: # gdb -batch -ex 'disassemble dispatch' ./c-switch Dump of assembler code for function dispatch: 0x0000000000400be0 <+0>: cmp $0x4,%edi 0x0000000000400be3 <+3>: ja 0x400c35 0x0000000000400be5 <+5>: lea 0x915f8(%rip),%rdx # 0x4921e4 0x0000000000400bec <+12>: mov %edi,%edi 0x0000000000400bee <+14>: movslq (%rdx,%rdi,4),%rax 0x0000000000400bf2 <+18>: add %rdx,%rax 0x0000000000400bf5 <+21>: callq 0x400c01 0x0000000000400bfa <+26>: pause 0x0000000000400bfc <+28>: lfence 0x0000000000400bff <+31>: jmp 0x400bfa 0x0000000000400c01 <+33>: mov %rax,(%rsp) 0x0000000000400c05 <+37>: retq 0x0000000000400c06 <+38>: nopw %cs:0x0(%rax,%rax,1) 0x0000000000400c10 <+48>: jmpq 0x400c90 0x0000000000400c15 <+53>: nopl (%rax) 0x0000000000400c18 <+56>: jmpq 0x400c70 0x0000000000400c1d <+61>: nopl (%rax) 0x0000000000400c20 <+64>: jmpq 0x400c50 0x0000000000400c25 <+69>: nopl (%rax) 0x0000000000400c28 <+72>: jmpq 0x400c40 0x0000000000400c2d <+77>: nopl (%rax) 0x0000000000400c30 <+80>: jmpq 0x400cb0 0x0000000000400c35 <+85>: push %rax 0x0000000000400c36 <+86>: callq 0x40dd80 End of assembler dump. * clang with -mretpoline emitting search tree: # gdb -batch -ex 'disassemble dispatch' ./c-switch Dump of assembler code for function dispatch: 0x0000000000400b30 <+0>: cmp $0x1,%edi 0x0000000000400b33 <+3>: jle 0x400b44 0x0000000000400b35 <+5>: cmp $0x2,%edi 0x0000000000400b38 <+8>: je 0x400b4d 0x0000000000400b3a <+10>: cmp $0x3,%edi 0x0000000000400b3d <+13>: jne 0x400b52 0x0000000000400b3f <+15>: jmpq 0x400c50 0x0000000000400b44 <+20>: test %edi,%edi 0x0000000000400b46 <+22>: jne 0x400b5c 0x0000000000400b48 <+24>: jmpq 0x400c20 0x0000000000400b4d <+29>: jmpq 0x400c40 0x0000000000400b52 <+34>: cmp $0x4,%edi 0x0000000000400b55 <+37>: jne 0x400b66 0x0000000000400b57 <+39>: jmpq 0x400c60 0x0000000000400b5c <+44>: cmp $0x1,%edi 0x0000000000400b5f <+47>: jne 0x400b66 0x0000000000400b61 <+49>: jmpq 0x400c30 0x0000000000400b66 <+54>: push %rax 0x0000000000400b67 <+55>: callq 0x40dd20 End of assembler dump. For sake of comparison, clang without -mretpoline: # gdb -batch -ex 'disassemble dispatch' ./c-switch Dump of assembler code for function dispatch: 0x0000000000400b30 <+0>: cmp $0x4,%edi 0x0000000000400b33 <+3>: ja 0x400b57 0x0000000000400b35 <+5>: mov %edi,%eax 0x0000000000400b37 <+7>: jmpq *0x492148(,%rax,8) 0x0000000000400b3e <+14>: jmpq 0x400bf0 0x0000000000400b43 <+19>: jmpq 0x400c30 0x0000000000400b48 <+24>: jmpq 0x400c10 0x0000000000400b4d <+29>: jmpq 0x400c20 0x0000000000400b52 <+34>: jmpq 0x400c00 0x0000000000400b57 <+39>: push %rax 0x0000000000400b58 <+40>: callq 0x40dcf0 End of assembler dump. Raising the cases to a high number (e.g. 100) will still result in similar code generation pattern with clang and gcc as above, in other words clang generally turns off jump table emission by having an extra expansion pass under retpoline build to turn indirectbr instructions from their IR into switch instructions as a built-in -mno-jump-table lowering of a switch (in this case, even if IR input already contained an indirect branch). For gcc, adding --param=case-values-threshold=20 as in similar fashion as s390 in order to raise the limit for x86 retpoline enabled builds results in a small vmlinux size increase of only 0.13% (before=18,027,528 after=18,051,192). For clang this option is ignored due to i) not being needed as mentioned and ii) not having above cmdline parameter. Non-retpoline-enabled builds with gcc continue to use the default case-values-threshold setting, so nothing changes here. [0] https://lore.kernel.org/netdev/20190129095754.9390-1-bjorn.topel@gmail.com/ and "The Path to DPDK Speeds for AF_XDP", LPC 2018, networking track: - http://vger.kernel.org/lpc_net2018_talks/lpc18_pres_af_xdp_perf-v3.pdf - http://vger.kernel.org/lpc_net2018_talks/lpc18_paper_af_xdp_perf-v2.pdf Signed-off-by: Daniel Borkmann Signed-off-by: Thomas Gleixner Acked-by: Jesper Dangaard Brouer Acked-by: Björn Töpel Acked-by: Linus Torvalds Cc: netdev@vger.kernel.org Cc: David S. Miller Cc: Magnus Karlsson Cc: Alexei Starovoitov Cc: Peter Zijlstra Cc: David Woodhouse Cc: Andy Lutomirski Cc: Borislav Petkov Link: https://lkml.kernel.org/r/20190221221941.29358-1-daniel@iogearbox.net Signed-off-by: Greg Kroah-Hartman --- arch/x86/Makefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/x86/Makefile b/arch/x86/Makefile index c5290aecdf06..f9ba149c60d1 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -242,6 +242,11 @@ KBUILD_CFLAGS += -fno-asynchronous-unwind-tables # Avoid indirect branches in kernel to deal with Spectre ifdef CONFIG_RETPOLINE KBUILD_CFLAGS += $(RETPOLINE_CFLAGS) + # Additionally, avoid generating expensive indirect jumps which + # are subject to retpolines for small number of switch cases. + # clang turns off jump table generation by default when under + # retpoline builds, however, gcc does not for x86. + KBUILD_CFLAGS += $(call cc-option,--param=case-values-threshold=20) endif archscripts: scripts_basic -- GitLab From e28951100515c9fd8f8d4b06ed96576e3527ad82 Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Mon, 25 Mar 2019 14:56:20 +0100 Subject: [PATCH 0290/1121] x86/retpolines: Disable switch jump tables when retpolines are enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit a9d57ef15cbe327fe54416dd194ee0ea66ae53a4 upstream. Commit ce02ef06fcf7 ("x86, retpolines: Raise limit for generating indirect calls from switch-case") raised the limit under retpolines to 20 switch cases where gcc would only then start to emit jump tables, and therefore effectively disabling the emission of slow indirect calls in this area. After this has been brought to attention to gcc folks [0], Martin Liska has then fixed gcc to align with clang by avoiding to generate switch jump tables entirely under retpolines. This is taking effect in gcc starting from stable version 8.4.0. Given kernel supports compilation with older versions of gcc where the fix is not being available or backported anymore, we need to keep the extra KBUILD_CFLAGS around for some time and generally set the -fno-jump-tables to align with what more recent gcc is doing automatically today. More than 20 switch cases are not expected to be fast-path critical, but it would still be good to align with gcc behavior for versions < 8.4.0 in order to have consistency across supported gcc versions. vmlinux size is slightly growing by 0.27% for older gcc. This flag is only set to work around affected gcc, no change for clang. [0] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86952 Suggested-by: Martin Liska Signed-off-by: Daniel Borkmann Signed-off-by: Thomas Gleixner Cc: David Woodhouse Cc: Linus Torvalds Cc: Jesper Dangaard Brouer Cc: Björn Töpel Cc: Magnus Karlsson Cc: Alexei Starovoitov Cc: H.J. Lu Cc: Alexei Starovoitov Cc: David S. Miller Link: https://lkml.kernel.org/r/20190325135620.14882-1-daniel@iogearbox.net Signed-off-by: Greg Kroah-Hartman --- arch/x86/Makefile | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/x86/Makefile b/arch/x86/Makefile index f9ba149c60d1..eb1f8f249dc3 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -245,8 +245,12 @@ ifdef CONFIG_RETPOLINE # Additionally, avoid generating expensive indirect jumps which # are subject to retpolines for small number of switch cases. # clang turns off jump table generation by default when under - # retpoline builds, however, gcc does not for x86. - KBUILD_CFLAGS += $(call cc-option,--param=case-values-threshold=20) + # retpoline builds, however, gcc does not for x86. This has + # only been fixed starting from gcc stable version 8.4.0 and + # onwards, but not for older ones. See gcc bug #86952. + ifndef CONFIG_CC_IS_CLANG + KBUILD_CFLAGS += $(call cc-option,-fno-jump-tables) + endif endif archscripts: scripts_basic -- GitLab From f7adeff6112ce12fb70dab378287d0d85917d240 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 30 Oct 2018 15:10:47 -0700 Subject: [PATCH 0291/1121] mm: Fix warning in insert_pfn() commit f2c57d91b0d96aa13ccff4e3b178038f17b00658 upstream. In DAX mode a write pagefault can race with write(2) in the following way: CPU0 CPU1 write fault for mapped zero page (hole) dax_iomap_rw() iomap_apply() xfs_file_iomap_begin() - allocates blocks dax_iomap_actor() invalidate_inode_pages2_range() - invalidates radix tree entries in given range dax_iomap_pte_fault() grab_mapping_entry() - no entry found, creates empty ... xfs_file_iomap_begin() - finds already allocated block ... vmf_insert_mixed_mkwrite() - WARNs and does nothing because there is still zero page mapped in PTE unmap_mapping_pages() This race results in WARN_ON from insert_pfn() and is occasionally triggered by fstest generic/344. Note that the race is otherwise harmless as before write(2) on CPU0 is finished, we will invalidate page tables properly and thus user of mmap will see modified data from write(2) from that point on. So just restrict the warning only to the case when the PFN in PTE is not zero page. Link: http://lkml.kernel.org/r/20180824154542.26872-1-jack@suse.cz Signed-off-by: Jan Kara Reviewed-by: Andrew Morton Cc: Ross Zwisler Cc: Dan Williams Cc: Dave Jiang Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- mm/memory.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/mm/memory.c b/mm/memory.c index fb9f7737c1ff..f99b64ca1303 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1804,10 +1804,15 @@ static int insert_pfn(struct vm_area_struct *vma, unsigned long addr, * in may not match the PFN we have mapped if the * mapped PFN is a writeable COW page. In the mkwrite * case we are creating a writable PTE for a shared - * mapping and we expect the PFNs to match. + * mapping and we expect the PFNs to match. If they + * don't match, we are likely racing with block + * allocation and mapping invalidation so just skip the + * update. */ - if (WARN_ON_ONCE(pte_pfn(*pte) != pfn_t_to_pfn(pfn))) + if (pte_pfn(*pte) != pfn_t_to_pfn(pfn)) { + WARN_ON_ONCE(!is_zero_pfn(pte_pfn(*pte))); goto out_unlock; + } entry = *pte; goto out_mkwrite; } else -- GitLab From 22f36db48781d0db6a01ee0113265984990c1a8e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 29 Apr 2019 15:56:26 +0200 Subject: [PATCH 0292/1121] Revert "block/loop: Use global lock for ioctl() operation." This reverts commit 57da9a9742200f391d1cf93fea389f7ddc25ec9a which is commit 310ca162d779efee8a2dc3731439680f3e9c1e86 upstream. Jan Kara has reported seeing problems with this patch applied, as has Salvatore Bonaccorso, so let's drop it for now. Reported-by: Salvatore Bonaccorso Reported-by: Jan Kara Cc: Tetsuo Handa Cc: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- drivers/block/loop.c | 58 ++++++++++++++++++++++---------------------- drivers/block/loop.h | 1 + 2 files changed, 30 insertions(+), 29 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 24a3fb35614f..bd447de4a5b8 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -82,7 +82,6 @@ static DEFINE_IDR(loop_index_idr); static DEFINE_MUTEX(loop_index_mutex); -static DEFINE_MUTEX(loop_ctl_mutex); static int max_part; static int part_shift; @@ -1019,7 +1018,7 @@ static int loop_clr_fd(struct loop_device *lo) */ if (atomic_read(&lo->lo_refcnt) > 1) { lo->lo_flags |= LO_FLAGS_AUTOCLEAR; - mutex_unlock(&loop_ctl_mutex); + mutex_unlock(&lo->lo_ctl_mutex); return 0; } @@ -1071,12 +1070,12 @@ static int loop_clr_fd(struct loop_device *lo) if (!part_shift) lo->lo_disk->flags |= GENHD_FL_NO_PART_SCAN; loop_unprepare_queue(lo); - mutex_unlock(&loop_ctl_mutex); + mutex_unlock(&lo->lo_ctl_mutex); /* - * Need not hold loop_ctl_mutex to fput backing file. - * Calling fput holding loop_ctl_mutex triggers a circular + * Need not hold lo_ctl_mutex to fput backing file. + * Calling fput holding lo_ctl_mutex triggers a circular * lock dependency possibility warning as fput can take - * bd_mutex which is usually taken before loop_ctl_mutex. + * bd_mutex which is usually taken before lo_ctl_mutex. */ fput(filp); return 0; @@ -1195,7 +1194,7 @@ loop_get_status(struct loop_device *lo, struct loop_info64 *info) int ret; if (lo->lo_state != Lo_bound) { - mutex_unlock(&loop_ctl_mutex); + mutex_unlock(&lo->lo_ctl_mutex); return -ENXIO; } @@ -1214,10 +1213,10 @@ loop_get_status(struct loop_device *lo, struct loop_info64 *info) lo->lo_encrypt_key_size); } - /* Drop loop_ctl_mutex while we call into the filesystem. */ + /* Drop lo_ctl_mutex while we call into the filesystem. */ path = lo->lo_backing_file->f_path; path_get(&path); - mutex_unlock(&loop_ctl_mutex); + mutex_unlock(&lo->lo_ctl_mutex); ret = vfs_getattr(&path, &stat, STATX_INO, AT_STATX_SYNC_AS_STAT); if (!ret) { info->lo_device = huge_encode_dev(stat.dev); @@ -1309,7 +1308,7 @@ loop_get_status_old(struct loop_device *lo, struct loop_info __user *arg) { int err; if (!arg) { - mutex_unlock(&loop_ctl_mutex); + mutex_unlock(&lo->lo_ctl_mutex); return -EINVAL; } err = loop_get_status(lo, &info64); @@ -1327,7 +1326,7 @@ loop_get_status64(struct loop_device *lo, struct loop_info64 __user *arg) { int err; if (!arg) { - mutex_unlock(&loop_ctl_mutex); + mutex_unlock(&lo->lo_ctl_mutex); return -EINVAL; } err = loop_get_status(lo, &info64); @@ -1402,7 +1401,7 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode, struct loop_device *lo = bdev->bd_disk->private_data; int err; - mutex_lock_nested(&loop_ctl_mutex, 1); + mutex_lock_nested(&lo->lo_ctl_mutex, 1); switch (cmd) { case LOOP_SET_FD: err = loop_set_fd(lo, mode, bdev, arg); @@ -1411,7 +1410,7 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode, err = loop_change_fd(lo, bdev, arg); break; case LOOP_CLR_FD: - /* loop_clr_fd would have unlocked loop_ctl_mutex on success */ + /* loop_clr_fd would have unlocked lo_ctl_mutex on success */ err = loop_clr_fd(lo); if (!err) goto out_unlocked; @@ -1424,7 +1423,7 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode, break; case LOOP_GET_STATUS: err = loop_get_status_old(lo, (struct loop_info __user *) arg); - /* loop_get_status() unlocks loop_ctl_mutex */ + /* loop_get_status() unlocks lo_ctl_mutex */ goto out_unlocked; case LOOP_SET_STATUS64: err = -EPERM; @@ -1434,7 +1433,7 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode, break; case LOOP_GET_STATUS64: err = loop_get_status64(lo, (struct loop_info64 __user *) arg); - /* loop_get_status() unlocks loop_ctl_mutex */ + /* loop_get_status() unlocks lo_ctl_mutex */ goto out_unlocked; case LOOP_SET_CAPACITY: err = -EPERM; @@ -1454,7 +1453,7 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode, default: err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL; } - mutex_unlock(&loop_ctl_mutex); + mutex_unlock(&lo->lo_ctl_mutex); out_unlocked: return err; @@ -1571,7 +1570,7 @@ loop_get_status_compat(struct loop_device *lo, int err; if (!arg) { - mutex_unlock(&loop_ctl_mutex); + mutex_unlock(&lo->lo_ctl_mutex); return -EINVAL; } err = loop_get_status(lo, &info64); @@ -1588,16 +1587,16 @@ static int lo_compat_ioctl(struct block_device *bdev, fmode_t mode, switch(cmd) { case LOOP_SET_STATUS: - mutex_lock(&loop_ctl_mutex); + mutex_lock(&lo->lo_ctl_mutex); err = loop_set_status_compat( lo, (const struct compat_loop_info __user *) arg); - mutex_unlock(&loop_ctl_mutex); + mutex_unlock(&lo->lo_ctl_mutex); break; case LOOP_GET_STATUS: - mutex_lock(&loop_ctl_mutex); + mutex_lock(&lo->lo_ctl_mutex); err = loop_get_status_compat( lo, (struct compat_loop_info __user *) arg); - /* loop_get_status() unlocks loop_ctl_mutex */ + /* loop_get_status() unlocks lo_ctl_mutex */ break; case LOOP_SET_CAPACITY: case LOOP_CLR_FD: @@ -1641,7 +1640,7 @@ static void __lo_release(struct loop_device *lo) if (atomic_dec_return(&lo->lo_refcnt)) return; - mutex_lock(&loop_ctl_mutex); + mutex_lock(&lo->lo_ctl_mutex); if (lo->lo_flags & LO_FLAGS_AUTOCLEAR) { /* * In autoclear mode, stop the loop thread @@ -1659,7 +1658,7 @@ static void __lo_release(struct loop_device *lo) blk_mq_unfreeze_queue(lo->lo_queue); } - mutex_unlock(&loop_ctl_mutex); + mutex_unlock(&lo->lo_ctl_mutex); } static void lo_release(struct gendisk *disk, fmode_t mode) @@ -1705,10 +1704,10 @@ static int unregister_transfer_cb(int id, void *ptr, void *data) struct loop_device *lo = ptr; struct loop_func_table *xfer = data; - mutex_lock(&loop_ctl_mutex); + mutex_lock(&lo->lo_ctl_mutex); if (lo->lo_encryption == xfer) loop_release_xfer(lo); - mutex_unlock(&loop_ctl_mutex); + mutex_unlock(&lo->lo_ctl_mutex); return 0; } @@ -1881,6 +1880,7 @@ static int loop_add(struct loop_device **l, int i) if (!part_shift) disk->flags |= GENHD_FL_NO_PART_SCAN; disk->flags |= GENHD_FL_EXT_DEVT; + mutex_init(&lo->lo_ctl_mutex); atomic_set(&lo->lo_refcnt, 0); lo->lo_number = i; spin_lock_init(&lo->lo_lock); @@ -1993,19 +1993,19 @@ static long loop_control_ioctl(struct file *file, unsigned int cmd, ret = loop_lookup(&lo, parm); if (ret < 0) break; - mutex_lock(&loop_ctl_mutex); + mutex_lock(&lo->lo_ctl_mutex); if (lo->lo_state != Lo_unbound) { ret = -EBUSY; - mutex_unlock(&loop_ctl_mutex); + mutex_unlock(&lo->lo_ctl_mutex); break; } if (atomic_read(&lo->lo_refcnt) > 0) { ret = -EBUSY; - mutex_unlock(&loop_ctl_mutex); + mutex_unlock(&lo->lo_ctl_mutex); break; } lo->lo_disk->private_data = NULL; - mutex_unlock(&loop_ctl_mutex); + mutex_unlock(&lo->lo_ctl_mutex); idr_remove(&loop_index_idr, lo->lo_number); loop_remove(lo); break; diff --git a/drivers/block/loop.h b/drivers/block/loop.h index b2251752452b..dfc54ceba410 100644 --- a/drivers/block/loop.h +++ b/drivers/block/loop.h @@ -54,6 +54,7 @@ struct loop_device { spinlock_t lo_lock; int lo_state; + struct mutex lo_ctl_mutex; struct kthread_worker worker; struct task_struct *worker_task; bool use_dio; -- GitLab From 748ed75029ebd0433d02eb97839fe6a08479ee4b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 24 Apr 2019 08:04:05 -0700 Subject: [PATCH 0293/1121] ipv4: add sanity checks in ipv4_link_failure() [ Upstream commit 20ff83f10f113c88d0bb74589389b05250994c16 ] Before calling __ip_options_compile(), we need to ensure the network header is a an IPv4 one, and that it is already pulled in skb->head. RAW sockets going through a tunnel can end up calling ipv4_link_failure() with total garbage in the skb, or arbitrary lengthes. syzbot report : BUG: KASAN: stack-out-of-bounds in memcpy include/linux/string.h:355 [inline] BUG: KASAN: stack-out-of-bounds in __ip_options_echo+0x294/0x1120 net/ipv4/ip_options.c:123 Write of size 69 at addr ffff888096abf068 by task syz-executor.4/9204 CPU: 0 PID: 9204 Comm: syz-executor.4 Not tainted 5.1.0-rc5+ #77 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x172/0x1f0 lib/dump_stack.c:113 print_address_description.cold+0x7c/0x20d mm/kasan/report.c:187 kasan_report.cold+0x1b/0x40 mm/kasan/report.c:317 check_memory_region_inline mm/kasan/generic.c:185 [inline] check_memory_region+0x123/0x190 mm/kasan/generic.c:191 memcpy+0x38/0x50 mm/kasan/common.c:133 memcpy include/linux/string.h:355 [inline] __ip_options_echo+0x294/0x1120 net/ipv4/ip_options.c:123 __icmp_send+0x725/0x1400 net/ipv4/icmp.c:695 ipv4_link_failure+0x29f/0x550 net/ipv4/route.c:1204 dst_link_failure include/net/dst.h:427 [inline] vti6_xmit net/ipv6/ip6_vti.c:514 [inline] vti6_tnl_xmit+0x10d4/0x1c0c net/ipv6/ip6_vti.c:553 __netdev_start_xmit include/linux/netdevice.h:4414 [inline] netdev_start_xmit include/linux/netdevice.h:4423 [inline] xmit_one net/core/dev.c:3292 [inline] dev_hard_start_xmit+0x1b2/0x980 net/core/dev.c:3308 __dev_queue_xmit+0x271d/0x3060 net/core/dev.c:3878 dev_queue_xmit+0x18/0x20 net/core/dev.c:3911 neigh_direct_output+0x16/0x20 net/core/neighbour.c:1527 neigh_output include/net/neighbour.h:508 [inline] ip_finish_output2+0x949/0x1740 net/ipv4/ip_output.c:229 ip_finish_output+0x73c/0xd50 net/ipv4/ip_output.c:317 NF_HOOK_COND include/linux/netfilter.h:278 [inline] ip_output+0x21f/0x670 net/ipv4/ip_output.c:405 dst_output include/net/dst.h:444 [inline] NF_HOOK include/linux/netfilter.h:289 [inline] raw_send_hdrinc net/ipv4/raw.c:432 [inline] raw_sendmsg+0x1d2b/0x2f20 net/ipv4/raw.c:663 inet_sendmsg+0x147/0x5d0 net/ipv4/af_inet.c:798 sock_sendmsg_nosec net/socket.c:651 [inline] sock_sendmsg+0xdd/0x130 net/socket.c:661 sock_write_iter+0x27c/0x3e0 net/socket.c:988 call_write_iter include/linux/fs.h:1866 [inline] new_sync_write+0x4c7/0x760 fs/read_write.c:474 __vfs_write+0xe4/0x110 fs/read_write.c:487 vfs_write+0x20c/0x580 fs/read_write.c:549 ksys_write+0x14f/0x2d0 fs/read_write.c:599 __do_sys_write fs/read_write.c:611 [inline] __se_sys_write fs/read_write.c:608 [inline] __x64_sys_write+0x73/0xb0 fs/read_write.c:608 do_syscall_64+0x103/0x610 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x49/0xbe RIP: 0033:0x458c29 Code: ad b8 fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 7b b8 fb ff c3 66 2e 0f 1f 84 00 00 00 00 RSP: 002b:00007f293b44bc78 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 0000000000458c29 RDX: 0000000000000014 RSI: 00000000200002c0 RDI: 0000000000000003 RBP: 000000000073bf00 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 00007f293b44c6d4 R13: 00000000004c8623 R14: 00000000004ded68 R15: 00000000ffffffff The buggy address belongs to the page: page:ffffea00025aafc0 count:0 mapcount:0 mapping:0000000000000000 index:0x0 flags: 0x1fffc0000000000() raw: 01fffc0000000000 0000000000000000 ffffffff025a0101 0000000000000000 raw: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000 page dumped because: kasan: bad access detected Memory state around the buggy address: ffff888096abef80: 00 00 00 f2 f2 f2 f2 f2 00 00 00 00 00 00 00 f2 ffff888096abf000: f2 f2 f2 f2 00 00 00 00 00 00 00 00 00 00 00 00 >ffff888096abf080: 00 00 f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 ^ ffff888096abf100: 00 00 00 00 f1 f1 f1 f1 00 00 f3 f3 00 00 00 00 ffff888096abf180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Fixes: ed0de45a1008 ("ipv4: recompile ip options in ipv4_link_failure") Signed-off-by: Eric Dumazet Cc: Stephen Suryaputra Acked-by: Willem de Bruijn Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/ipv4/route.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index c64f062d6323..6a7e187dd0a9 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1192,25 +1192,39 @@ static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie) return dst; } -static void ipv4_link_failure(struct sk_buff *skb) +static void ipv4_send_dest_unreach(struct sk_buff *skb) { struct ip_options opt; - struct rtable *rt; int res; /* Recompile ip options since IPCB may not be valid anymore. + * Also check we have a reasonable ipv4 header. */ - memset(&opt, 0, sizeof(opt)); - opt.optlen = ip_hdr(skb)->ihl*4 - sizeof(struct iphdr); + if (!pskb_network_may_pull(skb, sizeof(struct iphdr)) || + ip_hdr(skb)->version != 4 || ip_hdr(skb)->ihl < 5) + return; - rcu_read_lock(); - res = __ip_options_compile(dev_net(skb->dev), &opt, skb, NULL); - rcu_read_unlock(); + memset(&opt, 0, sizeof(opt)); + if (ip_hdr(skb)->ihl > 5) { + if (!pskb_network_may_pull(skb, ip_hdr(skb)->ihl * 4)) + return; + opt.optlen = ip_hdr(skb)->ihl * 4 - sizeof(struct iphdr); - if (res) - return; + rcu_read_lock(); + res = __ip_options_compile(dev_net(skb->dev), &opt, skb, NULL); + rcu_read_unlock(); + if (res) + return; + } __icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0, &opt); +} + +static void ipv4_link_failure(struct sk_buff *skb) +{ + struct rtable *rt; + + ipv4_send_dest_unreach(skb); rt = skb_rtable(skb); if (rt) -- GitLab From 3ff13dbace24a9fa8595e278290d6ff3aab2b0d7 Mon Sep 17 00:00:00 2001 From: Amit Cohen Date: Thu, 18 Apr 2019 07:14:16 +0000 Subject: [PATCH 0294/1121] mlxsw: spectrum: Fix autoneg status in ethtool [ Upstream commit 151f0dddbbfe4c35c9c5b64873115aafd436af9d ] If link is down and autoneg is set to on/off, the status in ethtool does not change. The reason is when the link is down the function returns with zero before changing autoneg value. Move the checking of link state (up/down) to be performed after setting autoneg value, in order to be sure that autoneg will change in any case. Fixes: 56ade8fe3fe1 ("mlxsw: spectrum: Add initial support for Spectrum ASIC") Signed-off-by: Amit Cohen Signed-off-by: Ido Schimmel Acked-by: Jiri Pirko Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c index 29d37355d8c6..ab09f9e43c79 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c @@ -2521,11 +2521,11 @@ mlxsw_sp_port_set_link_ksettings(struct net_device *dev, if (err) return err; + mlxsw_sp_port->link.autoneg = autoneg; + if (!netif_running(dev)) return 0; - mlxsw_sp_port->link.autoneg = autoneg; - mlxsw_sp_port_admin_status_set(mlxsw_sp_port, false); mlxsw_sp_port_admin_status_set(mlxsw_sp_port, true); -- GitLab From 6af464bfd6c444f32090ce5a6279c774e87a8472 Mon Sep 17 00:00:00 2001 From: Erez Alfasi Date: Thu, 11 Apr 2019 10:41:03 +0300 Subject: [PATCH 0295/1121] net/mlx5e: ethtool, Remove unsupported SFP EEPROM high pages query [ Upstream commit ace329f4ab3ba434be2adf618073c752d083b524 ] Querying EEPROM high pages data for SFP module is currently not supported by our driver and yet queried, resulting in invalid FW queries. Set the EEPROM ethtool data length to 256 for SFP module will limit the reading for page 0 only and prevent invalid FW queries. Fixes: bb64143eee8c ("net/mlx5e: Add ethtool support for dump module EEPROM") Signed-off-by: Erez Alfasi Signed-off-by: Saeed Mahameed Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c | 2 +- drivers/net/ethernet/mellanox/mlx5/core/port.c | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c index d9db3ad3d765..26ad27b3f687 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c @@ -1622,7 +1622,7 @@ static int mlx5e_get_module_info(struct net_device *netdev, break; case MLX5_MODULE_ID_SFP: modinfo->type = ETH_MODULE_SFF_8472; - modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN; + modinfo->eeprom_len = MLX5_EEPROM_PAGE_LENGTH; break; default: netdev_err(priv->netdev, "%s: cable type not recognized:0x%x\n", diff --git a/drivers/net/ethernet/mellanox/mlx5/core/port.c b/drivers/net/ethernet/mellanox/mlx5/core/port.c index ccb6287aeeb7..1d2bb7fa68b1 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/port.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/port.c @@ -392,10 +392,6 @@ int mlx5_query_module_eeprom(struct mlx5_core_dev *dev, size -= offset + size - MLX5_EEPROM_PAGE_LENGTH; i2c_addr = MLX5_I2C_ADDR_LOW; - if (offset >= MLX5_EEPROM_PAGE_LENGTH) { - i2c_addr = MLX5_I2C_ADDR_HIGH; - offset -= MLX5_EEPROM_PAGE_LENGTH; - } MLX5_SET(mcia_reg, in, l, 0); MLX5_SET(mcia_reg, in, module, module_num); -- GitLab From 8dcab85a9af5ef2d26ec690a82b3dcce4e1bd0bd Mon Sep 17 00:00:00 2001 From: Zhu Yanjun Date: Wed, 24 Apr 2019 02:56:42 -0400 Subject: [PATCH 0296/1121] net: rds: exchange of 8K and 1M pool [ Upstream commit 4b9fc7146249a6e0e3175d0acc033fdcd2bfcb17 ] Before the commit 490ea5967b0d ("RDS: IB: move FMR code to its own file"), when the dirty_count is greater than 9/10 of max_items of 8K pool, 1M pool is used, Vice versa. After the commit 490ea5967b0d ("RDS: IB: move FMR code to its own file"), the above is removed. When we make the following tests. Server: rds-stress -r 1.1.1.16 -D 1M Client: rds-stress -r 1.1.1.14 -s 1.1.1.16 -D 1M The following will appear. " connecting to 1.1.1.16:4000 negotiated options, tasks will start in 2 seconds Starting up..header from 1.1.1.166:4001 to id 4001 bogus .. tsks tx/s rx/s tx+rx K/s mbi K/s mbo K/s tx us/c rtt us cpu % 1 0 0 0.00 0.00 0.00 0.00 0.00 -1.00 1 0 0 0.00 0.00 0.00 0.00 0.00 -1.00 1 0 0 0.00 0.00 0.00 0.00 0.00 -1.00 1 0 0 0.00 0.00 0.00 0.00 0.00 -1.00 1 0 0 0.00 0.00 0.00 0.00 0.00 -1.00 ... " So this exchange between 8K and 1M pool is added back. Fixes: commit 490ea5967b0d ("RDS: IB: move FMR code to its own file") Signed-off-by: Zhu Yanjun Acked-by: Santosh Shilimkar Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/rds/ib_fmr.c | 11 +++++++++++ net/rds/ib_rdma.c | 3 --- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/net/rds/ib_fmr.c b/net/rds/ib_fmr.c index 86ef907067bb..353b59d3bd44 100644 --- a/net/rds/ib_fmr.c +++ b/net/rds/ib_fmr.c @@ -44,6 +44,17 @@ struct rds_ib_mr *rds_ib_alloc_fmr(struct rds_ib_device *rds_ibdev, int npages) else pool = rds_ibdev->mr_1m_pool; + if (atomic_read(&pool->dirty_count) >= pool->max_items / 10) + queue_delayed_work(rds_ib_mr_wq, &pool->flush_worker, 10); + + /* Switch pools if one of the pool is reaching upper limit */ + if (atomic_read(&pool->dirty_count) >= pool->max_items * 9 / 10) { + if (pool->pool_type == RDS_IB_MR_8K_POOL) + pool = rds_ibdev->mr_1m_pool; + else + pool = rds_ibdev->mr_8k_pool; + } + ibmr = rds_ib_try_reuse_ibmr(pool); if (ibmr) return ibmr; diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c index 9a3c54e659e9..fe5d2e8a95d9 100644 --- a/net/rds/ib_rdma.c +++ b/net/rds/ib_rdma.c @@ -442,9 +442,6 @@ struct rds_ib_mr *rds_ib_try_reuse_ibmr(struct rds_ib_mr_pool *pool) struct rds_ib_mr *ibmr = NULL; int iter = 0; - if (atomic_read(&pool->dirty_count) >= pool->max_items_soft / 10) - queue_delayed_work(rds_ib_mr_wq, &pool->flush_worker, 10); - while (1) { ibmr = rds_ib_reuse_mr(pool); if (ibmr) -- GitLab From 6653b30930d1f04a24c6de2fd9d65c953193d738 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Mon, 22 Apr 2019 15:15:32 +0530 Subject: [PATCH 0297/1121] net: stmmac: move stmmac_check_ether_addr() to driver probe [ Upstream commit b561af36b1841088552464cdc3f6371d92f17710 ] stmmac_check_ether_addr() checks the MAC address and assigns one in driver open(). In many cases when we create slave netdevice, the dev addr is inherited from master but the master dev addr maybe NULL at that time, so move this call to driver probe so that address is always valid. Signed-off-by: Xiaofei Shen Tested-by: Xiaofei Shen Signed-off-by: Sneh Shah Signed-off-by: Vinod Koul Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index f2429ec07b57..ecf3f8c1bc0e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -2582,8 +2582,6 @@ static int stmmac_open(struct net_device *dev) struct stmmac_priv *priv = netdev_priv(dev); int ret; - stmmac_check_ether_addr(priv); - if (priv->hw->pcs != STMMAC_PCS_RGMII && priv->hw->pcs != STMMAC_PCS_TBI && priv->hw->pcs != STMMAC_PCS_RTBI) { @@ -4213,6 +4211,8 @@ int stmmac_dvr_probe(struct device *device, if (ret) goto error_hw_init; + stmmac_check_ether_addr(priv); + /* Configure real RX and TX queues */ netif_set_real_num_rx_queues(ndev, priv->plat->rx_queues_to_use); netif_set_real_num_tx_queues(ndev, priv->plat->tx_queues_to_use); -- GitLab From 5f81c74b1f2ec834ae95db6898c7ef5320283f6a Mon Sep 17 00:00:00 2001 From: Su Bao Cheng Date: Thu, 18 Apr 2019 11:14:56 +0200 Subject: [PATCH 0298/1121] stmmac: pci: Adjust IOT2000 matching [ Upstream commit e0c1d14a1a3211dccf0540a6703ffbd5d2a75bdb ] Since there are more IOT2040 variants with identical hardware but different asset tags, the asset tag matching should be adjusted to support them. For the board name "SIMATIC IOT2000", currently there are 2 types of hardware, IOT2020 and IOT2040. The IOT2020 is identified by its unique asset tag. Match on it first. If we then match on the board name only, we will catch all IOT2040 variants. In the future there will be no other devices with the "SIMATIC IOT2000" DMI board name but different hardware. Signed-off-by: Su Bao Cheng Reviewed-by: Jan Kiszka Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c index d819e8eaba12..cc1e887e47b5 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c @@ -159,6 +159,12 @@ static const struct dmi_system_id quark_pci_dmi[] = { }, .driver_data = (void *)&galileo_stmmac_dmi_data, }, + /* + * There are 2 types of SIMATIC IOT2000: IOT20202 and IOT2040. + * The asset tag "6ES7647-0AA00-0YA2" is only for IOT2020 which + * has only one pci network device while other asset tags are + * for IOT2040 which has two. + */ { .matches = { DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"), @@ -170,8 +176,6 @@ static const struct dmi_system_id quark_pci_dmi[] = { { .matches = { DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"), - DMI_EXACT_MATCH(DMI_BOARD_ASSET_TAG, - "6ES7647-0AA00-1YA2"), }, .driver_data = (void *)&iot2040_stmmac_dmi_data, }, -- GitLab From edd3e48b4e5cd66c4814895d8a7813cc5f6a312b Mon Sep 17 00:00:00 2001 From: Hangbin Liu Date: Fri, 19 Apr 2019 14:31:00 +0800 Subject: [PATCH 0299/1121] team: fix possible recursive locking when add slaves [ Upstream commit 925b0c841e066b488cc3a60272472b2c56300704 ] If we add a bond device which is already the master of the team interface, we will hold the team->lock in team_add_slave() first and then request the lock in team_set_mac_address() again. The functions are called like: - team_add_slave() - team_port_add() - team_port_enter() - team_modeop_port_enter() - __set_port_dev_addr() - dev_set_mac_address() - bond_set_mac_address() - dev_set_mac_address() - team_set_mac_address Although team_upper_dev_link() would check the upper devices but it is called too late. Fix it by adding a checking before processing the slave. v2: Do not split the string in netdev_err() Fixes: 3d249d4ca7d0 ("net: introduce ethernet teaming device") Acked-by: Jiri Pirko Signed-off-by: Hangbin Liu Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/team/team.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index fea141e71705..e9a92ed5a308 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -1157,6 +1157,12 @@ static int team_port_add(struct team *team, struct net_device *port_dev) return -EINVAL; } + if (netdev_has_upper_dev(dev, port_dev)) { + netdev_err(dev, "Device %s is already an upper device of the team interface\n", + portname); + return -EBUSY; + } + if (port_dev->features & NETIF_F_VLAN_CHALLENGED && vlan_uses_dev(dev)) { netdev_err(dev, "Device %s is VLAN challenged and team device has VLAN set up\n", -- GitLab From 0cf41a93387a4db81ff499af52217305e7cb8f1a Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Mon, 16 Oct 2017 17:28:47 -0700 Subject: [PATCH 0300/1121] net/rose: Convert timers to use timer_setup() commit 4966babd904d7f8e9e20735f3637a98fd7ca538c upstream. In preparation for unconditionally passing the struct timer_list pointer to all timer callbacks, switch to using the new timer_setup() and from_timer() to pass the timer pointer explicitly. Cc: Ralf Baechle Cc: "David S. Miller" Cc: linux-hams@vger.kernel.org Cc: netdev@vger.kernel.org Signed-off-by: Kees Cook Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/rose/af_rose.c | 17 +++++++++-------- net/rose/rose_link.c | 16 +++++++--------- net/rose/rose_loopback.c | 9 +++------ net/rose/rose_route.c | 8 ++++---- net/rose/rose_timer.c | 30 +++++++++++++----------------- 5 files changed, 36 insertions(+), 44 deletions(-) diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index 4a9729257023..6a5c4992cf61 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c @@ -318,9 +318,11 @@ void rose_destroy_socket(struct sock *); /* * Handler for deferred kills. */ -static void rose_destroy_timer(unsigned long data) +static void rose_destroy_timer(struct timer_list *t) { - rose_destroy_socket((struct sock *)data); + struct sock *sk = from_timer(sk, t, sk_timer); + + rose_destroy_socket(sk); } /* @@ -353,8 +355,7 @@ void rose_destroy_socket(struct sock *sk) if (sk_has_allocations(sk)) { /* Defer: outstanding buffers */ - setup_timer(&sk->sk_timer, rose_destroy_timer, - (unsigned long)sk); + timer_setup(&sk->sk_timer, rose_destroy_timer, 0); sk->sk_timer.expires = jiffies + 10 * HZ; add_timer(&sk->sk_timer); } else @@ -538,8 +539,8 @@ static int rose_create(struct net *net, struct socket *sock, int protocol, sock->ops = &rose_proto_ops; sk->sk_protocol = protocol; - init_timer(&rose->timer); - init_timer(&rose->idletimer); + timer_setup(&rose->timer, NULL, 0); + timer_setup(&rose->idletimer, NULL, 0); rose->t1 = msecs_to_jiffies(sysctl_rose_call_request_timeout); rose->t2 = msecs_to_jiffies(sysctl_rose_reset_request_timeout); @@ -582,8 +583,8 @@ static struct sock *rose_make_new(struct sock *osk) sk->sk_state = TCP_ESTABLISHED; sock_copy_flags(sk, osk); - init_timer(&rose->timer); - init_timer(&rose->idletimer); + timer_setup(&rose->timer, NULL, 0); + timer_setup(&rose->idletimer, NULL, 0); orose = rose_sk(osk); rose->t1 = orose->t1; diff --git a/net/rose/rose_link.c b/net/rose/rose_link.c index c76638cc2cd5..cda4c6678ef1 100644 --- a/net/rose/rose_link.c +++ b/net/rose/rose_link.c @@ -27,8 +27,8 @@ #include #include -static void rose_ftimer_expiry(unsigned long); -static void rose_t0timer_expiry(unsigned long); +static void rose_ftimer_expiry(struct timer_list *); +static void rose_t0timer_expiry(struct timer_list *); static void rose_transmit_restart_confirmation(struct rose_neigh *neigh); static void rose_transmit_restart_request(struct rose_neigh *neigh); @@ -37,8 +37,7 @@ void rose_start_ftimer(struct rose_neigh *neigh) { del_timer(&neigh->ftimer); - neigh->ftimer.data = (unsigned long)neigh; - neigh->ftimer.function = &rose_ftimer_expiry; + neigh->ftimer.function = (TIMER_FUNC_TYPE)rose_ftimer_expiry; neigh->ftimer.expires = jiffies + msecs_to_jiffies(sysctl_rose_link_fail_timeout); @@ -49,8 +48,7 @@ static void rose_start_t0timer(struct rose_neigh *neigh) { del_timer(&neigh->t0timer); - neigh->t0timer.data = (unsigned long)neigh; - neigh->t0timer.function = &rose_t0timer_expiry; + neigh->t0timer.function = (TIMER_FUNC_TYPE)rose_t0timer_expiry; neigh->t0timer.expires = jiffies + msecs_to_jiffies(sysctl_rose_restart_request_timeout); @@ -77,13 +75,13 @@ static int rose_t0timer_running(struct rose_neigh *neigh) return timer_pending(&neigh->t0timer); } -static void rose_ftimer_expiry(unsigned long param) +static void rose_ftimer_expiry(struct timer_list *t) { } -static void rose_t0timer_expiry(unsigned long param) +static void rose_t0timer_expiry(struct timer_list *t) { - struct rose_neigh *neigh = (struct rose_neigh *)param; + struct rose_neigh *neigh = from_timer(neigh, t, t0timer); rose_transmit_restart_request(neigh); diff --git a/net/rose/rose_loopback.c b/net/rose/rose_loopback.c index 344456206b70..7af4f99c4a93 100644 --- a/net/rose/rose_loopback.c +++ b/net/rose/rose_loopback.c @@ -19,12 +19,13 @@ static struct sk_buff_head loopback_queue; static struct timer_list loopback_timer; static void rose_set_loopback_timer(void); +static void rose_loopback_timer(struct timer_list *unused); void rose_loopback_init(void) { skb_queue_head_init(&loopback_queue); - init_timer(&loopback_timer); + timer_setup(&loopback_timer, rose_loopback_timer, 0); } static int rose_loopback_running(void) @@ -50,20 +51,16 @@ int rose_loopback_queue(struct sk_buff *skb, struct rose_neigh *neigh) return 1; } -static void rose_loopback_timer(unsigned long); static void rose_set_loopback_timer(void) { del_timer(&loopback_timer); - loopback_timer.data = 0; - loopback_timer.function = &rose_loopback_timer; loopback_timer.expires = jiffies + 10; - add_timer(&loopback_timer); } -static void rose_loopback_timer(unsigned long param) +static void rose_loopback_timer(struct timer_list *unused) { struct sk_buff *skb; struct net_device *dev; diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c index 2741abec7ee7..d94d6110bb1c 100644 --- a/net/rose/rose_route.c +++ b/net/rose/rose_route.c @@ -104,8 +104,8 @@ static int __must_check rose_add_node(struct rose_route_struct *rose_route, skb_queue_head_init(&rose_neigh->queue); - init_timer(&rose_neigh->ftimer); - init_timer(&rose_neigh->t0timer); + timer_setup(&rose_neigh->ftimer, NULL, 0); + timer_setup(&rose_neigh->t0timer, NULL, 0); if (rose_route->ndigis != 0) { rose_neigh->digipeat = @@ -390,8 +390,8 @@ void rose_add_loopback_neigh(void) skb_queue_head_init(&sn->queue); - init_timer(&sn->ftimer); - init_timer(&sn->t0timer); + timer_setup(&sn->ftimer, NULL, 0); + timer_setup(&sn->t0timer, NULL, 0); spin_lock_bh(&rose_neigh_list_lock); sn->next = rose_neigh_list; diff --git a/net/rose/rose_timer.c b/net/rose/rose_timer.c index bc5469d6d9cb..3b89d66f15bb 100644 --- a/net/rose/rose_timer.c +++ b/net/rose/rose_timer.c @@ -29,8 +29,8 @@ #include static void rose_heartbeat_expiry(unsigned long); -static void rose_timer_expiry(unsigned long); -static void rose_idletimer_expiry(unsigned long); +static void rose_timer_expiry(struct timer_list *); +static void rose_idletimer_expiry(struct timer_list *); void rose_start_heartbeat(struct sock *sk) { @@ -49,8 +49,7 @@ void rose_start_t1timer(struct sock *sk) del_timer(&rose->timer); - rose->timer.data = (unsigned long)sk; - rose->timer.function = &rose_timer_expiry; + rose->timer.function = (TIMER_FUNC_TYPE)rose_timer_expiry; rose->timer.expires = jiffies + rose->t1; add_timer(&rose->timer); @@ -62,8 +61,7 @@ void rose_start_t2timer(struct sock *sk) del_timer(&rose->timer); - rose->timer.data = (unsigned long)sk; - rose->timer.function = &rose_timer_expiry; + rose->timer.function = (TIMER_FUNC_TYPE)rose_timer_expiry; rose->timer.expires = jiffies + rose->t2; add_timer(&rose->timer); @@ -75,8 +73,7 @@ void rose_start_t3timer(struct sock *sk) del_timer(&rose->timer); - rose->timer.data = (unsigned long)sk; - rose->timer.function = &rose_timer_expiry; + rose->timer.function = (TIMER_FUNC_TYPE)rose_timer_expiry; rose->timer.expires = jiffies + rose->t3; add_timer(&rose->timer); @@ -88,8 +85,7 @@ void rose_start_hbtimer(struct sock *sk) del_timer(&rose->timer); - rose->timer.data = (unsigned long)sk; - rose->timer.function = &rose_timer_expiry; + rose->timer.function = (TIMER_FUNC_TYPE)rose_timer_expiry; rose->timer.expires = jiffies + rose->hb; add_timer(&rose->timer); @@ -102,8 +98,7 @@ void rose_start_idletimer(struct sock *sk) del_timer(&rose->idletimer); if (rose->idle > 0) { - rose->idletimer.data = (unsigned long)sk; - rose->idletimer.function = &rose_idletimer_expiry; + rose->idletimer.function = (TIMER_FUNC_TYPE)rose_idletimer_expiry; rose->idletimer.expires = jiffies + rose->idle; add_timer(&rose->idletimer); @@ -163,10 +158,10 @@ static void rose_heartbeat_expiry(unsigned long param) bh_unlock_sock(sk); } -static void rose_timer_expiry(unsigned long param) +static void rose_timer_expiry(struct timer_list *t) { - struct sock *sk = (struct sock *)param; - struct rose_sock *rose = rose_sk(sk); + struct rose_sock *rose = from_timer(rose, t, timer); + struct sock *sk = &rose->sock; bh_lock_sock(sk); switch (rose->state) { @@ -192,9 +187,10 @@ static void rose_timer_expiry(unsigned long param) bh_unlock_sock(sk); } -static void rose_idletimer_expiry(unsigned long param) +static void rose_idletimer_expiry(struct timer_list *t) { - struct sock *sk = (struct sock *)param; + struct rose_sock *rose = from_timer(rose, t, idletimer); + struct sock *sk = &rose->sock; bh_lock_sock(sk); rose_clear_queues(sk); -- GitLab From 51ba221aef55daa8102ec2469099ea9b60ae2bfb Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 24 Apr 2019 05:35:00 -0700 Subject: [PATCH 0301/1121] net/rose: fix unbound loop in rose_loopback_timer() [ Upstream commit 0453c682459583910d611a96de928f4442205493 ] This patch adds a limit on the number of skbs that fuzzers can queue into loopback_queue. 1000 packets for rose loopback seems more than enough. Then, since we now have multiple cpus in most linux hosts, we also need to limit the number of skbs rose_loopback_timer() can dequeue at each round. rose_loopback_queue() can be drop-monitor friendly, calling consume_skb() or kfree_skb() appropriately. Finally, use mod_timer() instead of del_timer() + add_timer() syzbot report was : rcu: INFO: rcu_preempt self-detected stall on CPU rcu: 0-...!: (10499 ticks this GP) idle=536/1/0x4000000000000002 softirq=103291/103291 fqs=34 rcu: (t=10500 jiffies g=140321 q=323) rcu: rcu_preempt kthread starved for 10426 jiffies! g140321 f0x0 RCU_GP_WAIT_FQS(5) ->state=0x402 ->cpu=1 rcu: RCU grace-period kthread stack dump: rcu_preempt I29168 10 2 0x80000000 Call Trace: context_switch kernel/sched/core.c:2877 [inline] __schedule+0x813/0x1cc0 kernel/sched/core.c:3518 schedule+0x92/0x180 kernel/sched/core.c:3562 schedule_timeout+0x4db/0xfd0 kernel/time/timer.c:1803 rcu_gp_fqs_loop kernel/rcu/tree.c:1971 [inline] rcu_gp_kthread+0x962/0x17b0 kernel/rcu/tree.c:2128 kthread+0x357/0x430 kernel/kthread.c:253 ret_from_fork+0x3a/0x50 arch/x86/entry/entry_64.S:352 NMI backtrace for cpu 0 CPU: 0 PID: 7632 Comm: kworker/0:4 Not tainted 5.1.0-rc5+ #172 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Workqueue: events iterate_cleanup_work Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x172/0x1f0 lib/dump_stack.c:113 nmi_cpu_backtrace.cold+0x63/0xa4 lib/nmi_backtrace.c:101 nmi_trigger_cpumask_backtrace+0x1be/0x236 lib/nmi_backtrace.c:62 arch_trigger_cpumask_backtrace+0x14/0x20 arch/x86/kernel/apic/hw_nmi.c:38 trigger_single_cpu_backtrace include/linux/nmi.h:164 [inline] rcu_dump_cpu_stacks+0x183/0x1cf kernel/rcu/tree.c:1223 print_cpu_stall kernel/rcu/tree.c:1360 [inline] check_cpu_stall kernel/rcu/tree.c:1434 [inline] rcu_pending kernel/rcu/tree.c:3103 [inline] rcu_sched_clock_irq.cold+0x500/0xa4a kernel/rcu/tree.c:2544 update_process_times+0x32/0x80 kernel/time/timer.c:1635 tick_sched_handle+0xa2/0x190 kernel/time/tick-sched.c:161 tick_sched_timer+0x47/0x130 kernel/time/tick-sched.c:1271 __run_hrtimer kernel/time/hrtimer.c:1389 [inline] __hrtimer_run_queues+0x33e/0xde0 kernel/time/hrtimer.c:1451 hrtimer_interrupt+0x314/0x770 kernel/time/hrtimer.c:1509 local_apic_timer_interrupt arch/x86/kernel/apic/apic.c:1035 [inline] smp_apic_timer_interrupt+0x120/0x570 arch/x86/kernel/apic/apic.c:1060 apic_timer_interrupt+0xf/0x20 arch/x86/entry/entry_64.S:807 RIP: 0010:__sanitizer_cov_trace_pc+0x0/0x50 kernel/kcov.c:95 Code: 89 25 b4 6e ec 08 41 bc f4 ff ff ff e8 cd 5d ea ff 48 c7 05 9e 6e ec 08 00 00 00 00 e9 a4 e9 ff ff 90 90 90 90 90 90 90 90 90 <55> 48 89 e5 48 8b 75 08 65 48 8b 04 25 00 ee 01 00 65 8b 15 c8 60 RSP: 0018:ffff8880ae807ce0 EFLAGS: 00000286 ORIG_RAX: ffffffffffffff13 RAX: ffff88806fd40640 RBX: dffffc0000000000 RCX: ffffffff863fbc56 RDX: 0000000000000100 RSI: ffffffff863fbc1d RDI: ffff88808cf94228 RBP: ffff8880ae807d10 R08: ffff88806fd40640 R09: ffffed1015d00f8b R10: ffffed1015d00f8a R11: 0000000000000003 R12: ffff88808cf941c0 R13: 00000000fffff034 R14: ffff8882166cd840 R15: 0000000000000000 rose_loopback_timer+0x30d/0x3f0 net/rose/rose_loopback.c:91 call_timer_fn+0x190/0x720 kernel/time/timer.c:1325 expire_timers kernel/time/timer.c:1362 [inline] __run_timers kernel/time/timer.c:1681 [inline] __run_timers kernel/time/timer.c:1649 [inline] run_timer_softirq+0x652/0x1700 kernel/time/timer.c:1694 __do_softirq+0x266/0x95a kernel/softirq.c:293 do_softirq_own_stack+0x2a/0x40 arch/x86/entry/entry_64.S:1027 Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Eric Dumazet Reported-by: syzbot Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/rose/rose_loopback.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/net/rose/rose_loopback.c b/net/rose/rose_loopback.c index 7af4f99c4a93..094a6621f8e8 100644 --- a/net/rose/rose_loopback.c +++ b/net/rose/rose_loopback.c @@ -16,6 +16,7 @@ #include static struct sk_buff_head loopback_queue; +#define ROSE_LOOPBACK_LIMIT 1000 static struct timer_list loopback_timer; static void rose_set_loopback_timer(void); @@ -35,29 +36,27 @@ static int rose_loopback_running(void) int rose_loopback_queue(struct sk_buff *skb, struct rose_neigh *neigh) { - struct sk_buff *skbn; + struct sk_buff *skbn = NULL; - skbn = skb_clone(skb, GFP_ATOMIC); + if (skb_queue_len(&loopback_queue) < ROSE_LOOPBACK_LIMIT) + skbn = skb_clone(skb, GFP_ATOMIC); - kfree_skb(skb); - - if (skbn != NULL) { + if (skbn) { + consume_skb(skb); skb_queue_tail(&loopback_queue, skbn); if (!rose_loopback_running()) rose_set_loopback_timer(); + } else { + kfree_skb(skb); } return 1; } - static void rose_set_loopback_timer(void) { - del_timer(&loopback_timer); - - loopback_timer.expires = jiffies + 10; - add_timer(&loopback_timer); + mod_timer(&loopback_timer, jiffies + 10); } static void rose_loopback_timer(struct timer_list *unused) @@ -68,8 +67,12 @@ static void rose_loopback_timer(struct timer_list *unused) struct sock *sk; unsigned short frametype; unsigned int lci_i, lci_o; + int count; - while ((skb = skb_dequeue(&loopback_queue)) != NULL) { + for (count = 0; count < ROSE_LOOPBACK_LIMIT; count++) { + skb = skb_dequeue(&loopback_queue); + if (!skb) + return; if (skb->len < ROSE_MIN_LEN) { kfree_skb(skb); continue; @@ -106,6 +109,8 @@ static void rose_loopback_timer(struct timer_list *unused) kfree_skb(skb); } } + if (!skb_queue_empty(&loopback_queue)) + mod_timer(&loopback_timer, jiffies + 1); } void __exit rose_loopback_clear(void) -- GitLab From fd8e4afb2812bce3ceef6cfad9a08cdaf63f06d3 Mon Sep 17 00:00:00 2001 From: ZhangXiaoxu Date: Tue, 16 Apr 2019 09:47:24 +0800 Subject: [PATCH 0302/1121] ipv4: set the tcp_min_rtt_wlen range from 0 to one day [ Upstream commit 19fad20d15a6494f47f85d869f00b11343ee5c78 ] There is a UBSAN report as below: UBSAN: Undefined behaviour in net/ipv4/tcp_input.c:2877:56 signed integer overflow: 2147483647 * 1000 cannot be represented in type 'int' CPU: 3 PID: 0 Comm: swapper/3 Not tainted 5.1.0-rc4-00058-g582549e #1 Call Trace: dump_stack+0x8c/0xba ubsan_epilogue+0x11/0x60 handle_overflow+0x12d/0x170 ? ttwu_do_wakeup+0x21/0x320 __ubsan_handle_mul_overflow+0x12/0x20 tcp_ack_update_rtt+0x76c/0x780 tcp_clean_rtx_queue+0x499/0x14d0 tcp_ack+0x69e/0x1240 ? __wake_up_sync_key+0x2c/0x50 ? update_group_capacity+0x50/0x680 tcp_rcv_established+0x4e2/0xe10 tcp_v4_do_rcv+0x22b/0x420 tcp_v4_rcv+0xfe8/0x1190 ip_protocol_deliver_rcu+0x36/0x180 ip_local_deliver+0x15b/0x1a0 ip_rcv+0xac/0xd0 __netif_receive_skb_one_core+0x7f/0xb0 __netif_receive_skb+0x33/0xc0 netif_receive_skb_internal+0x84/0x1c0 napi_gro_receive+0x2a0/0x300 receive_buf+0x3d4/0x2350 ? detach_buf_split+0x159/0x390 virtnet_poll+0x198/0x840 ? reweight_entity+0x243/0x4b0 net_rx_action+0x25c/0x770 __do_softirq+0x19b/0x66d irq_exit+0x1eb/0x230 do_IRQ+0x7a/0x150 common_interrupt+0xf/0xf It can be reproduced by: echo 2147483647 > /proc/sys/net/ipv4/tcp_min_rtt_wlen Fixes: f672258391b42 ("tcp: track min RTT using windowed min-filter") Signed-off-by: ZhangXiaoxu Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- Documentation/networking/ip-sysctl.txt | 1 + net/ipv4/sysctl_net_ipv4.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index a054b5ad410a..828fcd6711b3 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -402,6 +402,7 @@ tcp_min_rtt_wlen - INTEGER minimum RTT when it is moved to a longer path (e.g., due to traffic engineering). A longer window makes the filter more resistant to RTT inflations such as transient congestion. The unit is seconds. + Possible values: 0 - 86400 (1 day) Default: 300 tcp_moderate_rcvbuf - BOOLEAN diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index d82e8344fc54..e8caab8e2f5c 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -45,6 +45,7 @@ static int tcp_syn_retries_min = 1; static int tcp_syn_retries_max = MAX_TCP_SYNCNT; static int ip_ping_group_range_min[] = { 0, 0 }; static int ip_ping_group_range_max[] = { GID_T_MAX, GID_T_MAX }; +static int one_day_secs = 24 * 3600; /* obsolete */ static int sysctl_tcp_low_latency __read_mostly; @@ -552,7 +553,9 @@ static struct ctl_table ipv4_table[] = { .data = &sysctl_tcp_min_rtt_wlen, .maxlen = sizeof(int), .mode = 0644, - .proc_handler = proc_dointvec + .proc_handler = proc_dointvec_minmax, + .extra1 = &zero, + .extra2 = &one_day_secs }, { .procname = "tcp_low_latency", -- GitLab From 07198c41d25aa963d33b2ccc7909c06655b6613c Mon Sep 17 00:00:00 2001 From: Diana Craciun Date: Wed, 12 Dec 2018 16:03:10 +0200 Subject: [PATCH 0303/1121] powerpc/fsl: Add FSL_PPC_BOOK3E as supported arch for nospectre_v2 boot arg commit e59f5bd759b7dee57593c5b6c0441609bda5d530 upstream. Signed-off-by: Diana Craciun Signed-off-by: Michael Ellerman Signed-off-by: Greg Kroah-Hartman --- Documentation/admin-guide/kernel-parameters.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 7d8b17ce8804..9372918e2b2a 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -2680,7 +2680,7 @@ nosmt=force: Force disable SMT, cannot be undone via the sysfs control file. - nospectre_v2 [X86] Disable all mitigations for the Spectre variant 2 + nospectre_v2 [X86,PPC_FSL_BOOK3E] Disable all mitigations for the Spectre variant 2 (indirect branch prediction) vulnerability. System may allow data leaks with this option, which is equivalent to spectre_v2=off. -- GitLab From 0a5112f20c1deca4b3899fdbf711f309ee977a18 Mon Sep 17 00:00:00 2001 From: Diana Craciun Date: Sat, 28 Jul 2018 09:06:39 +1000 Subject: [PATCH 0304/1121] Documentation: Add nospectre_v1 parameter commit 26cb1f36c43ee6e89d2a9f48a5a7500d5248f836 upstream. Currently only supported on powerpc. Signed-off-by: Diana Craciun Signed-off-by: Michael Ellerman Signed-off-by: Greg Kroah-Hartman --- Documentation/admin-guide/kernel-parameters.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 9372918e2b2a..94fa46d2d805 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -2680,6 +2680,10 @@ nosmt=force: Force disable SMT, cannot be undone via the sysfs control file. + nospectre_v1 [PPC] Disable mitigations for Spectre Variant 1 (bounds + check bypass). With this option data leaks are possible + in the system. + nospectre_v2 [X86,PPC_FSL_BOOK3E] Disable all mitigations for the Spectre variant 2 (indirect branch prediction) vulnerability. System may allow data leaks with this option, which is equivalent -- GitLab From 1c046f37313210e0c41b036fcd14c4bdb1581d47 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 2 May 2019 09:40:34 +0200 Subject: [PATCH 0305/1121] Linux 4.14.115 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 47a9f9883bdd..b27ffc1814e8 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 4 PATCHLEVEL = 14 -SUBLEVEL = 114 +SUBLEVEL = 115 EXTRAVERSION = NAME = Petit Gorille -- GitLab From 352890cf0697c7a9fd8382398e184eff12a7cb6d Mon Sep 17 00:00:00 2001 From: Ram Chandrasekar Date: Fri, 5 Apr 2019 13:39:19 -0600 Subject: [PATCH 0306/1121] ARM: dts: msm: Add skin mitigation for sm8150 sdx50 QRD Add skin mitigation to mitigate modem as per recommendation for sm8150 sdx50 QRD. Change-Id: I4534b667f02215a08469289e4e093e6c3be7aa74 Signed-off-by: Ram Chandrasekar --- .../boot/dts/qcom/sm8150-sdx50m-qrd.dtsi | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sm8150-sdx50m-qrd.dtsi b/arch/arm64/boot/dts/qcom/sm8150-sdx50m-qrd.dtsi index c68d6a07791f..dad29638edde 100644 --- a/arch/arm64/boot/dts/qcom/sm8150-sdx50m-qrd.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150-sdx50m-qrd.dtsi @@ -606,3 +606,119 @@ <0x49 0x70 0x28 0x74>; }; + +&thermal_zones { + modem1-pa1-step { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "step_wise"; + thermal-sensors = <&qmi_sensor 101>; + trips { + pa1_lvl0: active-config0 { + temperature = <40000>; + hysteresis = <5000>; + type = "passive"; + }; + pa1_lvl1: active-config1 { + temperature = <45000>; + hysteresis = <3000>; + type = "passive"; + }; + pa1_lvl2: active-config2 { + temperature = <52000>; + hysteresis = <4000>; + type = "passive"; + }; + }; + cooling-maps { + pa1_skin_lvl0 { + trip = <&pa1_lvl0>; + cooling-device = <&modem1_skin0 1 1>; + }; + pa1_skin_lvl1 { + trip = <&pa1_lvl1>; + cooling-device = <&modem1_skin0 2 2>; + }; + pa1_skin_lvl2 { + trip = <&pa1_lvl2>; + cooling-device = <&modem1_skin0 3 3>; + }; + }; + }; + + pa-therm2-step { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "step_wise"; + thermal-sensors = <&pm8150l_adc_tm ADC_AMUX_THM3_PU2>; + trips { + pa2_lvl0: active-config0 { + temperature = <40000>; + hysteresis = <5000>; + type = "passive"; + }; + pa2_lvl1: active-config1 { + temperature = <45000>; + hysteresis = <3000>; + type = "passive"; + }; + pa2_lvl2: active-config2 { + temperature = <52000>; + hysteresis = <4000>; + type = "passive"; + }; + }; + cooling-maps { + pa2_skin_lvl0 { + trip = <&pa2_lvl0>; + cooling-device = <&modem1_skin1 1 1>; + }; + pa2_skin_lvl1 { + trip = <&pa2_lvl1>; + cooling-device = <&modem1_skin1 2 2>; + }; + pa2_skin_lvl2 { + trip = <&pa2_lvl2>; + cooling-device = <&modem1_skin1 3 3>; + }; + }; + }; + + camera-ftherm-step { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "step_wise"; + thermal-sensors = <&pm8150l_adc_tm ADC_AMUX_THM1_PU2>; + trips { + cam_lvl0: active-config0 { + temperature = <34000>; + hysteresis = <4000>; + type = "passive"; + }; + cam_lvl1: active-config1 { + temperature = <43000>; + hysteresis = <3000>; + type = "passive"; + }; + cam_lvl2: active-config2 { + temperature = <52000>; + hysteresis = <4000>; + type = "passive"; + }; + }; + cooling-maps { + cam_skin_lvl0 { + trip = <&cam_lvl0>; + cooling-device = <&modem1_skin2 1 1>; + }; + cam_skin_lvl1 { + trip = <&cam_lvl1>; + cooling-device = <&modem1_skin2 2 2>; + }; + cam_skin_lvl2 { + trip = <&cam_lvl2>; + cooling-device = <&modem1_skin2 3 3>; + }; + }; + }; +}; -- GitLab From 760f8522ce08a24abac3208290f93fe3fffc0d6c Mon Sep 17 00:00:00 2001 From: Paulo Alcantara Date: Sun, 24 Feb 2019 21:55:28 -0300 Subject: [PATCH 0307/1121] selinux: use kernel linux/socket.h for genheaders and mdp commit dfbd199a7cfe3e3cd8531e1353cdbd7175bfbc5e upstream. When compiling genheaders and mdp from a newer host kernel, the following error happens: In file included from scripts/selinux/genheaders/genheaders.c:18: ./security/selinux/include/classmap.h:238:2: error: #error New address family defined, please update secclass_map. #error New address family defined, please update secclass_map. ^~~~~ make[3]: *** [scripts/Makefile.host:107: scripts/selinux/genheaders/genheaders] Error 1 make[2]: *** [scripts/Makefile.build:599: scripts/selinux/genheaders] Error 2 make[1]: *** [scripts/Makefile.build:599: scripts/selinux] Error 2 make[1]: *** Waiting for unfinished jobs.... Instead of relying on the host definition, include linux/socket.h in classmap.h to have PF_MAX. Cc: stable@vger.kernel.org Signed-off-by: Paulo Alcantara Acked-by: Stephen Smalley [PM: manually merge in mdp.c, subject line tweaks] Signed-off-by: Paul Moore Signed-off-by: Greg Kroah-Hartman --- scripts/selinux/genheaders/genheaders.c | 1 - scripts/selinux/mdp/mdp.c | 1 - security/selinux/include/classmap.h | 1 + 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/selinux/genheaders/genheaders.c b/scripts/selinux/genheaders/genheaders.c index fa48fabcb330..3cc4893d98cc 100644 --- a/scripts/selinux/genheaders/genheaders.c +++ b/scripts/selinux/genheaders/genheaders.c @@ -9,7 +9,6 @@ #include #include #include -#include struct security_class_mapping { const char *name; diff --git a/scripts/selinux/mdp/mdp.c b/scripts/selinux/mdp/mdp.c index ffe8179f5d41..c29fa4a6228d 100644 --- a/scripts/selinux/mdp/mdp.c +++ b/scripts/selinux/mdp/mdp.c @@ -32,7 +32,6 @@ #include #include #include -#include static void usage(char *name) { diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h index cc35695d97b4..45ef6a0c17cc 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ #include +#include #define COMMON_FILE_SOCK_PERMS "ioctl", "read", "write", "create", \ "getattr", "setattr", "lock", "relabelfrom", "relabelto", "append", "map" -- GitLab From f5bca75dc46701f4c0d1dcbaae401233ae7ff06b Mon Sep 17 00:00:00 2001 From: Alexander Kappner Date: Mon, 13 Nov 2017 17:44:20 -0800 Subject: [PATCH 0308/1121] usbnet: ipheth: prevent TX queue timeouts when device not ready commit bb1b40c7cb863f0800a6410c7dcb86cf3f28d3b1 upstream. iOS devices require the host to be "trusted" before servicing network packets. Establishing trust requires the user to confirm a dialog on the iOS device.Until trust is established, the iOS device will silently discard network packets from the host. Currently, the ipheth driver does not detect whether an iOS device has established trust with the host, and immediately sets up the transmit queues. This causes the following problems: - Kernel taint due to WARN() in netdev watchdog. - Dmesg spam ("TX timeout"). - Disruption of user space networking activity (dhcpd, etc...) when new interface comes up but cannot be used. - Unnecessary host and device wakeups and USB traffic Example dmesg output: [ 1101.319778] NETDEV WATCHDOG: eth1 (ipheth): transmit queue 0 timed out [ 1101.319817] ------------[ cut here ]------------ [ 1101.319828] WARNING: CPU: 0 PID: 0 at net/sched/sch_generic.c:316 dev_watchdog+0x20f/0x220 [ 1101.319831] Modules linked in: ipheth usbmon nvidia_drm(PO) nvidia_modeset(PO) nvidia(PO) iwlmvm mac80211 iwlwifi btusb btrtl btbcm btintel qmi_wwan bluetooth cfg80211 ecdh_generic thinkpad_acpi rfkill [last unloaded: ipheth] [ 1101.319861] CPU: 0 PID: 0 Comm: swapper/0 Tainted: P O 4.13.12.1 #1 [ 1101.319864] Hardware name: LENOVO 20ENCTO1WW/20ENCTO1WW, BIOS N1EET62W (1.35 ) 11/10/2016 [ 1101.319867] task: ffffffff81e11500 task.stack: ffffffff81e00000 [ 1101.319873] RIP: 0010:dev_watchdog+0x20f/0x220 [ 1101.319876] RSP: 0018:ffff8810a3c03e98 EFLAGS: 00010292 [ 1101.319880] RAX: 000000000000003a RBX: 0000000000000000 RCX: 0000000000000000 [ 1101.319883] RDX: ffff8810a3c15c48 RSI: ffffffff81ccbfc2 RDI: 00000000ffffffff [ 1101.319886] RBP: ffff880c04ebc41c R08: 0000000000000000 R09: 0000000000000379 [ 1101.319889] R10: 00000100696589d0 R11: 0000000000000378 R12: ffff880c04ebc000 [ 1101.319892] R13: 0000000000000000 R14: 0000000000000001 R15: ffff880c2865fc80 [ 1101.319896] FS: 0000000000000000(0000) GS:ffff8810a3c00000(0000) knlGS:0000000000000000 [ 1101.319899] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 1101.319902] CR2: 00007f3ff24ac000 CR3: 0000000001e0a000 CR4: 00000000003406f0 [ 1101.319905] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 1101.319908] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 1101.319910] Call Trace: [ 1101.319914] [ 1101.319921] ? dev_graft_qdisc+0x70/0x70 [ 1101.319928] ? dev_graft_qdisc+0x70/0x70 [ 1101.319934] ? call_timer_fn+0x2e/0x170 [ 1101.319939] ? dev_graft_qdisc+0x70/0x70 [ 1101.319944] ? run_timer_softirq+0x1ea/0x440 [ 1101.319951] ? timerqueue_add+0x54/0x80 [ 1101.319956] ? enqueue_hrtimer+0x38/0xa0 [ 1101.319963] ? __do_softirq+0xed/0x2e7 [ 1101.319970] ? irq_exit+0xb4/0xc0 [ 1101.319976] ? smp_apic_timer_interrupt+0x39/0x50 [ 1101.319981] ? apic_timer_interrupt+0x8c/0xa0 [ 1101.319983] [ 1101.319992] ? cpuidle_enter_state+0xfa/0x2a0 [ 1101.319999] ? do_idle+0x1a3/0x1f0 [ 1101.320004] ? cpu_startup_entry+0x5f/0x70 [ 1101.320011] ? start_kernel+0x444/0x44c [ 1101.320017] ? early_idt_handler_array+0x120/0x120 [ 1101.320023] ? x86_64_start_kernel+0x145/0x154 [ 1101.320028] ? secondary_startup_64+0x9f/0x9f [ 1101.320033] Code: 20 04 00 00 eb 9f 4c 89 e7 c6 05 59 44 71 00 01 e8 a7 df fd ff 89 d9 4c 89 e6 48 c7 c7 70 b7 cd 81 48 89 c2 31 c0 e8 97 64 90 ff <0f> ff eb bf 66 66 66 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 [ 1101.320103] ---[ end trace 0cc4d251e2b57080 ]--- [ 1101.320110] ipheth 1-5:4.2: ipheth_tx_timeout: TX timeout The last message "TX timeout" is repeated every 5 seconds until trust is established or the device is disconnected, filling up dmesg. The proposed patch eliminates the problem by, upon connection, keeping the TX queue and carrier disabled until a packet is first received from the iOS device. This is reflected by the confirmed_pairing variable in the device structure. Only after at least one packet has been received from the iOS device, the transmit queue and carrier are brought up during the periodic device poll in ipheth_carrier_set. Because the iOS device will always send a packet immediately upon trust being established, this should not delay the interface becoming useable. To prevent failed UBRs in ipheth_rcvbulk_callback from perpetually re-enabling the queue if it was disabled, a new check is added so only successful transfers re-enable the queue, whereas failed transfers only trigger an immediate poll. This has the added benefit of removing the periodic control requests to the iOS device until trust has been established and thus should reduce wakeup events on both the host and the iOS device. Signed-off-by: Alexander Kappner Signed-off-by: David S. Miller [groeck: Fixed context conflict seen because 45611c61dd50 was applied first] Signed-off-by: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- drivers/net/usb/ipheth.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c index aabbcfb6e6da..3918023a6568 100644 --- a/drivers/net/usb/ipheth.c +++ b/drivers/net/usb/ipheth.c @@ -148,6 +148,7 @@ struct ipheth_device { u8 bulk_in; u8 bulk_out; struct delayed_work carrier_work; + bool confirmed_pairing; }; static int ipheth_rx_submit(struct ipheth_device *dev, gfp_t mem_flags); @@ -259,7 +260,7 @@ static void ipheth_rcvbulk_callback(struct urb *urb) dev->net->stats.rx_packets++; dev->net->stats.rx_bytes += len; - + dev->confirmed_pairing = true; netif_rx(skb); ipheth_rx_submit(dev, GFP_ATOMIC); } @@ -280,14 +281,21 @@ static void ipheth_sndbulk_callback(struct urb *urb) dev_err(&dev->intf->dev, "%s: urb status: %d\n", __func__, status); - netif_wake_queue(dev->net); + if (status == 0) + netif_wake_queue(dev->net); + else + // on URB error, trigger immediate poll + schedule_delayed_work(&dev->carrier_work, 0); } static int ipheth_carrier_set(struct ipheth_device *dev) { struct usb_device *udev = dev->udev; int retval; - + if (!dev) + return 0; + if (!dev->confirmed_pairing) + return 0; retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, IPHETH_CTRL_ENDP), IPHETH_CMD_CARRIER_CHECK, /* request */ @@ -302,11 +310,14 @@ static int ipheth_carrier_set(struct ipheth_device *dev) return retval; } - if (dev->ctrl_buf[0] == IPHETH_CARRIER_ON) + if (dev->ctrl_buf[0] == IPHETH_CARRIER_ON) { netif_carrier_on(dev->net); - else + if (dev->tx_urb->status != -EINPROGRESS) + netif_wake_queue(dev->net); + } else { netif_carrier_off(dev->net); - + netif_stop_queue(dev->net); + } return 0; } @@ -386,7 +397,6 @@ static int ipheth_open(struct net_device *net) return retval; schedule_delayed_work(&dev->carrier_work, IPHETH_CARRIER_CHECK_TIMEOUT); - netif_start_queue(net); return retval; } @@ -489,7 +499,7 @@ static int ipheth_probe(struct usb_interface *intf, dev->udev = udev; dev->net = netdev; dev->intf = intf; - + dev->confirmed_pairing = false; /* Set up endpoints */ hintf = usb_altnum_to_altsetting(intf, IPHETH_ALT_INTFNUM); if (hintf == NULL) { @@ -540,7 +550,9 @@ static int ipheth_probe(struct usb_interface *intf, retval = -EIO; goto err_register_netdev; } - + // carrier down and transmit queues stopped until packet from device + netif_carrier_off(netdev); + netif_tx_stop_all_queues(netdev); dev_info(&intf->dev, "Apple iPhone USB Ethernet device attached\n"); return 0; -- GitLab From b41449d9be2103c15c22b988d10b6303fdadebd3 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Fri, 17 Nov 2017 14:02:09 -0600 Subject: [PATCH 0309/1121] usbnet: ipheth: fix potential null pointer dereference in ipheth_carrier_set commit 61c59355e0154a938b28710dfa6c1d8be2ddcefa upstream. _dev_ is being dereferenced before it is null checked, hence there is a potential null pointer dereference. Fix this by moving the pointer dereference after _dev_ has been null checked. Addresses-Coverity-ID: 1462020 Fixes: bb1b40c7cb86 ("usbnet: ipheth: prevent TX queue timeouts when device not ready") Signed-off-by: Gustavo A. R. Silva Signed-off-by: David S. Miller Signed-off-by: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- drivers/net/usb/ipheth.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c index 3918023a6568..3d8a70d3ea9b 100644 --- a/drivers/net/usb/ipheth.c +++ b/drivers/net/usb/ipheth.c @@ -290,12 +290,15 @@ static void ipheth_sndbulk_callback(struct urb *urb) static int ipheth_carrier_set(struct ipheth_device *dev) { - struct usb_device *udev = dev->udev; + struct usb_device *udev; int retval; + if (!dev) return 0; if (!dev->confirmed_pairing) return 0; + + udev = dev->udev; retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, IPHETH_CTRL_ENDP), IPHETH_CMD_CARRIER_CHECK, /* request */ -- GitLab From 94d99a2355e32ba8eae7bdfdf861f90286634cd9 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 11 Apr 2019 10:06:20 -0700 Subject: [PATCH 0310/1121] mm: make page ref count overflow check tighter and more explicit commit f958d7b528b1b40c44cfda5eabe2d82760d868c3 upstream. We have a VM_BUG_ON() to check that the page reference count doesn't underflow (or get close to overflow) by checking the sign of the count. That's all fine, but we actually want to allow people to use a "get page ref unless it's already very high" helper function, and we want that one to use the sign of the page ref (without triggering this VM_BUG_ON). Change the VM_BUG_ON to only check for small underflows (or _very_ close to overflowing), and ignore overflows which have strayed into negative territory. Acked-by: Matthew Wilcox Cc: Jann Horn Cc: stable@kernel.org Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- include/linux/mm.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index 58f2263de4de..4023819837a6 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -824,6 +824,10 @@ static inline bool is_device_public_page(const struct page *page) #endif /* CONFIG_DEVICE_PRIVATE || CONFIG_DEVICE_PUBLIC */ +/* 127: arbitrary random number, small enough to assemble well */ +#define page_ref_zero_or_close_to_overflow(page) \ + ((unsigned int) page_ref_count(page) + 127u <= 127u) + static inline void get_page(struct page *page) { page = compound_head(page); @@ -831,7 +835,7 @@ static inline void get_page(struct page *page) * Getting a normal page or the head of a compound page * requires to already have an elevated page->_refcount. */ - VM_BUG_ON_PAGE(page_ref_count(page) <= 0, page); + VM_BUG_ON_PAGE(page_ref_zero_or_close_to_overflow(page), page); page_ref_inc(page); } -- GitLab From 2a280d881726795ae490dc45bcaa9f6d4bf43741 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 11 Apr 2019 10:14:59 -0700 Subject: [PATCH 0311/1121] mm: add 'try_get_page()' helper function commit 88b1a17dfc3ed7728316478fae0f5ad508f50397 upstream. This is the same as the traditional 'get_page()' function, but instead of unconditionally incrementing the reference count of the page, it only does so if the count was "safe". It returns whether the reference count was incremented (and is marked __must_check, since the caller obviously has to be aware of it). Also like 'get_page()', you can't use this function unless you already had a reference to the page. The intent is that you can use this exactly like get_page(), but in situations where you want to limit the maximum reference count. The code currently does an unconditional WARN_ON_ONCE() if we ever hit the reference count issues (either zero or negative), as a notification that the conditional non-increment actually happened. NOTE! The count access for the "safety" check is inherently racy, but that doesn't matter since the buffer we use is basically half the range of the reference count (ie we look at the sign of the count). Acked-by: Matthew Wilcox Cc: Jann Horn Cc: stable@kernel.org Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- include/linux/mm.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/linux/mm.h b/include/linux/mm.h index 4023819837a6..ee0eae215210 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -839,6 +839,15 @@ static inline void get_page(struct page *page) page_ref_inc(page); } +static inline __must_check bool try_get_page(struct page *page) +{ + page = compound_head(page); + if (WARN_ON_ONCE(page_ref_count(page) <= 0)) + return false; + page_ref_inc(page); + return true; +} + static inline void put_page(struct page *page) { page = compound_head(page); -- GitLab From 04198de24771f6aaf6374979db64403101d809df Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 11 Apr 2019 10:49:19 -0700 Subject: [PATCH 0312/1121] mm: prevent get_user_pages() from overflowing page refcount commit 8fde12ca79aff9b5ba951fce1a2641901b8d8e64 upstream. If the page refcount wraps around past zero, it will be freed while there are still four billion references to it. One of the possible avenues for an attacker to try to make this happen is by doing direct IO on a page multiple times. This patch makes get_user_pages() refuse to take a new page reference if there are already more than two billion references to the page. Reported-by: Jann Horn Acked-by: Matthew Wilcox Cc: stable@kernel.org Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- mm/gup.c | 45 ++++++++++++++++++++++++++++++++++----------- mm/hugetlb.c | 13 +++++++++++++ 2 files changed, 47 insertions(+), 11 deletions(-) diff --git a/mm/gup.c b/mm/gup.c index 7c0e5b1bbcd4..babcbd6d99c3 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -153,7 +153,10 @@ static struct page *follow_page_pte(struct vm_area_struct *vma, } if (flags & FOLL_GET) { - get_page(page); + if (unlikely(!try_get_page(page))) { + page = ERR_PTR(-ENOMEM); + goto out; + } /* drop the pgmap reference now that we hold the page */ if (pgmap) { @@ -280,7 +283,10 @@ static struct page *follow_pmd_mask(struct vm_area_struct *vma, if (pmd_trans_unstable(pmd)) ret = -EBUSY; } else { - get_page(page); + if (unlikely(!try_get_page(page))) { + spin_unlock(ptl); + return ERR_PTR(-ENOMEM); + } spin_unlock(ptl); lock_page(page); ret = split_huge_page(page); @@ -464,7 +470,10 @@ static int get_gate_page(struct mm_struct *mm, unsigned long address, if (is_device_public_page(*page)) goto unmap; } - get_page(*page); + if (unlikely(!try_get_page(*page))) { + ret = -ENOMEM; + goto unmap; + } out: ret = 0; unmap: @@ -1365,6 +1374,20 @@ static void undo_dev_pagemap(int *nr, int nr_start, struct page **pages) } } +/* + * Return the compund head page with ref appropriately incremented, + * or NULL if that failed. + */ +static inline struct page *try_get_compound_head(struct page *page, int refs) +{ + struct page *head = compound_head(page); + if (WARN_ON_ONCE(page_ref_count(head) < 0)) + return NULL; + if (unlikely(!page_cache_add_speculative(head, refs))) + return NULL; + return head; +} + #ifdef __HAVE_ARCH_PTE_SPECIAL static int gup_pte_range(pmd_t pmd, unsigned long addr, unsigned long end, int write, struct page **pages, int *nr) @@ -1399,9 +1422,9 @@ static int gup_pte_range(pmd_t pmd, unsigned long addr, unsigned long end, VM_BUG_ON(!pfn_valid(pte_pfn(pte))); page = pte_page(pte); - head = compound_head(page); - if (!page_cache_get_speculative(head)) + head = try_get_compound_head(page, 1); + if (!head) goto pte_unmap; if (unlikely(pte_val(pte) != pte_val(*ptep))) { @@ -1537,8 +1560,8 @@ static int gup_huge_pmd(pmd_t orig, pmd_t *pmdp, unsigned long addr, refs++; } while (addr += PAGE_SIZE, addr != end); - head = compound_head(pmd_page(orig)); - if (!page_cache_add_speculative(head, refs)) { + head = try_get_compound_head(pmd_page(orig), refs); + if (!head) { *nr -= refs; return 0; } @@ -1575,8 +1598,8 @@ static int gup_huge_pud(pud_t orig, pud_t *pudp, unsigned long addr, refs++; } while (addr += PAGE_SIZE, addr != end); - head = compound_head(pud_page(orig)); - if (!page_cache_add_speculative(head, refs)) { + head = try_get_compound_head(pud_page(orig), refs); + if (!head) { *nr -= refs; return 0; } @@ -1612,8 +1635,8 @@ static int gup_huge_pgd(pgd_t orig, pgd_t *pgdp, unsigned long addr, refs++; } while (addr += PAGE_SIZE, addr != end); - head = compound_head(pgd_page(orig)); - if (!page_cache_add_speculative(head, refs)) { + head = try_get_compound_head(pgd_page(orig), refs); + if (!head) { *nr -= refs; return 0; } diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 7f75bd2fb8a7..64a62584290c 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -4255,6 +4255,19 @@ long follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma, pfn_offset = (vaddr & ~huge_page_mask(h)) >> PAGE_SHIFT; page = pte_page(huge_ptep_get(pte)); + + /* + * Instead of doing 'try_get_page()' below in the same_page + * loop, just check the count once here. + */ + if (unlikely(page_count(page) <= 0)) { + if (pages) { + spin_unlock(ptl); + remainder = 0; + err = -ENOMEM; + break; + } + } same_page: if (pages) { pages[i] = mem_map_offset(page, pfn_offset); -- GitLab From c88a0aa7ace7eb10dca42be59f21e2cbd263575e Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Fri, 5 Apr 2019 14:02:10 -0700 Subject: [PATCH 0313/1121] fs: prevent page refcount overflow in pipe_buf_get commit 15fab63e1e57be9fdb5eec1bbc5916e9825e9acb upstream. Change pipe_buf_get() to return a bool indicating whether it succeeded in raising the refcount of the page (if the thing in the pipe is a page). This removes another mechanism for overflowing the page refcount. All callers converted to handle a failure. Reported-by: Jann Horn Signed-off-by: Matthew Wilcox Cc: stable@kernel.org Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- fs/fuse/dev.c | 12 ++++++------ fs/pipe.c | 4 ++-- fs/splice.c | 12 ++++++++++-- include/linux/pipe_fs_i.h | 10 ++++++---- kernel/trace/trace.c | 6 +++++- 5 files changed, 29 insertions(+), 15 deletions(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 63fd33383413..770733106d6d 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -1981,10 +1981,8 @@ static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe, rem += pipe->bufs[(pipe->curbuf + idx) & (pipe->buffers - 1)].len; ret = -EINVAL; - if (rem < len) { - pipe_unlock(pipe); - goto out; - } + if (rem < len) + goto out_free; rem = len; while (rem) { @@ -2002,7 +2000,9 @@ static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe, pipe->curbuf = (pipe->curbuf + 1) & (pipe->buffers - 1); pipe->nrbufs--; } else { - pipe_buf_get(pipe, ibuf); + if (!pipe_buf_get(pipe, ibuf)) + goto out_free; + *obuf = *ibuf; obuf->flags &= ~PIPE_BUF_FLAG_GIFT; obuf->len = rem; @@ -2025,11 +2025,11 @@ static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe, ret = fuse_dev_do_write(fud, &cs, len); pipe_lock(pipe); +out_free: for (idx = 0; idx < nbuf; idx++) pipe_buf_release(pipe, &bufs[idx]); pipe_unlock(pipe); -out: kfree(bufs); return ret; } diff --git a/fs/pipe.c b/fs/pipe.c index 8f9628494981..fa3c2c25cec5 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -194,9 +194,9 @@ EXPORT_SYMBOL(generic_pipe_buf_steal); * in the tee() system call, when we duplicate the buffers in one * pipe into another. */ -void generic_pipe_buf_get(struct pipe_inode_info *pipe, struct pipe_buffer *buf) +bool generic_pipe_buf_get(struct pipe_inode_info *pipe, struct pipe_buffer *buf) { - get_page(buf->page); + return try_get_page(buf->page); } EXPORT_SYMBOL(generic_pipe_buf_get); diff --git a/fs/splice.c b/fs/splice.c index a598d444abe1..c84ac7e97e21 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -1571,7 +1571,11 @@ static int splice_pipe_to_pipe(struct pipe_inode_info *ipipe, * Get a reference to this pipe buffer, * so we can copy the contents over. */ - pipe_buf_get(ipipe, ibuf); + if (!pipe_buf_get(ipipe, ibuf)) { + if (ret == 0) + ret = -EFAULT; + break; + } *obuf = *ibuf; /* @@ -1645,7 +1649,11 @@ static int link_pipe(struct pipe_inode_info *ipipe, * Get a reference to this pipe buffer, * so we can copy the contents over. */ - pipe_buf_get(ipipe, ibuf); + if (!pipe_buf_get(ipipe, ibuf)) { + if (ret == 0) + ret = -EFAULT; + break; + } obuf = opipe->bufs + nbuf; *obuf = *ibuf; diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index 2dcf6e81b2e2..c251ad717345 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h @@ -108,18 +108,20 @@ struct pipe_buf_operations { /* * Get a reference to the pipe buffer. */ - void (*get)(struct pipe_inode_info *, struct pipe_buffer *); + bool (*get)(struct pipe_inode_info *, struct pipe_buffer *); }; /** * pipe_buf_get - get a reference to a pipe_buffer * @pipe: the pipe that the buffer belongs to * @buf: the buffer to get a reference to + * + * Return: %true if the reference was successfully obtained. */ -static inline void pipe_buf_get(struct pipe_inode_info *pipe, +static inline __must_check bool pipe_buf_get(struct pipe_inode_info *pipe, struct pipe_buffer *buf) { - buf->ops->get(pipe, buf); + return buf->ops->get(pipe, buf); } /** @@ -179,7 +181,7 @@ struct pipe_inode_info *alloc_pipe_info(void); void free_pipe_info(struct pipe_inode_info *); /* Generic pipe buffer ops functions */ -void generic_pipe_buf_get(struct pipe_inode_info *, struct pipe_buffer *); +bool generic_pipe_buf_get(struct pipe_inode_info *, struct pipe_buffer *); int generic_pipe_buf_confirm(struct pipe_inode_info *, struct pipe_buffer *); int generic_pipe_buf_steal(struct pipe_inode_info *, struct pipe_buffer *); int generic_pipe_buf_nosteal(struct pipe_inode_info *, struct pipe_buffer *); diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 591be15404a1..ace0e8f6f2b4 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -6739,12 +6739,16 @@ static void buffer_pipe_buf_release(struct pipe_inode_info *pipe, buf->private = 0; } -static void buffer_pipe_buf_get(struct pipe_inode_info *pipe, +static bool buffer_pipe_buf_get(struct pipe_inode_info *pipe, struct pipe_buffer *buf) { struct buffer_ref *ref = (struct buffer_ref *)buf->private; + if (refcount_read(&ref->refcount) > INT_MAX/2) + return false; + refcount_inc(&ref->refcount); + return true; } /* Pipe buffer operations for a buffer. */ -- GitLab From 93c2b843ca2c97ee04a2c404f8562cffae4419f6 Mon Sep 17 00:00:00 2001 From: Helen Koike Date: Mon, 4 Mar 2019 18:48:37 -0300 Subject: [PATCH 0314/1121] ARM: dts: bcm283x: Fix hdmi hpd gpio pull [ Upstream commit 544e784188f1dd7c797c70b213385e67d92005b6 ] Raspberry pi board model B revison 2 have the hot plug detector gpio active high (and not low as it was in the dts). Signed-off-by: Helen Koike Fixes: 49ac67e0c39c ("ARM: bcm2835: Add VC4 to the device tree.") Reviewed-by: Eric Anholt Signed-off-by: Eric Anholt Signed-off-by: Sasha Levin (Microsoft) --- arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts index 4bc70efe43d6..3178a5664942 100644 --- a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts +++ b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts @@ -93,7 +93,7 @@ }; &hdmi { - hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>; + hpd-gpios = <&gpio 46 GPIO_ACTIVE_HIGH>; }; &uart0 { -- GitLab From 3b2c5114a6c3017ac44bd9caf6211c825d701a1c Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Mon, 4 Mar 2019 12:33:28 +0100 Subject: [PATCH 0315/1121] s390: limit brk randomization to 32MB [ Upstream commit cd479eccd2e057116d504852814402a1e68ead80 ] For a 64-bit process the randomization of the program break is quite large with 1GB. That is as big as the randomization of the anonymous mapping base, for a test case started with '/lib/ld64.so.1 ' it can happen that the heap is placed after the stack. To avoid this limit the program break randomization to 32MB for 64-bit and keep 8MB for 31-bit. Reported-by: Stefan Liebler Signed-off-by: Martin Schwidefsky Signed-off-by: Sasha Levin (Microsoft) --- arch/s390/include/asm/elf.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/arch/s390/include/asm/elf.h b/arch/s390/include/asm/elf.h index 1a61b1b997f2..3055c030f765 100644 --- a/arch/s390/include/asm/elf.h +++ b/arch/s390/include/asm/elf.h @@ -252,11 +252,14 @@ do { \ /* * Cache aliasing on the latest machines calls for a mapping granularity - * of 512KB. For 64-bit processes use a 512KB alignment and a randomization - * of up to 1GB. For 31-bit processes the virtual address space is limited, - * use no alignment and limit the randomization to 8MB. + * of 512KB for the anonymous mapping base. For 64-bit processes use a + * 512KB alignment and a randomization of up to 1GB. For 31-bit processes + * the virtual address space is limited, use no alignment and limit the + * randomization to 8MB. + * For the additional randomization of the program break use 32MB for + * 64-bit and 8MB for 31-bit. */ -#define BRK_RND_MASK (is_compat_task() ? 0x7ffUL : 0x3ffffUL) +#define BRK_RND_MASK (is_compat_task() ? 0x7ffUL : 0x1fffUL) #define MMAP_RND_MASK (is_compat_task() ? 0x7ffUL : 0x3ff80UL) #define MMAP_ALIGN_MASK (is_compat_task() ? 0 : 0x7fUL) #define STACK_RND_MASK MMAP_RND_MASK -- GitLab From 74a9e727ea1b294330f4cd65b290c79e43fbe46d Mon Sep 17 00:00:00 2001 From: Aditya Pakki Date: Thu, 14 Mar 2019 15:31:40 -0500 Subject: [PATCH 0316/1121] qlcnic: Avoid potential NULL pointer dereference [ Upstream commit 5bf7295fe34a5251b1d241b9736af4697b590670 ] netdev_alloc_skb can fail and return a NULL pointer which is dereferenced without a check. The patch avoids such a scenario. Signed-off-by: Aditya Pakki Signed-off-by: David S. Miller Signed-off-by: Sasha Levin (Microsoft) --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c index 7f7deeaf1cf0..da042bc520d4 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c @@ -1047,6 +1047,8 @@ int qlcnic_do_lb_test(struct qlcnic_adapter *adapter, u8 mode) for (i = 0; i < QLCNIC_NUM_ILB_PKT; i++) { skb = netdev_alloc_skb(adapter->netdev, QLCNIC_ILB_PKT_SIZE); + if (!skb) + break; qlcnic_create_loopback_buff(skb->data, adapter->mac_addr); skb_put(skb, QLCNIC_ILB_PKT_SIZE); adapter->ahw->diag_cnt = 0; -- GitLab From fdad255b70c1132da2ba4fe56a625203f2794579 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 12 Mar 2019 12:10:59 +0100 Subject: [PATCH 0317/1121] netfilter: nft_set_rbtree: check for inactive element after flag mismatch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 05b7639da55f5555b9866a1f4b7e8995232a6323 ] Otherwise, we hit bogus ENOENT when removing elements. Fixes: e701001e7cbe ("netfilter: nft_rbtree: allow adjacent intervals with dynamic updates") Reported-by: VĂĄclav Zindulka Signed-off-by: Pablo Neira Ayuso Signed-off-by: Sasha Levin (Microsoft) --- net/netfilter/nft_set_rbtree.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/net/netfilter/nft_set_rbtree.c b/net/netfilter/nft_set_rbtree.c index d83a4ec5900d..6f3205de887f 100644 --- a/net/netfilter/nft_set_rbtree.c +++ b/net/netfilter/nft_set_rbtree.c @@ -224,10 +224,6 @@ static void *nft_rbtree_deactivate(const struct net *net, else if (d > 0) parent = parent->rb_right; else { - if (!nft_set_elem_active(&rbe->ext, genmask)) { - parent = parent->rb_left; - continue; - } if (nft_rbtree_interval_end(rbe) && !nft_rbtree_interval_end(this)) { parent = parent->rb_left; @@ -236,6 +232,9 @@ static void *nft_rbtree_deactivate(const struct net *net, nft_rbtree_interval_end(this)) { parent = parent->rb_right; continue; + } else if (!nft_set_elem_active(&rbe->ext, genmask)) { + parent = parent->rb_left; + continue; } nft_rbtree_flush(net, set, rbe); return rbe; -- GitLab From 208decebe101968ea9a9069b32c3f9883ac2298f Mon Sep 17 00:00:00 2001 From: Xin Long Date: Wed, 13 Mar 2019 16:33:29 +0800 Subject: [PATCH 0318/1121] netfilter: bridge: set skb transport_header before entering NF_INET_PRE_ROUTING [ Upstream commit e166e4fdaced850bee3d5ee12a5740258fb30587 ] Since Commit 21d1196a35f5 ("ipv4: set transport header earlier"), skb->transport_header has been always set before entering INET netfilter. This patch is to set skb->transport_header for bridge before entering INET netfilter by bridge-nf-call-iptables. It also fixes an issue that sctp_error() couldn't compute a right csum due to unset skb->transport_header. Fixes: e6d8b64b34aa ("net: sctp: fix and consolidate SCTP checksumming code") Reported-by: Li Shuang Suggested-by: Pablo Neira Ayuso Signed-off-by: Xin Long Acked-by: Neil Horman Acked-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso Signed-off-by: Sasha Levin (Microsoft) --- net/bridge/br_netfilter_hooks.c | 1 + net/bridge/br_netfilter_ipv6.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c index 5fd283d9929e..89936e0d55c9 100644 --- a/net/bridge/br_netfilter_hooks.c +++ b/net/bridge/br_netfilter_hooks.c @@ -512,6 +512,7 @@ static unsigned int br_nf_pre_routing(void *priv, nf_bridge->ipv4_daddr = ip_hdr(skb)->daddr; skb->protocol = htons(ETH_P_IP); + skb->transport_header = skb->network_header + ip_hdr(skb)->ihl * 4; NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, state->net, state->sk, skb, skb->dev, NULL, diff --git a/net/bridge/br_netfilter_ipv6.c b/net/bridge/br_netfilter_ipv6.c index 5811208863b7..09d5e0c7b3ba 100644 --- a/net/bridge/br_netfilter_ipv6.c +++ b/net/bridge/br_netfilter_ipv6.c @@ -235,6 +235,8 @@ unsigned int br_nf_pre_routing_ipv6(void *priv, nf_bridge->ipv6_daddr = ipv6_hdr(skb)->daddr; skb->protocol = htons(ETH_P_IPV6); + skb->transport_header = skb->network_header + sizeof(struct ipv6hdr); + NF_HOOK(NFPROTO_IPV6, NF_INET_PRE_ROUTING, state->net, state->sk, skb, skb->dev, NULL, br_nf_pre_routing_finish_ipv6); -- GitLab From ae35822a3ee0f9e2e86a8e878084eca7c08fa1e2 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Mon, 18 Mar 2019 16:40:55 +0100 Subject: [PATCH 0319/1121] s390/qeth: fix race when initializing the IP address table [ Upstream commit 7221b727f0079a32aca91f657141e1de564d4b97 ] The ucast IP table is utilized by some of the L3-specific sysfs attributes that qeth_l3_create_device_attributes() provides. So initialize the table _before_ registering the attributes. Fixes: ebccc7397e4a ("s390/qeth: add missing hash table initializations") Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller Signed-off-by: Sasha Levin (Microsoft) --- drivers/s390/net/qeth_l3_main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index a19f2dc69e8a..d9830c86d0c1 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -3022,12 +3022,14 @@ static int qeth_l3_probe_device(struct ccwgroup_device *gdev) struct qeth_card *card = dev_get_drvdata(&gdev->dev); int rc; + hash_init(card->ip_htable); + if (gdev->dev.type == &qeth_generic_devtype) { rc = qeth_l3_create_device_attributes(&gdev->dev); if (rc) return rc; } - hash_init(card->ip_htable); + hash_init(card->ip_mc_htable); card->options.layer2 = 0; card->info.hwtrap = 0; -- GitLab From 707615f47db3e240158abe732ef4f99e01c2a91f Mon Sep 17 00:00:00 2001 From: Mao Wenan Date: Fri, 8 Mar 2019 22:08:31 +0800 Subject: [PATCH 0320/1121] sc16is7xx: missing unregister/delete driver on error in sc16is7xx_init() [ Upstream commit ac0cdb3d990108df795b676cd0d0e65ac34b2273 ] Add the missing uart_unregister_driver() and i2c_del_driver() before return from sc16is7xx_init() in the error handling case. Signed-off-by: Mao Wenan Reviewed-by: Vladimir Zapolskiy Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin (Microsoft) --- drivers/tty/serial/sc16is7xx.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c index a79f18edf2bd..e48523da47ac 100644 --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c @@ -1483,7 +1483,7 @@ static int __init sc16is7xx_init(void) ret = i2c_add_driver(&sc16is7xx_i2c_uart_driver); if (ret < 0) { pr_err("failed to init sc16is7xx i2c --> %d\n", ret); - return ret; + goto err_i2c; } #endif @@ -1491,10 +1491,18 @@ static int __init sc16is7xx_init(void) ret = spi_register_driver(&sc16is7xx_spi_uart_driver); if (ret < 0) { pr_err("failed to init sc16is7xx spi --> %d\n", ret); - return ret; + goto err_spi; } #endif return ret; + +err_spi: +#ifdef CONFIG_SERIAL_SC16IS7XX_I2C + i2c_del_driver(&sc16is7xx_i2c_uart_driver); +#endif +err_i2c: + uart_unregister_driver(&sc16is7xx_uart); + return ret; } module_init(sc16is7xx_init); -- GitLab From 10a0ba2fd42e0d5061dbee62b4a5a66ee8267173 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20=C5=A0tetiar?= Date: Wed, 6 Mar 2019 17:54:03 +0100 Subject: [PATCH 0321/1121] serial: ar933x_uart: Fix build failure with disabled console MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 72ff51d8dd262d1fef25baedc2ac35116435be47 ] Andrey has reported on OpenWrt's bug tracking system[1], that he currently can't use ar93xx_uart as pure serial UART without console (CONFIG_SERIAL_8250_CONSOLE and CONFIG_SERIAL_AR933X_CONSOLE undefined), because compilation ends with following error: ar933x_uart.c: In function 'ar933x_uart_console_write': ar933x_uart.c:550:14: error: 'struct uart_port' has no member named 'sysrq' So this patch moves all the code related to console handling behind series of CONFIG_SERIAL_AR933X_CONSOLE ifdefs. 1. https://bugs.openwrt.org/index.php?do=details&task_id=2152 Cc: Greg Kroah-Hartman Cc: Jiri Slaby Cc: Andrey Batyiev Reported-by: Andrey Batyiev Tested-by: Andrey Batyiev Signed-off-by: Petr Ć tetiar Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin (Microsoft) --- drivers/tty/serial/ar933x_uart.c | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/drivers/tty/serial/ar933x_uart.c b/drivers/tty/serial/ar933x_uart.c index decc7f3c1ab2..ed545a61413c 100644 --- a/drivers/tty/serial/ar933x_uart.c +++ b/drivers/tty/serial/ar933x_uart.c @@ -52,11 +52,6 @@ struct ar933x_uart_port { struct clk *clk; }; -static inline bool ar933x_uart_console_enabled(void) -{ - return IS_ENABLED(CONFIG_SERIAL_AR933X_CONSOLE); -} - static inline unsigned int ar933x_uart_read(struct ar933x_uart_port *up, int offset) { @@ -511,6 +506,7 @@ static const struct uart_ops ar933x_uart_ops = { .verify_port = ar933x_uart_verify_port, }; +#ifdef CONFIG_SERIAL_AR933X_CONSOLE static struct ar933x_uart_port * ar933x_console_ports[CONFIG_SERIAL_AR933X_NR_UARTS]; @@ -607,14 +603,7 @@ static struct console ar933x_uart_console = { .index = -1, .data = &ar933x_uart_driver, }; - -static void ar933x_uart_add_console_port(struct ar933x_uart_port *up) -{ - if (!ar933x_uart_console_enabled()) - return; - - ar933x_console_ports[up->port.line] = up; -} +#endif /* CONFIG_SERIAL_AR933X_CONSOLE */ static struct uart_driver ar933x_uart_driver = { .owner = THIS_MODULE, @@ -703,7 +692,9 @@ static int ar933x_uart_probe(struct platform_device *pdev) baud = ar933x_uart_get_baud(port->uartclk, 0, AR933X_UART_MAX_STEP); up->max_baud = min_t(unsigned int, baud, AR933X_UART_MAX_BAUD); - ar933x_uart_add_console_port(up); +#ifdef CONFIG_SERIAL_AR933X_CONSOLE + ar933x_console_ports[up->port.line] = up; +#endif ret = uart_add_one_port(&ar933x_uart_driver, &up->port); if (ret) @@ -752,8 +743,9 @@ static int __init ar933x_uart_init(void) { int ret; - if (ar933x_uart_console_enabled()) - ar933x_uart_driver.cons = &ar933x_uart_console; +#ifdef CONFIG_SERIAL_AR933X_CONSOLE + ar933x_uart_driver.cons = &ar933x_uart_console; +#endif ret = uart_register_driver(&ar933x_uart_driver); if (ret) -- GitLab From 423ad0b9b095a23e3cde27f2e79e6835e134968e Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 19 Mar 2019 12:56:23 +0000 Subject: [PATCH 0322/1121] KVM: arm/arm64: vgic-its: Take the srcu lock when parsing the memslots [ Upstream commit 7494cec6cb3ba7385a6a223b81906384f15aae34 ] Calling kvm_is_visible_gfn() implies that we're parsing the memslots, and doing this without the srcu lock is frown upon: [12704.164532] ============================= [12704.164544] WARNING: suspicious RCU usage [12704.164560] 5.1.0-rc1-00008-g600025238f51-dirty #16 Tainted: G W [12704.164573] ----------------------------- [12704.164589] ./include/linux/kvm_host.h:605 suspicious rcu_dereference_check() usage! [12704.164602] other info that might help us debug this: [12704.164616] rcu_scheduler_active = 2, debug_locks = 1 [12704.164631] 6 locks held by qemu-system-aar/13968: [12704.164644] #0: 000000007ebdae4f (&kvm->lock){+.+.}, at: vgic_its_set_attr+0x244/0x3a0 [12704.164691] #1: 000000007d751022 (&its->its_lock){+.+.}, at: vgic_its_set_attr+0x250/0x3a0 [12704.164726] #2: 00000000219d2706 (&vcpu->mutex){+.+.}, at: lock_all_vcpus+0x64/0xd0 [12704.164761] #3: 00000000a760aecd (&vcpu->mutex){+.+.}, at: lock_all_vcpus+0x64/0xd0 [12704.164794] #4: 000000000ef8e31d (&vcpu->mutex){+.+.}, at: lock_all_vcpus+0x64/0xd0 [12704.164827] #5: 000000007a872093 (&vcpu->mutex){+.+.}, at: lock_all_vcpus+0x64/0xd0 [12704.164861] stack backtrace: [12704.164878] CPU: 2 PID: 13968 Comm: qemu-system-aar Tainted: G W 5.1.0-rc1-00008-g600025238f51-dirty #16 [12704.164887] Hardware name: rockchip evb_rk3399/evb_rk3399, BIOS 2019.04-rc3-00124-g2feec69fb1 03/15/2019 [12704.164896] Call trace: [12704.164910] dump_backtrace+0x0/0x138 [12704.164920] show_stack+0x24/0x30 [12704.164934] dump_stack+0xbc/0x104 [12704.164946] lockdep_rcu_suspicious+0xcc/0x110 [12704.164958] gfn_to_memslot+0x174/0x190 [12704.164969] kvm_is_visible_gfn+0x28/0x70 [12704.164980] vgic_its_check_id.isra.0+0xec/0x1e8 [12704.164991] vgic_its_save_tables_v0+0x1ac/0x330 [12704.165001] vgic_its_set_attr+0x298/0x3a0 [12704.165012] kvm_device_ioctl_attr+0x9c/0xd8 [12704.165022] kvm_device_ioctl+0x8c/0xf8 [12704.165035] do_vfs_ioctl+0xc8/0x960 [12704.165045] ksys_ioctl+0x8c/0xa0 [12704.165055] __arm64_sys_ioctl+0x28/0x38 [12704.165067] el0_svc_common+0xd8/0x138 [12704.165078] el0_svc_handler+0x38/0x78 [12704.165089] el0_svc+0x8/0xc Make sure the lock is taken when doing this. Fixes: bf308242ab98 ("KVM: arm/arm64: VGIC/ITS: protect kvm_read_guest() calls with SRCU lock") Reviewed-by: Eric Auger Signed-off-by: Marc Zyngier Signed-off-by: Sasha Levin (Microsoft) --- virt/kvm/arm/vgic/vgic-its.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/virt/kvm/arm/vgic/vgic-its.c b/virt/kvm/arm/vgic/vgic-its.c index d72b8481f250..dc06f5e40041 100644 --- a/virt/kvm/arm/vgic/vgic-its.c +++ b/virt/kvm/arm/vgic/vgic-its.c @@ -704,8 +704,9 @@ static bool vgic_its_check_id(struct vgic_its *its, u64 baser, u32 id, int l1_tbl_size = GITS_BASER_NR_PAGES(baser) * SZ_64K; u64 indirect_ptr, type = GITS_BASER_TYPE(baser); int esz = GITS_BASER_ENTRY_SIZE(baser); - int index; + int index, idx; gfn_t gfn; + bool ret; switch (type) { case GITS_BASER_TYPE_DEVICE: @@ -732,7 +733,8 @@ static bool vgic_its_check_id(struct vgic_its *its, u64 baser, u32 id, if (eaddr) *eaddr = addr; - return kvm_is_visible_gfn(its->dev->kvm, gfn); + + goto out; } /* calculate and check the index into the 1st level */ @@ -766,7 +768,12 @@ static bool vgic_its_check_id(struct vgic_its *its, u64 baser, u32 id, if (eaddr) *eaddr = indirect_ptr; - return kvm_is_visible_gfn(its->dev->kvm, gfn); + +out: + idx = srcu_read_lock(&its->dev->kvm->srcu); + ret = kvm_is_visible_gfn(its->dev->kvm, gfn); + srcu_read_unlock(&its->dev->kvm->srcu, idx); + return ret; } static int vgic_its_alloc_collection(struct vgic_its *its, -- GitLab From c276c78434bf90202df2072dd4ca3649dee84b2f Mon Sep 17 00:00:00 2001 From: Guido Kiener Date: Tue, 19 Mar 2019 19:12:03 +0100 Subject: [PATCH 0323/1121] usb: gadget: net2280: Fix overrun of OUT messages [ Upstream commit 9d6a54c1430647355a5e23434881b2ca3d192b48 ] The OUT endpoint normally blocks (NAK) subsequent packets when a short packet was received and returns an incomplete queue entry to the gadget driver. Thereby the gadget driver can detect a short packet when reading queue entries with a length that is not equal to a multiple of packet size. The start_queue() function enables receiving OUT packets regardless of the content of the OUT FIFO. This results in a race: With the current code, it's possible that the "!ep->is_in && (readl(&ep->regs->ep_stat) & BIT(NAK_OUT_PACKETS))" test in start_dma() will fail, then a short packet will be received, and then start_queue() will call stop_out_naking(). That's what we don't want (OUT naking gets turned off while there is data in the FIFO) because then the next driver request might receive a mixture of old and new packets. With the patch, this race can't occur because the FIFO's state is tested after we know that OUT naking is already turned on, and OUT naking is stopped only when both of the conditions are met. This ensures that all received data is delivered to the gadget driver, which can detect a short packet now before new packets are appended to the last short packet. Acked-by: Alan Stern Signed-off-by: Guido Kiener Signed-off-by: Felipe Balbi Signed-off-by: Sasha Levin (Microsoft) --- drivers/usb/gadget/udc/net2280.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c index 9cbb061582a7..a071ab0c163b 100644 --- a/drivers/usb/gadget/udc/net2280.c +++ b/drivers/usb/gadget/udc/net2280.c @@ -870,9 +870,6 @@ static void start_queue(struct net2280_ep *ep, u32 dmactl, u32 td_dma) (void) readl(&ep->dev->pci->pcimstctl); writel(BIT(DMA_START), &dma->dmastat); - - if (!ep->is_in) - stop_out_naking(ep); } static void start_dma(struct net2280_ep *ep, struct net2280_request *req) @@ -911,6 +908,7 @@ static void start_dma(struct net2280_ep *ep, struct net2280_request *req) writel(BIT(DMA_START), &dma->dmastat); return; } + stop_out_naking(ep); } tmp = dmactl_default; -- GitLab From 12d9d2e9ce986f89d86686559d29ac4a3fba674a Mon Sep 17 00:00:00 2001 From: Guido Kiener Date: Mon, 18 Mar 2019 09:18:33 +0100 Subject: [PATCH 0324/1121] usb: gadget: net2280: Fix net2280_dequeue() [ Upstream commit f1d3fba17cd4eeea20397f1324b7b9c69a6a935c ] When a request must be dequeued with net2280_dequeue() e.g. due to a device clear action and the same request is finished by the function scan_dma_completions() then the function net2280_dequeue() does not find the request in the following search loop and returns the error -EINVAL without restoring the status ep->stopped. Thus the endpoint keeps blocked and does not receive any data anymore. This fix restores the status and does not issue an error message. Acked-by: Alan Stern Signed-off-by: Guido Kiener Signed-off-by: Felipe Balbi Signed-off-by: Sasha Levin (Microsoft) --- drivers/usb/gadget/udc/net2280.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c index a071ab0c163b..170327f84ea1 100644 --- a/drivers/usb/gadget/udc/net2280.c +++ b/drivers/usb/gadget/udc/net2280.c @@ -1277,9 +1277,9 @@ static int net2280_dequeue(struct usb_ep *_ep, struct usb_request *_req) break; } if (&req->req != _req) { + ep->stopped = stopped; spin_unlock_irqrestore(&ep->dev->lock, flags); - dev_err(&ep->dev->pdev->dev, "%s: Request mismatch\n", - __func__); + ep_dbg(ep->dev, "%s: Request mismatch\n", __func__); return -EINVAL; } -- GitLab From 5aedac453b9bb16a00087cc6cd6f2138c8366f37 Mon Sep 17 00:00:00 2001 From: Guido Kiener Date: Mon, 18 Mar 2019 09:18:34 +0100 Subject: [PATCH 0325/1121] usb: gadget: net2272: Fix net2272_dequeue() [ Upstream commit 091dacc3cc10979ab0422f0a9f7fcc27eee97e69 ] Restore the status of ep->stopped in function net2272_dequeue(). When the given request is not found in the endpoint queue the function returns -EINVAL without restoring the state of ep->stopped. Thus the endpoint keeps blocked and does not transfer any data anymore. This fix is only compile-tested, since we do not have a corresponding hardware. An analogous fix was tested in the sibling driver. See "usb: gadget: net2280: Fix net2280_dequeue()" Acked-by: Alan Stern Signed-off-by: Guido Kiener Signed-off-by: Felipe Balbi Signed-off-by: Sasha Levin (Microsoft) --- drivers/usb/gadget/udc/net2272.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/gadget/udc/net2272.c b/drivers/usb/gadget/udc/net2272.c index e0759a826b60..7fb31a3b53e6 100644 --- a/drivers/usb/gadget/udc/net2272.c +++ b/drivers/usb/gadget/udc/net2272.c @@ -958,6 +958,7 @@ net2272_dequeue(struct usb_ep *_ep, struct usb_request *_req) break; } if (&req->req != _req) { + ep->stopped = stopped; spin_unlock_irqrestore(&ep->dev->lock, flags); return -EINVAL; } -- GitLab From a4ab77747e79a39c09a10f16a004453bce095e89 Mon Sep 17 00:00:00 2001 From: Marco Felsch Date: Mon, 4 Mar 2019 11:49:40 +0100 Subject: [PATCH 0326/1121] ARM: dts: pfla02: increase phy reset duration [ Upstream commit 032f85c9360fb1a08385c584c2c4ed114b33c260 ] Increase the reset duration to ensure correct phy functionality. The reset duration is taken from barebox commit 52fdd510de ("ARM: dts: pfla02: use long enough reset for ethernet phy"): Use a longer reset time for ethernet phy Micrel KSZ9031RNX. Otherwise a small percentage of modules have 'transmission timeouts' errors like barebox@Phytec phyFLEX-i.MX6 Quad Carrier-Board:/ ifup eth0 warning: No MAC address set. Using random address 7e:94:4d:02:f8:f3 eth0: 1000Mbps full duplex link detected eth0: transmission timeout T eth0: transmission timeout T eth0: transmission timeout T eth0: transmission timeout T eth0: transmission timeout Cc: Stefan Christ Cc: Christian Hemp Signed-off-by: Marco Felsch Fixes: 3180f956668e ("ARM: dts: Phytec imx6q pfla02 and pbab01 support") Signed-off-by: Shawn Guo Signed-off-by: Sasha Levin (Microsoft) --- arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi index d81b0078a100..25b0704c6054 100644 --- a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi +++ b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi @@ -89,6 +89,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enet>; phy-mode = "rgmii"; + phy-reset-duration = <10>; /* in msecs */ phy-reset-gpios = <&gpio3 23 GPIO_ACTIVE_LOW>; phy-supply = <&vdd_eth_io_reg>; status = "disabled"; -- GitLab From fce7c596c8bd726c07c09008134fa1ea9baceea1 Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Wed, 20 Mar 2019 15:02:00 +0100 Subject: [PATCH 0327/1121] net: ks8851: Dequeue RX packets explicitly [ Upstream commit 536d3680fd2dab5c39857d62a3e084198fc74ff9 ] The ks8851 driver lets the chip auto-dequeue received packets once they have been read in full. It achieves that by setting the ADRFE flag in the RXQCR register ("Auto-Dequeue RXQ Frame Enable"). However if allocation of a packet's socket buffer or retrieval of the packet over the SPI bus fails, the packet will not have been read in full and is not auto-dequeued. Such partial retrieval of a packet confuses the chip's RX queue management: On the next RX interrupt, the first packet read from the queue will be the one left there previously and this one can be retrieved without issues. But for any newly received packets, the frame header status and byte count registers (RXFHSR and RXFHBCR) contain bogus values, preventing their retrieval. The chip allows explicitly dequeueing a packet from the RX queue by setting the RRXEF flag in the RXQCR register ("Release RX Error Frame"). This could be used to dequeue the packet in case of an error, but if that error is a failed SPI transfer, it is unknown if the packet was transferred in full and was auto-dequeued or if it was only transferred in part and requires an explicit dequeue. The safest approach is thus to always dequeue packets explicitly and forgo auto-dequeueing. Without this change, I've witnessed packet retrieval break completely when an SPI DMA transfer fails, requiring a chip reset. Explicit dequeueing magically fixes this and makes packet retrieval absolutely robust for me. The chip's documentation suggests auto-dequeuing and uses the RRXEF flag only to dequeue error frames which the driver doesn't want to retrieve. But that seems to be a fair-weather approach. Signed-off-by: Lukas Wunner Cc: Frank Pavlic Cc: Ben Dooks Cc: Tristram Ha Signed-off-by: David S. Miller Signed-off-by: Sasha Levin (Microsoft) --- drivers/net/ethernet/micrel/ks8851.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c index 2fe96f1f3fe5..556666b0d756 100644 --- a/drivers/net/ethernet/micrel/ks8851.c +++ b/drivers/net/ethernet/micrel/ks8851.c @@ -526,9 +526,8 @@ static void ks8851_rx_pkts(struct ks8851_net *ks) /* set dma read address */ ks8851_wrreg16(ks, KS_RXFDPR, RXFDPR_RXFPAI | 0x00); - /* start the packet dma process, and set auto-dequeue rx */ - ks8851_wrreg16(ks, KS_RXQCR, - ks->rc_rxqcr | RXQCR_SDA | RXQCR_ADRFE); + /* start DMA access */ + ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr | RXQCR_SDA); if (rxlen > 4) { unsigned int rxalign; @@ -559,7 +558,8 @@ static void ks8851_rx_pkts(struct ks8851_net *ks) } } - ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr); + /* end DMA access and dequeue packet */ + ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr | RXQCR_RRXEF); } } -- GitLab From 79b7bb03cd4675bc7383420c15281cecf5fb6466 Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Wed, 20 Mar 2019 15:02:00 +0100 Subject: [PATCH 0328/1121] net: ks8851: Reassert reset pin if chip ID check fails [ Upstream commit 761cfa979a0c177d6c2d93ef5585cd79ae49a7d5 ] Commit 73fdeb82e963 ("net: ks8851: Add optional vdd_io regulator and reset gpio") amended the ks8851 driver to briefly assert the chip's reset pin on probe. It also amended the probe routine's error path to reassert the reset pin if a subsequent initialization step fails. However the commit misplaced reassertion of the reset pin in the error path such that it is not performed if the check of the Chip ID and Enable Register (CIDER) fails. The error path is therefore slightly asymmetrical to the probe routine's body. Fix it. Signed-off-by: Lukas Wunner Cc: Frank Pavlic Cc: Stephen Boyd Cc: Nishanth Menon Signed-off-by: David S. Miller Signed-off-by: Sasha Levin (Microsoft) --- drivers/net/ethernet/micrel/ks8851.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c index 556666b0d756..546a79b9cb15 100644 --- a/drivers/net/ethernet/micrel/ks8851.c +++ b/drivers/net/ethernet/micrel/ks8851.c @@ -1545,9 +1545,9 @@ static int ks8851_probe(struct spi_device *spi) free_irq(ndev->irq, ks); err_irq: +err_id: if (gpio_is_valid(gpio)) gpio_set_value(gpio, 0); -err_id: regulator_disable(ks->vdd_reg); err_reg: regulator_disable(ks->vdd_io); -- GitLab From 64e8347986d0962dfbb335c5a6754bb261c69aa9 Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Wed, 20 Mar 2019 15:02:00 +0100 Subject: [PATCH 0329/1121] net: ks8851: Delay requesting IRQ until opened [ Upstream commit d268f31552794abf5b6aa5af31021643411f25f5 ] The ks8851 driver currently requests the IRQ before registering the net_device. Because the net_device name is used as IRQ name and is still "eth%d" when the IRQ is requested, it's impossibe to tell IRQs apart if multiple ks8851 chips are present. Most other drivers delay requesting the IRQ until the net_device is opened. Do the same. The driver doesn't enable interrupts on the chip before opening the net_device and disables them when closing it, so there doesn't seem to be a need to request the IRQ already on probe. Signed-off-by: Lukas Wunner Cc: Frank Pavlic Cc: Ben Dooks Cc: Tristram Ha Signed-off-by: David S. Miller Signed-off-by: Sasha Levin (Microsoft) --- drivers/net/ethernet/micrel/ks8851.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c index 546a79b9cb15..b8f20aa2b7ad 100644 --- a/drivers/net/ethernet/micrel/ks8851.c +++ b/drivers/net/ethernet/micrel/ks8851.c @@ -776,6 +776,15 @@ static void ks8851_tx_work(struct work_struct *work) static int ks8851_net_open(struct net_device *dev) { struct ks8851_net *ks = netdev_priv(dev); + int ret; + + ret = request_threaded_irq(dev->irq, NULL, ks8851_irq, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, + dev->name, ks); + if (ret < 0) { + netdev_err(dev, "failed to get irq\n"); + return ret; + } /* lock the card, even if we may not actually be doing anything * else at the moment */ @@ -890,6 +899,8 @@ static int ks8851_net_stop(struct net_device *dev) dev_kfree_skb(txb); } + free_irq(dev->irq, ks); + return 0; } @@ -1520,14 +1531,6 @@ static int ks8851_probe(struct spi_device *spi) ks8851_read_selftest(ks); ks8851_init_mac(ks); - ret = request_threaded_irq(spi->irq, NULL, ks8851_irq, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, - ndev->name, ks); - if (ret < 0) { - dev_err(&spi->dev, "failed to get irq\n"); - goto err_irq; - } - ret = register_netdev(ndev); if (ret) { dev_err(&spi->dev, "failed to register network device\n"); @@ -1540,11 +1543,7 @@ static int ks8851_probe(struct spi_device *spi) return 0; - err_netdev: - free_irq(ndev->irq, ks); - -err_irq: err_id: if (gpio_is_valid(gpio)) gpio_set_value(gpio, 0); @@ -1565,7 +1564,6 @@ static int ks8851_remove(struct spi_device *spi) dev_info(&spi->dev, "remove\n"); unregister_netdev(priv->netdev); - free_irq(spi->irq, priv); if (gpio_is_valid(priv->gpio)) gpio_set_value(priv->gpio, 0); regulator_disable(priv->vdd_reg); -- GitLab From b6ca8ec8bb742625e8b2e19e1fcbb3936a543cef Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Wed, 20 Mar 2019 15:02:00 +0100 Subject: [PATCH 0330/1121] net: ks8851: Set initial carrier state to down [ Upstream commit 9624bafa5f6418b9ca5b3f66d1f6a6a2e8bf6d4c ] The ks8851 chip's initial carrier state is down. A Link Change Interrupt is signaled once interrupts are enabled if the carrier is up. The ks8851 driver has it backwards by assuming that the initial carrier state is up. The state is therefore misrepresented if the interface is opened with no cable attached. Fix it. The Link Change interrupt is sometimes not signaled unless the P1MBSR register (which contains the Link Status bit) is read on ->ndo_open(). This might be a hardware erratum. Read the register by calling mii_check_link(), which has the desirable side effect of setting the carrier state to down if the cable was detached while the interface was closed. Signed-off-by: Lukas Wunner Cc: Frank Pavlic Cc: Ben Dooks Cc: Tristram Ha Signed-off-by: David S. Miller Signed-off-by: Sasha Levin (Microsoft) --- drivers/net/ethernet/micrel/ks8851.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c index b8f20aa2b7ad..7ddaa7d88f1d 100644 --- a/drivers/net/ethernet/micrel/ks8851.c +++ b/drivers/net/ethernet/micrel/ks8851.c @@ -849,6 +849,7 @@ static int ks8851_net_open(struct net_device *dev) netif_dbg(ks, ifup, ks->netdev, "network device up\n"); mutex_unlock(&ks->lock); + mii_check_link(&ks->mii); return 0; } @@ -1510,6 +1511,7 @@ static int ks8851_probe(struct spi_device *spi) spi_set_drvdata(spi, ks); + netif_carrier_off(ks->netdev); ndev->if_port = IF_PORT_100BASET; ndev->netdev_ops = &ks8851_netdev_ops; ndev->irq = spi->irq; -- GitLab From 6849e040a935a09fdfee55c7f9fe12609921c489 Mon Sep 17 00:00:00 2001 From: Aditya Pakki Date: Wed, 20 Mar 2019 12:21:35 -0500 Subject: [PATCH 0331/1121] staging: rtl8188eu: Fix potential NULL pointer dereference of kcalloc [ Upstream commit 7671ce0d92933762f469266daf43bd34d422d58c ] hwxmits is allocated via kcalloc and not checked for failure before its dereference. The patch fixes this problem by returning error upstream in rtl8723bs, rtl8188eu. Signed-off-by: Aditya Pakki Acked-by: Mukesh Ojha Reviewed-by: Hans de Goede Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin (Microsoft) --- drivers/staging/rtl8188eu/core/rtw_xmit.c | 9 +++++++-- drivers/staging/rtl8188eu/include/rtw_xmit.h | 2 +- drivers/staging/rtl8723bs/core/rtw_xmit.c | 14 +++++++------- drivers/staging/rtl8723bs/include/rtw_xmit.h | 2 +- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_xmit.c b/drivers/staging/rtl8188eu/core/rtw_xmit.c index be2f46eb9f78..904b988ecc4e 100644 --- a/drivers/staging/rtl8188eu/core/rtw_xmit.c +++ b/drivers/staging/rtl8188eu/core/rtw_xmit.c @@ -188,7 +188,9 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter) pxmitpriv->free_xmit_extbuf_cnt = num_xmit_extbuf; - rtw_alloc_hwxmits(padapter); + res = rtw_alloc_hwxmits(padapter); + if (res == _FAIL) + goto exit; rtw_init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry); for (i = 0; i < 4; i++) @@ -1573,7 +1575,7 @@ s32 rtw_xmit_classifier(struct adapter *padapter, struct xmit_frame *pxmitframe) return res; } -void rtw_alloc_hwxmits(struct adapter *padapter) +s32 rtw_alloc_hwxmits(struct adapter *padapter) { struct hw_xmit *hwxmits; struct xmit_priv *pxmitpriv = &padapter->xmitpriv; @@ -1582,6 +1584,8 @@ void rtw_alloc_hwxmits(struct adapter *padapter) pxmitpriv->hwxmits = kcalloc(pxmitpriv->hwxmit_entry, sizeof(struct hw_xmit), GFP_KERNEL); + if (!pxmitpriv->hwxmits) + return _FAIL; hwxmits = pxmitpriv->hwxmits; @@ -1589,6 +1593,7 @@ void rtw_alloc_hwxmits(struct adapter *padapter) hwxmits[1] .sta_queue = &pxmitpriv->vi_pending; hwxmits[2] .sta_queue = &pxmitpriv->be_pending; hwxmits[3] .sta_queue = &pxmitpriv->bk_pending; + return _SUCCESS; } void rtw_free_hwxmits(struct adapter *padapter) diff --git a/drivers/staging/rtl8188eu/include/rtw_xmit.h b/drivers/staging/rtl8188eu/include/rtw_xmit.h index dd6b7a9a8d4a..1be4b478475a 100644 --- a/drivers/staging/rtl8188eu/include/rtw_xmit.h +++ b/drivers/staging/rtl8188eu/include/rtw_xmit.h @@ -342,7 +342,7 @@ s32 rtw_txframes_sta_ac_pending(struct adapter *padapter, void rtw_init_hwxmits(struct hw_xmit *phwxmit, int entry); s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter); void _rtw_free_xmit_priv(struct xmit_priv *pxmitpriv); -void rtw_alloc_hwxmits(struct adapter *padapter); +s32 rtw_alloc_hwxmits(struct adapter *padapter); void rtw_free_hwxmits(struct adapter *padapter); s32 rtw_xmit(struct adapter *padapter, struct sk_buff **pkt); diff --git a/drivers/staging/rtl8723bs/core/rtw_xmit.c b/drivers/staging/rtl8723bs/core/rtw_xmit.c index 022f654419e4..91dab7f8a739 100644 --- a/drivers/staging/rtl8723bs/core/rtw_xmit.c +++ b/drivers/staging/rtl8723bs/core/rtw_xmit.c @@ -271,7 +271,9 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter) } } - rtw_alloc_hwxmits(padapter); + res = rtw_alloc_hwxmits(padapter); + if (res == _FAIL) + goto exit; rtw_init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry); for (i = 0; i < 4; i++) { @@ -2157,7 +2159,7 @@ s32 rtw_xmit_classifier(struct adapter *padapter, struct xmit_frame *pxmitframe) return res; } -void rtw_alloc_hwxmits(struct adapter *padapter) +s32 rtw_alloc_hwxmits(struct adapter *padapter) { struct hw_xmit *hwxmits; struct xmit_priv *pxmitpriv = &padapter->xmitpriv; @@ -2168,10 +2170,8 @@ void rtw_alloc_hwxmits(struct adapter *padapter) pxmitpriv->hwxmits = (struct hw_xmit *)rtw_zmalloc(sizeof(struct hw_xmit) * pxmitpriv->hwxmit_entry); - if (pxmitpriv->hwxmits == NULL) { - DBG_871X("alloc hwxmits fail!...\n"); - return; - } + if (!pxmitpriv->hwxmits) + return _FAIL; hwxmits = pxmitpriv->hwxmits; @@ -2217,7 +2217,7 @@ void rtw_alloc_hwxmits(struct adapter *padapter) } - + return _SUCCESS; } void rtw_free_hwxmits(struct adapter *padapter) diff --git a/drivers/staging/rtl8723bs/include/rtw_xmit.h b/drivers/staging/rtl8723bs/include/rtw_xmit.h index 11571649cd2c..92236ca8a1ef 100644 --- a/drivers/staging/rtl8723bs/include/rtw_xmit.h +++ b/drivers/staging/rtl8723bs/include/rtw_xmit.h @@ -494,7 +494,7 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter); void _rtw_free_xmit_priv (struct xmit_priv *pxmitpriv); -void rtw_alloc_hwxmits(struct adapter *padapter); +s32 rtw_alloc_hwxmits(struct adapter *padapter); void rtw_free_hwxmits(struct adapter *padapter); -- GitLab From 726d8583abf43495475f5e95189bdeb28c57e015 Mon Sep 17 00:00:00 2001 From: Aditya Pakki Date: Wed, 20 Mar 2019 12:02:49 -0500 Subject: [PATCH 0332/1121] staging: rtlwifi: rtl8822b: fix to avoid potential NULL pointer dereference [ Upstream commit d70d70aec9632679dd00dcc1b1e8b2517e2c7da0 ] skb allocated via dev_alloc_skb can fail and return a NULL pointer. This patch avoids such a scenario and returns, consistent with other invocations. Signed-off-by: Aditya Pakki Reviewed-by: Mukesh Ojha Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin (Microsoft) --- drivers/staging/rtlwifi/rtl8822be/fw.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/rtlwifi/rtl8822be/fw.c b/drivers/staging/rtlwifi/rtl8822be/fw.c index acabb2470d55..02ca3157c5a5 100644 --- a/drivers/staging/rtlwifi/rtl8822be/fw.c +++ b/drivers/staging/rtlwifi/rtl8822be/fw.c @@ -752,6 +752,8 @@ void rtl8822be_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished) u1_rsvd_page_loc, 3); skb = dev_alloc_skb(totalpacketlen); + if (!skb) + return; memcpy((u8 *)skb_put(skb, totalpacketlen), &reserved_page_packet, totalpacketlen); -- GitLab From 9db1d06bd4ada8ffd0605cc31daca8f410aa7548 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 21 Mar 2019 09:26:38 +0300 Subject: [PATCH 0333/1121] staging: rtl8712: uninitialized memory in read_bbreg_hdl() [ Upstream commit 22c971db7dd4b0ad8dd88e99c407f7a1f4231a2e ] Colin King reported a bug in read_bbreg_hdl(): memcpy(pcmd->rsp, (u8 *)&val, pcmd->rspsz); The problem is that "val" is uninitialized. This code is obviously not useful, but so far as I can tell "pcmd->cmdcode" is never GEN_CMD_CODE(_Read_BBREG) so it's not harmful either. For now the easiest fix is to just call r8712_free_cmd_obj() and return. Fixes: 2865d42c78a9 ("staging: r8712u: Add the new driver to the mainline kernel") Reported-by: Colin Ian King Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin (Microsoft) --- drivers/staging/rtl8712/rtl8712_cmd.c | 10 +--------- drivers/staging/rtl8712/rtl8712_cmd.h | 2 +- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/staging/rtl8712/rtl8712_cmd.c b/drivers/staging/rtl8712/rtl8712_cmd.c index 0104aced113e..ccda04e916c5 100644 --- a/drivers/staging/rtl8712/rtl8712_cmd.c +++ b/drivers/staging/rtl8712/rtl8712_cmd.c @@ -159,17 +159,9 @@ static u8 write_macreg_hdl(struct _adapter *padapter, u8 *pbuf) static u8 read_bbreg_hdl(struct _adapter *padapter, u8 *pbuf) { - u32 val; - void (*pcmd_callback)(struct _adapter *dev, struct cmd_obj *pcmd); struct cmd_obj *pcmd = (struct cmd_obj *)pbuf; - if (pcmd->rsp && pcmd->rspsz > 0) - memcpy(pcmd->rsp, (u8 *)&val, pcmd->rspsz); - pcmd_callback = cmd_callback[pcmd->cmdcode].callback; - if (!pcmd_callback) - r8712_free_cmd_obj(pcmd); - else - pcmd_callback(padapter, pcmd); + r8712_free_cmd_obj(pcmd); return H2C_SUCCESS; } diff --git a/drivers/staging/rtl8712/rtl8712_cmd.h b/drivers/staging/rtl8712/rtl8712_cmd.h index 67e9e910aef9..d10a59d4a550 100644 --- a/drivers/staging/rtl8712/rtl8712_cmd.h +++ b/drivers/staging/rtl8712/rtl8712_cmd.h @@ -152,7 +152,7 @@ enum rtl8712_h2c_cmd { static struct _cmd_callback cmd_callback[] = { {GEN_CMD_CODE(_Read_MACREG), NULL}, /*0*/ {GEN_CMD_CODE(_Write_MACREG), NULL}, - {GEN_CMD_CODE(_Read_BBREG), &r8712_getbbrfreg_cmdrsp_callback}, + {GEN_CMD_CODE(_Read_BBREG), NULL}, {GEN_CMD_CODE(_Write_BBREG), NULL}, {GEN_CMD_CODE(_Read_RFREG), &r8712_getbbrfreg_cmdrsp_callback}, {GEN_CMD_CODE(_Write_RFREG), NULL}, /*5*/ -- GitLab From d1e7cfba1e8952b4d7f03d7acb14822c29f743e5 Mon Sep 17 00:00:00 2001 From: Aditya Pakki Date: Wed, 20 Mar 2019 10:42:32 -0500 Subject: [PATCH 0334/1121] staging: rtlwifi: Fix potential NULL pointer dereference of kzalloc [ Upstream commit 6a8ca24590a2136921439b376c926c11a6effc0e ] phydm.internal is allocated using kzalloc which is used multiple times without a check for NULL pointer. This patch avoids such a scenario by returning 0, consistent with the failure case. Signed-off-by: Aditya Pakki Reviewed-by: Mukesh Ojha Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin (Microsoft) --- drivers/staging/rtlwifi/phydm/rtl_phydm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/rtlwifi/phydm/rtl_phydm.c b/drivers/staging/rtlwifi/phydm/rtl_phydm.c index 85e490d3601f..cab563fefc34 100644 --- a/drivers/staging/rtlwifi/phydm/rtl_phydm.c +++ b/drivers/staging/rtlwifi/phydm/rtl_phydm.c @@ -191,6 +191,8 @@ static int rtl_phydm_init_priv(struct rtl_priv *rtlpriv, rtlpriv->phydm.internal = kzalloc(sizeof(struct phy_dm_struct), GFP_KERNEL); + if (!rtlpriv->phydm.internal) + return 0; _rtl_phydm_init_com_info(rtlpriv, ic, params); -- GitLab From 670588f2eb0f9f8ada16d834935bd535c31f482b Mon Sep 17 00:00:00 2001 From: Harini Katakam Date: Wed, 20 Mar 2019 19:12:22 +0530 Subject: [PATCH 0335/1121] net: macb: Add null check for PCLK and HCLK [ Upstream commit cd5afa91f078c0787be0a62b5ef90301c00b0271 ] Both PCLK and HCLK are "required" clocks according to macb devicetree documentation. There is a chance that devm_clk_get doesn't return a negative error but just a NULL clock structure instead. In such a case the driver proceeds as usual and uses pclk value 0 to calculate MDC divisor which is incorrect. Hence fix the same in clock initialization. Signed-off-by: Harini Katakam Signed-off-by: David S. Miller Signed-off-by: Sasha Levin (Microsoft) --- drivers/net/ethernet/cadence/macb_main.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 9046993947cc..2287749de087 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -2817,14 +2817,20 @@ static int macb_clk_init(struct platform_device *pdev, struct clk **pclk, *hclk = devm_clk_get(&pdev->dev, "hclk"); } - if (IS_ERR(*pclk)) { + if (IS_ERR_OR_NULL(*pclk)) { err = PTR_ERR(*pclk); + if (!err) + err = -ENODEV; + dev_err(&pdev->dev, "failed to get macb_clk (%u)\n", err); return err; } - if (IS_ERR(*hclk)) { + if (IS_ERR_OR_NULL(*hclk)) { err = PTR_ERR(*hclk); + if (!err) + err = -ENODEV; + dev_err(&pdev->dev, "failed to get hclk (%u)\n", err); return err; } -- GitLab From d2e7387e5128e2182a90e82ff36a5dab4cd0c1bc Mon Sep 17 00:00:00 2001 From: Davide Caratti Date: Wed, 20 Mar 2019 15:00:15 +0100 Subject: [PATCH 0336/1121] net/sched: don't dereference a->goto_chain to read the chain index [ Upstream commit fe384e2fa36ca084a456fd30558cccc75b4b3fbd ] callers of tcf_gact_goto_chain_index() can potentially read an old value of the chain index, or even dereference a NULL 'goto_chain' pointer, because 'goto_chain' and 'tcfa_action' are read in the traffic path without caring of concurrent write in the control path. The most recent value of chain index can be read also from a->tcfa_action (it's encoded there together with TC_ACT_GOTO_CHAIN bits), so we don't really need to dereference 'goto_chain': just read the chain id from the control action. Fixes: e457d86ada27 ("net: sched: add couple of goto_chain helpers") Signed-off-by: Davide Caratti Signed-off-by: David S. Miller Signed-off-by: Sasha Levin (Microsoft) --- include/net/tc_act/tc_gact.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/net/tc_act/tc_gact.h b/include/net/tc_act/tc_gact.h index e82d93346b63..bb74ea83d57d 100644 --- a/include/net/tc_act/tc_gact.h +++ b/include/net/tc_act/tc_gact.h @@ -51,7 +51,7 @@ static inline bool is_tcf_gact_goto_chain(const struct tc_action *a) static inline u32 tcf_gact_goto_chain_index(const struct tc_action *a) { - return a->goto_chain->index; + return READ_ONCE(a->tcfa_action) & TC_ACT_EXT_VAL_MASK; } #endif /* __NET_TC_GACT_H */ -- GitLab From d4644c90586bfcdac2800fe4e9a94b5cd35996c7 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Tue, 19 Mar 2019 01:30:09 +0900 Subject: [PATCH 0337/1121] ARM: dts: imx6qdl: Fix typo in imx6qdl-icore-rqs.dtsi [ Upstream commit 41b37f4c0fa67185691bcbd30201cad566f2f0d1 ] This patch fixes a spelling typo. Signed-off-by: Masanari Iida Fixes: cc42603de320 ("ARM: dts: imx6q-icore-rqs: Add Engicam IMX6 Q7 initial support") Signed-off-by: Shawn Guo Signed-off-by: Sasha Levin (Microsoft) --- arch/arm/boot/dts/imx6qdl-icore-rqs.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/imx6qdl-icore-rqs.dtsi b/arch/arm/boot/dts/imx6qdl-icore-rqs.dtsi index 7ca291e9dbdb..80f1b3fb6abc 100644 --- a/arch/arm/boot/dts/imx6qdl-icore-rqs.dtsi +++ b/arch/arm/boot/dts/imx6qdl-icore-rqs.dtsi @@ -222,7 +222,7 @@ pinctrl-2 = <&pinctrl_usdhc3_200mhz>; vmcc-supply = <®_sd3_vmmc>; cd-gpios = <&gpio1 1 GPIO_ACTIVE_LOW>; - bus-witdh = <4>; + bus-width = <4>; no-1-8-v; status = "okay"; }; @@ -233,7 +233,7 @@ pinctrl-1 = <&pinctrl_usdhc4_100mhz>; pinctrl-2 = <&pinctrl_usdhc4_200mhz>; vmcc-supply = <®_sd4_vmmc>; - bus-witdh = <8>; + bus-width = <8>; no-1-8-v; non-removable; status = "okay"; -- GitLab From b341405561703aaadd50d88cad873a9d287e8a48 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 21 Mar 2019 17:57:56 -0400 Subject: [PATCH 0338/1121] NFS: Fix a typo in nfs_init_timeout_values() [ Upstream commit 5a698243930c441afccec04e4d5dc8febfd2b775 ] Specifying a retrans=0 mount parameter to a NFS/TCP mount, is inadvertently causing the NFS client to rewrite any specified timeout parameter to the default of 60 seconds. Fixes: a956beda19a6 ("NFS: Allow the mount option retrans=0") Signed-off-by: Trond Myklebust Signed-off-by: Sasha Levin (Microsoft) --- fs/nfs/client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 7d6ddfd60271..a98d64a6eda5 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -459,7 +459,7 @@ void nfs_init_timeout_values(struct rpc_timeout *to, int proto, case XPRT_TRANSPORT_RDMA: if (retrans == NFS_UNSPEC_RETRANS) to->to_retries = NFS_DEF_TCP_RETRANS; - if (timeo == NFS_UNSPEC_TIMEO || to->to_retries == 0) + if (timeo == NFS_UNSPEC_TIMEO || to->to_initval == 0) to->to_initval = NFS_DEF_TCP_TIMEO * HZ / 10; if (to->to_initval > NFS_MAX_TCP_TIMEOUT) to->to_initval = NFS_MAX_TCP_TIMEOUT; -- GitLab From 709606ec20c9144c44b49cf5a1d4b91710a22e95 Mon Sep 17 00:00:00 2001 From: Wen Yang Date: Fri, 22 Mar 2019 11:04:07 +0800 Subject: [PATCH 0339/1121] net: xilinx: fix possible object reference leak [ Upstream commit fa3a419d2f674b431d38748cb58fb7da17ee8949 ] The call to of_parse_phandle returns a node pointer with refcount incremented thus it must be explicitly decremented after the last usage. Detected by coccinelle with the following warnings: ./drivers/net/ethernet/xilinx/xilinx_axienet_main.c:1624:1-7: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 1569, but without a corresponding object release within this function. Signed-off-by: Wen Yang Cc: Anirudha Sarangi Cc: John Linn Cc: "David S. Miller" Cc: Michal Simek Cc: netdev@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org Signed-off-by: David S. Miller Signed-off-by: Sasha Levin (Microsoft) --- drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index e74e1e897864..d46dc8cd1670 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -1575,12 +1575,14 @@ static int axienet_probe(struct platform_device *pdev) ret = of_address_to_resource(np, 0, &dmares); if (ret) { dev_err(&pdev->dev, "unable to get DMA resource\n"); + of_node_put(np); goto free_netdev; } lp->dma_regs = devm_ioremap_resource(&pdev->dev, &dmares); if (IS_ERR(lp->dma_regs)) { dev_err(&pdev->dev, "could not map DMA regs\n"); ret = PTR_ERR(lp->dma_regs); + of_node_put(np); goto free_netdev; } lp->rx_irq = irq_of_parse_and_map(np, 1); -- GitLab From 0f45a8b6c9cec97e42df825a2050d6c32c50e248 Mon Sep 17 00:00:00 2001 From: Wen Yang Date: Fri, 22 Mar 2019 11:04:08 +0800 Subject: [PATCH 0340/1121] net: ibm: fix possible object reference leak [ Upstream commit be693df3cf9dd113ff1d2c0d8150199efdba37f6 ] The call to ehea_get_eth_dn returns a node pointer with refcount incremented thus it must be explicitly decremented after the last usage. Detected by coccinelle with the following warnings: ./drivers/net/ethernet/ibm/ehea/ehea_main.c:3163:2-8: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 3154, but without a corresponding object release within this function. Signed-off-by: Wen Yang Cc: Douglas Miller Cc: "David S. Miller" Cc: netdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: David S. Miller Signed-off-by: Sasha Levin (Microsoft) --- drivers/net/ethernet/ibm/ehea/ehea_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/ibm/ehea/ehea_main.c b/drivers/net/ethernet/ibm/ehea/ehea_main.c index 4878b7169e0f..30cbdf0fed59 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_main.c +++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c @@ -3176,6 +3176,7 @@ static ssize_t ehea_probe_port(struct device *dev, if (ehea_add_adapter_mr(adapter)) { pr_err("creating MR failed\n"); + of_node_put(eth_dn); return -EIO; } -- GitLab From 6d18191c3eb53d25e2df7e46a86c3964efdb0394 Mon Sep 17 00:00:00 2001 From: Wen Yang Date: Fri, 22 Mar 2019 11:04:09 +0800 Subject: [PATCH 0341/1121] net: ethernet: ti: fix possible object reference leak [ Upstream commit 75eac7b5f68b0a0671e795ac636457ee27cc11d8 ] The call to of_get_child_by_name returns a node pointer with refcount incremented thus it must be explicitly decremented after the last usage. Detected by coccinelle with the following warnings: ./drivers/net/ethernet/ti/netcp_ethss.c:3661:2-8: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 3654, but without a corresponding object release within this function. ./drivers/net/ethernet/ti/netcp_ethss.c:3665:2-8: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 3654, but without a corresponding object release within this function. Signed-off-by: Wen Yang Cc: Wingman Kwok Cc: Murali Karicheri Cc: "David S. Miller" Cc: netdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: David S. Miller Signed-off-by: Sasha Levin (Microsoft) --- drivers/net/ethernet/ti/netcp_ethss.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/ti/netcp_ethss.c b/drivers/net/ethernet/ti/netcp_ethss.c index 28cb38af1a34..ff7a71ca0b13 100644 --- a/drivers/net/ethernet/ti/netcp_ethss.c +++ b/drivers/net/ethernet/ti/netcp_ethss.c @@ -3538,12 +3538,16 @@ static int gbe_probe(struct netcp_device *netcp_device, struct device *dev, ret = netcp_txpipe_init(&gbe_dev->tx_pipe, netcp_device, gbe_dev->dma_chan_name, gbe_dev->tx_queue_id); - if (ret) + if (ret) { + of_node_put(interfaces); return ret; + } ret = netcp_txpipe_open(&gbe_dev->tx_pipe); - if (ret) + if (ret) { + of_node_put(interfaces); return ret; + } /* Create network interfaces */ INIT_LIST_HEAD(&gbe_dev->gbe_intf_head); -- GitLab From ecb44816ba352d9bcf8e0d814d452cbbe45f8bfb Mon Sep 17 00:00:00 2001 From: Kangjie Lu Date: Sun, 24 Mar 2019 18:10:02 -0500 Subject: [PATCH 0342/1121] gpio: aspeed: fix a potential NULL pointer dereference [ Upstream commit 6cf4511e9729c00a7306cf94085f9cc3c52ee723 ] In case devm_kzalloc, the patch returns ENOMEM to avoid potential NULL pointer dereference. Signed-off-by: Kangjie Lu Reviewed-by: Andrew Jeffery Signed-off-by: Bartosz Golaszewski Signed-off-by: Sasha Levin (Microsoft) --- drivers/gpio/gpio-aspeed.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpio/gpio-aspeed.c b/drivers/gpio/gpio-aspeed.c index f03fe916eb9d..f6d1bda8a802 100644 --- a/drivers/gpio/gpio-aspeed.c +++ b/drivers/gpio/gpio-aspeed.c @@ -861,6 +861,8 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev) gpio->offset_timer = devm_kzalloc(&pdev->dev, gpio->chip.ngpio, GFP_KERNEL); + if (!gpio->offset_timer) + return -ENOMEM; return aspeed_gpio_setup_irqs(gpio, pdev); } -- GitLab From afc0ca59516b928d7efa6a416ee9d4b1bb52ef1e Mon Sep 17 00:00:00 2001 From: Jean-Philippe Brucker Date: Fri, 22 Mar 2019 15:26:56 +0000 Subject: [PATCH 0343/1121] drm/meson: Fix invalid pointer in meson_drv_unbind() [ Upstream commit 776e78677f514ecddd12dba48b9040958999bd5a ] meson_drv_bind() registers a meson_drm struct as the device's privdata, but meson_drv_unbind() tries to retrieve a drm_device. This may cause a segfault on shutdown: [ 5194.593429] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000197 ... [ 5194.788850] Call trace: [ 5194.791349] drm_dev_unregister+0x1c/0x118 [drm] [ 5194.795848] meson_drv_unbind+0x50/0x78 [meson_drm] Retrieve the right pointer in meson_drv_unbind(). Fixes: bbbe775ec5b5 ("drm: Add support for Amlogic Meson Graphic Controller") Signed-off-by: Jean-Philippe Brucker Acked-by: Neil Armstrong Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20190322152657.13752-1-jean-philippe.brucker@arm.com Signed-off-by: Sasha Levin (Microsoft) --- drivers/gpu/drm/meson/meson_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c index 5deb44ac6791..1a1b0b9cf1fa 100644 --- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c @@ -294,8 +294,8 @@ static int meson_drv_bind(struct device *dev) static void meson_drv_unbind(struct device *dev) { - struct drm_device *drm = dev_get_drvdata(dev); - struct meson_drm *priv = drm->dev_private; + struct meson_drm *priv = dev_get_drvdata(dev); + struct drm_device *drm = priv->drm; drm_dev_unregister(drm); drm_kms_helper_poll_fini(drm); -- GitLab From 12ec9f9267db6de43c524a5be7291f4863e4181d Mon Sep 17 00:00:00 2001 From: Jean-Philippe Brucker Date: Fri, 22 Mar 2019 15:26:57 +0000 Subject: [PATCH 0344/1121] drm/meson: Uninstall IRQ handler [ Upstream commit 2d8f92897ad816f5dda54b2ed2fd9f2d7cb1abde ] meson_drv_unbind() doesn't unregister the IRQ handler, which can lead to use-after-free if the IRQ fires after unbind: [ 64.656876] Unable to handle kernel paging request at virtual address ffff000011706dbc ... [ 64.662001] pc : meson_irq+0x18/0x30 [meson_drm] I'm assuming that a similar problem could happen on the error path of bind(), so uninstall the IRQ handler there as well. Fixes: bbbe775ec5b5 ("drm: Add support for Amlogic Meson Graphic Controller") Signed-off-by: Jean-Philippe Brucker Acked-by: Neil Armstrong Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20190322152657.13752-2-jean-philippe.brucker@arm.com Signed-off-by: Sasha Levin (Microsoft) --- drivers/gpu/drm/meson/meson_drv.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c index 1a1b0b9cf1fa..0608243c3387 100644 --- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c @@ -277,10 +277,12 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) ret = drm_dev_register(drm, 0); if (ret) - goto free_drm; + goto uninstall_irq; return 0; +uninstall_irq: + drm_irq_uninstall(drm); free_drm: drm_dev_unref(drm); @@ -298,6 +300,7 @@ static void meson_drv_unbind(struct device *dev) struct drm_device *drm = priv->drm; drm_dev_unregister(drm); + drm_irq_uninstall(drm); drm_kms_helper_poll_fini(drm); drm_fbdev_cma_fini(priv->fbdev); drm_mode_config_cleanup(drm); -- GitLab From 5d429f762470c15b7bc2d5b3f3bb2e5bb41c22d6 Mon Sep 17 00:00:00 2001 From: Kangjie Lu Date: Thu, 14 Mar 2019 01:30:59 -0500 Subject: [PATCH 0345/1121] scsi: qla4xxx: fix a potential NULL pointer dereference [ Upstream commit fba1bdd2a9a93f3e2181ec1936a3c2f6b37e7ed6 ] In case iscsi_lookup_endpoint fails, the fix returns -EINVAL to avoid NULL pointer dereference. Signed-off-by: Kangjie Lu Acked-by: Manish Rangankar Reviewed-by: Mukesh Ojha Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin (Microsoft) --- drivers/scsi/qla4xxx/ql4_os.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 22dc70a2138e..630b7404843d 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -3207,6 +3207,8 @@ static int qla4xxx_conn_bind(struct iscsi_cls_session *cls_session, if (iscsi_conn_bind(cls_session, cls_conn, is_leading)) return -EINVAL; ep = iscsi_lookup_endpoint(transport_fd); + if (!ep) + return -EINVAL; conn = cls_conn->dd_data; qla_conn = conn->dd_data; qla_conn->qla_ep = ep->dd_data; -- GitLab From 085df4a0edb58e5dfe6a661a5dcc5e0e3cfbf4c1 Mon Sep 17 00:00:00 2001 From: Aditya Pakki Date: Wed, 20 Mar 2019 10:27:11 -0500 Subject: [PATCH 0346/1121] usb: usb251xb: fix to avoid potential NULL pointer dereference [ Upstream commit 41f00e6e9e55546390031996b773e7f3c1d95928 ] of_match_device in usb251xb_probe can fail and returns a NULL pointer. The patch avoids a potential NULL pointer dereference in this scenario. Signed-off-by: Aditya Pakki Reviewed-by: Richard Leitner Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin (Microsoft) --- drivers/usb/misc/usb251xb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/misc/usb251xb.c b/drivers/usb/misc/usb251xb.c index 135c91c434bf..ba8fcdb377e8 100644 --- a/drivers/usb/misc/usb251xb.c +++ b/drivers/usb/misc/usb251xb.c @@ -530,7 +530,7 @@ static int usb251xb_probe(struct usb251xb *hub) dev); int err; - if (np) { + if (np && of_id) { err = usb251xb_get_ofdata(hub, (struct usb251xb_data *)of_id->data); if (err) { -- GitLab From cbce4a687c47514c5221a3506a69b83078e6a413 Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Tue, 26 Mar 2019 13:42:22 +0530 Subject: [PATCH 0347/1121] usb: u132-hcd: fix resource leak [ Upstream commit f276e002793cdb820862e8ea8f76769d56bba575 ] if platform_driver_register fails, cleanup the allocated resource gracefully. Signed-off-by: Mukesh Ojha Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin (Microsoft) --- drivers/usb/host/u132-hcd.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index 65c0086e25ae..8d349230b2c7 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c @@ -3208,6 +3208,9 @@ static int __init u132_hcd_init(void) printk(KERN_INFO "driver %s\n", hcd_name); workqueue = create_singlethread_workqueue("u132"); retval = platform_driver_register(&u132_platform_driver); + if (retval) + destroy_workqueue(workqueue); + return retval; } -- GitLab From 9b0d0e776dae15f613549ae6dcf0e097705c84df Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 26 Mar 2019 01:38:58 +0000 Subject: [PATCH 0348/1121] ceph: fix use-after-free on symlink traversal [ Upstream commit daf5cc27eed99afdea8d96e71b89ba41f5406ef6 ] free the symlink body after the same RCU delay we have for freeing the struct inode itself, so that traversal during RCU pathwalk wouldn't step into freed memory. Signed-off-by: Al Viro Reviewed-by: Jeff Layton Signed-off-by: Ilya Dryomov Signed-off-by: Sasha Levin (Microsoft) --- fs/ceph/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index a1492bdc6d03..f2b722f0df5d 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -520,6 +520,7 @@ static void ceph_i_callback(struct rcu_head *head) struct inode *inode = container_of(head, struct inode, i_rcu); struct ceph_inode_info *ci = ceph_inode(inode); + kfree(ci->i_symlink); kmem_cache_free(ceph_inode_cachep, ci); } @@ -551,7 +552,6 @@ void ceph_destroy_inode(struct inode *inode) ceph_put_snap_realm(mdsc, realm); } - kfree(ci->i_symlink); while ((n = rb_first(&ci->i_fragtree)) != NULL) { frag = rb_entry(n, struct ceph_inode_frag, node); rb_erase(n, &ci->i_fragtree); -- GitLab From 790d908cbdeea0bd711ffb25ba03a522fcbcd195 Mon Sep 17 00:00:00 2001 From: Steffen Maier Date: Tue, 26 Mar 2019 14:37:00 +0100 Subject: [PATCH 0349/1121] scsi: zfcp: reduce flood of fcrscn1 trace records on multi-element RSCN [ Upstream commit c8206579175c34a2546de8a74262456278a7795a ] If an incoming ELS of type RSCN contains more than one element, zfcp suboptimally causes repeated erp trigger NOP trace records for each previously failed port. These could be ports that went away. It loops over each RSCN element, and for each of those in an inner loop over all zfcp_ports. The trigger to recover failed ports should be just the reception of some RSCN, no matter how many elements it has. So we can loop over failed ports separately, and only then loop over each RSCN element to handle the non-failed ports. The call chain was: zfcp_fc_incoming_rscn for (i = 1; i < no_entries; i++) _zfcp_fc_incoming_rscn list_for_each_entry(port, &adapter->port_list, list) if (masked port->d_id match) zfcp_fc_test_link if (!port->d_id) zfcp_erp_port_reopen "fcrscn1" <=== In order the reduce the "flooding" of the REC trace area in such cases, we factor out handling the failed ports to be outside of the entries loop: zfcp_fc_incoming_rscn if (no_entries > 1) <=== list_for_each_entry(port, &adapter->port_list, list) <=== if (!port->d_id) zfcp_erp_port_reopen "fcrscn1" <=== for (i = 1; i < no_entries; i++) _zfcp_fc_incoming_rscn list_for_each_entry(port, &adapter->port_list, list) if (masked port->d_id match) zfcp_fc_test_link Abbreviated example trace records before this code change: Tag : fcrscn1 WWPN : 0x500507630310d327 ERP want : 0x02 ERP need : 0x02 Tag : fcrscn1 WWPN : 0x500507630310d327 ERP want : 0x02 ERP need : 0x00 NOP => superfluous trace record The last trace entry repeats if there are more than 2 RSCN elements. Signed-off-by: Steffen Maier Reviewed-by: Benjamin Block Reviewed-by: Jens Remus Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin (Microsoft) --- drivers/s390/scsi/zfcp_fc.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c index ca218c82321f..0c5fd722a72d 100644 --- a/drivers/s390/scsi/zfcp_fc.c +++ b/drivers/s390/scsi/zfcp_fc.c @@ -240,10 +240,6 @@ static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range, list_for_each_entry(port, &adapter->port_list, list) { if ((port->d_id & range) == (ntoh24(page->rscn_fid) & range)) zfcp_fc_test_link(port); - if (!port->d_id) - zfcp_erp_port_reopen(port, - ZFCP_STATUS_COMMON_ERP_FAILED, - "fcrscn1"); } read_unlock_irqrestore(&adapter->port_list_lock, flags); } @@ -251,6 +247,7 @@ static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range, static void zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req) { struct fsf_status_read_buffer *status_buffer = (void *)fsf_req->data; + struct zfcp_adapter *adapter = fsf_req->adapter; struct fc_els_rscn *head; struct fc_els_rscn_page *page; u16 i; @@ -264,6 +261,22 @@ static void zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req) no_entries = be16_to_cpu(head->rscn_plen) / sizeof(struct fc_els_rscn_page); + if (no_entries > 1) { + /* handle failed ports */ + unsigned long flags; + struct zfcp_port *port; + + read_lock_irqsave(&adapter->port_list_lock, flags); + list_for_each_entry(port, &adapter->port_list, list) { + if (port->d_id) + continue; + zfcp_erp_port_reopen(port, + ZFCP_STATUS_COMMON_ERP_FAILED, + "fcrscn1"); + } + read_unlock_irqrestore(&adapter->port_list_lock, flags); + } + for (i = 1; i < no_entries; i++) { /* skip head and start with 1st element */ page++; -- GitLab From 6a56dc1e2087e013446e69f5a4879575036eb995 Mon Sep 17 00:00:00 2001 From: raymond pang Date: Thu, 28 Mar 2019 12:19:25 +0000 Subject: [PATCH 0350/1121] libata: fix using DMA buffers on stack [ Upstream commit dd08a8d9a66de4b54575c294a92630299f7e0fe7 ] When CONFIG_VMAP_STACK=y, __pa() returns incorrect physical address for a stack virtual address. Stack DMA buffers must be avoided. Signed-off-by: raymond pang Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin (Microsoft) --- drivers/ata/libata-zpodd.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/drivers/ata/libata-zpodd.c b/drivers/ata/libata-zpodd.c index b3ed8f9953a8..173e6f2dd9af 100644 --- a/drivers/ata/libata-zpodd.c +++ b/drivers/ata/libata-zpodd.c @@ -52,38 +52,52 @@ static int eject_tray(struct ata_device *dev) /* Per the spec, only slot type and drawer type ODD can be supported */ static enum odd_mech_type zpodd_get_mech_type(struct ata_device *dev) { - char buf[16]; + char *buf; unsigned int ret; - struct rm_feature_desc *desc = (void *)(buf + 8); + struct rm_feature_desc *desc; struct ata_taskfile tf; static const char cdb[] = { GPCMD_GET_CONFIGURATION, 2, /* only 1 feature descriptor requested */ 0, 3, /* 3, removable medium feature */ 0, 0, 0,/* reserved */ - 0, sizeof(buf), + 0, 16, 0, 0, 0, }; + buf = kzalloc(16, GFP_KERNEL); + if (!buf) + return ODD_MECH_TYPE_UNSUPPORTED; + desc = (void *)(buf + 8); + ata_tf_init(dev, &tf); tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; tf.command = ATA_CMD_PACKET; tf.protocol = ATAPI_PROT_PIO; - tf.lbam = sizeof(buf); + tf.lbam = 16; ret = ata_exec_internal(dev, &tf, cdb, DMA_FROM_DEVICE, - buf, sizeof(buf), 0); - if (ret) + buf, 16, 0); + if (ret) { + kfree(buf); return ODD_MECH_TYPE_UNSUPPORTED; + } - if (be16_to_cpu(desc->feature_code) != 3) + if (be16_to_cpu(desc->feature_code) != 3) { + kfree(buf); return ODD_MECH_TYPE_UNSUPPORTED; + } - if (desc->mech_type == 0 && desc->load == 0 && desc->eject == 1) + if (desc->mech_type == 0 && desc->load == 0 && desc->eject == 1) { + kfree(buf); return ODD_MECH_TYPE_SLOT; - else if (desc->mech_type == 1 && desc->load == 0 && desc->eject == 1) + } else if (desc->mech_type == 1 && desc->load == 0 && + desc->eject == 1) { + kfree(buf); return ODD_MECH_TYPE_DRAWER; - else + } else { + kfree(buf); return ODD_MECH_TYPE_UNSUPPORTED; + } } /* Test if ODD is zero power ready by sense code */ -- GitLab From d23be337c71d9951d754c31f7c680a148535ea11 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 28 Mar 2019 14:13:47 +0100 Subject: [PATCH 0351/1121] gpio: of: Fix of_gpiochip_add() error path [ Upstream commit f7299d441a4da8a5088e651ea55023525a793a13 ] If the call to of_gpiochip_scan_gpios() in of_gpiochip_add() fails, no error handling is performed. This lead to the need of callers to call of_gpiochip_remove() on failure, which causes "BAD of_node_put() on ..." if the failure happened before the call to of_node_get(). Fix this by adding proper error handling. Note that calling gpiochip_remove_pin_ranges() multiple times causes no harm: subsequent calls are a no-op. Fixes: dfbd379ba9b7431e ("gpio: of: Return error if gpio hog configuration failed") Signed-off-by: Geert Uytterhoeven Reviewed-by: Mukesh Ojha Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin (Microsoft) --- drivers/gpio/gpiolib-of.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index ee8c046cab62..d6ed4e891b34 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -499,7 +499,13 @@ int of_gpiochip_add(struct gpio_chip *chip) of_node_get(chip->of_node); - return of_gpiochip_scan_gpios(chip); + status = of_gpiochip_scan_gpios(chip); + if (status) { + of_node_put(chip->of_node); + gpiochip_remove_pin_ranges(chip); + } + + return status; } void of_gpiochip_remove(struct gpio_chip *chip) -- GitLab From 03f9b44775f88a4b916f87fb9be6c6055e4647b9 Mon Sep 17 00:00:00 2001 From: Changbin Du Date: Mon, 25 Mar 2019 15:16:47 +0000 Subject: [PATCH 0352/1121] kconfig/[mn]conf: handle backspace (^H) key [ Upstream commit 9c38f1f044080392603c497ecca4d7d09876ff99 ] Backspace is not working on some terminal emulators which do not send the key code defined by terminfo. Terminals either send '^H' (8) or '^?' (127). But currently only '^?' is handled. Let's also handle '^H' for those terminals. Signed-off-by: Changbin Du Signed-off-by: Masahiro Yamada Signed-off-by: Sasha Levin (Microsoft) --- scripts/kconfig/lxdialog/inputbox.c | 3 ++- scripts/kconfig/nconf.c | 2 +- scripts/kconfig/nconf.gui.c | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/scripts/kconfig/lxdialog/inputbox.c b/scripts/kconfig/lxdialog/inputbox.c index d58de1dc5360..510049a7bd1d 100644 --- a/scripts/kconfig/lxdialog/inputbox.c +++ b/scripts/kconfig/lxdialog/inputbox.c @@ -126,7 +126,8 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width case KEY_DOWN: break; case KEY_BACKSPACE: - case 127: + case 8: /* ^H */ + case 127: /* ^? */ if (pos) { wattrset(dialog, dlg.inputbox.atr); if (input_x == 0) { diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index 003114779815..e8e1944fa09b 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -1048,7 +1048,7 @@ static int do_match(int key, struct match_state *state, int *ans) state->match_direction = FIND_NEXT_MATCH_UP; *ans = get_mext_match(state->pattern, state->match_direction); - } else if (key == KEY_BACKSPACE || key == 127) { + } else if (key == KEY_BACKSPACE || key == 8 || key == 127) { state->pattern[strlen(state->pattern)-1] = '\0'; adj_match_dir(&state->match_direction); } else diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c index a64b1c31253e..0b63357f1d33 100644 --- a/scripts/kconfig/nconf.gui.c +++ b/scripts/kconfig/nconf.gui.c @@ -439,7 +439,8 @@ int dialog_inputbox(WINDOW *main_window, case KEY_F(F_EXIT): case KEY_F(F_BACK): break; - case 127: + case 8: /* ^H */ + case 127: /* ^? */ case KEY_BACKSPACE: if (cursor_position > 0) { memmove(&result[cursor_position-1], -- GitLab From 0af211ec4928af9a01a1b0c81e999e00cd728706 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Thu, 28 Mar 2019 11:44:59 +0100 Subject: [PATCH 0353/1121] iommu/amd: Reserve exclusion range in iova-domain [ Upstream commit 8aafaaf2212192012f5bae305bb31cdf7681d777 ] If a device has an exclusion range specified in the IVRS table, this region needs to be reserved in the iova-domain of that device. This hasn't happened until now and can cause data corruption on data transfered with these devices. Treat exclusion ranges as reserved regions in the iommu-core to fix the problem. Fixes: be2a022c0dd0 ('x86, AMD IOMMU: add functions to parse IOMMU memory mapping requirements for devices') Signed-off-by: Joerg Roedel Reviewed-by: Gary R Hook Signed-off-by: Sasha Levin (Microsoft) --- drivers/iommu/amd_iommu.c | 9 ++++++--- drivers/iommu/amd_iommu_init.c | 7 ++++--- drivers/iommu/amd_iommu_types.h | 2 ++ 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index bd339bfe0d15..684f7cdd814b 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -3127,21 +3127,24 @@ static void amd_iommu_get_resv_regions(struct device *dev, return; list_for_each_entry(entry, &amd_iommu_unity_map, list) { + int type, prot = 0; size_t length; - int prot = 0; if (devid < entry->devid_start || devid > entry->devid_end) continue; + type = IOMMU_RESV_DIRECT; length = entry->address_end - entry->address_start; if (entry->prot & IOMMU_PROT_IR) prot |= IOMMU_READ; if (entry->prot & IOMMU_PROT_IW) prot |= IOMMU_WRITE; + if (entry->prot & IOMMU_UNITY_MAP_FLAG_EXCL_RANGE) + /* Exclusion range */ + type = IOMMU_RESV_RESERVED; region = iommu_alloc_resv_region(entry->address_start, - length, prot, - IOMMU_RESV_DIRECT); + length, prot, type); if (!region) { pr_err("Out of memory allocating dm-regions for %s\n", dev_name(dev)); diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index b97984a5ddad..91d7718625a6 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -1980,6 +1980,9 @@ static int __init init_unity_map_range(struct ivmd_header *m) if (e == NULL) return -ENOMEM; + if (m->flags & IVMD_FLAG_EXCL_RANGE) + init_exclusion_range(m); + switch (m->type) { default: kfree(e); @@ -2026,9 +2029,7 @@ static int __init init_memory_definitions(struct acpi_table_header *table) while (p < end) { m = (struct ivmd_header *)p; - if (m->flags & IVMD_FLAG_EXCL_RANGE) - init_exclusion_range(m); - else if (m->flags & IVMD_FLAG_UNITY_MAP) + if (m->flags & (IVMD_FLAG_UNITY_MAP | IVMD_FLAG_EXCL_RANGE)) init_unity_map_range(m); p += m->length; diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h index f6b24c7d8b70..3054c0971759 100644 --- a/drivers/iommu/amd_iommu_types.h +++ b/drivers/iommu/amd_iommu_types.h @@ -369,6 +369,8 @@ #define IOMMU_PROT_IR 0x01 #define IOMMU_PROT_IW 0x02 +#define IOMMU_UNITY_MAP_FLAG_EXCL_RANGE (1 << 2) + /* IOMMU capabilities */ #define IOMMU_CAP_IOTLB 24 #define IOMMU_CAP_NPCACHE 26 -- GitLab From fd76b2d5045f0a23e4fa2199500af326e5a1081c Mon Sep 17 00:00:00 2001 From: Andrei Vagin Date: Thu, 28 Mar 2019 20:44:13 -0700 Subject: [PATCH 0354/1121] ptrace: take into account saved_sigmask in PTRACE{GET,SET}SIGMASK [ Upstream commit fcfc2aa0185f4a731d05a21e9f359968fdfd02e7 ] There are a few system calls (pselect, ppoll, etc) which replace a task sigmask while they are running in a kernel-space When a task calls one of these syscalls, the kernel saves a current sigmask in task->saved_sigmask and sets a syscall sigmask. On syscall-exit-stop, ptrace traps a task before restoring the saved_sigmask, so PTRACE_GETSIGMASK returns the syscall sigmask and PTRACE_SETSIGMASK does nothing, because its sigmask is replaced by saved_sigmask, when the task returns to user-space. This patch fixes this problem. PTRACE_GETSIGMASK returns saved_sigmask if it's set. PTRACE_SETSIGMASK drops the TIF_RESTORE_SIGMASK flag. Link: http://lkml.kernel.org/r/20181120060616.6043-1-avagin@gmail.com Fixes: 29000caecbe8 ("ptrace: add ability to get/set signal-blocked mask") Signed-off-by: Andrei Vagin Acked-by: Oleg Nesterov Cc: "Eric W. Biederman" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Sasha Levin (Microsoft) --- include/linux/sched/signal.h | 18 ++++++++++++++++++ kernel/ptrace.c | 15 +++++++++++++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h index fbf86ecd149d..bcaba7e8ca6e 100644 --- a/include/linux/sched/signal.h +++ b/include/linux/sched/signal.h @@ -377,10 +377,20 @@ static inline void set_restore_sigmask(void) set_thread_flag(TIF_RESTORE_SIGMASK); WARN_ON(!test_thread_flag(TIF_SIGPENDING)); } + +static inline void clear_tsk_restore_sigmask(struct task_struct *tsk) +{ + clear_tsk_thread_flag(tsk, TIF_RESTORE_SIGMASK); +} + static inline void clear_restore_sigmask(void) { clear_thread_flag(TIF_RESTORE_SIGMASK); } +static inline bool test_tsk_restore_sigmask(struct task_struct *tsk) +{ + return test_tsk_thread_flag(tsk, TIF_RESTORE_SIGMASK); +} static inline bool test_restore_sigmask(void) { return test_thread_flag(TIF_RESTORE_SIGMASK); @@ -398,6 +408,10 @@ static inline void set_restore_sigmask(void) current->restore_sigmask = true; WARN_ON(!test_thread_flag(TIF_SIGPENDING)); } +static inline void clear_tsk_restore_sigmask(struct task_struct *tsk) +{ + tsk->restore_sigmask = false; +} static inline void clear_restore_sigmask(void) { current->restore_sigmask = false; @@ -406,6 +420,10 @@ static inline bool test_restore_sigmask(void) { return current->restore_sigmask; } +static inline bool test_tsk_restore_sigmask(struct task_struct *tsk) +{ + return tsk->restore_sigmask; +} static inline bool test_and_clear_restore_sigmask(void) { if (!current->restore_sigmask) diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 84b1367935e4..f1c85b6c39ae 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -29,6 +29,7 @@ #include #include #include +#include /* * Access another process' address space via ptrace. @@ -925,18 +926,26 @@ int ptrace_request(struct task_struct *child, long request, ret = ptrace_setsiginfo(child, &siginfo); break; - case PTRACE_GETSIGMASK: + case PTRACE_GETSIGMASK: { + sigset_t *mask; + if (addr != sizeof(sigset_t)) { ret = -EINVAL; break; } - if (copy_to_user(datavp, &child->blocked, sizeof(sigset_t))) + if (test_tsk_restore_sigmask(child)) + mask = &child->saved_sigmask; + else + mask = &child->blocked; + + if (copy_to_user(datavp, mask, sizeof(sigset_t))) ret = -EFAULT; else ret = 0; break; + } case PTRACE_SETSIGMASK: { sigset_t new_set; @@ -962,6 +971,8 @@ int ptrace_request(struct task_struct *child, long request, child->blocked = new_set; spin_unlock_irq(&child->sighand->siglock); + clear_tsk_restore_sigmask(child); + ret = 0; break; } -- GitLab From 464f7643bbcfb383a3a5436c58eb5c512e791c51 Mon Sep 17 00:00:00 2001 From: Kangjie Lu Date: Sat, 9 Mar 2019 00:04:11 -0600 Subject: [PATCH 0355/1121] leds: pca9532: fix a potential NULL pointer dereference [ Upstream commit 0aab8e4df4702b31314a27ec4b0631dfad0fae0a ] In case of_match_device cannot find a match, return -EINVAL to avoid NULL pointer dereference. Fixes: fa4191a609f2 ("leds: pca9532: Add device tree support") Signed-off-by: Kangjie Lu Signed-off-by: Jacek Anaszewski Signed-off-by: Sasha Levin (Microsoft) --- drivers/leds/leds-pca9532.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/leds/leds-pca9532.c b/drivers/leds/leds-pca9532.c index 7fea18b0c15d..7cb4d685a1f1 100644 --- a/drivers/leds/leds-pca9532.c +++ b/drivers/leds/leds-pca9532.c @@ -513,6 +513,7 @@ static int pca9532_probe(struct i2c_client *client, const struct i2c_device_id *id) { int devid; + const struct of_device_id *of_id; struct pca9532_data *data = i2c_get_clientdata(client); struct pca9532_platform_data *pca9532_pdata = dev_get_platdata(&client->dev); @@ -528,8 +529,11 @@ static int pca9532_probe(struct i2c_client *client, dev_err(&client->dev, "no platform data\n"); return -EINVAL; } - devid = (int)(uintptr_t)of_match_device( - of_pca9532_leds_match, &client->dev)->data; + of_id = of_match_device(of_pca9532_leds_match, + &client->dev); + if (unlikely(!of_id)) + return -EINVAL; + devid = (int)(uintptr_t) of_id->data; } else { devid = id->driver_data; } -- GitLab From 6d1510d86ef67e5fadb8038671e2ec43416daf7f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 4 May 2019 09:15:23 +0200 Subject: [PATCH 0356/1121] Linux 4.14.116 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b27ffc1814e8..7dcaffff08a3 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 4 PATCHLEVEL = 14 -SUBLEVEL = 115 +SUBLEVEL = 116 EXTRAVERSION = NAME = Petit Gorille -- GitLab From 0f36e8ef37042ff5db96ebb8b31a80e54ccb6234 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= Date: Sat, 4 May 2019 03:42:27 -0700 Subject: [PATCH 0357/1121] ANDROID: cuttlefish 4.14: enable CONFIG_CRYPTO_AES_NI_INTEL=y MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a recommended configuration option and is listed in: android-4.{9,14,19}/android-recommended-x86.config Generated via: echo 'CONFIG_CRYPTO_AES_NI_INTEL=y' >> arch/x86/configs/x86_64_cuttlefish_defconfig echo 'CONFIG_CRYPTO_AES_NI_INTEL=y' >> arch/arm64/configs/cuttlefish_defconfig make ARCH=x86_64 x86_64_cuttlefish_defconfig make ARCH=x86_64 savedefconfig cat defconfig > arch/x86/configs/x86_64_cuttlefish_defconfig make ARCH=arm64 cuttlefish_defconfig make ARCH=arm64 savedefconfig cat defconfig > arch/arm64/configs/cuttlefish_defconfig rm defconfig Signed-off-by: Maciej Ć»enczykowski Change-Id: I78113acbbe3874ae9bf2f47c2573a4fa40f9b978 --- arch/x86/configs/x86_64_cuttlefish_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig index 2960fa16be1b..9b96bb74af07 100644 --- a/arch/x86/configs/x86_64_cuttlefish_defconfig +++ b/arch/x86/configs/x86_64_cuttlefish_defconfig @@ -479,6 +479,7 @@ CONFIG_CRYPTO_RSA=y # CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set CONFIG_CRYPTO_ADIANTUM=y CONFIG_CRYPTO_SHA512=y +CONFIG_CRYPTO_AES_NI_INTEL=y CONFIG_CRYPTO_LZ4=y CONFIG_CRYPTO_ZSTD=y CONFIG_CRYPTO_DEV_VIRTIO=y -- GitLab From d58c72910a052bead05439e361a936143af9df52 Mon Sep 17 00:00:00 2001 From: Maria Yu Date: Mon, 15 Apr 2019 12:41:12 +0800 Subject: [PATCH 0358/1121] sched/fair: Allow load bigger task load balance when nr_running is 2 When there is only 2 tasks in 1 cpu and the other task is currently running, allow load bigger task to be balanced if the other task is currently running. Change-Id: I489e9624ba010f9293272a67585e8209a786b787 Signed-off-by: Maria Yu --- kernel/sched/fair.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 9c68ee82be70..a8cadfc5b366 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -9274,7 +9274,17 @@ static int detach_tasks(struct lb_env *env) if (sched_feat(LB_MIN) && load < 16 && !env->sd->nr_balance_failed) goto next; - if ((load / 2) > env->imbalance) + /* + * p is not running task when we goes until here, so if p is one + * of the 2 task in src cpu rq and not the running one, + * that means it is the only task that can be balanced. + * So only when there is other tasks can be balanced or + * there is situation to ignore big task, it is needed + * to skip the task load bigger than 2*imbalance. + */ + if (((cpu_rq(env->src_cpu)->nr_running > 2) || + (env->flags & LBF_IGNORE_BIG_TASKS)) && + ((load / 2) > env->imbalance)) goto next; detach_task(p, env); -- GitLab From c1658e57c5ed0fb7eec422843f915f8c59e6264f Mon Sep 17 00:00:00 2001 From: Maria Yu Date: Fri, 26 Apr 2019 15:20:18 +0800 Subject: [PATCH 0359/1121] sched/fair: Check env src_grp_nr_running for active load balance When do active load balance needed check, the environment may changed, so check for env's src_grp_nr_running before src rq h_nr_running check to ensure that's the same envrionment data we tried to do active load balance. Change-Id: Ia9539a43e9769c4936f06ecfcc11864984c50c29 Signed-off-by: Maria Yu --- kernel/sched/fair.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 9c68ee82be70..654acfb2aa9b 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -10809,6 +10809,7 @@ static int need_active_balance(struct lb_env *env) * available on dst_cpu. */ if ((env->idle != CPU_NOT_IDLE) && + (env->src_grp_nr_running == 1) && (env->src_rq->cfs.h_nr_running == 1)) { if ((check_cpu_capacity(env->src_rq, sd)) && (capacity_of(env->src_cpu)*sd->imbalance_pct < capacity_of(env->dst_cpu)*100)) @@ -10818,6 +10819,7 @@ static int need_active_balance(struct lb_env *env) if ((env->idle != CPU_NOT_IDLE) && (capacity_of(env->src_cpu) < capacity_of(env->dst_cpu)) && ((capacity_orig_of(env->src_cpu) < capacity_orig_of(env->dst_cpu))) && + (env->src_grp_nr_running == 1) && env->src_rq->cfs.h_nr_running == 1 && cpu_overutilized(env->src_cpu) && !cpu_overutilized(env->dst_cpu)) { -- GitLab From e6222ba1f95d5cc893f279b2d8ab17b8b9795b03 Mon Sep 17 00:00:00 2001 From: Tejas Prajapati Date: Wed, 24 Apr 2019 16:36:20 +0530 Subject: [PATCH 0360/1121] msm: camera: reqmgr: Skip reset if no request from UMD In case of slot is marked as skip idx it will apply the request and try to reset a previous slot which might have the request for which we have got a bubble. To make sure this does not happen, reset a slot only when the request is valid request and not the last applied request. Change-Id: I03a542baffcd332e030d352df5ce19f4dbcc0dd6 Signed-off-by: Tejas Prajapati --- .../msm/camera/cam_req_mgr/cam_req_mgr_core.c | 11 ++++++++--- .../msm/camera/cam_req_mgr/cam_req_mgr_core.h | 2 ++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c index ee3e94da8aa1..cbb908c7086a 100644 --- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c +++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c @@ -351,7 +351,8 @@ static void __cam_req_mgr_reset_req_slot(struct cam_req_mgr_core_link *link, CAM_DBG(CAM_CRM, "RESET: idx: %d: slot->status %d", idx, slot->status); /* Check if CSL has already pushed new request*/ - if (slot->status == CRM_SLOT_STATUS_REQ_ADDED) + if (slot->status == CRM_SLOT_STATUS_REQ_ADDED || + in_q->last_applied_idx == idx) return; /* Reset input queue slot */ @@ -512,9 +513,11 @@ static int __cam_req_mgr_send_req(struct cam_req_mgr_core_link *link, } if (link->req.apply_data[pd].skip_idx || link->req.apply_data[pd].req_id < 0) { - CAM_DBG(CAM_CRM, "skip %d req_id %lld", + CAM_DBG(CAM_CRM, + "skip %d req_id %lld pd %d dev_name %s", link->req.apply_data[pd].skip_idx, - link->req.apply_data[pd].req_id); + link->req.apply_data[pd].req_id, + pd, dev->dev_info.name); continue; } if (!(dev->dev_info.trigger & trigger)) @@ -1122,6 +1125,8 @@ static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link, slot->req_id, link->link_hdl); idx = in_q->rd_idx; + if (slot->req_id > 0) + in_q->last_applied_idx = idx; reset_step = link->max_delay; if (link->sync_link) { if ((link->in_msync_mode) && diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.h b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.h index 26f5426b67b0..ff522fad6996 100644 --- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.h +++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.h @@ -233,12 +233,14 @@ struct cam_req_mgr_slot { * @slot : request slot holding incoming request id and bubble info. * @rd_idx : indicates slot index currently in process. * @wr_idx : indicates slot index to hold new upcoming req. + * @last_applied_idx : indicates slot index last applied successfully. */ struct cam_req_mgr_req_queue { int32_t num_slots; struct cam_req_mgr_slot slot[MAX_REQ_SLOTS]; int32_t rd_idx; int32_t wr_idx; + int32_t last_applied_idx; }; /** -- GitLab From 9aaf796019b7dd3199ae67824b70a06c46ca9090 Mon Sep 17 00:00:00 2001 From: Rishabh Jain Date: Tue, 7 May 2019 14:21:41 +0530 Subject: [PATCH 0361/1121] msm: camera: Fix cpas axi clk rate overflow Change the clk variable type from int32_t to int64_t to avoid integer overflow. Change-Id: I4031b5389792d57b573f41ab9e3b2d9990640e5a Signed-off-by: Rishabh Jain --- .../media/platform/msm/camera/cam_cpas/cam_cpas_hw.c | 6 +++--- .../platform/msm/camera/cam_utils/cam_soc_util.c | 12 ++++++------ .../platform/msm/camera/cam_utils/cam_soc_util.h | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/media/platform/msm/camera/cam_cpas/cam_cpas_hw.c b/drivers/media/platform/msm/camera/cam_cpas/cam_cpas_hw.c index a05901afba71..4276b356da73 100644 --- a/drivers/media/platform/msm/camera/cam_cpas/cam_cpas_hw.c +++ b/drivers/media/platform/msm/camera/cam_cpas/cam_cpas_hw.c @@ -568,7 +568,7 @@ static int cam_cpas_util_set_camnoc_axi_clk_rate( struct cam_cpas_axi_port *curr_axi_port = NULL; struct cam_cpas_axi_port *temp_axi_port = NULL; uint64_t required_camnoc_bw = 0; - int32_t clk_rate = 0; + int64_t clk_rate = 0; list_for_each_entry_safe(curr_axi_port, temp_axi_port, &cpas_core->axi_ports_list_head, sibling_port) { @@ -596,13 +596,13 @@ static int cam_cpas_util_set_camnoc_axi_clk_rate( clk_rate = required_camnoc_bw / soc_private->camnoc_bus_width; - CAM_DBG(CAM_CPAS, "Setting camnoc axi clk rate : %llu %d", + CAM_DBG(CAM_CPAS, "Setting camnoc axi clk rate : %llu %lld", required_camnoc_bw, clk_rate); rc = cam_soc_util_set_src_clk_rate(soc_info, clk_rate); if (rc) CAM_ERR(CAM_CPAS, - "Failed in setting camnoc axi clk %llu %d %d", + "Failed in setting camnoc axi clk %llu %lld %d", required_camnoc_bw, clk_rate, rc); } diff --git a/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.c b/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.c index 8ba6deb54fbc..7df30337e2ec 100644 --- a/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.c +++ b/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.c @@ -23,7 +23,7 @@ static char supported_clk_info[256]; static char debugfs_dir_name[64]; static int cam_soc_util_get_clk_level(struct cam_hw_soc_info *soc_info, - int32_t src_clk_idx, int32_t clk_rate) + int32_t src_clk_idx, int64_t clk_rate) { int i; long clk_rate_round; @@ -38,7 +38,7 @@ static int cam_soc_util_get_clk_level(struct cam_hw_soc_info *soc_info, for (i = 0; i < CAM_MAX_VOTE; i++) { if (soc_info->clk_rate[i][src_clk_idx] >= clk_rate_round) { CAM_DBG(CAM_UTIL, - "soc = %d round rate = %ld actual = %d", + "soc = %d round rate = %ld actual = %lld", soc_info->clk_rate[i][src_clk_idx], clk_rate_round, clk_rate); return i; @@ -387,7 +387,7 @@ int cam_soc_util_set_clk_flags(struct cam_hw_soc_info *soc_info, * @return: Success or failure */ static int cam_soc_util_set_clk_rate(struct clk *clk, const char *clk_name, - int32_t clk_rate) + int64_t clk_rate) { int rc = 0; long clk_rate_round; @@ -395,7 +395,7 @@ static int cam_soc_util_set_clk_rate(struct clk *clk, const char *clk_name, if (!clk || !clk_name) return -EINVAL; - CAM_DBG(CAM_UTIL, "set %s, rate %d", clk_name, clk_rate); + CAM_DBG(CAM_UTIL, "set %s, rate %lld", clk_name, clk_rate); if (clk_rate > 0) { clk_rate_round = clk_round_rate(clk, clk_rate); CAM_DBG(CAM_UTIL, "new_rate %ld", clk_rate_round); @@ -431,7 +431,7 @@ static int cam_soc_util_set_clk_rate(struct clk *clk, const char *clk_name, } int cam_soc_util_set_src_clk_rate(struct cam_hw_soc_info *soc_info, - int32_t clk_rate) + int64_t clk_rate) { int32_t src_clk_idx; struct clk *clk = NULL; @@ -452,7 +452,7 @@ int cam_soc_util_set_src_clk_rate(struct cam_hw_soc_info *soc_info, if (soc_info->cam_cx_ipeak_enable && clk_rate >= 0) { apply_level = cam_soc_util_get_clk_level(soc_info, src_clk_idx, clk_rate); - CAM_DBG(CAM_UTIL, "set %s, rate %d dev_name = %s\n" + CAM_DBG(CAM_UTIL, "set %s, rate %lld dev_name = %s\n" "apply level = %d", soc_info->clk_name[src_clk_idx], clk_rate, soc_info->dev_name, apply_level); diff --git a/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.h b/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.h index 0ee8445c0129..d0bab027790e 100644 --- a/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.h +++ b/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.h @@ -390,7 +390,7 @@ int cam_soc_util_set_clk_flags(struct cam_hw_soc_info *soc_info, * @return: success or failure */ int cam_soc_util_set_src_clk_rate(struct cam_hw_soc_info *soc_info, - int32_t clk_rate); + int64_t clk_rate); /** * cam_soc_util_get_option_clk_by_name() -- GitLab From c3d06de015a2349c16a3f3b87f78925a36c34464 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 28 Apr 2019 18:04:11 +0200 Subject: [PATCH 0362/1121] ALSA: line6: use dynamic buffers commit e5c812e84f0dece3400d5caf42522287e6ef139f upstream. The line6 driver uses a lot of USB buffers off of the stack, which is not allowed on many systems, causing the driver to crash on some of them. Fix this up by dynamically allocating the buffers with kmalloc() which allows for proper DMA-able memory. Reported-by: Christo Gouws Reported-by: Alan Stern Tested-by: Christo Gouws Cc: stable Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/usb/line6/driver.c | 60 ++++++++++++++++++++++---------------- sound/usb/line6/podhd.c | 21 +++++++------ sound/usb/line6/toneport.c | 24 +++++++++++---- 3 files changed, 65 insertions(+), 40 deletions(-) diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index 167aebf8276e..b223de3defc4 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -344,12 +344,16 @@ int line6_read_data(struct usb_line6 *line6, unsigned address, void *data, { struct usb_device *usbdev = line6->usbdev; int ret; - unsigned char len; + unsigned char *len; unsigned count; if (address > 0xffff || datalen > 0xff) return -EINVAL; + len = kmalloc(sizeof(*len), GFP_KERNEL); + if (!len) + return -ENOMEM; + /* query the serial number: */ ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, @@ -358,7 +362,7 @@ int line6_read_data(struct usb_line6 *line6, unsigned address, void *data, if (ret < 0) { dev_err(line6->ifcdev, "read request failed (error %d)\n", ret); - return ret; + goto exit; } /* Wait for data length. We'll get 0xff until length arrives. */ @@ -368,28 +372,29 @@ int line6_read_data(struct usb_line6 *line6, unsigned address, void *data, ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, - 0x0012, 0x0000, &len, 1, + 0x0012, 0x0000, len, 1, LINE6_TIMEOUT * HZ); if (ret < 0) { dev_err(line6->ifcdev, "receive length failed (error %d)\n", ret); - return ret; + goto exit; } - if (len != 0xff) + if (*len != 0xff) break; } - if (len == 0xff) { + ret = -EIO; + if (*len == 0xff) { dev_err(line6->ifcdev, "read failed after %d retries\n", count); - return -EIO; - } else if (len != datalen) { + goto exit; + } else if (*len != datalen) { /* should be equal or something went wrong */ dev_err(line6->ifcdev, "length mismatch (expected %d, got %d)\n", - (int)datalen, (int)len); - return -EIO; + (int)datalen, (int)*len); + goto exit; } /* receive the result: */ @@ -398,12 +403,12 @@ int line6_read_data(struct usb_line6 *line6, unsigned address, void *data, 0x0013, 0x0000, data, datalen, LINE6_TIMEOUT * HZ); - if (ret < 0) { + if (ret < 0) dev_err(line6->ifcdev, "read failed (error %d)\n", ret); - return ret; - } - return 0; +exit: + kfree(len); + return ret; } EXPORT_SYMBOL_GPL(line6_read_data); @@ -415,12 +420,16 @@ int line6_write_data(struct usb_line6 *line6, unsigned address, void *data, { struct usb_device *usbdev = line6->usbdev; int ret; - unsigned char status; + unsigned char *status; int count; if (address > 0xffff || datalen > 0xffff) return -EINVAL; + status = kmalloc(sizeof(*status), GFP_KERNEL); + if (!status) + return -ENOMEM; + ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, 0x0022, address, data, datalen, @@ -429,7 +438,7 @@ int line6_write_data(struct usb_line6 *line6, unsigned address, void *data, if (ret < 0) { dev_err(line6->ifcdev, "write request failed (error %d)\n", ret); - return ret; + goto exit; } for (count = 0; count < LINE6_READ_WRITE_MAX_RETRIES; count++) { @@ -440,28 +449,29 @@ int line6_write_data(struct usb_line6 *line6, unsigned address, void *data, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 0x0012, 0x0000, - &status, 1, LINE6_TIMEOUT * HZ); + status, 1, LINE6_TIMEOUT * HZ); if (ret < 0) { dev_err(line6->ifcdev, "receiving status failed (error %d)\n", ret); - return ret; + goto exit; } - if (status != 0xff) + if (*status != 0xff) break; } - if (status == 0xff) { + if (*status == 0xff) { dev_err(line6->ifcdev, "write failed after %d retries\n", count); - return -EIO; - } else if (status != 0) { + ret = -EIO; + } else if (*status != 0) { dev_err(line6->ifcdev, "write failed (error %d)\n", ret); - return -EIO; + ret = -EIO; } - - return 0; +exit: + kfree(status); + return ret; } EXPORT_SYMBOL_GPL(line6_write_data); diff --git a/sound/usb/line6/podhd.c b/sound/usb/line6/podhd.c index 451007c27743..ee6a68c6e1c1 100644 --- a/sound/usb/line6/podhd.c +++ b/sound/usb/line6/podhd.c @@ -224,28 +224,32 @@ static void podhd_startup_start_workqueue(unsigned long data) static int podhd_dev_start(struct usb_line6_podhd *pod) { int ret; - u8 init_bytes[8]; + u8 *init_bytes; int i; struct usb_device *usbdev = pod->line6.usbdev; + init_bytes = kmalloc(8, GFP_KERNEL); + if (!init_bytes) + return -ENOMEM; + ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, 0x11, 0, NULL, 0, LINE6_TIMEOUT * HZ); if (ret < 0) { dev_err(pod->line6.ifcdev, "read request failed (error %d)\n", ret); - return ret; + goto exit; } /* NOTE: looks like some kind of ping message */ ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 0x11, 0x0, - &init_bytes, 3, LINE6_TIMEOUT * HZ); + init_bytes, 3, LINE6_TIMEOUT * HZ); if (ret < 0) { dev_err(pod->line6.ifcdev, "receive length failed (error %d)\n", ret); - return ret; + goto exit; } pod->firmware_version = @@ -254,7 +258,7 @@ static int podhd_dev_start(struct usb_line6_podhd *pod) for (i = 0; i <= 16; i++) { ret = line6_read_data(&pod->line6, 0xf000 + 0x08 * i, init_bytes, 8); if (ret < 0) - return ret; + goto exit; } ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), @@ -262,10 +266,9 @@ static int podhd_dev_start(struct usb_line6_podhd *pod) USB_TYPE_STANDARD | USB_RECIP_DEVICE | USB_DIR_OUT, 1, 0, NULL, 0, LINE6_TIMEOUT * HZ); - if (ret < 0) - return ret; - - return 0; +exit: + kfree(init_bytes); + return ret; } static void podhd_startup_workqueue(struct work_struct *work) diff --git a/sound/usb/line6/toneport.c b/sound/usb/line6/toneport.c index ba7975c0d03d..4bdedfa87487 100644 --- a/sound/usb/line6/toneport.c +++ b/sound/usb/line6/toneport.c @@ -365,15 +365,20 @@ static bool toneport_has_source_select(struct usb_line6_toneport *toneport) /* Setup Toneport device. */ -static void toneport_setup(struct usb_line6_toneport *toneport) +static int toneport_setup(struct usb_line6_toneport *toneport) { - int ticks; + int *ticks; struct usb_line6 *line6 = &toneport->line6; struct usb_device *usbdev = line6->usbdev; + ticks = kmalloc(sizeof(*ticks), GFP_KERNEL); + if (!ticks) + return -ENOMEM; + /* sync time on device with host: */ - ticks = (int)get_seconds(); - line6_write_data(line6, 0x80c6, &ticks, 4); + *ticks = (int)get_seconds(); + line6_write_data(line6, 0x80c6, ticks, 4); + kfree(ticks); /* enable device: */ toneport_send_cmd(usbdev, 0x0301, 0x0000); @@ -388,6 +393,7 @@ static void toneport_setup(struct usb_line6_toneport *toneport) toneport_update_led(toneport); mod_timer(&toneport->timer, jiffies + TONEPORT_PCM_DELAY * HZ); + return 0; } /* @@ -451,7 +457,9 @@ static int toneport_init(struct usb_line6 *line6, return err; } - toneport_setup(toneport); + err = toneport_setup(toneport); + if (err) + return err; /* register audio system: */ return snd_card_register(line6->card); @@ -463,7 +471,11 @@ static int toneport_init(struct usb_line6 *line6, */ static int toneport_reset_resume(struct usb_interface *interface) { - toneport_setup(usb_get_intfdata(interface)); + int err; + + err = toneport_setup(usb_get_intfdata(interface)); + if (err) + return err; return line6_resume(interface); } #endif -- GitLab From b8ed0714321f0797e4e8a55740719df34dee9b7d Mon Sep 17 00:00:00 2001 From: Shmulik Ladkani Date: Mon, 29 Apr 2019 16:39:30 +0300 Subject: [PATCH 0363/1121] ipv4: ip_do_fragment: Preserve skb_iif during fragmentation [ Upstream commit d2f0c961148f65bc73eda72b9fa3a4e80973cb49 ] Previously, during fragmentation after forwarding, skb->skb_iif isn't preserved, i.e. 'ip_copy_metadata' does not copy skb_iif from given 'from' skb. As a result, ip_do_fragment's creates fragments with zero skb_iif, leading to inconsistent behavior. Assume for example an eBPF program attached at tc egress (post forwarding) that examines __sk_buff->ingress_ifindex: - the correct iif is observed if forwarding path does not involve fragmentation/refragmentation - a bogus iif is observed if forwarding path involves fragmentation/refragmentatiom Fix, by preserving skb_iif during 'ip_copy_metadata'. Signed-off-by: Shmulik Ladkani Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/ipv4/ip_output.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index e2dd325bed9b..34d49f76d1a7 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -518,6 +518,7 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from) to->pkt_type = from->pkt_type; to->priority = from->priority; to->protocol = from->protocol; + to->skb_iif = from->skb_iif; skb_dst_drop(to); skb_dst_copy(to, from); to->dev = from->dev; -- GitLab From 8b27c0e62854014d84eab7f3290ad3b379b411cc Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sat, 27 Apr 2019 16:49:06 -0700 Subject: [PATCH 0364/1121] ipv6/flowlabel: wait rcu grace period before put_pid() [ Upstream commit 6c0afef5fb0c27758f4d52b2210c61b6bd8b4470 ] syzbot was able to catch a use-after-free read in pid_nr_ns() [1] ip6fl_seq_show() seems to use RCU protection, dereferencing fl->owner.pid but fl_free() releases fl->owner.pid before rcu grace period is started. [1] BUG: KASAN: use-after-free in pid_nr_ns+0x128/0x140 kernel/pid.c:407 Read of size 4 at addr ffff888094012a04 by task syz-executor.0/18087 CPU: 0 PID: 18087 Comm: syz-executor.0 Not tainted 5.1.0-rc6+ #89 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x172/0x1f0 lib/dump_stack.c:113 print_address_description.cold+0x7c/0x20d mm/kasan/report.c:187 kasan_report.cold+0x1b/0x40 mm/kasan/report.c:317 __asan_report_load4_noabort+0x14/0x20 mm/kasan/generic_report.c:131 pid_nr_ns+0x128/0x140 kernel/pid.c:407 ip6fl_seq_show+0x2f8/0x4f0 net/ipv6/ip6_flowlabel.c:794 seq_read+0xad3/0x1130 fs/seq_file.c:268 proc_reg_read+0x1fe/0x2c0 fs/proc/inode.c:227 do_loop_readv_writev fs/read_write.c:701 [inline] do_loop_readv_writev fs/read_write.c:688 [inline] do_iter_read+0x4a9/0x660 fs/read_write.c:922 vfs_readv+0xf0/0x160 fs/read_write.c:984 kernel_readv fs/splice.c:358 [inline] default_file_splice_read+0x475/0x890 fs/splice.c:413 do_splice_to+0x12a/0x190 fs/splice.c:876 splice_direct_to_actor+0x2d2/0x970 fs/splice.c:953 do_splice_direct+0x1da/0x2a0 fs/splice.c:1062 do_sendfile+0x597/0xd00 fs/read_write.c:1443 __do_sys_sendfile64 fs/read_write.c:1498 [inline] __se_sys_sendfile64 fs/read_write.c:1490 [inline] __x64_sys_sendfile64+0x15a/0x220 fs/read_write.c:1490 do_syscall_64+0x103/0x610 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x49/0xbe RIP: 0033:0x458da9 Code: ad b8 fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 7b b8 fb ff c3 66 2e 0f 1f 84 00 00 00 00 RSP: 002b:00007f300d24bc78 EFLAGS: 00000246 ORIG_RAX: 0000000000000028 RAX: ffffffffffffffda RBX: 0000000000000004 RCX: 0000000000458da9 RDX: 00000000200000c0 RSI: 0000000000000008 RDI: 0000000000000007 RBP: 000000000073bf00 R08: 0000000000000000 R09: 0000000000000000 R10: 000000000000005a R11: 0000000000000246 R12: 00007f300d24c6d4 R13: 00000000004c5fa3 R14: 00000000004da748 R15: 00000000ffffffff Allocated by task 17543: save_stack+0x45/0xd0 mm/kasan/common.c:75 set_track mm/kasan/common.c:87 [inline] __kasan_kmalloc mm/kasan/common.c:497 [inline] __kasan_kmalloc.constprop.0+0xcf/0xe0 mm/kasan/common.c:470 kasan_slab_alloc+0xf/0x20 mm/kasan/common.c:505 slab_post_alloc_hook mm/slab.h:437 [inline] slab_alloc mm/slab.c:3393 [inline] kmem_cache_alloc+0x11a/0x6f0 mm/slab.c:3555 alloc_pid+0x55/0x8f0 kernel/pid.c:168 copy_process.part.0+0x3b08/0x7980 kernel/fork.c:1932 copy_process kernel/fork.c:1709 [inline] _do_fork+0x257/0xfd0 kernel/fork.c:2226 __do_sys_clone kernel/fork.c:2333 [inline] __se_sys_clone kernel/fork.c:2327 [inline] __x64_sys_clone+0xbf/0x150 kernel/fork.c:2327 do_syscall_64+0x103/0x610 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x49/0xbe Freed by task 7789: save_stack+0x45/0xd0 mm/kasan/common.c:75 set_track mm/kasan/common.c:87 [inline] __kasan_slab_free+0x102/0x150 mm/kasan/common.c:459 kasan_slab_free+0xe/0x10 mm/kasan/common.c:467 __cache_free mm/slab.c:3499 [inline] kmem_cache_free+0x86/0x260 mm/slab.c:3765 put_pid.part.0+0x111/0x150 kernel/pid.c:111 put_pid+0x20/0x30 kernel/pid.c:105 fl_free+0xbe/0xe0 net/ipv6/ip6_flowlabel.c:102 ip6_fl_gc+0x295/0x3e0 net/ipv6/ip6_flowlabel.c:152 call_timer_fn+0x190/0x720 kernel/time/timer.c:1325 expire_timers kernel/time/timer.c:1362 [inline] __run_timers kernel/time/timer.c:1681 [inline] __run_timers kernel/time/timer.c:1649 [inline] run_timer_softirq+0x652/0x1700 kernel/time/timer.c:1694 __do_softirq+0x266/0x95a kernel/softirq.c:293 The buggy address belongs to the object at ffff888094012a00 which belongs to the cache pid_2 of size 88 The buggy address is located 4 bytes inside of 88-byte region [ffff888094012a00, ffff888094012a58) The buggy address belongs to the page: page:ffffea0002500480 count:1 mapcount:0 mapping:ffff88809a483080 index:0xffff888094012980 flags: 0x1fffc0000000200(slab) raw: 01fffc0000000200 ffffea00018a3508 ffffea0002524a88 ffff88809a483080 raw: ffff888094012980 ffff888094012000 000000010000001b 0000000000000000 page dumped because: kasan: bad access detected Memory state around the buggy address: ffff888094012900: fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc fc ffff888094012980: fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc fc >ffff888094012a00: fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc fc ^ ffff888094012a80: fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc fc ffff888094012b00: fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc fc Fixes: 4f82f45730c6 ("net ip6 flowlabel: Make owner a union of struct pid * and kuid_t") Signed-off-by: Eric Dumazet Cc: Eric W. Biederman Reported-by: syzbot Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/ipv6/ip6_flowlabel.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index 15535ee327c5..6324ad6eb347 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c @@ -94,15 +94,21 @@ static struct ip6_flowlabel *fl_lookup(struct net *net, __be32 label) return fl; } +static void fl_free_rcu(struct rcu_head *head) +{ + struct ip6_flowlabel *fl = container_of(head, struct ip6_flowlabel, rcu); + + if (fl->share == IPV6_FL_S_PROCESS) + put_pid(fl->owner.pid); + kfree(fl->opt); + kfree(fl); +} + static void fl_free(struct ip6_flowlabel *fl) { - if (fl) { - if (fl->share == IPV6_FL_S_PROCESS) - put_pid(fl->owner.pid); - kfree(fl->opt); - kfree_rcu(fl, rcu); - } + if (fl) + call_rcu(&fl->rcu, fl_free_rcu); } static void fl_release(struct ip6_flowlabel *fl) -- GitLab From c572cfef4a599c049dfbe787fb861a1ecc5980dd Mon Sep 17 00:00:00 2001 From: Willem de Bruijn Date: Thu, 25 Apr 2019 12:06:54 -0400 Subject: [PATCH 0365/1121] ipv6: invert flowlabel sharing check in process and user mode [ Upstream commit 95c169251bf734aa555a1e8043e4d88ec97a04ec ] A request for a flowlabel fails in process or user exclusive mode must fail if the caller pid or uid does not match. Invert the test. Previously, the test was unsafe wrt PID recycling, but indeed tested for inequality: fl1->owner != fl->owner Fixes: 4f82f45730c68 ("net ip6 flowlabel: Make owner a union of struct pid* and kuid_t") Signed-off-by: Willem de Bruijn Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/ipv6/ip6_flowlabel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index 6324ad6eb347..6fa2bc236d9e 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c @@ -640,9 +640,9 @@ int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen) if (fl1->share == IPV6_FL_S_EXCL || fl1->share != fl->share || ((fl1->share == IPV6_FL_S_PROCESS) && - (fl1->owner.pid == fl->owner.pid)) || + (fl1->owner.pid != fl->owner.pid)) || ((fl1->share == IPV6_FL_S_USER) && - uid_eq(fl1->owner.uid, fl->owner.uid))) + !uid_eq(fl1->owner.uid, fl->owner.uid))) goto release; err = -ENOMEM; -- GitLab From a5d0034533de766dc3b908da43b172d5d3c295a6 Mon Sep 17 00:00:00 2001 From: Xin Long Date: Mon, 29 Apr 2019 14:16:19 +0800 Subject: [PATCH 0366/1121] sctp: avoid running the sctp state machine recursively [ Upstream commit fbd019737d71e405f86549fd738f81e2ff3dd073 ] Ying triggered a call trace when doing an asconf testing: BUG: scheduling while atomic: swapper/12/0/0x10000100 Call Trace: [] dump_stack+0x19/0x1b [] __schedule_bug+0x64/0x72 [] __schedule+0x9ba/0xa00 [] __cond_resched+0x26/0x30 [] _cond_resched+0x3a/0x50 [] kmem_cache_alloc_node+0x38/0x200 [] __alloc_skb+0x5d/0x2d0 [] sctp_packet_transmit+0x610/0xa20 [sctp] [] sctp_outq_flush+0x2ce/0xc00 [sctp] [] sctp_outq_uncork+0x1c/0x20 [sctp] [] sctp_cmd_interpreter.isra.22+0xc8/0x1460 [sctp] [] sctp_do_sm+0xe1/0x350 [sctp] [] sctp_primitive_ASCONF+0x3d/0x50 [sctp] [] sctp_cmd_interpreter.isra.22+0x114/0x1460 [sctp] [] sctp_do_sm+0xe1/0x350 [sctp] [] sctp_assoc_bh_rcv+0xf4/0x1b0 [sctp] [] sctp_inq_push+0x51/0x70 [sctp] [] sctp_rcv+0xa8b/0xbd0 [sctp] As it shows, the first sctp_do_sm() running under atomic context (NET_RX softirq) invoked sctp_primitive_ASCONF() that uses GFP_KERNEL flag later, and this flag is supposed to be used in non-atomic context only. Besides, sctp_do_sm() was called recursively, which is not expected. Vlad tried to fix this recursive call in Commit c0786693404c ("sctp: Fix oops when sending queued ASCONF chunks") by introducing a new command SCTP_CMD_SEND_NEXT_ASCONF. But it didn't work as this command is still used in the first sctp_do_sm() call, and sctp_primitive_ASCONF() will be called in this command again. To avoid calling sctp_do_sm() recursively, we send the next queued ASCONF not by sctp_primitive_ASCONF(), but by sctp_sf_do_prm_asconf() in the 1st sctp_do_sm() directly. Reported-by: Ying Xu Signed-off-by: Xin Long Acked-by: Neil Horman Acked-by: Marcelo Ricardo Leitner Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- include/net/sctp/command.h | 1 - net/sctp/sm_sideeffect.c | 29 ----------------------------- net/sctp/sm_statefuns.c | 35 +++++++++++++++++++++++++++-------- 3 files changed, 27 insertions(+), 38 deletions(-) diff --git a/include/net/sctp/command.h b/include/net/sctp/command.h index b55c6a48a206..d44d17b29189 100644 --- a/include/net/sctp/command.h +++ b/include/net/sctp/command.h @@ -104,7 +104,6 @@ enum sctp_verb { SCTP_CMD_T1_RETRAN, /* Mark for retransmission after T1 timeout */ SCTP_CMD_UPDATE_INITTAG, /* Update peer inittag */ SCTP_CMD_SEND_MSG, /* Send the whole use message */ - SCTP_CMD_SEND_NEXT_ASCONF, /* Send the next ASCONF after ACK */ SCTP_CMD_PURGE_ASCONF_QUEUE, /* Purge all asconf queues.*/ SCTP_CMD_SET_ASOC, /* Restore association context */ SCTP_CMD_LAST diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index e2d9a4b49c9c..fb857cf09ecd 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c @@ -1092,32 +1092,6 @@ static void sctp_cmd_send_msg(struct sctp_association *asoc, } -/* Sent the next ASCONF packet currently stored in the association. - * This happens after the ASCONF_ACK was succeffully processed. - */ -static void sctp_cmd_send_asconf(struct sctp_association *asoc) -{ - struct net *net = sock_net(asoc->base.sk); - - /* Send the next asconf chunk from the addip chunk - * queue. - */ - if (!list_empty(&asoc->addip_chunk_list)) { - struct list_head *entry = asoc->addip_chunk_list.next; - struct sctp_chunk *asconf = list_entry(entry, - struct sctp_chunk, list); - list_del_init(entry); - - /* Hold the chunk until an ASCONF_ACK is received. */ - sctp_chunk_hold(asconf); - if (sctp_primitive_ASCONF(net, asoc, asconf)) - sctp_chunk_free(asconf); - else - asoc->addip_last_asconf = asconf; - } -} - - /* These three macros allow us to pull the debugging code out of the * main flow of sctp_do_sm() to keep attention focused on the real * functionality there. @@ -1763,9 +1737,6 @@ static int sctp_cmd_interpreter(enum sctp_event event_type, } sctp_cmd_send_msg(asoc, cmd->obj.msg, gfp); break; - case SCTP_CMD_SEND_NEXT_ASCONF: - sctp_cmd_send_asconf(asoc); - break; case SCTP_CMD_PURGE_ASCONF_QUEUE: sctp_asconf_queue_teardown(asoc); break; diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 01b078172306..a2e058127ef7 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c @@ -3756,6 +3756,29 @@ enum sctp_disposition sctp_sf_do_asconf(struct net *net, return SCTP_DISPOSITION_CONSUME; } +static enum sctp_disposition sctp_send_next_asconf( + struct net *net, + const struct sctp_endpoint *ep, + struct sctp_association *asoc, + const union sctp_subtype type, + struct sctp_cmd_seq *commands) +{ + struct sctp_chunk *asconf; + struct list_head *entry; + + if (list_empty(&asoc->addip_chunk_list)) + return SCTP_DISPOSITION_CONSUME; + + entry = asoc->addip_chunk_list.next; + asconf = list_entry(entry, struct sctp_chunk, list); + + list_del_init(entry); + sctp_chunk_hold(asconf); + asoc->addip_last_asconf = asconf; + + return sctp_sf_do_prm_asconf(net, ep, asoc, type, asconf, commands); +} + /* * ADDIP Section 4.3 General rules for address manipulation * When building TLV parameters for the ASCONF Chunk that will add or @@ -3847,14 +3870,10 @@ enum sctp_disposition sctp_sf_do_asconf_ack(struct net *net, SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO)); if (!sctp_process_asconf_ack((struct sctp_association *)asoc, - asconf_ack)) { - /* Successfully processed ASCONF_ACK. We can - * release the next asconf if we have one. - */ - sctp_add_cmd_sf(commands, SCTP_CMD_SEND_NEXT_ASCONF, - SCTP_NULL()); - return SCTP_DISPOSITION_CONSUME; - } + asconf_ack)) + return sctp_send_next_asconf(net, ep, + (struct sctp_association *)asoc, + type, commands); abort = sctp_make_abort(asoc, asconf_ack, sizeof(struct sctp_errhdr)); -- GitLab From 538d6cdb9f16388339db661b4254c7a2e0e89c67 Mon Sep 17 00:00:00 2001 From: Willem de Bruijn Date: Mon, 29 Apr 2019 11:53:18 -0400 Subject: [PATCH 0367/1121] packet: validate msg_namelen in send directly [ Upstream commit 486efdc8f6ce802b27e15921d2353cc740c55451 ] Packet sockets in datagram mode take a destination address. Verify its length before passing to dev_hard_header. Prior to 2.6.14-rc3, the send code ignored sll_halen. This is established behavior. Directly compare msg_namelen to dev->addr_len. Change v1->v2: initialize addr in all paths Fixes: 6b8d95f1795c4 ("packet: validate address length if non-zero") Suggested-by: David Laight Signed-off-by: Willem de Bruijn Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/packet/af_packet.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index e8ca6aa3a32f..e522316a80c7 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -2641,8 +2641,8 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) void *ph; DECLARE_SOCKADDR(struct sockaddr_ll *, saddr, msg->msg_name); bool need_wait = !(msg->msg_flags & MSG_DONTWAIT); + unsigned char *addr = NULL; int tp_len, size_max; - unsigned char *addr; void *data; int len_sum = 0; int status = TP_STATUS_AVAILABLE; @@ -2653,7 +2653,6 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) if (likely(saddr == NULL)) { dev = packet_cached_dev_get(po); proto = po->num; - addr = NULL; } else { err = -EINVAL; if (msg->msg_namelen < sizeof(struct sockaddr_ll)) @@ -2663,10 +2662,13 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) sll_addr))) goto out; proto = saddr->sll_protocol; - addr = saddr->sll_halen ? saddr->sll_addr : NULL; dev = dev_get_by_index(sock_net(&po->sk), saddr->sll_ifindex); - if (addr && dev && saddr->sll_halen < dev->addr_len) - goto out_put; + if (po->sk.sk_socket->type == SOCK_DGRAM) { + if (dev && msg->msg_namelen < dev->addr_len + + offsetof(struct sockaddr_ll, sll_addr)) + goto out_put; + addr = saddr->sll_addr; + } } err = -ENXIO; @@ -2838,7 +2840,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) struct sk_buff *skb; struct net_device *dev; __be16 proto; - unsigned char *addr; + unsigned char *addr = NULL; int err, reserve = 0; struct sockcm_cookie sockc; struct virtio_net_hdr vnet_hdr = { 0 }; @@ -2855,7 +2857,6 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) if (likely(saddr == NULL)) { dev = packet_cached_dev_get(po); proto = po->num; - addr = NULL; } else { err = -EINVAL; if (msg->msg_namelen < sizeof(struct sockaddr_ll)) @@ -2863,10 +2864,13 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) if (msg->msg_namelen < (saddr->sll_halen + offsetof(struct sockaddr_ll, sll_addr))) goto out; proto = saddr->sll_protocol; - addr = saddr->sll_halen ? saddr->sll_addr : NULL; dev = dev_get_by_index(sock_net(sk), saddr->sll_ifindex); - if (addr && dev && saddr->sll_halen < dev->addr_len) - goto out_unlock; + if (sock->type == SOCK_DGRAM) { + if (dev && msg->msg_namelen < dev->addr_len + + offsetof(struct sockaddr_ll, sll_addr)) + goto out_unlock; + addr = saddr->sll_addr; + } } err = -ENXIO; -- GitLab From bfd91d22f7f206edac9aeac30c1b94d06e36457c Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Thu, 25 Apr 2019 22:31:50 -0400 Subject: [PATCH 0368/1121] bnxt_en: Improve multicast address setup logic. [ Upstream commit b4e30e8e7ea1d1e35ffd64ca46f7d9a7f227b4bf ] The driver builds a list of multicast addresses and sends it to the firmware when the driver's ndo_set_rx_mode() is called. In rare cases, the firmware can fail this call if internal resources to add multicast addresses are exhausted. In that case, we should try the call again by setting the ALL_MCAST flag which is more guaranteed to succeed. Fixes: c0c050c58d84 ("bnxt_en: New Broadcom ethernet driver.") Signed-off-by: Michael Chan Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 446577a1a6a5..7f255c88a2a0 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -6768,8 +6768,15 @@ static int bnxt_cfg_rx_mode(struct bnxt *bp) skip_uc: rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, 0); + if (rc && vnic->mc_list_count) { + netdev_info(bp->dev, "Failed setting MC filters rc: %d, turning on ALL_MCAST mode\n", + rc); + vnic->rx_mask |= CFA_L2_SET_RX_MASK_REQ_MASK_ALL_MCAST; + vnic->mc_list_count = 0; + rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, 0); + } if (rc) - netdev_err(bp->dev, "HWRM cfa l2 rx mask failure rc: %x\n", + netdev_err(bp->dev, "HWRM cfa l2 rx mask failure rc: %d\n", rc); return rc; -- GitLab From 882e20df08ccf05fa3e4da759ea6b680e1aef7b6 Mon Sep 17 00:00:00 2001 From: Vasundhara Volam Date: Thu, 25 Apr 2019 22:31:51 -0400 Subject: [PATCH 0369/1121] bnxt_en: Free short FW command HWRM memory in error path in bnxt_init_one() [ Upstream commit f9099d611449836a51a65f40ea7dc9cb5f2f665e ] In the bnxt_init_one() error path, short FW command request memory is not freed. This patch fixes it. Fixes: e605db801bde ("bnxt_en: Support for Short Firmware Message") Signed-off-by: Vasundhara Volam Signed-off-by: Michael Chan Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 7f255c88a2a0..687b01bf1ea9 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -8241,6 +8241,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) bnxt_clear_int_mode(bp); init_err_pci_clean: + bnxt_free_hwrm_short_cmd_req(bp); bnxt_free_hwrm_resources(bp); bnxt_cleanup_pci(bp); -- GitLab From ccb784fd2248122501c9e19aa5ea2329e987ec7d Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 30 Apr 2019 08:34:08 +0100 Subject: [PATCH 0370/1121] rxrpc: Fix net namespace cleanup [ Upstream commit b13023421b5179413421333f602850914f6a7ad8 ] In rxrpc_destroy_all_calls(), there are two phases: (1) make sure the ->calls list is empty, emitting error messages if not, and (2) wait for the RCU cleanup to happen on outstanding calls (ie. ->nr_calls becomes 0). To avoid taking the call_lock, the function prechecks ->calls and if empty, it returns to avoid taking the lock - this is wrong, however: it still needs to go and do the second phase and wait for ->nr_calls to become 0. Without this, the rxrpc_net struct may get deallocated before we get to the RCU cleanup for the last calls. This can lead to: Slab corruption (Not tainted): kmalloc-16k start=ffff88802b178000, len=16384 050: 6b 6b 6b 6b 6b 6b 6b 6b 61 6b 6b 6b 6b 6b 6b 6b kkkkkkkkakkkkkkk Note the "61" at offset 0x58. This corresponds to the ->nr_calls member of struct rxrpc_net (which is >9k in size, and thus allocated out of the 16k slab). Fix this by flipping the condition on the if-statement, putting the locked section inside the if-body and dropping the return from there. The function will then always go on to wait for the RCU cleanup on outstanding calls. Fixes: 2baec2c3f854 ("rxrpc: Support network namespacing") Signed-off-by: David Howells Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/rxrpc/call_object.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/net/rxrpc/call_object.c b/net/rxrpc/call_object.c index 8a5a42e8ec23..ddaa471a2607 100644 --- a/net/rxrpc/call_object.c +++ b/net/rxrpc/call_object.c @@ -684,27 +684,27 @@ void rxrpc_destroy_all_calls(struct rxrpc_net *rxnet) _enter(""); - if (list_empty(&rxnet->calls)) - return; + if (!list_empty(&rxnet->calls)) { + write_lock(&rxnet->call_lock); - write_lock(&rxnet->call_lock); + while (!list_empty(&rxnet->calls)) { + call = list_entry(rxnet->calls.next, + struct rxrpc_call, link); + _debug("Zapping call %p", call); - while (!list_empty(&rxnet->calls)) { - call = list_entry(rxnet->calls.next, struct rxrpc_call, link); - _debug("Zapping call %p", call); + rxrpc_see_call(call); + list_del_init(&call->link); - rxrpc_see_call(call); - list_del_init(&call->link); + pr_err("Call %p still in use (%d,%s,%lx,%lx)!\n", + call, atomic_read(&call->usage), + rxrpc_call_states[call->state], + call->flags, call->events); - pr_err("Call %p still in use (%d,%s,%lx,%lx)!\n", - call, atomic_read(&call->usage), - rxrpc_call_states[call->state], - call->flags, call->events); + write_unlock(&rxnet->call_lock); + cond_resched(); + write_lock(&rxnet->call_lock); + } write_unlock(&rxnet->call_lock); - cond_resched(); - write_lock(&rxnet->call_lock); } - - write_unlock(&rxnet->call_lock); } -- GitLab From 8fd0a7a186889a0a2b2a79e8a86754714bedf37a Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Thu, 25 Apr 2019 00:33:00 +0200 Subject: [PATCH 0371/1121] net: phy: marvell: Fix buffer overrun with stats counters [ Upstream commit fdfdf86720a34527f777cbe0d8599bf0528fa146 ] marvell_get_sset_count() returns how many statistics counters there are. If the PHY supports fibre, there are 3, otherwise two. marvell_get_strings() does not make this distinction, and always returns 3 strings. This then often results in writing past the end of the buffer for the strings. Fixes: 2170fef78a40 ("Marvell phy: add field to get errors from fiber link.") Signed-off-by: Andrew Lunn Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/phy/marvell.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index e9e67c22c8bb..727b991312a4 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -1497,9 +1497,10 @@ static int marvell_get_sset_count(struct phy_device *phydev) static void marvell_get_strings(struct phy_device *phydev, u8 *data) { + int count = marvell_get_sset_count(phydev); int i; - for (i = 0; i < ARRAY_SIZE(marvell_hw_stats); i++) { + for (i = 0; i < count; i++) { memcpy(data + i * ETH_GSTRING_LEN, marvell_hw_stats[i].string, ETH_GSTRING_LEN); } @@ -1536,9 +1537,10 @@ static u64 marvell_get_stat(struct phy_device *phydev, int i) static void marvell_get_stats(struct phy_device *phydev, struct ethtool_stats *stats, u64 *data) { + int count = marvell_get_sset_count(phydev); int i; - for (i = 0; i < ARRAY_SIZE(marvell_hw_stats); i++) + for (i = 0; i < count; i++) data[i] = marvell_get_stat(phydev, i); } -- GitLab From 8ce917131a74aeb3bde5b3a483011716ffb63a75 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 30 Apr 2019 13:44:19 +0300 Subject: [PATCH 0372/1121] net: dsa: bcm_sf2: fix buffer overflow doing set_rxnfc [ Upstream commit f949a12fd697479f68d99dc65e9bbab68ee49043 ] The "fs->location" is a u32 that comes from the user in ethtool_set_rxnfc(). We can't pass unclamped values to test_bit() or it results in an out of bounds access beyond the end of the bitmap. Fixes: 7318166cacad ("net: dsa: bcm_sf2: Add support for ethtool::rxnfc") Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/dsa/bcm_sf2_cfp.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/dsa/bcm_sf2_cfp.c b/drivers/net/dsa/bcm_sf2_cfp.c index 8a1da7e67707..7f8d269dd75a 100644 --- a/drivers/net/dsa/bcm_sf2_cfp.c +++ b/drivers/net/dsa/bcm_sf2_cfp.c @@ -130,6 +130,9 @@ static int bcm_sf2_cfp_rule_set(struct dsa_switch *ds, int port, (fs->m_ext.vlan_etype || fs->m_ext.data[1])) return -EINVAL; + if (fs->location != RX_CLS_LOC_ANY && fs->location >= CFP_NUM_RULES) + return -EINVAL; + if (fs->location != RX_CLS_LOC_ANY && test_bit(fs->location, priv->cfp.used)) return -EBUSY; @@ -330,6 +333,9 @@ static int bcm_sf2_cfp_rule_del(struct bcm_sf2_priv *priv, int port, int ret; u32 reg; + if (loc >= CFP_NUM_RULES) + return -EINVAL; + /* Refuse deletion of unused rules, and the default reserved rule */ if (!test_bit(loc, priv->cfp.used) || loc == 0) return -EINVAL; -- GitLab From 13a1d1adadfbbf0ab67e1f6799e84ffcc2f09fca Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Tue, 6 Feb 2018 15:36:48 -0800 Subject: [PATCH 0373/1121] kasan: remove redundant initialization of variable 'real_size' commit 48c232395431c23d35cf3b4c5a090bd793316578 upstream. Variable real_size is initialized with a value that is never read, it is re-assigned a new value later on, hence the initialization is redundant and can be removed. Cleans up clang warning: lib/test_kasan.c:422:21: warning: Value stored to 'real_size' during its initialization is never read Link: http://lkml.kernel.org/r/20180206144950.32457-1-colin.king@canonical.com Signed-off-by: Colin Ian King Acked-by: Andrey Ryabinin Reviewed-by: Andrew Morton Cc: Alexander Potapenko Cc: Dmitry Vyukov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Andrey Konovalov Signed-off-by: Greg Kroah-Hartman --- lib/test_kasan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/test_kasan.c b/lib/test_kasan.c index a25c9763fce1..d6e46dd1350b 100644 --- a/lib/test_kasan.c +++ b/lib/test_kasan.c @@ -389,7 +389,7 @@ static noinline void __init kasan_stack_oob(void) static noinline void __init ksize_unpoisons_memory(void) { char *ptr; - size_t size = 123, real_size = size; + size_t size = 123, real_size; pr_info("ksize() unpoisons the whole allocated chunk\n"); ptr = kmalloc(size, GFP_KERNEL); -- GitLab From bd6afee7a597532ad35bb7b009addbf4e91b238f Mon Sep 17 00:00:00 2001 From: Andrey Konovalov Date: Tue, 10 Apr 2018 16:30:39 -0700 Subject: [PATCH 0374/1121] kasan: prevent compiler from optimizing away memset in tests commit 69ca372c100fba99c78ef826a1795aa86e4f01a8 upstream. A compiler can optimize away memset calls by replacing them with mov instructions. There are KASAN tests that specifically test that KASAN correctly handles memset calls so we don't want this optimization to happen. The solution is to add -fno-builtin flag to test_kasan.ko Link: http://lkml.kernel.org/r/105ec9a308b2abedb1a0d1fdced0c22d765e4732.1519924383.git.andreyknvl@google.com Signed-off-by: Andrey Konovalov Acked-by: Andrey Ryabinin Cc: Alexander Potapenko Cc: Dmitry Vyukov Cc: Geert Uytterhoeven Cc: Nick Terrell Cc: Chris Mason Cc: Yury Norov Cc: Al Viro Cc: "Luis R . Rodriguez" Cc: Palmer Dabbelt Cc: "Paul E . McKenney" Cc: Jeff Layton Cc: "Jason A . Donenfeld" Cc: Kostya Serebryany Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Andrey Konovalov Signed-off-by: Greg Kroah-Hartman --- lib/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Makefile b/lib/Makefile index b8f2c16fccaa..b1ac45032903 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -50,6 +50,7 @@ obj-$(CONFIG_TEST_FIRMWARE) += test_firmware.o obj-$(CONFIG_TEST_SYSCTL) += test_sysctl.o obj-$(CONFIG_TEST_HASH) += test_hash.o test_siphash.o obj-$(CONFIG_TEST_KASAN) += test_kasan.o +CFLAGS_test_kasan.o += -fno-builtin obj-$(CONFIG_TEST_KSTRTOX) += test-kstrtox.o obj-$(CONFIG_TEST_LIST_SORT) += test_list_sort.o obj-$(CONFIG_TEST_LKM) += test_module.o -- GitLab From 6c3e7b2d4ee212f3fb3da22caeb7a7a9d91ecc70 Mon Sep 17 00:00:00 2001 From: Julien Thierry Date: Wed, 25 Oct 2017 10:04:33 +0100 Subject: [PATCH 0375/1121] arm64: Fix single stepping in kernel traps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 6436beeee5721a8e906e9eabf866f12d04470437 upstream. Software Step exception is missing after stepping a trapped instruction. Ensure SPSR.SS gets set to 0 after emulating/skipping a trapped instruction before doing ERET. Cc: Catalin Marinas Cc: Mark Rutland Signed-off-by: Julien Thierry Reviewed-by: Alex BennĂ©e [will: replaced AARCH32_INSN_SIZE with 4] Signed-off-by: Will Deacon Signed-off-by: Andrey Konovalov Signed-off-by: Greg Kroah-Hartman --- arch/arm64/include/asm/traps.h | 6 ++++++ arch/arm64/kernel/armv8_deprecated.c | 8 ++++---- arch/arm64/kernel/cpufeature.c | 2 +- arch/arm64/kernel/traps.c | 21 ++++++++++++++++----- 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/arch/arm64/include/asm/traps.h b/arch/arm64/include/asm/traps.h index d131501c6222..45e3da34bdc4 100644 --- a/arch/arm64/include/asm/traps.h +++ b/arch/arm64/include/asm/traps.h @@ -37,6 +37,12 @@ void unregister_undef_hook(struct undef_hook *hook); void arm64_notify_segfault(struct pt_regs *regs, unsigned long addr); +/* + * Move regs->pc to next instruction and do necessary setup before it + * is executed. + */ +void arm64_skip_faulting_instruction(struct pt_regs *regs, unsigned long size); + static inline int __in_irqentry_text(unsigned long ptr) { return ptr >= (unsigned long)&__irqentry_text_start && diff --git a/arch/arm64/kernel/armv8_deprecated.c b/arch/arm64/kernel/armv8_deprecated.c index d06fbe4cd38d..a4dc115d7659 100644 --- a/arch/arm64/kernel/armv8_deprecated.c +++ b/arch/arm64/kernel/armv8_deprecated.c @@ -431,7 +431,7 @@ static int swp_handler(struct pt_regs *regs, u32 instr) pr_warn_ratelimited("\"%s\" (%ld) uses obsolete SWP{B} instruction at 0x%llx\n", current->comm, (unsigned long)current->pid, regs->pc); - regs->pc += 4; + arm64_skip_faulting_instruction(regs, 4); return 0; fault: @@ -512,7 +512,7 @@ static int cp15barrier_handler(struct pt_regs *regs, u32 instr) pr_warn_ratelimited("\"%s\" (%ld) uses deprecated CP15 Barrier instruction at 0x%llx\n", current->comm, (unsigned long)current->pid, regs->pc); - regs->pc += 4; + arm64_skip_faulting_instruction(regs, 4); return 0; } @@ -586,14 +586,14 @@ static int compat_setend_handler(struct pt_regs *regs, u32 big_endian) static int a32_setend_handler(struct pt_regs *regs, u32 instr) { int rc = compat_setend_handler(regs, (instr >> 9) & 1); - regs->pc += 4; + arm64_skip_faulting_instruction(regs, 4); return rc; } static int t16_setend_handler(struct pt_regs *regs, u32 instr) { int rc = compat_setend_handler(regs, (instr >> 3) & 1); - regs->pc += 2; + arm64_skip_faulting_instruction(regs, 2); return rc; } diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 003dd39225a0..29b5b72b7877 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -1398,7 +1398,7 @@ static int emulate_mrs(struct pt_regs *regs, u32 insn) if (!rc) { dst = aarch64_insn_decode_register(AARCH64_INSN_REGTYPE_RT, insn); pt_regs_write_reg(regs, dst, val); - regs->pc += 4; + arm64_skip_faulting_instruction(regs, AARCH64_INSN_SIZE); } return rc; diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index 4cacc33d07ce..efe99e8bbb7c 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -296,6 +296,17 @@ void arm64_notify_die(const char *str, struct pt_regs *regs, } } +void arm64_skip_faulting_instruction(struct pt_regs *regs, unsigned long size) +{ + regs->pc += size; + + /* + * If we were single stepping, we want to get the step exception after + * we return from the trap. + */ + user_fastforward_single_step(current); +} + static LIST_HEAD(undef_hook); static DEFINE_RAW_SPINLOCK(undef_lock); @@ -483,7 +494,7 @@ static void user_cache_maint_handler(unsigned int esr, struct pt_regs *regs) if (ret) arm64_notify_segfault(regs, address); else - regs->pc += 4; + arm64_skip_faulting_instruction(regs, AARCH64_INSN_SIZE); } static void ctr_read_handler(unsigned int esr, struct pt_regs *regs) @@ -493,7 +504,7 @@ static void ctr_read_handler(unsigned int esr, struct pt_regs *regs) pt_regs_write_reg(regs, rt, val); - regs->pc += 4; + arm64_skip_faulting_instruction(regs, AARCH64_INSN_SIZE); } static void cntvct_read_handler(unsigned int esr, struct pt_regs *regs) @@ -501,7 +512,7 @@ static void cntvct_read_handler(unsigned int esr, struct pt_regs *regs) int rt = (esr & ESR_ELx_SYS64_ISS_RT_MASK) >> ESR_ELx_SYS64_ISS_RT_SHIFT; pt_regs_write_reg(regs, rt, arch_counter_get_cntvct()); - regs->pc += 4; + arm64_skip_faulting_instruction(regs, AARCH64_INSN_SIZE); } static void cntfrq_read_handler(unsigned int esr, struct pt_regs *regs) @@ -509,7 +520,7 @@ static void cntfrq_read_handler(unsigned int esr, struct pt_regs *regs) int rt = (esr & ESR_ELx_SYS64_ISS_RT_MASK) >> ESR_ELx_SYS64_ISS_RT_SHIFT; pt_regs_write_reg(regs, rt, arch_timer_get_rate()); - regs->pc += 4; + arm64_skip_faulting_instruction(regs, AARCH64_INSN_SIZE); } struct sys64_hook { @@ -756,7 +767,7 @@ static int bug_handler(struct pt_regs *regs, unsigned int esr) } /* If thread survives, skip over the BUG instruction and continue: */ - regs->pc += AARCH64_INSN_SIZE; /* skip BRK and resume */ + arm64_skip_faulting_instruction(regs, AARCH64_INSN_SIZE); return DBG_HOOK_HANDLED; } -- GitLab From 3e7acc963f9c034717771a3b0898afa239c81481 Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Tue, 3 Apr 2018 11:22:51 +0100 Subject: [PATCH 0376/1121] arm64: only advance singlestep for user instruction traps commit 9478f1927e6ef9ef5e1ad761af1c98aa8e40b7f5 upstream. Our arm64_skip_faulting_instruction() helper advances the userspace singlestep state machine, but this is also called by the kernel BRK handler, as used for WARN*(). Thus, if we happen to hit a WARN*() while the user singlestep state machine is in the active-no-pending state, we'll advance to the active-pending state without having executed a user instruction, and will take a step exception earlier than expected when we return to userspace. Let's fix this by only advancing the state machine when skipping a user instruction. Signed-off-by: Mark Rutland Cc: Andrey Konovalov Cc: Catalin Marinas Cc: Will Deacon Signed-off-by: Will Deacon Signed-off-by: Andrey Konovalov Signed-off-by: Greg Kroah-Hartman --- arch/arm64/kernel/traps.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index efe99e8bbb7c..74259ae9c7f2 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -304,7 +304,8 @@ void arm64_skip_faulting_instruction(struct pt_regs *regs, unsigned long size) * If we were single stepping, we want to get the step exception after * we return from the trap. */ - user_fastforward_single_step(current); + if (user_mode(regs)) + user_fastforward_single_step(current); } static LIST_HEAD(undef_hook); -- GitLab From 2e12ca448960b348d05c0afabc9eb574edcd8253 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 16 Jan 2018 17:34:00 +0100 Subject: [PATCH 0377/1121] caif: reduce stack size with KASAN commit ce6289661b14a8b391d90db918c91b6d6da6540a upstream. When CONFIG_KASAN is set, we can use relatively large amounts of kernel stack space: net/caif/cfctrl.c:555:1: warning: the frame size of 1600 bytes is larger than 1280 bytes [-Wframe-larger-than=] This adds convenience wrappers around cfpkt_extr_head(), which is responsible for most of the stack growth. With those wrapper functions, gcc apparently starts reusing the stack slots for each instance, thus avoiding the problem. Signed-off-by: Arnd Bergmann Signed-off-by: David S. Miller Signed-off-by: Andrey Konovalov Signed-off-by: Greg Kroah-Hartman --- include/net/caif/cfpkt.h | 27 ++++++++++++++++++++++ net/caif/cfctrl.c | 50 ++++++++++++++++++---------------------- 2 files changed, 49 insertions(+), 28 deletions(-) diff --git a/include/net/caif/cfpkt.h b/include/net/caif/cfpkt.h index fe328c52c46b..801489bb14c3 100644 --- a/include/net/caif/cfpkt.h +++ b/include/net/caif/cfpkt.h @@ -32,6 +32,33 @@ void cfpkt_destroy(struct cfpkt *pkt); */ int cfpkt_extr_head(struct cfpkt *pkt, void *data, u16 len); +static inline u8 cfpkt_extr_head_u8(struct cfpkt *pkt) +{ + u8 tmp; + + cfpkt_extr_head(pkt, &tmp, 1); + + return tmp; +} + +static inline u16 cfpkt_extr_head_u16(struct cfpkt *pkt) +{ + __le16 tmp; + + cfpkt_extr_head(pkt, &tmp, 2); + + return le16_to_cpu(tmp); +} + +static inline u32 cfpkt_extr_head_u32(struct cfpkt *pkt) +{ + __le32 tmp; + + cfpkt_extr_head(pkt, &tmp, 4); + + return le32_to_cpu(tmp); +} + /* * Peek header from packet. * Reads data from packet without changing packet. diff --git a/net/caif/cfctrl.c b/net/caif/cfctrl.c index f5afda1abc76..4dc82e9a855d 100644 --- a/net/caif/cfctrl.c +++ b/net/caif/cfctrl.c @@ -352,15 +352,14 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) u8 cmdrsp; u8 cmd; int ret = -1; - u16 tmp16; u8 len; u8 param[255]; - u8 linkid; + u8 linkid = 0; struct cfctrl *cfctrl = container_obj(layer); struct cfctrl_request_info rsp, *req; - cfpkt_extr_head(pkt, &cmdrsp, 1); + cmdrsp = cfpkt_extr_head_u8(pkt); cmd = cmdrsp & CFCTRL_CMD_MASK; if (cmd != CFCTRL_CMD_LINK_ERR && CFCTRL_RSP_BIT != (CFCTRL_RSP_BIT & cmdrsp) @@ -378,13 +377,12 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) u8 physlinkid; u8 prio; u8 tmp; - u32 tmp32; u8 *cp; int i; struct cfctrl_link_param linkparam; memset(&linkparam, 0, sizeof(linkparam)); - cfpkt_extr_head(pkt, &tmp, 1); + tmp = cfpkt_extr_head_u8(pkt); serv = tmp & CFCTRL_SRV_MASK; linkparam.linktype = serv; @@ -392,13 +390,13 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) servtype = tmp >> 4; linkparam.chtype = servtype; - cfpkt_extr_head(pkt, &tmp, 1); + tmp = cfpkt_extr_head_u8(pkt); physlinkid = tmp & 0x07; prio = tmp >> 3; linkparam.priority = prio; linkparam.phyid = physlinkid; - cfpkt_extr_head(pkt, &endpoint, 1); + endpoint = cfpkt_extr_head_u8(pkt); linkparam.endpoint = endpoint & 0x03; switch (serv) { @@ -407,45 +405,43 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) if (CFCTRL_ERR_BIT & cmdrsp) break; /* Link ID */ - cfpkt_extr_head(pkt, &linkid, 1); + linkid = cfpkt_extr_head_u8(pkt); break; case CFCTRL_SRV_VIDEO: - cfpkt_extr_head(pkt, &tmp, 1); + tmp = cfpkt_extr_head_u8(pkt); linkparam.u.video.connid = tmp; if (CFCTRL_ERR_BIT & cmdrsp) break; /* Link ID */ - cfpkt_extr_head(pkt, &linkid, 1); + linkid = cfpkt_extr_head_u8(pkt); break; case CFCTRL_SRV_DATAGRAM: - cfpkt_extr_head(pkt, &tmp32, 4); linkparam.u.datagram.connid = - le32_to_cpu(tmp32); + cfpkt_extr_head_u32(pkt); if (CFCTRL_ERR_BIT & cmdrsp) break; /* Link ID */ - cfpkt_extr_head(pkt, &linkid, 1); + linkid = cfpkt_extr_head_u8(pkt); break; case CFCTRL_SRV_RFM: /* Construct a frame, convert * DatagramConnectionID * to network format long and copy it out... */ - cfpkt_extr_head(pkt, &tmp32, 4); linkparam.u.rfm.connid = - le32_to_cpu(tmp32); + cfpkt_extr_head_u32(pkt); cp = (u8 *) linkparam.u.rfm.volume; - for (cfpkt_extr_head(pkt, &tmp, 1); + for (tmp = cfpkt_extr_head_u8(pkt); cfpkt_more(pkt) && tmp != '\0'; - cfpkt_extr_head(pkt, &tmp, 1)) + tmp = cfpkt_extr_head_u8(pkt)) *cp++ = tmp; *cp = '\0'; if (CFCTRL_ERR_BIT & cmdrsp) break; /* Link ID */ - cfpkt_extr_head(pkt, &linkid, 1); + linkid = cfpkt_extr_head_u8(pkt); break; case CFCTRL_SRV_UTIL: @@ -454,13 +450,11 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) * to network format long and copy it out... */ /* Fifosize KB */ - cfpkt_extr_head(pkt, &tmp16, 2); linkparam.u.utility.fifosize_kb = - le16_to_cpu(tmp16); + cfpkt_extr_head_u16(pkt); /* Fifosize bufs */ - cfpkt_extr_head(pkt, &tmp16, 2); linkparam.u.utility.fifosize_bufs = - le16_to_cpu(tmp16); + cfpkt_extr_head_u16(pkt); /* name */ cp = (u8 *) linkparam.u.utility.name; caif_assert(sizeof(linkparam.u.utility.name) @@ -468,24 +462,24 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) for (i = 0; i < UTILITY_NAME_LENGTH && cfpkt_more(pkt); i++) { - cfpkt_extr_head(pkt, &tmp, 1); + tmp = cfpkt_extr_head_u8(pkt); *cp++ = tmp; } /* Length */ - cfpkt_extr_head(pkt, &len, 1); + len = cfpkt_extr_head_u8(pkt); linkparam.u.utility.paramlen = len; /* Param Data */ cp = linkparam.u.utility.params; while (cfpkt_more(pkt) && len--) { - cfpkt_extr_head(pkt, &tmp, 1); + tmp = cfpkt_extr_head_u8(pkt); *cp++ = tmp; } if (CFCTRL_ERR_BIT & cmdrsp) break; /* Link ID */ - cfpkt_extr_head(pkt, &linkid, 1); + linkid = cfpkt_extr_head_u8(pkt); /* Length */ - cfpkt_extr_head(pkt, &len, 1); + len = cfpkt_extr_head_u8(pkt); /* Param Data */ cfpkt_extr_head(pkt, ¶m, len); break; @@ -522,7 +516,7 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) } break; case CFCTRL_CMD_LINK_DESTROY: - cfpkt_extr_head(pkt, &linkid, 1); + linkid = cfpkt_extr_head_u8(pkt); cfctrl->res.linkdestroy_rsp(cfctrl->serv.layer.up, linkid); break; case CFCTRL_CMD_LINK_ERR: -- GitLab From b4a9378e93cd27d10cc2900748f54c66acfe2603 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Wed, 24 Apr 2019 16:34:25 +0800 Subject: [PATCH 0378/1121] ALSA: hda/realtek - Add new Dell platform for headset mode commit 0a29c57b76624723b6b00c027e0e992d130ace49 upstream. Add two Dell platform for headset mode. [ Note: this is a further correction / addition of the previous pin-based quirks for Dell machines; another entry for ALC236 with the d-mic pin 0x12 and an entry for ALC295 -- tiwai ] Fixes: b26e36b7ef36 ("ALSA: hda/realtek - add two more pin configuration sets to quirk table") Signed-off-by: Kailang Yang Cc: Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/pci/hda/patch_realtek.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index b9e720cb6f02..8c0372d0dd93 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6745,6 +6745,10 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { {0x21, 0x02211020}), SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, {0x21, 0x02211020}), + SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, + {0x12, 0x40000000}, + {0x14, 0x90170110}, + {0x21, 0x02211020}), SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, {0x14, 0x90170110}, {0x21, 0x02211020}), @@ -6985,6 +6989,9 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE, ALC292_STANDARD_PINS, {0x13, 0x90a60140}), + SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, + {0x14, 0x90170110}, + {0x21, 0x04211020}), SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, ALC295_STANDARD_PINS, {0x17, 0x21014020}, -- GitLab From bfa5aa541c1ed6ec031551c1b7817410b2f09b41 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Fri, 26 Apr 2019 16:13:54 +0800 Subject: [PATCH 0379/1121] ALSA: hda/realtek - Fixed Dell AIO speaker noise commit 0700d3d117a7f110ddddbd83873e13652f69c54b upstream. Fixed Dell AIO speaker noise. spec->gen.auto_mute_via_amp = 1, this option was solved speaker white noise at boot. codec->power_save_node = 0, this option was solved speaker noise at resume back. Fixes: 9226665159f0 ("ALSA: hda/realtek - Fix Dell AIO LineOut issue") Signed-off-by: Kailang Yang Cc: Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/pci/hda/patch_realtek.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 8c0372d0dd93..f44d08fe20fc 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5294,6 +5294,8 @@ static void alc274_fixup_bind_dacs(struct hda_codec *codec, return; spec->gen.preferred_dacs = preferred_pairs; + spec->gen.auto_mute_via_amp = 1; + codec->power_save_node = 0; } static void alc_fixup_disable_mic_vref(struct hda_codec *codec, -- GitLab From 5696fa3f42168ee33256c0b0b72ca963d224327f Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 23 Apr 2019 14:48:29 -0400 Subject: [PATCH 0380/1121] USB: yurex: Fix protection fault after device removal commit ef61eb43ada6c1d6b94668f0f514e4c268093ff3 upstream. The syzkaller USB fuzzer found a general-protection-fault bug in the yurex driver. The fault occurs when a device has been unplugged; the driver's interrupt-URB handler logs an error message referring to the device by name, after the device has been unregistered and its name deallocated. This problem is caused by the fact that the interrupt URB isn't cancelled until the driver's private data structure is released, which can happen long after the device is gone. The cure is to make sure that the interrupt URB is killed before yurex_disconnect() returns; this is exactly the sort of thing that usb_poison_urb() was meant for. Signed-off-by: Alan Stern Reported-and-tested-by: syzbot+2eb9121678bdb36e6d57@syzkaller.appspotmail.com CC: Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/yurex.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/misc/yurex.c b/drivers/usb/misc/yurex.c index 4f48f5730e12..8ee98bc6c468 100644 --- a/drivers/usb/misc/yurex.c +++ b/drivers/usb/misc/yurex.c @@ -318,6 +318,7 @@ static void yurex_disconnect(struct usb_interface *interface) usb_deregister_dev(interface, &yurex_class); /* prevent more I/O from starting */ + usb_poison_urb(dev->urb); mutex_lock(&dev->io_mutex); dev->interface = NULL; mutex_unlock(&dev->io_mutex); -- GitLab From 0bb71c26b3aab30ebfbc52dda7aaaa173f210f7c Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 22 Apr 2019 11:16:04 -0400 Subject: [PATCH 0381/1121] USB: w1 ds2490: Fix bug caused by improper use of altsetting array commit c114944d7d67f24e71562fcfc18d550ab787e4d4 upstream. The syzkaller USB fuzzer spotted a slab-out-of-bounds bug in the ds2490 driver. This bug is caused by improper use of the altsetting array in the usb_interface structure (the array's entries are not always stored in numerical order), combined with a naive assumption that all interfaces probed by the driver will have the expected number of altsettings. The bug can be fixed by replacing references to the possibly non-existent intf->altsetting[alt] entry with the guaranteed-to-exist intf->cur_altsetting entry. Signed-off-by: Alan Stern Reported-and-tested-by: syzbot+d65f673b847a1a96cdba@syzkaller.appspotmail.com CC: Signed-off-by: Greg Kroah-Hartman --- drivers/w1/masters/ds2490.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/w1/masters/ds2490.c b/drivers/w1/masters/ds2490.c index c423bdb982bb..2ec0dfcd5b97 100644 --- a/drivers/w1/masters/ds2490.c +++ b/drivers/w1/masters/ds2490.c @@ -1018,15 +1018,15 @@ static int ds_probe(struct usb_interface *intf, /* alternative 3, 1ms interrupt (greatly speeds search), 64 byte bulk */ alt = 3; err = usb_set_interface(dev->udev, - intf->altsetting[alt].desc.bInterfaceNumber, alt); + intf->cur_altsetting->desc.bInterfaceNumber, alt); if (err) { dev_err(&dev->udev->dev, "Failed to set alternative setting %d " "for %d interface: err=%d.\n", alt, - intf->altsetting[alt].desc.bInterfaceNumber, err); + intf->cur_altsetting->desc.bInterfaceNumber, err); goto err_out_clear; } - iface_desc = &intf->altsetting[alt]; + iface_desc = intf->cur_altsetting; if (iface_desc->desc.bNumEndpoints != NUM_EP-1) { pr_info("Num endpoints=%d. It is not DS9490R.\n", iface_desc->desc.bNumEndpoints); -- GitLab From e390de579b0b75125a8a5fdf02b396a0ba71e898 Mon Sep 17 00:00:00 2001 From: Malte Leip Date: Sun, 14 Apr 2019 12:00:12 +0200 Subject: [PATCH 0382/1121] usb: usbip: fix isoc packet num validation in get_pipe commit c409ca3be3c6ff3a1eeb303b191184e80d412862 upstream. Change the validation of number_of_packets in get_pipe to compare the number of packets to a fixed maximum number of packets allowed, set to be 1024. This number was chosen due to it being used by other drivers as well, for example drivers/usb/host/uhci-q.c Background/reason: The get_pipe function in stub_rx.c validates the number of packets in isochronous mode and aborts with an error if that number is too large, in order to prevent malicious input from possibly triggering large memory allocations. This was previously done by checking whether pdu->u.cmd_submit.number_of_packets is bigger than the number of packets that would be needed for pdu->u.cmd_submit.transfer_buffer_length bytes if all except possibly the last packet had maximum length, given by usb_endpoint_maxp(epd) * usb_endpoint_maxp_mult(epd). This leads to an error if URBs with packets shorter than the maximum possible length are submitted, which is allowed according to Documentation/driver-api/usb/URB.rst and occurs for example with the snd-usb-audio driver. Fixes: c6688ef9f297 ("usbip: fix stub_rx: harden CMD_SUBMIT path to handle malicious input") Signed-off-by: Malte Leip Cc: stable Acked-by: Shuah Khan Signed-off-by: Greg Kroah-Hartman --- drivers/usb/usbip/stub_rx.c | 12 +++--------- drivers/usb/usbip/usbip_common.h | 7 +++++++ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/usb/usbip/stub_rx.c b/drivers/usb/usbip/stub_rx.c index 5b807185f79e..777a4058c407 100644 --- a/drivers/usb/usbip/stub_rx.c +++ b/drivers/usb/usbip/stub_rx.c @@ -383,16 +383,10 @@ static int get_pipe(struct stub_device *sdev, struct usbip_header *pdu) } if (usb_endpoint_xfer_isoc(epd)) { - /* validate packet size and number of packets */ - unsigned int maxp, packets, bytes; - - maxp = usb_endpoint_maxp(epd); - maxp *= usb_endpoint_maxp_mult(epd); - bytes = pdu->u.cmd_submit.transfer_buffer_length; - packets = DIV_ROUND_UP(bytes, maxp); - + /* validate number of packets */ if (pdu->u.cmd_submit.number_of_packets < 0 || - pdu->u.cmd_submit.number_of_packets > packets) { + pdu->u.cmd_submit.number_of_packets > + USBIP_MAX_ISO_PACKETS) { dev_err(&sdev->udev->dev, "CMD_SUBMIT: isoc invalid num packets %d\n", pdu->u.cmd_submit.number_of_packets); diff --git a/drivers/usb/usbip/usbip_common.h b/drivers/usb/usbip/usbip_common.h index c81c44c13a56..59097145cfc0 100644 --- a/drivers/usb/usbip/usbip_common.h +++ b/drivers/usb/usbip/usbip_common.h @@ -135,6 +135,13 @@ extern struct device_attribute dev_attr_usbip_debug; #define USBIP_DIR_OUT 0x00 #define USBIP_DIR_IN 0x01 +/* + * Arbitrary limit for the maximum number of isochronous packets in an URB, + * compare for example the uhci_submit_isochronous function in + * drivers/usb/host/uhci-q.c + */ +#define USBIP_MAX_ISO_PACKETS 1024 + /** * struct usbip_header_basic - data pertinent to every request * @command: the usbip request type -- GitLab From aef2cb19ab9e8fdb97e2c58957711a220f8138c1 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 15 Apr 2019 11:51:38 -0400 Subject: [PATCH 0383/1121] USB: core: Fix unterminated string returned by usb_string() commit c01c348ecdc66085e44912c97368809612231520 upstream. Some drivers (such as the vub300 MMC driver) expect usb_string() to return a properly NUL-terminated string, even when an error occurs. (In fact, vub300's probe routine doesn't bother to check the return code from usb_string().) When the driver goes on to use an unterminated string, it leads to kernel errors such as stack-out-of-bounds, as found by the syzkaller USB fuzzer. An out-of-range string index argument is not at all unlikely, given that some devices don't provide string descriptors and therefore list 0 as the value for their string indexes. This patch makes usb_string() return a properly terminated empty string along with the -EINVAL error code when an out-of-range index is encountered. And since a USB string index is a single-byte value, indexes >= 256 are just as invalid as values of 0 or below. Signed-off-by: Alan Stern Reported-by: syzbot+b75b85111c10b8d680f1@syzkaller.appspotmail.com CC: Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/message.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 1fe3c5d3be5f..c3f3f6370f64 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -818,9 +818,11 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size) if (dev->state == USB_STATE_SUSPENDED) return -EHOSTUNREACH; - if (size <= 0 || !buf || !index) + if (size <= 0 || !buf) return -EINVAL; buf[0] = 0; + if (index <= 0 || index >= 256) + return -EINVAL; tbuf = kmalloc(256, GFP_NOIO); if (!tbuf) return -ENOMEM; -- GitLab From 20ea0648cc1623778ff286b829613b9bd2523272 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 19 Apr 2019 13:52:38 -0400 Subject: [PATCH 0384/1121] USB: core: Fix bug caused by duplicate interface PM usage counter commit c2b71462d294cf517a0bc6e4fd6424d7cee5596f upstream. The syzkaller fuzzer reported a bug in the USB hub driver which turned out to be caused by a negative runtime-PM usage counter. This allowed a hub to be runtime suspended at a time when the driver did not expect it. The symptom is a WARNING issued because the hub's status URB is submitted while it is already active: URB 0000000031fb463e submitted while active WARNING: CPU: 0 PID: 2917 at drivers/usb/core/urb.c:363 The negative runtime-PM usage count was caused by an unfortunate design decision made when runtime PM was first implemented for USB. At that time, USB class drivers were allowed to unbind from their interfaces without balancing the usage counter (i.e., leaving it with a positive count). The core code would take care of setting the counter back to 0 before allowing another driver to bind to the interface. Later on when runtime PM was implemented for the entire kernel, the opposite decision was made: Drivers were required to balance their runtime-PM get and put calls. In order to maintain backward compatibility, however, the USB subsystem adapted to the new implementation by keeping an independent usage counter for each interface and using it to automatically adjust the normal usage counter back to 0 whenever a driver was unbound. This approach involves duplicating information, but what is worse, it doesn't work properly in cases where a USB class driver delays decrementing the usage counter until after the driver's disconnect() routine has returned and the counter has been adjusted back to 0. Doing so would cause the usage counter to become negative. There's even a warning about this in the USB power management documentation! As it happens, this is exactly what the hub driver does. The kick_hub_wq() routine increments the runtime-PM usage counter, and the corresponding decrement is carried out by hub_event() in the context of the hub_wq work-queue thread. This work routine may sometimes run after the driver has been unbound from its interface, and when it does it causes the usage counter to go negative. It is not possible for hub_disconnect() to wait for a pending hub_event() call to finish, because hub_disconnect() is called with the device lock held and hub_event() acquires that lock. The only feasible fix is to reverse the original design decision: remove the duplicate interface-specific usage counter and require USB drivers to balance their runtime PM gets and puts. As far as I know, all existing drivers currently do this. Signed-off-by: Alan Stern Reported-and-tested-by: syzbot+7634edaea4d0b341c625@syzkaller.appspotmail.com CC: Signed-off-by: Greg Kroah-Hartman --- Documentation/driver-api/usb/power-management.rst | 14 +++++++++----- drivers/usb/core/driver.c | 13 ------------- drivers/usb/storage/realtek_cr.c | 13 +++++-------- include/linux/usb.h | 2 -- 4 files changed, 14 insertions(+), 28 deletions(-) diff --git a/Documentation/driver-api/usb/power-management.rst b/Documentation/driver-api/usb/power-management.rst index 79beb807996b..4a74cf6f2797 100644 --- a/Documentation/driver-api/usb/power-management.rst +++ b/Documentation/driver-api/usb/power-management.rst @@ -370,11 +370,15 @@ autosuspend the interface's device. When the usage counter is = 0 then the interface is considered to be idle, and the kernel may autosuspend the device. -Drivers need not be concerned about balancing changes to the usage -counter; the USB core will undo any remaining "get"s when a driver -is unbound from its interface. As a corollary, drivers must not call -any of the ``usb_autopm_*`` functions after their ``disconnect`` -routine has returned. +Drivers must be careful to balance their overall changes to the usage +counter. Unbalanced "get"s will remain in effect when a driver is +unbound from its interface, preventing the device from going into +runtime suspend should the interface be bound to a driver again. On +the other hand, drivers are allowed to achieve this balance by calling +the ``usb_autopm_*`` functions even after their ``disconnect`` routine +has returned -- say from within a work-queue routine -- provided they +retain an active reference to the interface (via ``usb_get_intf`` and +``usb_put_intf``). Drivers using the async routines are responsible for their own synchronization and mutual exclusion. diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 79d2c0bf7870..687558e27c36 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -473,11 +473,6 @@ static int usb_unbind_interface(struct device *dev) pm_runtime_disable(dev); pm_runtime_set_suspended(dev); - /* Undo any residual pm_autopm_get_interface_* calls */ - for (r = atomic_read(&intf->pm_usage_cnt); r > 0; --r) - usb_autopm_put_interface_no_suspend(intf); - atomic_set(&intf->pm_usage_cnt, 0); - if (!error) usb_autosuspend_device(udev); @@ -1628,7 +1623,6 @@ void usb_autopm_put_interface(struct usb_interface *intf) int status; usb_mark_last_busy(udev); - atomic_dec(&intf->pm_usage_cnt); status = pm_runtime_put_sync(&intf->dev); dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n", __func__, atomic_read(&intf->dev.power.usage_count), @@ -1657,7 +1651,6 @@ void usb_autopm_put_interface_async(struct usb_interface *intf) int status; usb_mark_last_busy(udev); - atomic_dec(&intf->pm_usage_cnt); status = pm_runtime_put(&intf->dev); dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n", __func__, atomic_read(&intf->dev.power.usage_count), @@ -1679,7 +1672,6 @@ void usb_autopm_put_interface_no_suspend(struct usb_interface *intf) struct usb_device *udev = interface_to_usbdev(intf); usb_mark_last_busy(udev); - atomic_dec(&intf->pm_usage_cnt); pm_runtime_put_noidle(&intf->dev); } EXPORT_SYMBOL_GPL(usb_autopm_put_interface_no_suspend); @@ -1710,8 +1702,6 @@ int usb_autopm_get_interface(struct usb_interface *intf) status = pm_runtime_get_sync(&intf->dev); if (status < 0) pm_runtime_put_sync(&intf->dev); - else - atomic_inc(&intf->pm_usage_cnt); dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n", __func__, atomic_read(&intf->dev.power.usage_count), status); @@ -1745,8 +1735,6 @@ int usb_autopm_get_interface_async(struct usb_interface *intf) status = pm_runtime_get(&intf->dev); if (status < 0 && status != -EINPROGRESS) pm_runtime_put_noidle(&intf->dev); - else - atomic_inc(&intf->pm_usage_cnt); dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n", __func__, atomic_read(&intf->dev.power.usage_count), status); @@ -1770,7 +1758,6 @@ void usb_autopm_get_interface_no_resume(struct usb_interface *intf) struct usb_device *udev = interface_to_usbdev(intf); usb_mark_last_busy(udev); - atomic_inc(&intf->pm_usage_cnt); pm_runtime_get_noresume(&intf->dev); } EXPORT_SYMBOL_GPL(usb_autopm_get_interface_no_resume); diff --git a/drivers/usb/storage/realtek_cr.c b/drivers/usb/storage/realtek_cr.c index ec83b3b5efa9..1a6df40f8b53 100644 --- a/drivers/usb/storage/realtek_cr.c +++ b/drivers/usb/storage/realtek_cr.c @@ -775,18 +775,16 @@ static void rts51x_suspend_timer_fn(unsigned long data) break; case RTS51X_STAT_IDLE: case RTS51X_STAT_SS: - usb_stor_dbg(us, "RTS51X_STAT_SS, intf->pm_usage_cnt:%d, power.usage:%d\n", - atomic_read(&us->pusb_intf->pm_usage_cnt), + usb_stor_dbg(us, "RTS51X_STAT_SS, power.usage:%d\n", atomic_read(&us->pusb_intf->dev.power.usage_count)); - if (atomic_read(&us->pusb_intf->pm_usage_cnt) > 0) { + if (atomic_read(&us->pusb_intf->dev.power.usage_count) > 0) { usb_stor_dbg(us, "Ready to enter SS state\n"); rts51x_set_stat(chip, RTS51X_STAT_SS); /* ignore mass storage interface's children */ pm_suspend_ignore_children(&us->pusb_intf->dev, true); usb_autopm_put_interface_async(us->pusb_intf); - usb_stor_dbg(us, "RTS51X_STAT_SS 01, intf->pm_usage_cnt:%d, power.usage:%d\n", - atomic_read(&us->pusb_intf->pm_usage_cnt), + usb_stor_dbg(us, "RTS51X_STAT_SS 01, power.usage:%d\n", atomic_read(&us->pusb_intf->dev.power.usage_count)); } break; @@ -819,11 +817,10 @@ static void rts51x_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) int ret; if (working_scsi(srb)) { - usb_stor_dbg(us, "working scsi, intf->pm_usage_cnt:%d, power.usage:%d\n", - atomic_read(&us->pusb_intf->pm_usage_cnt), + usb_stor_dbg(us, "working scsi, power.usage:%d\n", atomic_read(&us->pusb_intf->dev.power.usage_count)); - if (atomic_read(&us->pusb_intf->pm_usage_cnt) <= 0) { + if (atomic_read(&us->pusb_intf->dev.power.usage_count) <= 0) { ret = usb_autopm_get_interface(us->pusb_intf); usb_stor_dbg(us, "working scsi, ret=%d\n", ret); } diff --git a/include/linux/usb.h b/include/linux/usb.h index 8c7ba40cf021..a22a3e139e96 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -200,7 +200,6 @@ usb_find_last_int_out_endpoint(struct usb_host_interface *alt, * @dev: driver model's view of this device * @usb_dev: if an interface is bound to the USB major, this will point * to the sysfs representation for that device. - * @pm_usage_cnt: PM usage counter for this interface * @reset_ws: Used for scheduling resets from atomic context. * @resetting_device: USB core reset the device, so use alt setting 0 as * current; needs bandwidth alloc after reset. @@ -257,7 +256,6 @@ struct usb_interface { struct device dev; /* interface specific device info */ struct device *usb_dev; - atomic_t pm_usage_cnt; /* usage counter for autosuspend */ struct work_struct reset_ws; /* for resets in atomic context */ }; #define to_usb_interface(d) container_of(d, struct usb_interface, dev) -- GitLab From 204fd0bdccca09d21a5d4608e370b31071a84de5 Mon Sep 17 00:00:00 2001 From: Minchan Kim Date: Wed, 31 Jan 2018 16:16:55 -0800 Subject: [PATCH 0385/1121] mm: do not stall register_shrinker() commit e496612c5130567fc9d5f1969ca4b86665aa3cbb upstream. Shakeel Butt reported he has observed in production systems that the job loader gets stuck for 10s of seconds while doing a mount operation. It turns out that it was stuck in register_shrinker() because some unrelated job was under memory pressure and was spending time in shrink_slab(). Machines have a lot of shrinkers registered and jobs under memory pressure have to traverse all of those memcg-aware shrinkers and affect unrelated jobs which want to register their own shrinkers. To solve the issue, this patch simply bails out slab shrinking if it is found that someone wants to register a shrinker in parallel. A downside is it could cause unfair shrinking between shrinkers. However, it should be rare and we can add compilcated logic if we find it's not enough. [akpm@linux-foundation.org: tweak code comment] Link: http://lkml.kernel.org/r/20171115005602.GB23810@bbox Link: http://lkml.kernel.org/r/1511481899-20335-1-git-send-email-minchan@kernel.org Signed-off-by: Minchan Kim Signed-off-by: Shakeel Butt Reported-by: Shakeel Butt Tested-by: Shakeel Butt Acked-by: Johannes Weiner Acked-by: Michal Hocko Cc: Tetsuo Handa Cc: Anshuman Khandual Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds [rkolchmeyer: Backported to 4.14: adjusted context] Signed-off-by: Robert Kolchmeyer Signed-off-by: Greg Kroah-Hartman --- mm/vmscan.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/mm/vmscan.c b/mm/vmscan.c index 9734e62654fa..99837e931f53 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -502,6 +502,15 @@ static unsigned long shrink_slab(gfp_t gfp_mask, int nid, sc.nid = 0; freed += do_shrink_slab(&sc, shrinker, nr_scanned, nr_eligible); + /* + * Bail out if someone want to register a new shrinker to + * prevent the regsitration from being stalled for long periods + * by parallel ongoing shrinking. + */ + if (rwsem_is_contended(&shrinker_rwsem)) { + freed = freed ? : 1; + break; + } } up_read(&shrinker_rwsem); -- GitLab From be055737bee4cb0055da99a91eae6859268a599c Mon Sep 17 00:00:00 2001 From: Yufen Yu Date: Wed, 13 Mar 2019 18:54:59 +0100 Subject: [PATCH 0386/1121] nvme-loop: init nvmet_ctrl fatal_err_work when allocate [ Upstream commit d11de63f2b519f0a162b834013b6d3a46dbf3886 ] After commit 4d43d395fe (workqueue: Try to catch flush_work() without INIT_WORK()), it can cause warning when delete nvme-loop device, trace like: [ 76.601272] Call Trace: [ 76.601646] ? del_timer+0x72/0xa0 [ 76.602156] __cancel_work_timer+0x1ae/0x270 [ 76.602791] cancel_work_sync+0x14/0x20 [ 76.603407] nvmet_ctrl_free+0x1b7/0x2f0 [nvmet] [ 76.604091] ? free_percpu+0x168/0x300 [ 76.604652] nvmet_sq_destroy+0x106/0x240 [nvmet] [ 76.605346] nvme_loop_destroy_admin_queue+0x30/0x60 [nvme_loop] [ 76.606220] nvme_loop_shutdown_ctrl+0xc3/0xf0 [nvme_loop] [ 76.607026] nvme_loop_delete_ctrl_host+0x19/0x30 [nvme_loop] [ 76.607871] nvme_do_delete_ctrl+0x75/0xb0 [ 76.608477] nvme_sysfs_delete+0x7d/0xc0 [ 76.609057] dev_attr_store+0x24/0x40 [ 76.609603] sysfs_kf_write+0x4c/0x60 [ 76.610144] kernfs_fop_write+0x19a/0x260 [ 76.610742] __vfs_write+0x1c/0x60 [ 76.611246] vfs_write+0xfa/0x280 [ 76.611739] ksys_write+0x6e/0x120 [ 76.612238] __x64_sys_write+0x1e/0x30 [ 76.612787] do_syscall_64+0xbf/0x3a0 [ 76.613329] entry_SYSCALL_64_after_hwframe+0x44/0xa9 We fix it by moving fatal_err_work init to nvmet_alloc_ctrl(), which may more reasonable. Signed-off-by: Yufen Yu Reviewed-by: Sagi Grimberg Reviewed-by: Bart Van Assche Signed-off-by: Christoph Hellwig Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin --- drivers/nvme/target/core.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index 5fa7856f6b34..09a39f4aaf82 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c @@ -746,6 +746,15 @@ bool nvmet_host_allowed(struct nvmet_req *req, struct nvmet_subsys *subsys, return __nvmet_host_allowed(subsys, hostnqn); } +static void nvmet_fatal_error_handler(struct work_struct *work) +{ + struct nvmet_ctrl *ctrl = + container_of(work, struct nvmet_ctrl, fatal_err_work); + + pr_err("ctrl %d fatal error occurred!\n", ctrl->cntlid); + ctrl->ops->delete_ctrl(ctrl); +} + u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn, struct nvmet_req *req, u32 kato, struct nvmet_ctrl **ctrlp) { @@ -785,6 +794,7 @@ u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn, INIT_WORK(&ctrl->async_event_work, nvmet_async_event_work); INIT_LIST_HEAD(&ctrl->async_events); + INIT_WORK(&ctrl->fatal_err_work, nvmet_fatal_error_handler); memcpy(ctrl->subsysnqn, subsysnqn, NVMF_NQN_SIZE); memcpy(ctrl->hostnqn, hostnqn, NVMF_NQN_SIZE); @@ -887,21 +897,11 @@ void nvmet_ctrl_put(struct nvmet_ctrl *ctrl) kref_put(&ctrl->ref, nvmet_ctrl_free); } -static void nvmet_fatal_error_handler(struct work_struct *work) -{ - struct nvmet_ctrl *ctrl = - container_of(work, struct nvmet_ctrl, fatal_err_work); - - pr_err("ctrl %d fatal error occurred!\n", ctrl->cntlid); - ctrl->ops->delete_ctrl(ctrl); -} - void nvmet_ctrl_fatal_error(struct nvmet_ctrl *ctrl) { mutex_lock(&ctrl->lock); if (!(ctrl->csts & NVME_CSTS_CFS)) { ctrl->csts |= NVME_CSTS_CFS; - INIT_WORK(&ctrl->fatal_err_work, nvmet_fatal_error_handler); schedule_work(&ctrl->fatal_err_work); } mutex_unlock(&ctrl->lock); -- GitLab From 800935e187289b0fd7f54b498def60566e25eb77 Mon Sep 17 00:00:00 2001 From: Kangjie Lu Date: Thu, 14 Mar 2019 00:24:02 -0500 Subject: [PATCH 0387/1121] HID: logitech: check the return value of create_singlethread_workqueue [ Upstream commit 6c44b15e1c9076d925d5236ddadf1318b0a25ce2 ] create_singlethread_workqueue may fail and return NULL. The fix checks if it is NULL to avoid NULL pointer dereference. Also, the fix moves the call of create_singlethread_workqueue earlier to avoid resource-release issues. Signed-off-by: Kangjie Lu Signed-off-by: Jiri Kosina Signed-off-by: Sasha Levin --- drivers/hid/hid-logitech-hidpp.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 614054af904a..b83d4173fc7f 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -1907,6 +1907,13 @@ static int hidpp_ff_init(struct hidpp_device *hidpp, u8 feature_index) kfree(data); return -ENOMEM; } + data->wq = create_singlethread_workqueue("hidpp-ff-sendqueue"); + if (!data->wq) { + kfree(data->effect_ids); + kfree(data); + return -ENOMEM; + } + data->hidpp = hidpp; data->feature_index = feature_index; data->version = version; @@ -1951,7 +1958,6 @@ static int hidpp_ff_init(struct hidpp_device *hidpp, u8 feature_index) /* ignore boost value at response.fap.params[2] */ /* init the hardware command queue */ - data->wq = create_singlethread_workqueue("hidpp-ff-sendqueue"); atomic_set(&data->workqueue_size, 0); /* initialize with zero autocenter to get wheel in usable state */ -- GitLab From f70b76152308816d44e22a3566d7b7ddd1c8c21b Mon Sep 17 00:00:00 2001 From: "He, Bo" Date: Thu, 14 Mar 2019 02:28:21 +0000 Subject: [PATCH 0388/1121] HID: debug: fix race condition with between rdesc_show() and device removal [ Upstream commit cef0d4948cb0a02db37ebfdc320e127c77ab1637 ] There is a race condition that could happen if hid_debug_rdesc_show() is running while hdev is in the process of going away (device removal, system suspend, etc) which could result in NULL pointer dereference: BUG: unable to handle kernel paging request at 0000000783316040 CPU: 1 PID: 1512 Comm: getevent Tainted: G U O 4.19.20-quilt-2e5dc0ac-00029-gc455a447dd55 #1 RIP: 0010:hid_dump_device+0x9b/0x160 Call Trace: hid_debug_rdesc_show+0x72/0x1d0 seq_read+0xe0/0x410 full_proxy_read+0x5f/0x90 __vfs_read+0x3a/0x170 vfs_read+0xa0/0x150 ksys_read+0x58/0xc0 __x64_sys_read+0x1a/0x20 do_syscall_64+0x55/0x110 entry_SYSCALL_64_after_hwframe+0x49/0xbe Grab driver_input_lock to make sure the input device exists throughout the whole process of dumping the rdesc. [jkosina@suse.cz: update changelog a bit] Signed-off-by: he, bo Signed-off-by: "Zhang, Jun" Signed-off-by: Jiri Kosina Signed-off-by: Sasha Levin --- drivers/hid/hid-debug.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c index a90967cd4987..a0bcbb633b67 100644 --- a/drivers/hid/hid-debug.c +++ b/drivers/hid/hid-debug.c @@ -1060,10 +1060,15 @@ static int hid_debug_rdesc_show(struct seq_file *f, void *p) seq_printf(f, "\n\n"); /* dump parsed data and input mappings */ + if (down_interruptible(&hdev->driver_input_lock)) + return 0; + hid_dump_device(hdev, f); seq_printf(f, "\n"); hid_dump_input_mapping(hdev, f); + up(&hdev->driver_input_lock); + return 0; } -- GitLab From 94cee4ed4ca5747f4b2d8788a59909ee4ead58a5 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 20 Mar 2019 11:32:14 +0100 Subject: [PATCH 0389/1121] rtc: sh: Fix invalid alarm warning for non-enabled alarm [ Upstream commit 15d82d22498784966df8e4696174a16b02cc1052 ] When no alarm has been programmed on RSK-RZA1, an error message is printed during boot: rtc rtc0: invalid alarm value: 2019-03-14T255:255:255 sh_rtc_read_alarm_value() returns 0xff when querying a hardware alarm field that is not enabled. __rtc_read_alarm() validates the received alarm values, and fills in missing fields when needed. While 0xff is handled fine for the year, month, and day fields, and corrected as considered being out-of-range, this is not the case for the hour, minute, and second fields, where -1 is expected for missing fields. Fix this by returning -1 instead, as this value is handled fine for all fields. Signed-off-by: Geert Uytterhoeven Signed-off-by: Alexandre Belloni Signed-off-by: Sasha Levin --- drivers/rtc/rtc-sh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index 6c2d3989f967..9b6a927149a4 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c @@ -462,7 +462,7 @@ static int sh_rtc_set_time(struct device *dev, struct rtc_time *tm) static inline int sh_rtc_read_alarm_value(struct sh_rtc *rtc, int reg_off) { unsigned int byte; - int value = 0xff; /* return 0xff for ignored values */ + int value = -1; /* return -1 for ignored values */ byte = readb(rtc->regbase + reg_off); if (byte & AR_ENB) { -- GitLab From d8e291aea0bcc20960cbaafd6568c0e7561bab53 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 23 Feb 2019 14:27:10 +0100 Subject: [PATCH 0390/1121] batman-adv: Reduce claim hash refcnt only for removed entry [ Upstream commit 4ba104f468bbfc27362c393815d03aa18fb7a20f ] The batadv_hash_remove is a function which searches the hashtable for an entry using a needle, a hashtable bucket selection function and a compare function. It will lock the bucket list and delete an entry when the compare function matches it with the needle. It returns the pointer to the hlist_node which matches or NULL when no entry matches the needle. The batadv_bla_del_claim is not itself protected in anyway to avoid that any other function is modifying the hashtable between the search for the entry and the call to batadv_hash_remove. It can therefore happen that the entry either doesn't exist anymore or an entry was deleted which is not the same object as the needle. In such an situation, the reference counter (for the reference stored in the hashtable) must not be reduced for the needle. Instead the reference counter of the actually removed entry has to be reduced. Otherwise the reference counter will underflow and the object might be freed before all its references were dropped. The kref helpers reported this problem as: refcount_t: underflow; use-after-free. Fixes: 23721387c409 ("batman-adv: add basic bridge loop avoidance code") Signed-off-by: Sven Eckelmann Signed-off-by: Simon Wunderlich Signed-off-by: Sasha Levin --- net/batman-adv/bridge_loop_avoidance.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index c3c848f64fdd..c761c0c233e4 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -803,6 +803,8 @@ static void batadv_bla_del_claim(struct batadv_priv *bat_priv, const u8 *mac, const unsigned short vid) { struct batadv_bla_claim search_claim, *claim; + struct batadv_bla_claim *claim_removed_entry; + struct hlist_node *claim_removed_node; ether_addr_copy(search_claim.addr, mac); search_claim.vid = vid; @@ -813,10 +815,18 @@ static void batadv_bla_del_claim(struct batadv_priv *bat_priv, batadv_dbg(BATADV_DBG_BLA, bat_priv, "%s(): %pM, vid %d\n", __func__, mac, batadv_print_vid(vid)); - batadv_hash_remove(bat_priv->bla.claim_hash, batadv_compare_claim, - batadv_choose_claim, claim); - batadv_claim_put(claim); /* reference from the hash is gone */ + claim_removed_node = batadv_hash_remove(bat_priv->bla.claim_hash, + batadv_compare_claim, + batadv_choose_claim, claim); + if (!claim_removed_node) + goto free_claim; + /* reference from the hash is gone */ + claim_removed_entry = hlist_entry(claim_removed_node, + struct batadv_bla_claim, hash_entry); + batadv_claim_put(claim_removed_entry); + +free_claim: /* don't need the reference from hash_find() anymore */ batadv_claim_put(claim); } -- GitLab From ddb84b0fd459431a04ff1712a4d10083c0527a88 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 23 Feb 2019 14:27:10 +0100 Subject: [PATCH 0391/1121] batman-adv: Reduce tt_local hash refcnt only for removed entry [ Upstream commit 3d65b9accab4a7ed5038f6df403fbd5e298398c7 ] The batadv_hash_remove is a function which searches the hashtable for an entry using a needle, a hashtable bucket selection function and a compare function. It will lock the bucket list and delete an entry when the compare function matches it with the needle. It returns the pointer to the hlist_node which matches or NULL when no entry matches the needle. The batadv_tt_local_remove is not itself protected in anyway to avoid that any other function is modifying the hashtable between the search for the entry and the call to batadv_hash_remove. It can therefore happen that the entry either doesn't exist anymore or an entry was deleted which is not the same object as the needle. In such an situation, the reference counter (for the reference stored in the hashtable) must not be reduced for the needle. Instead the reference counter of the actually removed entry has to be reduced. Otherwise the reference counter will underflow and the object might be freed before all its references were dropped. The kref helpers reported this problem as: refcount_t: underflow; use-after-free. Fixes: ef72706a0543 ("batman-adv: protect tt_local_entry from concurrent delete events") Signed-off-by: Sven Eckelmann Signed-off-by: Simon Wunderlich Signed-off-by: Sasha Levin --- net/batman-adv/translation-table.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 9da3455847ff..6c3e446abeed 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -1313,9 +1313,10 @@ u16 batadv_tt_local_remove(struct batadv_priv *bat_priv, const u8 *addr, unsigned short vid, const char *message, bool roaming) { + struct batadv_tt_local_entry *tt_removed_entry; struct batadv_tt_local_entry *tt_local_entry; u16 flags, curr_flags = BATADV_NO_FLAGS; - void *tt_entry_exists; + struct hlist_node *tt_removed_node; tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid); if (!tt_local_entry) @@ -1344,15 +1345,18 @@ u16 batadv_tt_local_remove(struct batadv_priv *bat_priv, const u8 *addr, */ batadv_tt_local_event(bat_priv, tt_local_entry, BATADV_TT_CLIENT_DEL); - tt_entry_exists = batadv_hash_remove(bat_priv->tt.local_hash, + tt_removed_node = batadv_hash_remove(bat_priv->tt.local_hash, batadv_compare_tt, batadv_choose_tt, &tt_local_entry->common); - if (!tt_entry_exists) + if (!tt_removed_node) goto out; - /* extra call to free the local tt entry */ - batadv_tt_local_entry_put(tt_local_entry); + /* drop reference of remove hash entry */ + tt_removed_entry = hlist_entry(tt_removed_node, + struct batadv_tt_local_entry, + common.hash_entry); + batadv_tt_local_entry_put(tt_removed_entry); out: if (tt_local_entry) -- GitLab From 82000f004027a950c46e0e0441d0c98b890166f3 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 23 Feb 2019 14:27:10 +0100 Subject: [PATCH 0392/1121] batman-adv: Reduce tt_global hash refcnt only for removed entry [ Upstream commit f131a56880d10932931e74773fb8702894a94a75 ] The batadv_hash_remove is a function which searches the hashtable for an entry using a needle, a hashtable bucket selection function and a compare function. It will lock the bucket list and delete an entry when the compare function matches it with the needle. It returns the pointer to the hlist_node which matches or NULL when no entry matches the needle. The batadv_tt_global_free is not itself protected in anyway to avoid that any other function is modifying the hashtable between the search for the entry and the call to batadv_hash_remove. It can therefore happen that the entry either doesn't exist anymore or an entry was deleted which is not the same object as the needle. In such an situation, the reference counter (for the reference stored in the hashtable) must not be reduced for the needle. Instead the reference counter of the actually removed entry has to be reduced. Otherwise the reference counter will underflow and the object might be freed before all its references were dropped. The kref helpers reported this problem as: refcount_t: underflow; use-after-free. Fixes: 7683fdc1e886 ("batman-adv: protect the local and the global trans-tables with rcu") Reported-by: Martin Weinelt Signed-off-by: Sven Eckelmann Acked-by: Antonio Quartulli Signed-off-by: Simon Wunderlich Signed-off-by: Sasha Levin --- net/batman-adv/translation-table.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 6c3e446abeed..020a8adc4cce 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -614,14 +614,26 @@ static void batadv_tt_global_free(struct batadv_priv *bat_priv, struct batadv_tt_global_entry *tt_global, const char *message) { + struct batadv_tt_global_entry *tt_removed_entry; + struct hlist_node *tt_removed_node; + batadv_dbg(BATADV_DBG_TT, bat_priv, "Deleting global tt entry %pM (vid: %d): %s\n", tt_global->common.addr, batadv_print_vid(tt_global->common.vid), message); - batadv_hash_remove(bat_priv->tt.global_hash, batadv_compare_tt, - batadv_choose_tt, &tt_global->common); - batadv_tt_global_entry_put(tt_global); + tt_removed_node = batadv_hash_remove(bat_priv->tt.global_hash, + batadv_compare_tt, + batadv_choose_tt, + &tt_global->common); + if (!tt_removed_node) + return; + + /* drop reference of remove hash entry */ + tt_removed_entry = hlist_entry(tt_removed_node, + struct batadv_tt_global_entry, + common.hash_entry); + batadv_tt_global_entry_put(tt_removed_entry); } /** -- GitLab From 30ad7c9f9e7b6f71872bcf2ef31cd70b7a0b74a6 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Wed, 20 Mar 2019 13:14:00 -0700 Subject: [PATCH 0393/1121] ARM: dts: rockchip: Fix gpu opp node names for rk3288 [ Upstream commit d040e4e8deeaa8257d6aa260e29ad69832b5d630 ] The device tree compiler yells like this: Warning (unit_address_vs_reg): /gpu-opp-table/opp@100000000: node has a unit name, but no reg property Let's match the cpu opp node names and use a dash. Signed-off-by: Douglas Anderson Reviewed-by: Matthias Kaehlcke Signed-off-by: Heiko Stuebner Signed-off-by: Sasha Levin --- arch/arm/boot/dts/rk3288.dtsi | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index f7a951afd281..5a7888581eea 100644 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -1181,27 +1181,27 @@ gpu_opp_table: gpu-opp-table { compatible = "operating-points-v2"; - opp@100000000 { + opp-100000000 { opp-hz = /bits/ 64 <100000000>; opp-microvolt = <950000>; }; - opp@200000000 { + opp-200000000 { opp-hz = /bits/ 64 <200000000>; opp-microvolt = <950000>; }; - opp@300000000 { + opp-300000000 { opp-hz = /bits/ 64 <300000000>; opp-microvolt = <1000000>; }; - opp@400000000 { + opp-400000000 { opp-hz = /bits/ 64 <400000000>; opp-microvolt = <1100000>; }; - opp@500000000 { + opp-500000000 { opp-hz = /bits/ 64 <500000000>; opp-microvolt = <1200000>; }; - opp@600000000 { + opp-600000000 { opp-hz = /bits/ 64 <600000000>; opp-microvolt = <1250000>; }; -- GitLab From 498957921b0c639cc0bfe15cf68f678a1ae44104 Mon Sep 17 00:00:00 2001 From: Arvind Sankar Date: Sat, 2 Mar 2019 11:01:17 -0500 Subject: [PATCH 0394/1121] igb: Fix WARN_ONCE on runtime suspend [ Upstream commit dabb8338be533c18f50255cf39ff4f66d4dabdbe ] The runtime_suspend device callbacks are not supposed to save configuration state or change the power state. Commit fb29f76cc566 ("igb: Fix an issue that PME is not enabled during runtime suspend") changed the driver to not save configuration state during runtime suspend, however the driver callback still put the device into a low-power state. This causes a warning in the pci pm core and results in pci_pm_runtime_suspend not calling pci_save_state or pci_finish_runtime_suspend. Fix this by not changing the power state either, leaving that to pci pm core, and make the same change for suspend callback as well. Also move a couple of defines into the appropriate header file instead of inline in the .c file. Fixes: fb29f76cc566 ("igb: Fix an issue that PME is not enabled during runtime suspend") Signed-off-by: Arvind Sankar Reviewed-by: Kai-Heng Feng Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher Signed-off-by: Sasha Levin --- .../net/ethernet/intel/igb/e1000_defines.h | 2 + drivers/net/ethernet/intel/igb/igb_main.c | 57 +++---------------- 2 files changed, 10 insertions(+), 49 deletions(-) diff --git a/drivers/net/ethernet/intel/igb/e1000_defines.h b/drivers/net/ethernet/intel/igb/e1000_defines.h index 1de82f247312..d258a75c934b 100644 --- a/drivers/net/ethernet/intel/igb/e1000_defines.h +++ b/drivers/net/ethernet/intel/igb/e1000_defines.h @@ -214,6 +214,8 @@ /* enable link status from external LINK_0 and LINK_1 pins */ #define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */ #define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */ +#define E1000_CTRL_ADVD3WUC 0x00100000 /* D3 WUC */ +#define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000 /* PHY PM enable */ #define E1000_CTRL_SDP0_DIR 0x00400000 /* SDP0 Data direction */ #define E1000_CTRL_SDP1_DIR 0x00800000 /* SDP1 Data direction */ #define E1000_CTRL_RST 0x04000000 /* Global reset */ diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 8892ea5cbb01..71b235f935d9 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -7934,9 +7934,7 @@ static int __igb_shutdown(struct pci_dev *pdev, bool *enable_wake, struct e1000_hw *hw = &adapter->hw; u32 ctrl, rctl, status; u32 wufc = runtime ? E1000_WUFC_LNKC : adapter->wol; -#ifdef CONFIG_PM - int retval = 0; -#endif + bool wake; rtnl_lock(); netif_device_detach(netdev); @@ -7949,14 +7947,6 @@ static int __igb_shutdown(struct pci_dev *pdev, bool *enable_wake, igb_clear_interrupt_scheme(adapter); rtnl_unlock(); -#ifdef CONFIG_PM - if (!runtime) { - retval = pci_save_state(pdev); - if (retval) - return retval; - } -#endif - status = rd32(E1000_STATUS); if (status & E1000_STATUS_LU) wufc &= ~E1000_WUFC_LNKC; @@ -7973,10 +7963,6 @@ static int __igb_shutdown(struct pci_dev *pdev, bool *enable_wake, } ctrl = rd32(E1000_CTRL); - /* advertise wake from D3Cold */ - #define E1000_CTRL_ADVD3WUC 0x00100000 - /* phy power management enable */ - #define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000 ctrl |= E1000_CTRL_ADVD3WUC; wr32(E1000_CTRL, ctrl); @@ -7990,12 +7976,15 @@ static int __igb_shutdown(struct pci_dev *pdev, bool *enable_wake, wr32(E1000_WUFC, 0); } - *enable_wake = wufc || adapter->en_mng_pt; - if (!*enable_wake) + wake = wufc || adapter->en_mng_pt; + if (!wake) igb_power_down_link(adapter); else igb_power_up_link(adapter); + if (enable_wake) + *enable_wake = wake; + /* Release control of h/w to f/w. If f/w is AMT enabled, this * would have already happened in close and is redundant. */ @@ -8038,22 +8027,7 @@ static void igb_deliver_wake_packet(struct net_device *netdev) static int __maybe_unused igb_suspend(struct device *dev) { - int retval; - bool wake; - struct pci_dev *pdev = to_pci_dev(dev); - - retval = __igb_shutdown(pdev, &wake, 0); - if (retval) - return retval; - - if (wake) { - pci_prepare_to_sleep(pdev); - } else { - pci_wake_from_d3(pdev, false); - pci_set_power_state(pdev, PCI_D3hot); - } - - return 0; + return __igb_shutdown(to_pci_dev(dev), NULL, 0); } static int __maybe_unused igb_resume(struct device *dev) @@ -8124,22 +8098,7 @@ static int __maybe_unused igb_runtime_idle(struct device *dev) static int __maybe_unused igb_runtime_suspend(struct device *dev) { - struct pci_dev *pdev = to_pci_dev(dev); - int retval; - bool wake; - - retval = __igb_shutdown(pdev, &wake, 1); - if (retval) - return retval; - - if (wake) { - pci_prepare_to_sleep(pdev); - } else { - pci_wake_from_d3(pdev, false); - pci_set_power_state(pdev, PCI_D3hot); - } - - return 0; + return __igb_shutdown(to_pci_dev(dev), NULL, 1); } static int __maybe_unused igb_runtime_resume(struct device *dev) -- GitLab From c8bab3fcb370afd8881e3980d32dfa71e32b9105 Mon Sep 17 00:00:00 2001 From: Omri Kahalon Date: Sun, 24 Feb 2019 16:31:08 +0200 Subject: [PATCH 0395/1121] net/mlx5: E-Switch, Fix esw manager vport indication for more vport commands [ Upstream commit eca4a928585ac08147e5cc8e2111ecbc6279ee31 ] Traditionally, the PF (Physical Function) which resides on vport 0 was the E-switch manager. Since the ECPF (Embedded CPU Physical Function), which resides on vport 0xfffe, was introduced as the E-Switch manager, the assumption that the E-switch manager is on vport 0 is incorrect. Since the eswitch code already uses the actual vport value, all we need is to always set other_vport=1. Signed-off-by: Omri Kahalon Reviewed-by: Max Gurtovoy Signed-off-by: Saeed Mahameed Signed-off-by: Sasha Levin --- drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c index d2914116af8e..090d54275a7d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c @@ -79,8 +79,7 @@ static int arm_vport_context_events_cmd(struct mlx5_core_dev *dev, u16 vport, opcode, MLX5_CMD_OP_MODIFY_NIC_VPORT_CONTEXT); MLX5_SET(modify_nic_vport_context_in, in, field_select.change_event, 1); MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport); - if (vport) - MLX5_SET(modify_nic_vport_context_in, in, other_vport, 1); + MLX5_SET(modify_nic_vport_context_in, in, other_vport, 1); nic_vport_ctx = MLX5_ADDR_OF(modify_nic_vport_context_in, in, nic_vport_context); @@ -108,8 +107,7 @@ static int modify_esw_vport_context_cmd(struct mlx5_core_dev *dev, u16 vport, MLX5_SET(modify_esw_vport_context_in, in, opcode, MLX5_CMD_OP_MODIFY_ESW_VPORT_CONTEXT); MLX5_SET(modify_esw_vport_context_in, in, vport_number, vport); - if (vport) - MLX5_SET(modify_esw_vport_context_in, in, other_vport, 1); + MLX5_SET(modify_esw_vport_context_in, in, other_vport, 1); return mlx5_cmd_exec(dev, in, inlen, out, sizeof(out)); } -- GitLab From 389233e2df9fa97f55dcf9c26bd20313462067d0 Mon Sep 17 00:00:00 2001 From: Konstantin Khorenko Date: Thu, 28 Mar 2019 13:29:21 +0300 Subject: [PATCH 0396/1121] bonding: show full hw address in sysfs for slave entries [ Upstream commit 18bebc6dd3281955240062655a4df35eef2c46b3 ] Bond expects ethernet hwaddr for its slave, but it can be longer than 6 bytes - infiniband interface for example. # cat /sys/devices//net/ib0/address 80:00:02:08:fe:80:00:00:00:00:00:00:7c:fe:90:03:00:be:5d:e1 # cat /sys/devices//net/ib0/bonding_slave/perm_hwaddr 80:00:02:08:fe:80 So print full hwaddr in sysfs "bonding_slave/perm_hwaddr" as well. Signed-off-by: Konstantin Khorenko Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/bonding/bond_sysfs_slave.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/bonding/bond_sysfs_slave.c b/drivers/net/bonding/bond_sysfs_slave.c index 7d16c51e6913..641a532b67cb 100644 --- a/drivers/net/bonding/bond_sysfs_slave.c +++ b/drivers/net/bonding/bond_sysfs_slave.c @@ -55,7 +55,9 @@ static SLAVE_ATTR_RO(link_failure_count); static ssize_t perm_hwaddr_show(struct slave *slave, char *buf) { - return sprintf(buf, "%pM\n", slave->perm_hwaddr); + return sprintf(buf, "%*phC\n", + slave->dev->addr_len, + slave->perm_hwaddr); } static SLAVE_ATTR_RO(perm_hwaddr); -- GitLab From 4d8c8240e7afd0a3e8634d674ede26d3315c8af5 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Wed, 27 Mar 2019 22:35:36 +0200 Subject: [PATCH 0397/1121] net: stmmac: ratelimit RX error logs [ Upstream commit 972c9be784e077bc56472c78243e0326e525b689 ] Ratelimit RX error logs. Signed-off-by: Aaro Koskinen Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index ecf3f8c1bc0e..0f85e540001f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -3413,9 +3413,10 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) * ignored */ if (frame_len > priv->dma_buf_sz) { - netdev_err(priv->dev, - "len %d larger than size (%d)\n", - frame_len, priv->dma_buf_sz); + if (net_ratelimit()) + netdev_err(priv->dev, + "len %d larger than size (%d)\n", + frame_len, priv->dma_buf_sz); priv->dev->stats.rx_length_errors++; break; } @@ -3473,9 +3474,10 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) } else { skb = rx_q->rx_skbuff[entry]; if (unlikely(!skb)) { - netdev_err(priv->dev, - "%s: Inconsistent Rx chain\n", - priv->dev->name); + if (net_ratelimit()) + netdev_err(priv->dev, + "%s: Inconsistent Rx chain\n", + priv->dev->name); priv->dev->stats.rx_dropped++; break; } -- GitLab From 7292d0e64efe301ec85f079fcfa4b61515d83f40 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Wed, 27 Mar 2019 22:35:38 +0200 Subject: [PATCH 0398/1121] net: stmmac: don't overwrite discard_frame status [ Upstream commit 1b746ce8b397e58f9e40ce5c63b7198de6930482 ] If we have error bits set, the discard_frame status will get overwritten by checksum bit checks, which might set the status back to good one. Fix by checking the COE status only if the frame is good. Signed-off-by: Aaro Koskinen Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/stmicro/stmmac/enh_desc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c index acd65a4f94d4..cdfe9a350ac0 100644 --- a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c +++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c @@ -231,9 +231,10 @@ static int enh_desc_get_rx_status(void *data, struct stmmac_extra_stats *x, * It doesn't match with the information reported into the databook. * At any rate, we need to understand if the CSUM hw computation is ok * and report this info to the upper layers. */ - ret = enh_desc_coe_rdes0(!!(rdes0 & RDES0_IPC_CSUM_ERROR), - !!(rdes0 & RDES0_FRAME_TYPE), - !!(rdes0 & ERDES0_RX_MAC_ADDR)); + if (likely(ret == good_frame)) + ret = enh_desc_coe_rdes0(!!(rdes0 & RDES0_IPC_CSUM_ERROR), + !!(rdes0 & RDES0_FRAME_TYPE), + !!(rdes0 & ERDES0_RX_MAC_ADDR)); if (unlikely(rdes0 & RDES0_DRIBBLING)) x->dribbling_bit++; -- GitLab From 77d561c1935dfac1db3f3a985df0c54f99c16654 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Wed, 27 Mar 2019 22:35:39 +0200 Subject: [PATCH 0399/1121] net: stmmac: fix dropping of multi-descriptor RX frames [ Upstream commit 8ac0c24fe1c256af6644caf3d311029440ec2fbd ] Packets without the last descriptor set should be dropped early. If we receive a frame larger than the DMA buffer, the HW will continue using the next descriptor. Driver mistakes these as individual frames, and sometimes a truncated frame (without the LD set) may look like a valid packet. This fixes a strange issue where the system replies to 4098-byte ping although the MTU/DMA buffer size is set to 4096, and yet at the same time it's logging an oversized packet. Signed-off-by: Aaro Koskinen Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/stmicro/stmmac/enh_desc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c index cdfe9a350ac0..f2150efddc88 100644 --- a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c +++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c @@ -201,6 +201,11 @@ static int enh_desc_get_rx_status(void *data, struct stmmac_extra_stats *x, if (unlikely(rdes0 & RDES0_OWN)) return dma_own; + if (unlikely(!(rdes0 & RDES0_LAST_DESCRIPTOR))) { + stats->rx_length_errors++; + return discard_frame; + } + if (unlikely(rdes0 & RDES0_ERROR_SUMMARY)) { if (unlikely(rdes0 & RDES0_DESCRIPTOR_ERROR)) { x->rx_desc++; -- GitLab From 87f74cd974d69fb33ec00dca26f7655eb0569a79 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Wed, 27 Mar 2019 22:35:40 +0200 Subject: [PATCH 0400/1121] net: stmmac: don't log oversized frames [ Upstream commit 057a0c5642a2ff2db7c421cdcde34294a23bf37b ] This is log is harmful as it can trigger multiple times per packet. Delete it. Signed-off-by: Aaro Koskinen Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/stmicro/stmmac/norm_desc.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c index db4cee57bb24..66c17bab5997 100644 --- a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c +++ b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c @@ -91,8 +91,6 @@ static int ndesc_get_rx_status(void *data, struct stmmac_extra_stats *x, return dma_own; if (unlikely(!(rdes0 & RDES0_LAST_DESCRIPTOR))) { - pr_warn("%s: Oversized frame spanned multiple buffers\n", - __func__); stats->rx_length_errors++; return discard_frame; } -- GitLab From f9c04ee063108bfe16a7232429402866aa0ddd26 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 26 Mar 2019 01:39:50 +0000 Subject: [PATCH 0401/1121] jffs2: fix use-after-free on symlink traversal [ Upstream commit 4fdcfab5b5537c21891e22e65996d4d0dd8ab4ca ] free the symlink body after the same RCU delay we have for freeing the struct inode itself, so that traversal during RCU pathwalk wouldn't step into freed memory. Signed-off-by: Al Viro Signed-off-by: Sasha Levin --- fs/jffs2/readinode.c | 5 ----- fs/jffs2/super.c | 5 ++++- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c index 389ea53ea487..bccfc40b3a74 100644 --- a/fs/jffs2/readinode.c +++ b/fs/jffs2/readinode.c @@ -1414,11 +1414,6 @@ void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f) jffs2_kill_fragtree(&f->fragtree, deleted?c:NULL); - if (f->target) { - kfree(f->target); - f->target = NULL; - } - fds = f->dents; while(fds) { fd = fds; diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c index 83340496645b..9a9f30eddbbb 100644 --- a/fs/jffs2/super.c +++ b/fs/jffs2/super.c @@ -47,7 +47,10 @@ static struct inode *jffs2_alloc_inode(struct super_block *sb) static void jffs2_i_callback(struct rcu_head *head) { struct inode *inode = container_of(head, struct inode, i_rcu); - kmem_cache_free(jffs2_inode_cachep, JFFS2_INODE_INFO(inode)); + struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); + + kfree(f->target); + kmem_cache_free(jffs2_inode_cachep, f); } static void jffs2_destroy_inode(struct inode *inode) -- GitLab From c49cf5c84735c8b72a62ea779ef517def26c3783 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 26 Mar 2019 01:43:37 +0000 Subject: [PATCH 0402/1121] debugfs: fix use-after-free on symlink traversal [ Upstream commit 93b919da64c15b90953f96a536e5e61df896ca57 ] symlink body shouldn't be freed without an RCU delay. Switch debugfs to ->destroy_inode() and use of call_rcu(); free both the inode and symlink body in the callback. Similar to solution for bpf, only here it's even more obvious that ->evict_inode() can be dropped. Signed-off-by: Al Viro Signed-off-by: Sasha Levin --- fs/debugfs/inode.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index ccfe1e1cb6bc..f4df6feec271 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -170,19 +170,24 @@ static int debugfs_show_options(struct seq_file *m, struct dentry *root) return 0; } -static void debugfs_evict_inode(struct inode *inode) +static void debugfs_i_callback(struct rcu_head *head) { - truncate_inode_pages_final(&inode->i_data); - clear_inode(inode); + struct inode *inode = container_of(head, struct inode, i_rcu); if (S_ISLNK(inode->i_mode)) kfree(inode->i_link); + free_inode_nonrcu(inode); +} + +static void debugfs_destroy_inode(struct inode *inode) +{ + call_rcu(&inode->i_rcu, debugfs_i_callback); } static const struct super_operations debugfs_super_operations = { .statfs = simple_statfs, .remount_fs = debugfs_remount, .show_options = debugfs_show_options, - .evict_inode = debugfs_evict_inode, + .destroy_inode = debugfs_destroy_inode, }; static struct vfsmount *debugfs_automount(struct path *path) -- GitLab From 8217b8ee7b2143db7fa5d934f320e198fd16cdc5 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Tue, 2 Apr 2019 12:26:36 +0200 Subject: [PATCH 0403/1121] rtc: da9063: set uie_unsupported when relevant [ Upstream commit 882c5e552ffd06856de42261460f46e18319d259 ] The DA9063AD doesn't support alarms on any seconds and its granularity is the minute. Set uie_unsupported in that case. Reported-by: Wolfram Sang Reported-by: Geert Uytterhoeven Reviewed-by: Wolfram Sang Tested-by: Wolfram Sang Acked-by: Steve Twiss Signed-off-by: Alexandre Belloni Signed-off-by: Sasha Levin --- drivers/rtc/rtc-da9063.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/rtc/rtc-da9063.c b/drivers/rtc/rtc-da9063.c index f85cae240f12..7e92e491c2e7 100644 --- a/drivers/rtc/rtc-da9063.c +++ b/drivers/rtc/rtc-da9063.c @@ -480,6 +480,13 @@ static int da9063_rtc_probe(struct platform_device *pdev) da9063_data_to_tm(data, &rtc->alarm_time, rtc); rtc->rtc_sync = false; + /* + * TODO: some models have alarms on a minute boundary but still support + * real hardware interrupts. Add this once the core supports it. + */ + if (config->rtc_data_start != RTC_SEC) + rtc->rtc_dev->uie_unsupported = 1; + irq_alarm = platform_get_irq_byname(pdev, "ALARM"); ret = devm_request_threaded_irq(&pdev->dev, irq_alarm, NULL, da9063_alarm_event, -- GitLab From 5dbaaaa9cc6106acfda3924b5af583807634a995 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 2 Apr 2019 09:57:13 -0700 Subject: [PATCH 0404/1121] HID: input: add mapping for Assistant key [ Upstream commit ce856634af8cda3490947df8ac1ef5843e6356af ] According to HUTRR89 usage 0x1cb from the consumer page was assigned to allow launching desktop-aware assistant application, so let's add the mapping. Signed-off-by: Dmitry Torokhov Signed-off-by: Jiri Kosina Signed-off-by: Sasha Levin --- drivers/hid/hid-input.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index d146a9b545ee..1aa7d268686b 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -973,6 +973,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel case 0x1b8: map_key_clear(KEY_VIDEO); break; case 0x1bc: map_key_clear(KEY_MESSENGER); break; case 0x1bd: map_key_clear(KEY_INFO); break; + case 0x1cb: map_key_clear(KEY_ASSISTANT); break; case 0x201: map_key_clear(KEY_NEW); break; case 0x202: map_key_clear(KEY_OPEN); break; case 0x203: map_key_clear(KEY_CLOSE); break; -- GitLab From 5a56270b66047fb20b12252f97bcf10688f4ddb7 Mon Sep 17 00:00:00 2001 From: Louis Taylor Date: Wed, 3 Apr 2019 12:36:20 -0600 Subject: [PATCH 0405/1121] vfio/pci: use correct format characters [ Upstream commit 426b046b748d1f47e096e05bdcc6fb4172791307 ] When compiling with -Wformat, clang emits the following warnings: drivers/vfio/pci/vfio_pci.c:1601:5: warning: format specifies type 'unsigned short' but the argument has type 'unsigned int' [-Wformat] vendor, device, subvendor, subdevice, ^~~~~~ drivers/vfio/pci/vfio_pci.c:1601:13: warning: format specifies type 'unsigned short' but the argument has type 'unsigned int' [-Wformat] vendor, device, subvendor, subdevice, ^~~~~~ drivers/vfio/pci/vfio_pci.c:1601:21: warning: format specifies type 'unsigned short' but the argument has type 'unsigned int' [-Wformat] vendor, device, subvendor, subdevice, ^~~~~~~~~ drivers/vfio/pci/vfio_pci.c:1601:32: warning: format specifies type 'unsigned short' but the argument has type 'unsigned int' [-Wformat] vendor, device, subvendor, subdevice, ^~~~~~~~~ drivers/vfio/pci/vfio_pci.c:1605:5: warning: format specifies type 'unsigned short' but the argument has type 'unsigned int' [-Wformat] vendor, device, subvendor, subdevice, ^~~~~~ drivers/vfio/pci/vfio_pci.c:1605:13: warning: format specifies type 'unsigned short' but the argument has type 'unsigned int' [-Wformat] vendor, device, subvendor, subdevice, ^~~~~~ drivers/vfio/pci/vfio_pci.c:1605:21: warning: format specifies type 'unsigned short' but the argument has type 'unsigned int' [-Wformat] vendor, device, subvendor, subdevice, ^~~~~~~~~ drivers/vfio/pci/vfio_pci.c:1605:32: warning: format specifies type 'unsigned short' but the argument has type 'unsigned int' [-Wformat] vendor, device, subvendor, subdevice, ^~~~~~~~~ The types of these arguments are unconditionally defined, so this patch updates the format character to the correct ones for unsigned ints. Link: https://github.com/ClangBuiltLinux/linux/issues/378 Signed-off-by: Louis Taylor Reviewed-by: Nick Desaulniers Signed-off-by: Alex Williamson Signed-off-by: Sasha Levin --- drivers/vfio/pci/vfio_pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index 695b9d1a1aae..6f5cc67e343e 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c @@ -1443,11 +1443,11 @@ static void __init vfio_pci_fill_ids(void) rc = pci_add_dynid(&vfio_pci_driver, vendor, device, subvendor, subdevice, class, class_mask, 0); if (rc) - pr_warn("failed to add dynamic id [%04hx:%04hx[%04hx:%04hx]] class %#08x/%08x (%d)\n", + pr_warn("failed to add dynamic id [%04x:%04x[%04x:%04x]] class %#08x/%08x (%d)\n", vendor, device, subvendor, subdevice, class, class_mask, rc); else - pr_info("add [%04hx:%04hx[%04hx:%04hx]] class %#08x/%08x\n", + pr_info("add [%04x:%04x[%04x:%04x]] class %#08x/%08x\n", vendor, device, subvendor, subdevice, class, class_mask); } -- GitLab From 7f7ca34f2934f5fbf21dfb0e332ef1b80b86e757 Mon Sep 17 00:00:00 2001 From: Xose Vazquez Perez Date: Sat, 30 Mar 2019 15:43:31 +0100 Subject: [PATCH 0406/1121] scsi: core: add new RDAC LENOVO/DE_Series device [ Upstream commit 1cb1d2c64e812928fe0a40b8f7e74523d0283dbe ] Blacklist "Universal Xport" LUN. It's used for in-band storage array management. Also add model to the rdac dh family. Cc: Martin Wilck Cc: Hannes Reinecke Cc: NetApp RDAC team Cc: Christophe Varoqui Cc: James E.J. Bottomley Cc: Martin K. Petersen Cc: SCSI ML Cc: DM ML Signed-off-by: Xose Vazquez Perez Reviewed-by: Martin Wilck Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/scsi_devinfo.c | 1 + drivers/scsi/scsi_dh.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index 6b594bc7d94a..022fcd2e4702 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c @@ -248,6 +248,7 @@ static struct { {"NETAPP", "Universal Xport", "*", BLIST_NO_ULD_ATTACH}, {"LSI", "Universal Xport", "*", BLIST_NO_ULD_ATTACH}, {"ENGENIO", "Universal Xport", "*", BLIST_NO_ULD_ATTACH}, + {"LENOVO", "Universal Xport", "*", BLIST_NO_ULD_ATTACH}, {"SMSC", "USB 2 HS-CF", NULL, BLIST_SPARSELUN | BLIST_INQUIRY_36}, {"SONY", "CD-ROM CDU-8001", NULL, BLIST_BORKEN}, {"SONY", "TSL", NULL, BLIST_FORCELUN}, /* DDS3 & DDS4 autoloaders */ diff --git a/drivers/scsi/scsi_dh.c b/drivers/scsi/scsi_dh.c index 375cede0c534..c9bc6f058424 100644 --- a/drivers/scsi/scsi_dh.c +++ b/drivers/scsi/scsi_dh.c @@ -75,6 +75,7 @@ static const struct scsi_dh_blist scsi_dh_blist[] = { {"NETAPP", "INF-01-00", "rdac", }, {"LSI", "INF-01-00", "rdac", }, {"ENGENIO", "INF-01-00", "rdac", }, + {"LENOVO", "DE_Series", "rdac", }, {NULL, NULL, NULL }, }; -- GitLab From 20e5957d817049a2aeacc30ba0c802e9f3f28621 Mon Sep 17 00:00:00 2001 From: Michael Kelley Date: Mon, 1 Apr 2019 16:10:52 +0000 Subject: [PATCH 0407/1121] scsi: storvsc: Fix calculation of sub-channel count [ Upstream commit 382e06d11e075a40b4094b6ef809f8d4bcc7ab2a ] When the number of sub-channels offered by Hyper-V is >= the number of CPUs in the VM, calculate the correct number of sub-channels. The current code produces one too many. This scenario arises only when the number of CPUs is artificially restricted (for example, with maxcpus= on the kernel boot line), because Hyper-V normally offers a sub-channel count < number of CPUs. While the current code doesn't break, the extra sub-channel is unbalanced across the CPUs (for example, a total of 5 channels on a VM with 4 CPUs). Signed-off-by: Michael Kelley Reviewed-by: Vitaly Kuznetsov Reviewed-by: Long Li Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/storvsc_drv.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index beb585ddc07d..5adeb1e4b186 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -658,13 +658,22 @@ static void handle_sc_creation(struct vmbus_channel *new_sc) static void handle_multichannel_storage(struct hv_device *device, int max_chns) { struct storvsc_device *stor_device; - int num_cpus = num_online_cpus(); int num_sc; struct storvsc_cmd_request *request; struct vstor_packet *vstor_packet; int ret, t; - num_sc = ((max_chns > num_cpus) ? num_cpus : max_chns); + /* + * If the number of CPUs is artificially restricted, such as + * with maxcpus=1 on the kernel boot line, Hyper-V could offer + * sub-channels >= the number of CPUs. These sub-channels + * should not be created. The primary channel is already created + * and assigned to one CPU, so check against # CPUs - 1. + */ + num_sc = min((int)(num_online_cpus() - 1), max_chns); + if (!num_sc) + return; + stor_device = get_out_stor_device(device); if (!stor_device) return; -- GitLab From 91c4d62493a277ecfa8201da62e663af68507248 Mon Sep 17 00:00:00 2001 From: Liubin Shu Date: Thu, 4 Apr 2019 16:46:42 +0800 Subject: [PATCH 0408/1121] net: hns: fix KASAN: use-after-free in hns_nic_net_xmit_hw() [ Upstream commit 3a39a12ad364a9acd1038ba8da67cd8430f30de4 ] This patch is trying to fix the issue due to: [27237.844750] BUG: KASAN: use-after-free in hns_nic_net_xmit_hw+0x708/0xa18[hns_enet_drv] After hnae_queue_xmit() in hns_nic_net_xmit_hw(), can be interrupted by interruptions, and than call hns_nic_tx_poll_one() to handle the new packets, and free the skb. So, when turn back to hns_nic_net_xmit_hw(), calling skb->len will cause use-after-free. This patch update tx ring statistics in hns_nic_tx_poll_one() to fix the bug. Signed-off-by: Liubin Shu Signed-off-by: Zhen Lei Signed-off-by: Yonglong Liu Signed-off-by: Peng Li Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/hisilicon/hns/hns_enet.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c b/drivers/net/ethernet/hisilicon/hns/hns_enet.c index d30c28fba249..15739eae3da1 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c @@ -376,8 +376,6 @@ netdev_tx_t hns_nic_net_xmit_hw(struct net_device *ndev, wmb(); /* commit all data before submit */ assert(skb->queue_mapping < priv->ae_handle->q_num); hnae_queue_xmit(priv->ae_handle->qs[skb->queue_mapping], buf_num); - ring->stats.tx_pkts++; - ring->stats.tx_bytes += skb->len; return NETDEV_TX_OK; @@ -1099,6 +1097,9 @@ static int hns_nic_tx_poll_one(struct hns_nic_ring_data *ring_data, /* issue prefetch for next Tx descriptor */ prefetch(&ring->desc_cb[ring->next_to_clean]); } + /* update tx ring statistics. */ + ring->stats.tx_pkts += pkts; + ring->stats.tx_bytes += bytes; NETIF_TX_UNLOCK(ring); -- GitLab From 8d160e7b3da8f0c169a6d616ce32f62e16986419 Mon Sep 17 00:00:00 2001 From: Yonglong Liu Date: Thu, 4 Apr 2019 16:46:43 +0800 Subject: [PATCH 0409/1121] net: hns: Use NAPI_POLL_WEIGHT for hns driver [ Upstream commit acb1ce15a61154aa501891d67ebf79bc9ea26818 ] When the HNS driver loaded, always have an error print: "netif_napi_add() called with weight 256" This is because the kernel checks the NAPI polling weights requested by drivers and it prints an error message if a driver requests a weight bigger than 64. So use NAPI_POLL_WEIGHT to fix it. Signed-off-by: Yonglong Liu Signed-off-by: Peng Li Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/hisilicon/hns/hns_enet.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c b/drivers/net/ethernet/hisilicon/hns/hns_enet.c index 15739eae3da1..8fd040817804 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c @@ -29,9 +29,6 @@ #define SERVICE_TIMER_HZ (1 * HZ) -#define NIC_TX_CLEAN_MAX_NUM 256 -#define NIC_RX_CLEAN_MAX_NUM 64 - #define RCB_IRQ_NOT_INITED 0 #define RCB_IRQ_INITED 1 #define HNS_BUFFER_SIZE_2048 2048 @@ -2270,7 +2267,7 @@ static int hns_nic_init_ring_data(struct hns_nic_priv *priv) hns_nic_tx_fini_pro_v2; netif_napi_add(priv->netdev, &rd->napi, - hns_nic_common_poll, NIC_TX_CLEAN_MAX_NUM); + hns_nic_common_poll, NAPI_POLL_WEIGHT); rd->ring->irq_init_flag = RCB_IRQ_NOT_INITED; } for (i = h->q_num; i < h->q_num * 2; i++) { @@ -2283,7 +2280,7 @@ static int hns_nic_init_ring_data(struct hns_nic_priv *priv) hns_nic_rx_fini_pro_v2; netif_napi_add(priv->netdev, &rd->napi, - hns_nic_common_poll, NIC_RX_CLEAN_MAX_NUM); + hns_nic_common_poll, NAPI_POLL_WEIGHT); rd->ring->irq_init_flag = RCB_IRQ_NOT_INITED; } -- GitLab From e6492610237a65b5de9080a0f67c7b1936754d76 Mon Sep 17 00:00:00 2001 From: Yonglong Liu Date: Thu, 4 Apr 2019 16:46:44 +0800 Subject: [PATCH 0410/1121] net: hns: Fix probabilistic memory overwrite when HNS driver initialized [ Upstream commit c0b0984426814f3a9251873b689e67d34d8ccd84 ] When reboot the system again and again, may cause a memory overwrite. [ 15.638922] systemd[1]: Reached target Swap. [ 15.667561] tun: Universal TUN/TAP device driver, 1.6 [ 15.676756] Bridge firewalling registered [ 17.344135] Unable to handle kernel paging request at virtual address 0000000200000040 [ 17.352179] Mem abort info: [ 17.355007] ESR = 0x96000004 [ 17.358105] Exception class = DABT (current EL), IL = 32 bits [ 17.364112] SET = 0, FnV = 0 [ 17.367209] EA = 0, S1PTW = 0 [ 17.370393] Data abort info: [ 17.373315] ISV = 0, ISS = 0x00000004 [ 17.377206] CM = 0, WnR = 0 [ 17.380214] user pgtable: 4k pages, 48-bit VAs, pgdp = (____ptrval____) [ 17.386926] [0000000200000040] pgd=0000000000000000 [ 17.391878] Internal error: Oops: 96000004 [#1] SMP [ 17.396824] CPU: 23 PID: 95 Comm: kworker/u130:0 Tainted: G E 4.19.25-1.2.78.aarch64 #1 [ 17.414175] Hardware name: Huawei TaiShan 2280 /BC11SPCD, BIOS 1.54 08/16/2018 [ 17.425615] Workqueue: events_unbound async_run_entry_fn [ 17.435151] pstate: 00000005 (nzcv daif -PAN -UAO) [ 17.444139] pc : __mutex_lock.isra.1+0x74/0x540 [ 17.453002] lr : __mutex_lock.isra.1+0x3c/0x540 [ 17.461701] sp : ffff000100d9bb60 [ 17.469146] x29: ffff000100d9bb60 x28: 0000000000000000 [ 17.478547] x27: 0000000000000000 x26: ffff802fb8945000 [ 17.488063] x25: 0000000000000000 x24: ffff802fa32081a8 [ 17.497381] x23: 0000000000000002 x22: ffff801fa2b15220 [ 17.506701] x21: ffff000009809000 x20: ffff802fa23a0888 [ 17.515980] x19: ffff801fa2b15220 x18: 0000000000000000 [ 17.525272] x17: 0000000200000000 x16: 0000000200000000 [ 17.534511] x15: 0000000000000000 x14: 0000000000000000 [ 17.543652] x13: ffff000008d95db8 x12: 000000000000000d [ 17.552780] x11: ffff000008d95d90 x10: 0000000000000b00 [ 17.561819] x9 : ffff000100d9bb90 x8 : ffff802fb89d6560 [ 17.570829] x7 : 0000000000000004 x6 : 00000004a1801d05 [ 17.579839] x5 : 0000000000000000 x4 : 0000000000000000 [ 17.588852] x3 : ffff802fb89d5a00 x2 : 0000000000000000 [ 17.597734] x1 : 0000000200000000 x0 : 0000000200000000 [ 17.606631] Process kworker/u130:0 (pid: 95, stack limit = 0x(____ptrval____)) [ 17.617438] Call trace: [ 17.623349] __mutex_lock.isra.1+0x74/0x540 [ 17.630927] __mutex_lock_slowpath+0x24/0x30 [ 17.638602] mutex_lock+0x50/0x60 [ 17.645295] drain_workqueue+0x34/0x198 [ 17.652623] __sas_drain_work+0x7c/0x168 [ 17.659903] sas_drain_work+0x60/0x68 [ 17.666947] hisi_sas_scan_finished+0x30/0x40 [hisi_sas_main] [ 17.676129] do_scsi_scan_host+0x70/0xb0 [ 17.683534] do_scan_async+0x20/0x228 [ 17.690586] async_run_entry_fn+0x4c/0x1d0 [ 17.697997] process_one_work+0x1b4/0x3f8 [ 17.705296] worker_thread+0x54/0x470 Every time the call trace is not the same, but the overwrite address is always the same: Unable to handle kernel paging request at virtual address 0000000200000040 The root cause is, when write the reg XGMAC_MAC_TX_LF_RF_CONTROL_REG, didn't use the io_base offset. Signed-off-by: Yonglong Liu Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c index 51e7e9f5af49..70de7b5d28af 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c @@ -129,7 +129,7 @@ static void hns_xgmac_lf_rf_control_init(struct mac_driver *mac_drv) dsaf_set_bit(val, XGMAC_UNIDIR_EN_B, 0); dsaf_set_bit(val, XGMAC_RF_TX_EN_B, 1); dsaf_set_field(val, XGMAC_LF_RF_INSERT_M, XGMAC_LF_RF_INSERT_S, 0); - dsaf_write_reg(mac_drv, XGMAC_MAC_TX_LF_RF_CONTROL_REG, val); + dsaf_write_dev(mac_drv, XGMAC_MAC_TX_LF_RF_CONTROL_REG, val); } /** -- GitLab From e141a7c339a6bcfe7b11ee7393a934e34dab591d Mon Sep 17 00:00:00 2001 From: Yonglong Liu Date: Thu, 4 Apr 2019 16:46:45 +0800 Subject: [PATCH 0411/1121] net: hns: fix ICMP6 neighbor solicitation messages discard problem [ Upstream commit f058e46855dcbc28edb2ed4736f38a71fd19cadb ] ICMP6 neighbor solicitation messages will be discard by the Hip06 chips, because of not setting forwarding pool. Enable promisc mode has the same problem. This patch fix the wrong forwarding table configs for the multicast vague matching when enable promisc mode, and add forwarding pool for the forwarding table. Signed-off-by: Yonglong Liu Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- .../ethernet/hisilicon/hns/hns_dsaf_main.c | 33 +++++++++++++++---- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c index 7e82dfbb4340..7d0f3cd8a002 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c @@ -2743,6 +2743,17 @@ int hns_dsaf_get_regs_count(void) return DSAF_DUMP_REGS_NUM; } +static int hns_dsaf_get_port_id(u8 port) +{ + if (port < DSAF_SERVICE_NW_NUM) + return port; + + if (port >= DSAF_BASE_INNER_PORT_NUM) + return port - DSAF_BASE_INNER_PORT_NUM + DSAF_SERVICE_NW_NUM; + + return -EINVAL; +} + static void set_promisc_tcam_enable(struct dsaf_device *dsaf_dev, u32 port) { struct dsaf_tbl_tcam_ucast_cfg tbl_tcam_ucast = {0, 1, 0, 0, 0x80}; @@ -2808,23 +2819,33 @@ static void set_promisc_tcam_enable(struct dsaf_device *dsaf_dev, u32 port) memset(&temp_key, 0x0, sizeof(temp_key)); mask_entry.addr[0] = 0x01; hns_dsaf_set_mac_key(dsaf_dev, &mask_key, mask_entry.in_vlan_id, - port, mask_entry.addr); + 0xf, mask_entry.addr); tbl_tcam_mcast.tbl_mcast_item_vld = 1; tbl_tcam_mcast.tbl_mcast_old_en = 0; - if (port < DSAF_SERVICE_NW_NUM) { - mskid = port; - } else if (port >= DSAF_BASE_INNER_PORT_NUM) { - mskid = port - DSAF_BASE_INNER_PORT_NUM + DSAF_SERVICE_NW_NUM; - } else { + /* set MAC port to handle multicast */ + mskid = hns_dsaf_get_port_id(port); + if (mskid == -EINVAL) { dev_err(dsaf_dev->dev, "%s,pnum(%d)error,key(%#x:%#x)\n", dsaf_dev->ae_dev.name, port, mask_key.high.val, mask_key.low.val); return; } + dsaf_set_bit(tbl_tcam_mcast.tbl_mcast_port_msk[mskid / 32], + mskid % 32, 1); + /* set pool bit map to handle multicast */ + mskid = hns_dsaf_get_port_id(port_num); + if (mskid == -EINVAL) { + dev_err(dsaf_dev->dev, + "%s, pool bit map pnum(%d)error,key(%#x:%#x)\n", + dsaf_dev->ae_dev.name, port_num, + mask_key.high.val, mask_key.low.val); + return; + } dsaf_set_bit(tbl_tcam_mcast.tbl_mcast_port_msk[mskid / 32], mskid % 32, 1); + memcpy(&temp_key, &mask_key, sizeof(mask_key)); hns_dsaf_tcam_mc_cfg_vague(dsaf_dev, entry_index, &tbl_tcam_data_mc, (struct dsaf_tbl_tcam_data *)(&mask_key), -- GitLab From 717215dfb85a10ae366abd6560be26d8a914f48a Mon Sep 17 00:00:00 2001 From: Yonglong Liu Date: Thu, 4 Apr 2019 16:46:46 +0800 Subject: [PATCH 0412/1121] net: hns: Fix WARNING when remove HNS driver with SMMU enabled [ Upstream commit 8601a99d7c0256b7a7fdd1ab14cf6c1f1dfcadc6 ] When enable SMMU, remove HNS driver will cause a WARNING: [ 141.924177] WARNING: CPU: 36 PID: 2708 at drivers/iommu/dma-iommu.c:443 __iommu_dma_unmap+0xc0/0xc8 [ 141.954673] Modules linked in: hns_enet_drv(-) [ 141.963615] CPU: 36 PID: 2708 Comm: rmmod Tainted: G W 5.0.0-rc1-28723-gb729c57de95c-dirty #32 [ 141.983593] Hardware name: Huawei D05/D05, BIOS Hisilicon D05 UEFI Nemo 1.8 RC0 08/31/2017 [ 142.000244] pstate: 60000005 (nZCv daif -PAN -UAO) [ 142.009886] pc : __iommu_dma_unmap+0xc0/0xc8 [ 142.018476] lr : __iommu_dma_unmap+0xc0/0xc8 [ 142.027066] sp : ffff000013533b90 [ 142.033728] x29: ffff000013533b90 x28: ffff8013e6983600 [ 142.044420] x27: 0000000000000000 x26: 0000000000000000 [ 142.055113] x25: 0000000056000000 x24: 0000000000000015 [ 142.065806] x23: 0000000000000028 x22: ffff8013e66eee68 [ 142.076499] x21: ffff8013db919800 x20: 0000ffffefbff000 [ 142.087192] x19: 0000000000001000 x18: 0000000000000007 [ 142.097885] x17: 000000000000000e x16: 0000000000000001 [ 142.108578] x15: 0000000000000019 x14: 363139343a70616d [ 142.119270] x13: 6e75656761705f67 x12: 0000000000000000 [ 142.129963] x11: 00000000ffffffff x10: 0000000000000006 [ 142.140656] x9 : 1346c1aa88093500 x8 : ffff0000114de4e0 [ 142.151349] x7 : 6662666578303d72 x6 : ffff0000105ffec8 [ 142.162042] x5 : 0000000000000000 x4 : 0000000000000000 [ 142.172734] x3 : 00000000ffffffff x2 : ffff0000114de500 [ 142.183427] x1 : 0000000000000000 x0 : 0000000000000035 [ 142.194120] Call trace: [ 142.199030] __iommu_dma_unmap+0xc0/0xc8 [ 142.206920] iommu_dma_unmap_page+0x20/0x28 [ 142.215335] __iommu_unmap_page+0x40/0x60 [ 142.223399] hnae_unmap_buffer+0x110/0x134 [ 142.231639] hnae_free_desc+0x6c/0x10c [ 142.239177] hnae_fini_ring+0x14/0x34 [ 142.246540] hnae_fini_queue+0x2c/0x40 [ 142.254080] hnae_put_handle+0x38/0xcc [ 142.261619] hns_nic_dev_remove+0x54/0xfc [hns_enet_drv] [ 142.272312] platform_drv_remove+0x24/0x64 [ 142.280552] device_release_driver_internal+0x17c/0x20c [ 142.291070] driver_detach+0x4c/0x90 [ 142.298259] bus_remove_driver+0x5c/0xd8 [ 142.306148] driver_unregister+0x2c/0x54 [ 142.314037] platform_driver_unregister+0x10/0x18 [ 142.323505] hns_nic_dev_driver_exit+0x14/0xf0c [hns_enet_drv] [ 142.335248] __arm64_sys_delete_module+0x214/0x25c [ 142.344891] el0_svc_common+0xb0/0x10c [ 142.352430] el0_svc_handler+0x24/0x80 [ 142.359968] el0_svc+0x8/0x7c0 [ 142.366104] ---[ end trace 60ad1cd58e63c407 ]--- The tx ring buffer map when xmit and unmap when xmit done. So in hnae_init_ring() did not map tx ring buffer, but in hnae_fini_ring() have a unmap operation for tx ring buffer, which is already unmapped when xmit done, than cause this WARNING. The hnae_alloc_buffers() is called in hnae_init_ring(), so the hnae_free_buffers() should be in hnae_fini_ring(), not in hnae_free_desc(). In hnae_fini_ring(), adds a check is_rx_ring() as in hnae_init_ring(). When the ring buffer is tx ring, adds a piece of code to ensure that the tx ring is unmap. Signed-off-by: Yonglong Liu Signed-off-by: Peng Li Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/hisilicon/hns/hnae.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.c b/drivers/net/ethernet/hisilicon/hns/hnae.c index 79d03f8ee7b1..c7fa97a7e1f4 100644 --- a/drivers/net/ethernet/hisilicon/hns/hnae.c +++ b/drivers/net/ethernet/hisilicon/hns/hnae.c @@ -150,7 +150,6 @@ static int hnae_alloc_buffers(struct hnae_ring *ring) /* free desc along with its attached buffer */ static void hnae_free_desc(struct hnae_ring *ring) { - hnae_free_buffers(ring); dma_unmap_single(ring_to_dev(ring), ring->desc_dma_addr, ring->desc_num * sizeof(ring->desc[0]), ring_to_dma_dir(ring)); @@ -183,6 +182,9 @@ static int hnae_alloc_desc(struct hnae_ring *ring) /* fini ring, also free the buffer for the ring */ static void hnae_fini_ring(struct hnae_ring *ring) { + if (is_rx_ring(ring)) + hnae_free_buffers(ring); + hnae_free_desc(ring); kfree(ring->desc_cb); ring->desc_cb = NULL; -- GitLab From 1b19cbd71eaa65b6df7a2c594baf4f7c25c98f57 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Fri, 5 Apr 2019 18:38:49 -0700 Subject: [PATCH 0413/1121] kmemleak: powerpc: skip scanning holes in the .bss section [ Upstream commit 298a32b132087550d3fa80641ca58323c5dfd4d9 ] Commit 2d4f567103ff ("KVM: PPC: Introduce kvm_tmp framework") adds kvm_tmp[] into the .bss section and then free the rest of unused spaces back to the page allocator. kernel_init kvm_guest_init kvm_free_tmp free_reserved_area free_unref_page free_unref_page_prepare With DEBUG_PAGEALLOC=y, it will unmap those pages from kernel. As the result, kmemleak scan will trigger a panic when it scans the .bss section with unmapped pages. This patch creates dedicated kmemleak objects for the .data, .bss and potentially .data..ro_after_init sections to allow partial freeing via the kmemleak_free_part() in the powerpc kvm_free_tmp() function. Link: http://lkml.kernel.org/r/20190321171917.62049-1-catalin.marinas@arm.com Signed-off-by: Catalin Marinas Reported-by: Qian Cai Acked-by: Michael Ellerman (powerpc) Tested-by: Qian Cai Cc: Paul Mackerras Cc: Benjamin Herrenschmidt Cc: Avi Kivity Cc: Paolo Bonzini Cc: Radim Krcmar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Sasha Levin --- arch/powerpc/kernel/kvm.c | 7 +++++++ mm/kmemleak.c | 16 +++++++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c index 9ad37f827a97..7b59cc853abf 100644 --- a/arch/powerpc/kernel/kvm.c +++ b/arch/powerpc/kernel/kvm.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -712,6 +713,12 @@ static void kvm_use_magic_page(void) static __init void kvm_free_tmp(void) { + /* + * Inform kmemleak about the hole in the .bss section since the + * corresponding pages will be unmapped with DEBUG_PAGEALLOC=y. + */ + kmemleak_free_part(&kvm_tmp[kvm_tmp_index], + ARRAY_SIZE(kvm_tmp) - kvm_tmp_index); free_reserved_area(&kvm_tmp[kvm_tmp_index], &kvm_tmp[ARRAY_SIZE(kvm_tmp)], -1, NULL); } diff --git a/mm/kmemleak.c b/mm/kmemleak.c index d9e0be2a8189..337be9aacb7a 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c @@ -1492,11 +1492,6 @@ static void kmemleak_scan(void) } rcu_read_unlock(); - /* data/bss scanning */ - scan_large_block(_sdata, _edata); - scan_large_block(__bss_start, __bss_stop); - scan_large_block(__start_ro_after_init, __end_ro_after_init); - #ifdef CONFIG_SMP /* per-cpu sections scanning */ for_each_possible_cpu(i) @@ -2027,6 +2022,17 @@ void __init kmemleak_init(void) } local_irq_restore(flags); + /* register the data/bss sections */ + create_object((unsigned long)_sdata, _edata - _sdata, + KMEMLEAK_GREY, GFP_ATOMIC); + create_object((unsigned long)__bss_start, __bss_stop - __bss_start, + KMEMLEAK_GREY, GFP_ATOMIC); + /* only register .data..ro_after_init if not within .data */ + if (__start_ro_after_init < _sdata || __end_ro_after_init > _edata) + create_object((unsigned long)__start_ro_after_init, + __end_ro_after_init - __start_ro_after_init, + KMEMLEAK_GREY, GFP_ATOMIC); + /* * This is the point where tracking allocations is safe. Automatic * scanning is started during the late initcall. Add the early logged -- GitLab From 250b62d1f0b0cb28ade5a311d5a3727bd0f846df Mon Sep 17 00:00:00 2001 From: Mike Kravetz Date: Fri, 5 Apr 2019 18:39:06 -0700 Subject: [PATCH 0414/1121] hugetlbfs: fix memory leak for resv_map [ Upstream commit 58b6e5e8f1addd44583d61b0a03c0f5519527e35 ] When mknod is used to create a block special file in hugetlbfs, it will allocate an inode and kmalloc a 'struct resv_map' via resv_map_alloc(). inode->i_mapping->private_data will point the newly allocated resv_map. However, when the device special file is opened bd_acquire() will set inode->i_mapping to bd_inode->i_mapping. Thus the pointer to the allocated resv_map is lost and the structure is leaked. Programs to reproduce: mount -t hugetlbfs nodev hugetlbfs mknod hugetlbfs/dev b 0 0 exec 30<> hugetlbfs/dev umount hugetlbfs/ resv_map structures are only needed for inodes which can have associated page allocations. To fix the leak, only allocate resv_map for those inodes which could possibly be associated with page allocations. Link: http://lkml.kernel.org/r/20190401213101.16476-1-mike.kravetz@oracle.com Signed-off-by: Mike Kravetz Reviewed-by: Andrew Morton Reported-by: Yufen Yu Suggested-by: Yufen Yu Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Sasha Levin --- fs/hugetlbfs/inode.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index eb6f3de29f69..dd28a9b287da 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -730,11 +730,17 @@ static struct inode *hugetlbfs_get_inode(struct super_block *sb, umode_t mode, dev_t dev) { struct inode *inode; - struct resv_map *resv_map; + struct resv_map *resv_map = NULL; - resv_map = resv_map_alloc(); - if (!resv_map) - return NULL; + /* + * Reserve maps are only needed for inodes that can have associated + * page allocations. + */ + if (S_ISREG(mode) || S_ISLNK(mode)) { + resv_map = resv_map_alloc(); + if (!resv_map) + return NULL; + } inode = new_inode(sb); if (inode) { @@ -766,8 +772,10 @@ static struct inode *hugetlbfs_get_inode(struct super_block *sb, break; } lockdep_annotate_inode_mutex_key(inode); - } else - kref_put(&resv_map->refs, resv_map_release); + } else { + if (resv_map) + kref_put(&resv_map->refs, resv_map_release); + } return inode; } -- GitLab From 55bf50acb0ffaafd2468975e16ed1d66fa9abaa5 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 5 Apr 2019 18:39:30 -0700 Subject: [PATCH 0415/1121] sh: fix multiple function definition build errors [ Upstream commit acaf892ecbf5be7710ae05a61fd43c668f68ad95 ] Many of the sh CPU-types have their own plat_irq_setup() and arch_init_clk_ops() functions, so these same (empty) functions in arch/sh/boards/of-generic.c are not needed and cause build errors. If there is some case where these empty functions are needed, they can be retained by marking them as "__weak" while at the same time making builds that do not need them succeed. Fixes these build errors: arch/sh/boards/of-generic.o: In function `plat_irq_setup': (.init.text+0x134): multiple definition of `plat_irq_setup' arch/sh/kernel/cpu/sh2/setup-sh7619.o:(.init.text+0x30): first defined here arch/sh/boards/of-generic.o: In function `arch_init_clk_ops': (.init.text+0x118): multiple definition of `arch_init_clk_ops' arch/sh/kernel/cpu/sh2/clock-sh7619.o:(.init.text+0x0): first defined here Link: http://lkml.kernel.org/r/9ee4e0c5-f100-86a2-bd4d-1d3287ceab31@infradead.org Signed-off-by: Randy Dunlap Reported-by: kbuild test robot Cc: Takashi Iwai Cc: Yoshinori Sato Cc: Rich Felker Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Sasha Levin --- arch/sh/boards/of-generic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/sh/boards/of-generic.c b/arch/sh/boards/of-generic.c index 4feb7c86f4ac..5e83ea12303b 100644 --- a/arch/sh/boards/of-generic.c +++ b/arch/sh/boards/of-generic.c @@ -180,10 +180,10 @@ static struct sh_machine_vector __initmv sh_of_generic_mv = { struct sh_clk_ops; -void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx) +void __init __weak arch_init_clk_ops(struct sh_clk_ops **ops, int idx) { } -void __init plat_irq_setup(void) +void __init __weak plat_irq_setup(void) { } -- GitLab From a02e20ef7b0d89d1b38796ee6da129c62cc83363 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Tue, 19 Feb 2019 08:49:56 -0800 Subject: [PATCH 0416/1121] xsysace: Fix error handling in ace_setup [ Upstream commit 47b16820c490149c2923e8474048f2c6e7557cab ] If xace hardware reports a bad version number, the error handling code in ace_setup() calls put_disk(), followed by queue cleanup. However, since the disk data structure has the queue pointer set, put_disk() also cleans and releases the queue. This results in blk_cleanup_queue() accessing an already released data structure, which in turn may result in a crash such as the following. [ 10.681671] BUG: Kernel NULL pointer dereference at 0x00000040 [ 10.681826] Faulting instruction address: 0xc0431480 [ 10.682072] Oops: Kernel access of bad area, sig: 11 [#1] [ 10.682251] BE PAGE_SIZE=4K PREEMPT Xilinx Virtex440 [ 10.682387] Modules linked in: [ 10.682528] CPU: 0 PID: 1 Comm: swapper Tainted: G W 5.0.0-rc6-next-20190218+ #2 [ 10.682733] NIP: c0431480 LR: c043147c CTR: c0422ad8 [ 10.682863] REGS: cf82fbe0 TRAP: 0300 Tainted: G W (5.0.0-rc6-next-20190218+) [ 10.683065] MSR: 00029000 CR: 22000222 XER: 00000000 [ 10.683236] DEAR: 00000040 ESR: 00000000 [ 10.683236] GPR00: c043147c cf82fc90 cf82ccc0 00000000 00000000 00000000 00000002 00000000 [ 10.683236] GPR08: 00000000 00000000 c04310bc 00000000 22000222 00000000 c0002c54 00000000 [ 10.683236] GPR16: 00000000 00000001 c09aa39c c09021b0 c09021dc 00000007 c0a68c08 00000000 [ 10.683236] GPR24: 00000001 ced6d400 ced6dcf0 c0815d9c 00000000 00000000 00000000 cedf0800 [ 10.684331] NIP [c0431480] blk_mq_run_hw_queue+0x28/0x114 [ 10.684473] LR [c043147c] blk_mq_run_hw_queue+0x24/0x114 [ 10.684602] Call Trace: [ 10.684671] [cf82fc90] [c043147c] blk_mq_run_hw_queue+0x24/0x114 (unreliable) [ 10.684854] [cf82fcc0] [c04315bc] blk_mq_run_hw_queues+0x50/0x7c [ 10.685002] [cf82fce0] [c0422b24] blk_set_queue_dying+0x30/0x68 [ 10.685154] [cf82fcf0] [c0423ec0] blk_cleanup_queue+0x34/0x14c [ 10.685306] [cf82fd10] [c054d73c] ace_probe+0x3dc/0x508 [ 10.685445] [cf82fd50] [c052d740] platform_drv_probe+0x4c/0xb8 [ 10.685592] [cf82fd70] [c052abb0] really_probe+0x20c/0x32c [ 10.685728] [cf82fda0] [c052ae58] driver_probe_device+0x68/0x464 [ 10.685877] [cf82fdc0] [c052b500] device_driver_attach+0xb4/0xe4 [ 10.686024] [cf82fde0] [c052b5dc] __driver_attach+0xac/0xfc [ 10.686161] [cf82fe00] [c0528428] bus_for_each_dev+0x80/0xc0 [ 10.686314] [cf82fe30] [c0529b3c] bus_add_driver+0x144/0x234 [ 10.686457] [cf82fe50] [c052c46c] driver_register+0x88/0x15c [ 10.686610] [cf82fe60] [c09de288] ace_init+0x4c/0xac [ 10.686742] [cf82fe80] [c0002730] do_one_initcall+0xac/0x330 [ 10.686888] [cf82fee0] [c09aafd0] kernel_init_freeable+0x34c/0x478 [ 10.687043] [cf82ff30] [c0002c6c] kernel_init+0x18/0x114 [ 10.687188] [cf82ff40] [c000f2f0] ret_from_kernel_thread+0x14/0x1c [ 10.687349] Instruction dump: [ 10.687435] 3863ffd4 4bfffd70 9421ffd0 7c0802a6 93c10028 7c9e2378 93e1002c 38810008 [ 10.687637] 7c7f1b78 90010034 4bfffc25 813f008c <81290040> 75290100 4182002c 80810008 [ 10.688056] ---[ end trace 13c9ff51d41b9d40 ]--- Fix the problem by setting the disk queue pointer to NULL before calling put_disk(). A more comprehensive fix might be to rearrange the code to check the hardware version before initializing data structures, but I don't know if this would have undesirable side effects, and it would increase the complexity of backporting the fix to older kernels. Fixes: 74489a91dd43a ("Add support for Xilinx SystemACE CompactFlash interface") Acked-by: Michal Simek Signed-off-by: Guenter Roeck Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin --- drivers/block/xsysace.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index 14459d66ef0c..51ff7ee1b2b1 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c @@ -1063,6 +1063,8 @@ static int ace_setup(struct ace_device *ace) return 0; err_read: + /* prevent double queue cleanup */ + ace->gd->queue = NULL; put_disk(ace->gd); err_alloc_disk: blk_cleanup_queue(ace->queue); -- GitLab From 4d5252412a5270e84e90f5654d076e98a05ac602 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 25 Mar 2019 16:50:42 +0100 Subject: [PATCH 0417/1121] ARM: orion: don't use using 64-bit DMA masks [ Upstream commit cd92d74d67c811dc22544430b9ac3029f5bd64c5 ] clang warns about statically defined DMA masks from the DMA_BIT_MASK macro with length 64: arch/arm/plat-orion/common.c:625:29: error: shift count >= width of type [-Werror,-Wshift-count-overflow] .coherent_dma_mask = DMA_BIT_MASK(64), ^~~~~~~~~~~~~~~~ include/linux/dma-mapping.h:141:54: note: expanded from macro 'DMA_BIT_MASK' #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1)) The ones in orion shouldn't really be 64 bit masks, so changing them to what the driver can support avoids the warning. Signed-off-by: Arnd Bergmann Signed-off-by: Olof Johansson Signed-off-by: Sasha Levin --- arch/arm/plat-orion/common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c index a2399fd66e97..1e970873439c 100644 --- a/arch/arm/plat-orion/common.c +++ b/arch/arm/plat-orion/common.c @@ -622,7 +622,7 @@ static struct platform_device orion_xor0_shared = { .resource = orion_xor0_shared_resources, .dev = { .dma_mask = &orion_xor_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(64), + .coherent_dma_mask = DMA_BIT_MASK(32), .platform_data = &orion_xor0_pdata, }, }; @@ -683,7 +683,7 @@ static struct platform_device orion_xor1_shared = { .resource = orion_xor1_shared_resources, .dev = { .dma_mask = &orion_xor_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(64), + .coherent_dma_mask = DMA_BIT_MASK(32), .platform_data = &orion_xor1_pdata, }, }; -- GitLab From 46ac9ab8458da81f093a655b4c0827715a0797bf Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 25 Mar 2019 16:50:43 +0100 Subject: [PATCH 0418/1121] ARM: iop: don't use using 64-bit DMA masks [ Upstream commit 2125801ccce19249708ca3245d48998e70569ab8 ] clang warns about statically defined DMA masks from the DMA_BIT_MASK macro with length 64: arch/arm/mach-iop13xx/setup.c:303:35: error: shift count >= width of type [-Werror,-Wshift-count-overflow] static u64 iop13xx_adma_dmamask = DMA_BIT_MASK(64); ^~~~~~~~~~~~~~~~ include/linux/dma-mapping.h:141:54: note: expanded from macro 'DMA_BIT_MASK' #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1)) ^ ~~~ The ones in iop shouldn't really be 64 bit masks, so changing them to what the driver can support avoids the warning. Signed-off-by: Arnd Bergmann Signed-off-by: Olof Johansson Signed-off-by: Sasha Levin --- arch/arm/mach-iop13xx/setup.c | 8 ++++---- arch/arm/mach-iop13xx/tpmi.c | 10 +++++----- arch/arm/plat-iop/adma.c | 6 +++--- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/arch/arm/mach-iop13xx/setup.c b/arch/arm/mach-iop13xx/setup.c index 53c316f7301e..fe4932fda01d 100644 --- a/arch/arm/mach-iop13xx/setup.c +++ b/arch/arm/mach-iop13xx/setup.c @@ -300,7 +300,7 @@ static struct resource iop13xx_adma_2_resources[] = { } }; -static u64 iop13xx_adma_dmamask = DMA_BIT_MASK(64); +static u64 iop13xx_adma_dmamask = DMA_BIT_MASK(32); static struct iop_adma_platform_data iop13xx_adma_0_data = { .hw_id = 0, .pool_size = PAGE_SIZE, @@ -324,7 +324,7 @@ static struct platform_device iop13xx_adma_0_channel = { .resource = iop13xx_adma_0_resources, .dev = { .dma_mask = &iop13xx_adma_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(64), + .coherent_dma_mask = DMA_BIT_MASK(32), .platform_data = (void *) &iop13xx_adma_0_data, }, }; @@ -336,7 +336,7 @@ static struct platform_device iop13xx_adma_1_channel = { .resource = iop13xx_adma_1_resources, .dev = { .dma_mask = &iop13xx_adma_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(64), + .coherent_dma_mask = DMA_BIT_MASK(32), .platform_data = (void *) &iop13xx_adma_1_data, }, }; @@ -348,7 +348,7 @@ static struct platform_device iop13xx_adma_2_channel = { .resource = iop13xx_adma_2_resources, .dev = { .dma_mask = &iop13xx_adma_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(64), + .coherent_dma_mask = DMA_BIT_MASK(32), .platform_data = (void *) &iop13xx_adma_2_data, }, }; diff --git a/arch/arm/mach-iop13xx/tpmi.c b/arch/arm/mach-iop13xx/tpmi.c index db511ec2b1df..116feb6b261e 100644 --- a/arch/arm/mach-iop13xx/tpmi.c +++ b/arch/arm/mach-iop13xx/tpmi.c @@ -152,7 +152,7 @@ static struct resource iop13xx_tpmi_3_resources[] = { } }; -u64 iop13xx_tpmi_mask = DMA_BIT_MASK(64); +u64 iop13xx_tpmi_mask = DMA_BIT_MASK(32); static struct platform_device iop13xx_tpmi_0_device = { .name = "iop-tpmi", .id = 0, @@ -160,7 +160,7 @@ static struct platform_device iop13xx_tpmi_0_device = { .resource = iop13xx_tpmi_0_resources, .dev = { .dma_mask = &iop13xx_tpmi_mask, - .coherent_dma_mask = DMA_BIT_MASK(64), + .coherent_dma_mask = DMA_BIT_MASK(32), }, }; @@ -171,7 +171,7 @@ static struct platform_device iop13xx_tpmi_1_device = { .resource = iop13xx_tpmi_1_resources, .dev = { .dma_mask = &iop13xx_tpmi_mask, - .coherent_dma_mask = DMA_BIT_MASK(64), + .coherent_dma_mask = DMA_BIT_MASK(32), }, }; @@ -182,7 +182,7 @@ static struct platform_device iop13xx_tpmi_2_device = { .resource = iop13xx_tpmi_2_resources, .dev = { .dma_mask = &iop13xx_tpmi_mask, - .coherent_dma_mask = DMA_BIT_MASK(64), + .coherent_dma_mask = DMA_BIT_MASK(32), }, }; @@ -193,7 +193,7 @@ static struct platform_device iop13xx_tpmi_3_device = { .resource = iop13xx_tpmi_3_resources, .dev = { .dma_mask = &iop13xx_tpmi_mask, - .coherent_dma_mask = DMA_BIT_MASK(64), + .coherent_dma_mask = DMA_BIT_MASK(32), }, }; diff --git a/arch/arm/plat-iop/adma.c b/arch/arm/plat-iop/adma.c index a4d1f8de3b5b..d9612221e484 100644 --- a/arch/arm/plat-iop/adma.c +++ b/arch/arm/plat-iop/adma.c @@ -143,7 +143,7 @@ struct platform_device iop3xx_dma_0_channel = { .resource = iop3xx_dma_0_resources, .dev = { .dma_mask = &iop3xx_adma_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(64), + .coherent_dma_mask = DMA_BIT_MASK(32), .platform_data = (void *) &iop3xx_dma_0_data, }, }; @@ -155,7 +155,7 @@ struct platform_device iop3xx_dma_1_channel = { .resource = iop3xx_dma_1_resources, .dev = { .dma_mask = &iop3xx_adma_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(64), + .coherent_dma_mask = DMA_BIT_MASK(32), .platform_data = (void *) &iop3xx_dma_1_data, }, }; @@ -167,7 +167,7 @@ struct platform_device iop3xx_aau_channel = { .resource = iop3xx_aau_resources, .dev = { .dma_mask = &iop3xx_adma_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(64), + .coherent_dma_mask = DMA_BIT_MASK(32), .platform_data = (void *) &iop3xx_aau_data, }, }; -- GitLab From e1c70389a518337bd7e6965269b2ce8a501e019e Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Thu, 2 May 2019 15:29:47 +0000 Subject: [PATCH 0419/1121] perf/x86/amd: Update generic hardware cache events for Family 17h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 0e3b74e26280f2cf8753717a950b97d424da6046 upstream. Add a new amd_hw_cache_event_ids_f17h assignment structure set for AMD families 17h and above, since a lot has changed. Specifically: L1 Data Cache The data cache access counter remains the same on Family 17h. For DC misses, PMCx041's definition changes with Family 17h, so instead we use the L2 cache accesses from L1 data cache misses counter (PMCx060,umask=0xc8). For DC hardware prefetch events, Family 17h breaks compatibility for PMCx067 "Data Prefetcher", so instead, we use PMCx05a "Hardware Prefetch DC Fills." L1 Instruction Cache PMCs 0x80 and 0x81 (32-byte IC fetches and misses) are backward compatible on Family 17h. For prefetches, we remove the erroneous PMCx04B assignment which counts how many software data cache prefetch load instructions were dispatched. LL - Last Level Cache Removing PMCs 7D, 7E, and 7F assignments, as they do not exist on Family 17h, where the last level cache is L3. L3 counters can be accessed using the existing AMD Uncore driver. Data TLB On Intel machines, data TLB accesses ("dTLB-loads") are assigned to counters that count load/store instructions retired. This is inconsistent with instruction TLB accesses, where Intel implementations report iTLB misses that hit in the STLB. Ideally, dTLB-loads would count higher level dTLB misses that hit in lower level TLBs, and dTLB-load-misses would report those that also missed in those lower-level TLBs, therefore causing a page table walk. That would be consistent with instruction TLB operation, remove the redundancy between dTLB-loads and L1-dcache-loads, and prevent perf from producing artificially low percentage ratios, i.e. the "0.01%" below: 42,550,869 L1-dcache-loads 41,591,860 dTLB-loads 4,802 dTLB-load-misses # 0.01% of all dTLB cache hits 7,283,682 L1-dcache-stores 7,912,392 dTLB-stores 310 dTLB-store-misses On AMD Families prior to 17h, the "Data Cache Accesses" counter is used, which is slightly better than load/store instructions retired, but still counts in terms of individual load/store operations instead of TLB operations. So, for AMD Families 17h and higher, this patch assigns "dTLB-loads" to a counter for L1 dTLB misses that hit in the L2 dTLB, and "dTLB-load-misses" to a counter for L1 DTLB misses that caused L2 DTLB misses and therefore also caused page table walks. This results in a much more accurate view of data TLB performance: 60,961,781 L1-dcache-loads 4,601 dTLB-loads 963 dTLB-load-misses # 20.93% of all dTLB cache hits Note that for all AMD families, data loads and stores are combined in a single accesses counter, so no 'L1-dcache-stores' are reported separately, and stores are counted with loads in 'L1-dcache-loads'. Also note that the "% of all dTLB cache hits" string is misleading because (a) "dTLB cache": although TLBs can be considered caches for page tables, in this context, it can be misinterpreted as data cache hits because the figures are similar (at least on Intel), and (b) not all those loads (technically accesses) technically "hit" at that hardware level. "% of all dTLB accesses" would be more clear/accurate. Instruction TLB On Intel machines, 'iTLB-loads' measure iTLB misses that hit in the STLB, and 'iTLB-load-misses' measure iTLB misses that also missed in the STLB and completed a page table walk. For AMD Family 17h and above, for 'iTLB-loads' we replace the erroneous instruction cache fetches counter with PMCx084 "L1 ITLB Miss, L2 ITLB Hit". For 'iTLB-load-misses' we still use PMCx085 "L1 ITLB Miss, L2 ITLB Miss", but set a 0xff umask because without it the event does not get counted. Branch Predictor (BPU) PMCs 0xc2 and 0xc3 continue to be valid across all AMD Families. Node Level Events Family 17h does not have a PMCx0e9 counter, and corresponding counters have not been made available publicly, so for now, we mark them as unsupported for Families 17h and above. Reference: "Open-Source Register Reference For AMD Family 17h Processors Models 00h-2Fh" Released 7/17/2018, Publication #56255, Revision 3.03: https://www.amd.com/system/files/TechDocs/56255_OSRR.pdf [ mingo: tidied up the line breaks. ] Signed-off-by: Kim Phillips Cc: # v4.9+ Cc: Alexander Shishkin Cc: Arnaldo Carvalho de Melo Cc: Borislav Petkov Cc: H. Peter Anvin Cc: Janakarajan Natarajan Cc: Jiri Olsa Cc: Linus Torvalds Cc: Martin LiĆĄka Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Pu Wen Cc: Stephane Eranian Cc: Suravee Suthikulpanit Cc: Thomas Gleixner Cc: Thomas Lendacky Cc: Vince Weaver Cc: linux-kernel@vger.kernel.org Cc: linux-perf-users@vger.kernel.org Fixes: e40ed1542dd7 ("perf/x86: Add perf support for AMD family-17h processors") Signed-off-by: Ingo Molnar Signed-off-by: Greg Kroah-Hartman --- arch/x86/events/amd/core.c | 111 ++++++++++++++++++++++++++++++++++++- 1 file changed, 108 insertions(+), 3 deletions(-) diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c index 263af6312329..27ade3cb6482 100644 --- a/arch/x86/events/amd/core.c +++ b/arch/x86/events/amd/core.c @@ -116,6 +116,110 @@ static __initconst const u64 amd_hw_cache_event_ids }, }; +static __initconst const u64 amd_hw_cache_event_ids_f17h + [PERF_COUNT_HW_CACHE_MAX] + [PERF_COUNT_HW_CACHE_OP_MAX] + [PERF_COUNT_HW_CACHE_RESULT_MAX] = { +[C(L1D)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = 0x0040, /* Data Cache Accesses */ + [C(RESULT_MISS)] = 0xc860, /* L2$ access from DC Miss */ + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = 0, + [C(RESULT_MISS)] = 0, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = 0xff5a, /* h/w prefetch DC Fills */ + [C(RESULT_MISS)] = 0, + }, +}, +[C(L1I)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = 0x0080, /* Instruction cache fetches */ + [C(RESULT_MISS)] = 0x0081, /* Instruction cache misses */ + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = -1, + [C(RESULT_MISS)] = -1, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = 0, + [C(RESULT_MISS)] = 0, + }, +}, +[C(LL)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = 0, + [C(RESULT_MISS)] = 0, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = 0, + [C(RESULT_MISS)] = 0, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = 0, + [C(RESULT_MISS)] = 0, + }, +}, +[C(DTLB)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = 0xff45, /* All L2 DTLB accesses */ + [C(RESULT_MISS)] = 0xf045, /* L2 DTLB misses (PT walks) */ + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = 0, + [C(RESULT_MISS)] = 0, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = 0, + [C(RESULT_MISS)] = 0, + }, +}, +[C(ITLB)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = 0x0084, /* L1 ITLB misses, L2 ITLB hits */ + [C(RESULT_MISS)] = 0xff85, /* L1 ITLB misses, L2 misses */ + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = -1, + [C(RESULT_MISS)] = -1, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = -1, + [C(RESULT_MISS)] = -1, + }, +}, +[C(BPU)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = 0x00c2, /* Retired Branch Instr. */ + [C(RESULT_MISS)] = 0x00c3, /* Retired Mispredicted BI */ + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = -1, + [C(RESULT_MISS)] = -1, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = -1, + [C(RESULT_MISS)] = -1, + }, +}, +[C(NODE)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = 0, + [C(RESULT_MISS)] = 0, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = -1, + [C(RESULT_MISS)] = -1, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = -1, + [C(RESULT_MISS)] = -1, + }, +}, +}; + /* * AMD Performance Monitor K7 and later, up to and including Family 16h: */ @@ -861,9 +965,10 @@ __init int amd_pmu_init(void) x86_pmu.amd_nb_constraints = 0; } - /* Events are common for all AMDs */ - memcpy(hw_cache_event_ids, amd_hw_cache_event_ids, - sizeof(hw_cache_event_ids)); + if (boot_cpu_data.x86 >= 0x17) + memcpy(hw_cache_event_ids, amd_hw_cache_event_ids_f17h, sizeof(hw_cache_event_ids)); + else + memcpy(hw_cache_event_ids, amd_hw_cache_event_ids, sizeof(hw_cache_event_ids)); return 0; } -- GitLab From 9e63b08bd50ab241e9f36a9c6a74ebb1e9f730b7 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 9 Apr 2019 11:49:17 -0700 Subject: [PATCH 0420/1121] Bluetooth: btusb: request wake pin with NOAUTOEN commit 771acc7e4a6e5dba779cb1a7fd851a164bc81033 upstream. Badly-designed systems might have (for example) active-high wake pins that default to high (e.g., because of external pull ups) until they have an active firmware which starts driving it low. This can cause an interrupt storm in the time between request_irq() and disable_irq(). We don't support shared interrupts here, so let's just pre-configure the interrupt to avoid auto-enabling it. Fixes: fd913ef7ce61 ("Bluetooth: btusb: Add out-of-band wakeup support") Fixes: 5364a0b4f4be ("arm64: dts: rockchip: move QCA6174A wakeup pin into its USB node") Signed-off-by: Brian Norris Reviewed-by: Matthias Kaehlcke Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/bluetooth/btusb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index b8dffe937f4f..dae8723dde8c 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -2893,6 +2893,7 @@ static int btusb_config_oob_wake(struct hci_dev *hdev) return 0; } + irq_set_status_flags(irq, IRQ_NOAUTOEN); ret = devm_request_irq(&hdev->dev, irq, btusb_oob_wake_handler, 0, "OOB Wake-on-BT", data); if (ret) { @@ -2907,7 +2908,6 @@ static int btusb_config_oob_wake(struct hci_dev *hdev) } data->oob_wake_irq = irq; - disable_irq(irq); bt_dev_info(hdev, "OOB Wake-on-BT configured at IRQ %u", irq); return 0; } -- GitLab From 799d952f7932d3b5878c7209058b7850f1d1a64d Mon Sep 17 00:00:00 2001 From: Jeremy Fertic Date: Tue, 11 Dec 2018 17:55:00 -0700 Subject: [PATCH 0421/1121] staging: iio: adt7316: allow adt751x to use internal vref for all dacs commit 10bfe7cc1739c22f0aa296b39e53f61e9e3f4d99 upstream. With adt7516/7/9, internal vref is available for dacs a and b, dacs c and d, or all dacs. The driver doesn't currently support internal vref for all dacs. Change the else if to an if so both bits are checked rather than just one or the other. Signed-off-by: Jeremy Fertic Fixes: 35f6b6b86ede ("staging: iio: new ADT7316/7/8 and ADT7516/7/9 driver") Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/addac/adt7316.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/iio/addac/adt7316.c b/drivers/staging/iio/addac/adt7316.c index b2bce26499f5..68ed94e28e86 100644 --- a/drivers/staging/iio/addac/adt7316.c +++ b/drivers/staging/iio/addac/adt7316.c @@ -1086,7 +1086,7 @@ static ssize_t adt7316_store_DAC_internal_Vref(struct device *dev, ldac_config = chip->ldac_config & (~ADT7516_DAC_IN_VREF_MASK); if (data & 0x1) ldac_config |= ADT7516_DAC_AB_IN_VREF; - else if (data & 0x2) + if (data & 0x2) ldac_config |= ADT7516_DAC_CD_IN_VREF; } else { ret = kstrtou8(buf, 16, &data); -- GitLab From 8b6eca90e5d1c2ba672c082f100088c85110cdfb Mon Sep 17 00:00:00 2001 From: Jeremy Fertic Date: Sat, 22 Dec 2018 21:57:42 -0700 Subject: [PATCH 0422/1121] staging: iio: adt7316: fix the dac read calculation commit 45130fb030aec26ac28b4bb23344901df3ec3b7f upstream. The calculation of the current dac value is using the wrong bits of the dac lsb register. Create two macros to shift the lsb register value into lsb position, depending on whether the dac is 10 or 12 bit. Initialize data to 0 so, with an 8 bit dac, the msb register value can be bitwise ORed with data. Fixes: 35f6b6b86ede ("staging: iio: new ADT7316/7/8 and ADT7516/7/9 driver") Signed-off-by: Jeremy Fertic Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/addac/adt7316.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/staging/iio/addac/adt7316.c b/drivers/staging/iio/addac/adt7316.c index 68ed94e28e86..e4e70f7f96e6 100644 --- a/drivers/staging/iio/addac/adt7316.c +++ b/drivers/staging/iio/addac/adt7316.c @@ -47,6 +47,8 @@ #define ADT7516_MSB_AIN3 0xA #define ADT7516_MSB_AIN4 0xB #define ADT7316_DA_DATA_BASE 0x10 +#define ADT7316_DA_10_BIT_LSB_SHIFT 6 +#define ADT7316_DA_12_BIT_LSB_SHIFT 4 #define ADT7316_DA_MSB_DATA_REGS 4 #define ADT7316_LSB_DAC_A 0x10 #define ADT7316_MSB_DAC_A 0x11 @@ -1408,7 +1410,7 @@ static IIO_DEVICE_ATTR(ex_analog_temp_offset, 0644, static ssize_t adt7316_show_DAC(struct adt7316_chip_info *chip, int channel, char *buf) { - u16 data; + u16 data = 0; u8 msb, lsb, offset; int ret; @@ -1433,7 +1435,11 @@ static ssize_t adt7316_show_DAC(struct adt7316_chip_info *chip, if (ret) return -EIO; - data = (msb << offset) + (lsb & ((1 << offset) - 1)); + if (chip->dac_bits == 12) + data = lsb >> ADT7316_DA_12_BIT_LSB_SHIFT; + else if (chip->dac_bits == 10) + data = lsb >> ADT7316_DA_10_BIT_LSB_SHIFT; + data |= msb << offset; return sprintf(buf, "%d\n", data); } -- GitLab From d253ff1a595fae749b479cb3bd3fd1b53478a65c Mon Sep 17 00:00:00 2001 From: Jeremy Fertic Date: Sat, 22 Dec 2018 21:57:43 -0700 Subject: [PATCH 0423/1121] staging: iio: adt7316: fix the dac write calculation commit 78accaea117c1ae878774974fab91ac4a0b0e2b0 upstream. The lsb calculation is not masking the correct bits from the user input. Subtract 1 from (1 << offset) to correctly set up the mask to be applied to user input. The lsb register stores its value starting at the bit 7 position. adt7316_store_DAC() currently assumes the value is at the other end of the register. Shift the lsb value before storing it in a new variable lsb_reg, and write this variable to the lsb register. Fixes: 35f6b6b86ede ("staging: iio: new ADT7316/7/8 and ADT7516/7/9 driver") Signed-off-by: Jeremy Fertic Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/addac/adt7316.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/staging/iio/addac/adt7316.c b/drivers/staging/iio/addac/adt7316.c index e4e70f7f96e6..7378aa7730ef 100644 --- a/drivers/staging/iio/addac/adt7316.c +++ b/drivers/staging/iio/addac/adt7316.c @@ -1447,7 +1447,7 @@ static ssize_t adt7316_show_DAC(struct adt7316_chip_info *chip, static ssize_t adt7316_store_DAC(struct adt7316_chip_info *chip, int channel, const char *buf, size_t len) { - u8 msb, lsb, offset; + u8 msb, lsb, lsb_reg, offset; u16 data; int ret; @@ -1465,9 +1465,13 @@ static ssize_t adt7316_store_DAC(struct adt7316_chip_info *chip, return -EINVAL; if (chip->dac_bits > 8) { - lsb = data & (1 << offset); + lsb = data & ((1 << offset) - 1); + if (chip->dac_bits == 12) + lsb_reg = lsb << ADT7316_DA_12_BIT_LSB_SHIFT; + else + lsb_reg = lsb << ADT7316_DA_10_BIT_LSB_SHIFT; ret = chip->bus.write(chip->bus.client, - ADT7316_DA_DATA_BASE + channel * 2, lsb); + ADT7316_DA_DATA_BASE + channel * 2, lsb_reg); if (ret) return -EIO; } -- GitLab From ff7ec1b8e6f74d3b2d1de18983f2358de33a5f26 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Fri, 25 Jan 2019 10:34:51 -0800 Subject: [PATCH 0424/1121] scsi: RDMA/srpt: Fix a credit leak for aborted commands commit 40ca8757291ca7a8775498112d320205b2a2e571 upstream. Make sure that the next time a response is sent to the initiator that the credit it had allocated for the aborted request gets freed. Cc: Doug Ledford Cc: Jason Gunthorpe Cc: Nicholas Bellinger Cc: Mike Christie Cc: Hannes Reinecke Cc: Christoph Hellwig Fixes: 131e6abc674e ("target: Add TFO->abort_task for aborted task resources release") # v3.15 Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/ulp/srpt/ib_srpt.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 47f3f562d86f..94161ca526fc 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -2381,8 +2381,19 @@ static void srpt_queue_tm_rsp(struct se_cmd *cmd) srpt_queue_response(cmd); } +/* + * This function is called for aborted commands if no response is sent to the + * initiator. Make sure that the credits freed by aborting a command are + * returned to the initiator the next time a response is sent by incrementing + * ch->req_lim_delta. + */ static void srpt_aborted_task(struct se_cmd *cmd) { + struct srpt_send_ioctx *ioctx = container_of(cmd, + struct srpt_send_ioctx, cmd); + struct srpt_rdma_ch *ch = ioctx->ch; + + atomic_inc(&ch->req_lim_delta); } static int srpt_queue_status(struct se_cmd *cmd) -- GitLab From 0d7ae54867f917d4f3b50508e036002051410b6b Mon Sep 17 00:00:00 2001 From: Arnaud Pouliquen Date: Fri, 5 Apr 2019 11:19:11 +0200 Subject: [PATCH 0425/1121] ASoC: stm32: fix sai driver name initialisation commit 17d3069ccf06970e2db3f7cbf4335f207524279e upstream. This patch fixes the sai driver structure overwriting which results in a cpu dai name equal NULL. Fixes: 3e086ed ("ASoC: stm32: add SAI driver") Signed-off-by: Arnaud Pouliquen Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- sound/soc/stm/stm32_sai_sub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c index 90d439613899..48b4286100d4 100644 --- a/sound/soc/stm/stm32_sai_sub.c +++ b/sound/soc/stm/stm32_sai_sub.c @@ -873,7 +873,6 @@ static int stm32_sai_sub_dais_init(struct platform_device *pdev, if (!sai->cpu_dai_drv) return -ENOMEM; - sai->cpu_dai_drv->name = dev_name(&pdev->dev); if (STM_SAI_IS_PLAYBACK(sai)) { memcpy(sai->cpu_dai_drv, &stm32_sai_playback_dai, sizeof(stm32_sai_playback_dai)); @@ -883,6 +882,7 @@ static int stm32_sai_sub_dais_init(struct platform_device *pdev, sizeof(stm32_sai_capture_dai)); sai->cpu_dai_drv->capture.stream_name = sai->cpu_dai_drv->name; } + sai->cpu_dai_drv->name = dev_name(&pdev->dev); return 0; } -- GitLab From 2fecdc27f5cdbf97c6f7a10bfc45e620182fc10c Mon Sep 17 00:00:00 2001 From: Daniel Jurgens Date: Sat, 2 Feb 2019 11:09:42 +0200 Subject: [PATCH 0426/1121] IB/core: Unregister notifier before freeing MAD security commit d60667fc398ed34b3c7456b020481c55c760e503 upstream. If the notifier runs after the security context is freed an access of freed memory can occur. Fixes: 47a2b338fe63 ("IB/core: Enforce security on management datagrams") Signed-off-by: Daniel Jurgens Reviewed-by: Parav Pandit Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/core/security.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/core/security.c b/drivers/infiniband/core/security.c index 59b2f96d986a..ca16a53b9389 100644 --- a/drivers/infiniband/core/security.c +++ b/drivers/infiniband/core/security.c @@ -732,9 +732,10 @@ void ib_mad_agent_security_cleanup(struct ib_mad_agent *agent) if (!rdma_protocol_ib(agent->device, agent->port_num)) return; - security_ib_free_security(agent->security); if (agent->lsm_nb_reg) unregister_lsm_notifier(&agent->lsm_nb); + + security_ib_free_security(agent->security); } int ib_mad_enforce_security(struct ib_mad_agent_private *map, u16 pkey_index) -- GitLab From e800edf7c578de03b3111c479dc256d2cde807ce Mon Sep 17 00:00:00 2001 From: Daniel Jurgens Date: Sat, 2 Feb 2019 11:09:43 +0200 Subject: [PATCH 0427/1121] IB/core: Fix potential memory leak while creating MAD agents commit 6e88e672b69f0e627acdae74a527b730ea224b6b upstream. If the MAD agents isn't allowed to manage the subnet, or fails to register for the LSM notifier, the security context is leaked. Free the context in these cases. Fixes: 47a2b338fe63 ("IB/core: Enforce security on management datagrams") Signed-off-by: Daniel Jurgens Reviewed-by: Parav Pandit Reported-by: Parav Pandit Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/core/security.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/core/security.c b/drivers/infiniband/core/security.c index ca16a53b9389..a3dd88c57be7 100644 --- a/drivers/infiniband/core/security.c +++ b/drivers/infiniband/core/security.c @@ -715,16 +715,20 @@ int ib_mad_agent_security_setup(struct ib_mad_agent *agent, agent->device->name, agent->port_num); if (ret) - return ret; + goto free_security; agent->lsm_nb.notifier_call = ib_mad_agent_security_change; ret = register_lsm_notifier(&agent->lsm_nb); if (ret) - return ret; + goto free_security; agent->smp_allowed = true; agent->lsm_nb_reg = true; return 0; + +free_security: + security_ib_free_security(agent->security); + return ret; } void ib_mad_agent_security_cleanup(struct ib_mad_agent *agent) -- GitLab From e29f63815be8b097c5f2c4156aef1a9849fa4060 Mon Sep 17 00:00:00 2001 From: Yuval Avnery Date: Tue, 22 Jan 2019 09:02:05 +0200 Subject: [PATCH 0428/1121] IB/core: Destroy QP if XRC QP fails commit 535005ca8e5e71918d64074032f4b9d4fef8981e upstream. The open-coded variant missed destroy of SELinux created QP, reuse already existing ib_detroy_qp() call and use this opportunity to clean ib_create_qp() from double prints and unclear exit paths. Reported-by: Parav Pandit Fixes: d291f1a65232 ("IB/core: Enforce PKey security on QPs") Signed-off-by: Yuval Avnery Reviewed-by: Parav Pandit Reviewed-by: Daniel Jurgens Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/core/verbs.c | 41 +++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index 6d59af07d338..d21c86dd27d8 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c @@ -766,8 +766,8 @@ struct ib_qp *ib_open_qp(struct ib_xrcd *xrcd, } EXPORT_SYMBOL(ib_open_qp); -static struct ib_qp *ib_create_xrc_qp(struct ib_qp *qp, - struct ib_qp_init_attr *qp_init_attr) +static struct ib_qp *create_xrc_qp(struct ib_qp *qp, + struct ib_qp_init_attr *qp_init_attr) { struct ib_qp *real_qp = qp; @@ -782,10 +782,10 @@ static struct ib_qp *ib_create_xrc_qp(struct ib_qp *qp, qp = __ib_open_qp(real_qp, qp_init_attr->event_handler, qp_init_attr->qp_context); - if (!IS_ERR(qp)) - __ib_insert_xrcd_qp(qp_init_attr->xrcd, real_qp); - else - real_qp->device->destroy_qp(real_qp); + if (IS_ERR(qp)) + return qp; + + __ib_insert_xrcd_qp(qp_init_attr->xrcd, real_qp); return qp; } @@ -816,10 +816,8 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd, return qp; ret = ib_create_qp_security(qp, device); - if (ret) { - ib_destroy_qp(qp); - return ERR_PTR(ret); - } + if (ret) + goto err; qp->device = device; qp->real_qp = qp; @@ -834,8 +832,15 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd, INIT_LIST_HEAD(&qp->sig_mrs); qp->port = 0; - if (qp_init_attr->qp_type == IB_QPT_XRC_TGT) - return ib_create_xrc_qp(qp, qp_init_attr); + if (qp_init_attr->qp_type == IB_QPT_XRC_TGT) { + struct ib_qp *xrc_qp = create_xrc_qp(qp, qp_init_attr); + + if (IS_ERR(xrc_qp)) { + ret = PTR_ERR(xrc_qp); + goto err; + } + return xrc_qp; + } qp->event_handler = qp_init_attr->event_handler; qp->qp_context = qp_init_attr->qp_context; @@ -863,11 +868,8 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd, if (qp_init_attr->cap.max_rdma_ctxs) { ret = rdma_rw_init_mrs(qp, qp_init_attr); - if (ret) { - pr_err("failed to init MR pool ret= %d\n", ret); - ib_destroy_qp(qp); - return ERR_PTR(ret); - } + if (ret) + goto err; } /* @@ -880,6 +882,11 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd, device->attrs.max_sge_rd); return qp; + +err: + ib_destroy_qp(qp); + return ERR_PTR(ret); + } EXPORT_SYMBOL(ib_create_qp); -- GitLab From 22cac0dc8e3cd54438a923b3a60d6c4c89ec0994 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Wed, 3 Apr 2019 15:14:44 -0700 Subject: [PATCH 0429/1121] Input: snvs_pwrkey - initialize necessary driver data before enabling IRQ commit bf2a7ca39fd3ab47ef71c621a7ee69d1813b1f97 upstream. SNVS IRQ is requested before necessary driver data initialized, if there is a pending IRQ during driver probe phase, kernel NULL pointer panic will occur in IRQ handler. To avoid such scenario, just initialize necessary driver data before enabling IRQ. This patch is inspired by NXP's internal kernel tree. Fixes: d3dc6e232215 ("input: keyboard: imx: add snvs power key driver") Signed-off-by: Anson Huang Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/keyboard/snvs_pwrkey.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/input/keyboard/snvs_pwrkey.c b/drivers/input/keyboard/snvs_pwrkey.c index 7544888c4749..b8dbde746b4e 100644 --- a/drivers/input/keyboard/snvs_pwrkey.c +++ b/drivers/input/keyboard/snvs_pwrkey.c @@ -156,6 +156,9 @@ static int imx_snvs_pwrkey_probe(struct platform_device *pdev) return error; } + pdata->input = input; + platform_set_drvdata(pdev, pdata); + error = devm_request_irq(&pdev->dev, pdata->irq, imx_snvs_pwrkey_interrupt, 0, pdev->name, pdev); @@ -171,9 +174,6 @@ static int imx_snvs_pwrkey_probe(struct platform_device *pdev) return error; } - pdata->input = input; - platform_set_drvdata(pdev, pdata); - device_init_wakeup(&pdev->dev, pdata->wakeup); return 0; -- GitLab From ea882befb39c6db2cf8f9a33ff8ceb4e45475d48 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 5 Feb 2019 14:40:40 -0800 Subject: [PATCH 0430/1121] Input: stmfts - acknowledge that setting brightness is a blocking call commit 937c4e552fd1174784045684740edfcea536159d upstream. We need to turn regulators on and off when switching brightness, and that may block, therefore we have to set stmfts_brightness_set() as LED's brightness_set_blocking() method. Fixes: 78bcac7b2ae1 ("Input: add support for the STMicroelectronics FingerTip touchscreen") Acked-by: Andi Shyti Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/touchscreen/stmfts.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c index 025bae3853cc..c72662c979e7 100644 --- a/drivers/input/touchscreen/stmfts.c +++ b/drivers/input/touchscreen/stmfts.c @@ -111,27 +111,29 @@ struct stmfts_data { bool running; }; -static void stmfts_brightness_set(struct led_classdev *led_cdev, +static int stmfts_brightness_set(struct led_classdev *led_cdev, enum led_brightness value) { struct stmfts_data *sdata = container_of(led_cdev, struct stmfts_data, led_cdev); int err; - if (value == sdata->led_status || !sdata->ledvdd) - return; - - if (!value) { - regulator_disable(sdata->ledvdd); - } else { - err = regulator_enable(sdata->ledvdd); - if (err) - dev_warn(&sdata->client->dev, - "failed to disable ledvdd regulator: %d\n", - err); + if (value != sdata->led_status && sdata->ledvdd) { + if (!value) { + regulator_disable(sdata->ledvdd); + } else { + err = regulator_enable(sdata->ledvdd); + if (err) { + dev_warn(&sdata->client->dev, + "failed to disable ledvdd regulator: %d\n", + err); + return err; + } + } + sdata->led_status = value; } - sdata->led_status = value; + return 0; } static enum led_brightness stmfts_brightness_get(struct led_classdev *led_cdev) @@ -613,7 +615,7 @@ static int stmfts_enable_led(struct stmfts_data *sdata) sdata->led_cdev.name = STMFTS_DEV_NAME; sdata->led_cdev.max_brightness = LED_ON; sdata->led_cdev.brightness = LED_OFF; - sdata->led_cdev.brightness_set = stmfts_brightness_set; + sdata->led_cdev.brightness_set_blocking = stmfts_brightness_set; sdata->led_cdev.brightness_get = stmfts_brightness_get; err = devm_led_classdev_register(&sdata->client->dev, &sdata->led_cdev); -- GitLab From fdffa672620989dc4e03bcf4dc644fa8bf5618bb Mon Sep 17 00:00:00 2001 From: Ondrej Mosnacek Date: Fri, 21 Dec 2018 21:18:52 +0100 Subject: [PATCH 0431/1121] selinux: never allow relabeling on context mounts commit a83d6ddaebe541570291205cb538e35ad4ff94f9 upstream. In the SECURITY_FS_USE_MNTPOINT case we never want to allow relabeling files/directories, so we should never set the SBLABEL_MNT flag. The 'special handling' in selinux_is_sblabel_mnt() is only intended for when the behavior is set to SECURITY_FS_USE_GENFS. While there, make the logic in selinux_is_sblabel_mnt() more explicit and add a BUILD_BUG_ON() to make sure that introducing a new SECURITY_FS_USE_* forces a review of the logic. Fixes: d5f3a5f6e7e7 ("selinux: add security in-core xattr support for pstore and debugfs") Signed-off-by: Ondrej Mosnacek Reviewed-by: Stephen Smalley Signed-off-by: Paul Moore Signed-off-by: Greg Kroah-Hartman --- security/selinux/hooks.c | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index b72aa48f6478..5f7bfc65c446 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -471,16 +471,10 @@ static int may_context_mount_inode_relabel(u32 sid, return rc; } -static int selinux_is_sblabel_mnt(struct super_block *sb) +static int selinux_is_genfs_special_handling(struct super_block *sb) { - struct superblock_security_struct *sbsec = sb->s_security; - - return sbsec->behavior == SECURITY_FS_USE_XATTR || - sbsec->behavior == SECURITY_FS_USE_TRANS || - sbsec->behavior == SECURITY_FS_USE_TASK || - sbsec->behavior == SECURITY_FS_USE_NATIVE || - /* Special handling. Genfs but also in-core setxattr handler */ - !strcmp(sb->s_type->name, "sysfs") || + /* Special handling. Genfs but also in-core setxattr handler */ + return !strcmp(sb->s_type->name, "sysfs") || !strcmp(sb->s_type->name, "pstore") || !strcmp(sb->s_type->name, "debugfs") || !strcmp(sb->s_type->name, "tracefs") || @@ -490,6 +484,34 @@ static int selinux_is_sblabel_mnt(struct super_block *sb) !strcmp(sb->s_type->name, "cgroup2"))); } +static int selinux_is_sblabel_mnt(struct super_block *sb) +{ + struct superblock_security_struct *sbsec = sb->s_security; + + /* + * IMPORTANT: Double-check logic in this function when adding a new + * SECURITY_FS_USE_* definition! + */ + BUILD_BUG_ON(SECURITY_FS_USE_MAX != 7); + + switch (sbsec->behavior) { + case SECURITY_FS_USE_XATTR: + case SECURITY_FS_USE_TRANS: + case SECURITY_FS_USE_TASK: + case SECURITY_FS_USE_NATIVE: + return 1; + + case SECURITY_FS_USE_GENFS: + return selinux_is_genfs_special_handling(sb); + + /* Never allow relabeling on context mounts */ + case SECURITY_FS_USE_MNTPOINT: + case SECURITY_FS_USE_NONE: + default: + return 0; + } +} + static int sb_finish_set_opts(struct super_block *sb) { struct superblock_security_struct *sbsec = sb->s_security; -- GitLab From 63b4ace5eb664f366adff9d4375f6f41ab946ada Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 26 Feb 2019 10:09:35 +0530 Subject: [PATCH 0432/1121] powerpc/mm/hash: Handle mmap_min_addr correctly in get_unmapped_area topdown search commit 3b4d07d2674f6b4a9281031f99d1f7efd325b16d upstream. When doing top-down search the low_limit is not PAGE_SIZE but rather max(PAGE_SIZE, mmap_min_addr). This handle cases in which mmap_min_addr > PAGE_SIZE. Fixes: fba2369e6ceb ("mm: use vm_unmapped_area() on powerpc architecture") Reviewed-by: Laurent Dufour Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/mm/slice.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c index 8baaa6c6f21c..e4db715ebe06 100644 --- a/arch/powerpc/mm/slice.c +++ b/arch/powerpc/mm/slice.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -328,6 +329,7 @@ static unsigned long slice_find_area_topdown(struct mm_struct *mm, int pshift = max_t(int, mmu_psize_defs[psize].shift, PAGE_SHIFT); unsigned long addr, found, prev; struct vm_unmapped_area_info info; + unsigned long min_addr = max(PAGE_SIZE, mmap_min_addr); info.flags = VM_UNMAPPED_AREA_TOPDOWN; info.length = len; @@ -344,7 +346,7 @@ static unsigned long slice_find_area_topdown(struct mm_struct *mm, if (high_limit > DEFAULT_MAP_WINDOW) addr += mm->context.addr_limit - DEFAULT_MAP_WINDOW; - while (addr > PAGE_SIZE) { + while (addr > min_addr) { info.high_limit = addr; if (!slice_scan_available(addr - 1, available, 0, &addr)) continue; @@ -356,8 +358,8 @@ static unsigned long slice_find_area_topdown(struct mm_struct *mm, * Check if we need to reduce the range, or if we can * extend it to cover the previous available slice. */ - if (addr < PAGE_SIZE) - addr = PAGE_SIZE; + if (addr < min_addr) + addr = min_addr; else if (slice_scan_available(addr - 1, available, 0, &prev)) { addr = prev; goto prev_slice; @@ -479,7 +481,7 @@ unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len, addr = _ALIGN_UP(addr, page_size); slice_dbg(" aligned addr=%lx\n", addr); /* Ignore hint if it's too large or overlaps a VMA */ - if (addr > high_limit - len || + if (addr > high_limit - len || addr < mmap_min_addr || !slice_area_is_free(mm, addr, len)) addr = 0; } -- GitLab From 5323688fc3ed7064a3a4a70f2aa6be8dcddfe330 Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Mon, 25 Feb 2019 12:59:40 -0800 Subject: [PATCH 0433/1121] x86/mce: Improve error message when kernel cannot recover, p2 commit 41f035a86b5b72a4f947c38e94239d20d595352a upstream. In c7d606f560e4 ("x86/mce: Improve error message when kernel cannot recover") a case was added for a machine check caused by a DATA access to poison memory from the kernel. A case should have been added also for an uncorrectable error during an instruction fetch in the kernel. Add that extra case so the error message now reads: mce: [Hardware Error]: Machine check: Instruction fetch error in kernel Fixes: c7d606f560e4 ("x86/mce: Improve error message when kernel cannot recover") Signed-off-by: Tony Luck Signed-off-by: Borislav Petkov Cc: "H. Peter Anvin" Cc: Ingo Molnar Cc: Pu Wen Cc: Thomas Gleixner Cc: x86-ml Link: https://lkml.kernel.org/r/20190225205940.15226-1-tony.luck@intel.com Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/cpu/mcheck/mce-severity.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/x86/kernel/cpu/mcheck/mce-severity.c b/arch/x86/kernel/cpu/mcheck/mce-severity.c index c51353569492..20d133ec3ef9 100644 --- a/arch/x86/kernel/cpu/mcheck/mce-severity.c +++ b/arch/x86/kernel/cpu/mcheck/mce-severity.c @@ -148,6 +148,11 @@ static struct severity { SER, MASK(MCI_STATUS_OVER|MCI_UC_SAR|MCI_ADDR|MCACOD, MCI_UC_SAR|MCI_ADDR|MCACOD_DATA), KERNEL ), + MCESEV( + PANIC, "Instruction fetch error in kernel", + SER, MASK(MCI_STATUS_OVER|MCI_UC_SAR|MCI_ADDR|MCACOD, MCI_UC_SAR|MCI_ADDR|MCACOD_INSTR), + KERNEL + ), #endif MCESEV( PANIC, "Action required: unknown MCACOD", -- GitLab From 502a97abc4ee6adf5884d61006201860fc7c2ace Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20M=C3=BCller?= Date: Mon, 8 Apr 2019 15:33:54 +0200 Subject: [PATCH 0434/1121] clk: x86: Add system specific quirk to mark clocks as critical MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 7c2e07130090ae001a97a6b65597830d6815e93e upstream. Since commit 648e921888ad ("clk: x86: Stop marking clocks as CLK_IS_CRITICAL"), the pmc_plt_clocks of the Bay Trail SoC are unconditionally gated off. Unfortunately this will break systems where these clocks are used for external purposes beyond the kernel's knowledge. Fix it by implementing a system specific quirk to mark the necessary pmc_plt_clks as critical. Fixes: 648e921888ad ("clk: x86: Stop marking clocks as CLK_IS_CRITICAL") Signed-off-by: David MĂŒller Signed-off-by: Hans de Goede Reviewed-by: Andy Shevchenko Signed-off-by: Stephen Boyd Signed-off-by: Greg Kroah-Hartman --- drivers/clk/x86/clk-pmc-atom.c | 14 ++++++++++--- drivers/platform/x86/pmc_atom.c | 21 +++++++++++++++++++ .../linux/platform_data/x86/clk-pmc-atom.h | 3 +++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/drivers/clk/x86/clk-pmc-atom.c b/drivers/clk/x86/clk-pmc-atom.c index d977193842df..19174835693b 100644 --- a/drivers/clk/x86/clk-pmc-atom.c +++ b/drivers/clk/x86/clk-pmc-atom.c @@ -165,7 +165,7 @@ static const struct clk_ops plt_clk_ops = { }; static struct clk_plt *plt_clk_register(struct platform_device *pdev, int id, - void __iomem *base, + const struct pmc_clk_data *pmc_data, const char **parent_names, int num_parents) { @@ -184,9 +184,17 @@ static struct clk_plt *plt_clk_register(struct platform_device *pdev, int id, init.num_parents = num_parents; pclk->hw.init = &init; - pclk->reg = base + PMC_CLK_CTL_OFFSET + id * PMC_CLK_CTL_SIZE; + pclk->reg = pmc_data->base + PMC_CLK_CTL_OFFSET + id * PMC_CLK_CTL_SIZE; spin_lock_init(&pclk->lock); + /* + * On some systems, the pmc_plt_clocks already enabled by the + * firmware are being marked as critical to avoid them being + * gated by the clock framework. + */ + if (pmc_data->critical && plt_clk_is_enabled(&pclk->hw)) + init.flags |= CLK_IS_CRITICAL; + ret = devm_clk_hw_register(&pdev->dev, &pclk->hw); if (ret) { pclk = ERR_PTR(ret); @@ -332,7 +340,7 @@ static int plt_clk_probe(struct platform_device *pdev) return PTR_ERR(parent_names); for (i = 0; i < PMC_CLK_NUM; i++) { - data->clks[i] = plt_clk_register(pdev, i, pmc_data->base, + data->clks[i] = plt_clk_register(pdev, i, pmc_data, parent_names, data->nparents); if (IS_ERR(data->clks[i])) { err = PTR_ERR(data->clks[i]); diff --git a/drivers/platform/x86/pmc_atom.c b/drivers/platform/x86/pmc_atom.c index 77bac859342d..75f69cf0d45f 100644 --- a/drivers/platform/x86/pmc_atom.c +++ b/drivers/platform/x86/pmc_atom.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -421,11 +422,27 @@ static int pmc_dbgfs_register(struct pmc_dev *pmc) } #endif /* CONFIG_DEBUG_FS */ +/* + * Some systems need one or more of their pmc_plt_clks to be + * marked as critical. + */ +static const struct dmi_system_id critclk_systems[] __initconst = { + { + .ident = "MPL CEC1x", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "MPL AG"), + DMI_MATCH(DMI_PRODUCT_NAME, "CEC10 Family"), + }, + }, + { /*sentinel*/ } +}; + static int pmc_setup_clks(struct pci_dev *pdev, void __iomem *pmc_regmap, const struct pmc_data *pmc_data) { struct platform_device *clkdev; struct pmc_clk_data *clk_data; + const struct dmi_system_id *d = dmi_first_match(critclk_systems); clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL); if (!clk_data) @@ -433,6 +450,10 @@ static int pmc_setup_clks(struct pci_dev *pdev, void __iomem *pmc_regmap, clk_data->base = pmc_regmap; /* offset is added by client */ clk_data->clks = pmc_data->clks; + if (d) { + clk_data->critical = true; + pr_info("%s critclks quirk enabled\n", d->ident); + } clkdev = platform_device_register_data(&pdev->dev, "clk-pmc-atom", PLATFORM_DEVID_NONE, diff --git a/include/linux/platform_data/x86/clk-pmc-atom.h b/include/linux/platform_data/x86/clk-pmc-atom.h index 3ab892208343..7a37ac27d0fb 100644 --- a/include/linux/platform_data/x86/clk-pmc-atom.h +++ b/include/linux/platform_data/x86/clk-pmc-atom.h @@ -35,10 +35,13 @@ struct pmc_clk { * * @base: PMC clock register base offset * @clks: pointer to set of registered clocks, typically 0..5 + * @critical: flag to indicate if firmware enabled pmc_plt_clks + * should be marked as critial or not */ struct pmc_clk_data { void __iomem *base; const struct pmc_clk *clks; + bool critical; }; #endif /* __PLATFORM_DATA_X86_CLK_PMC_ATOM_H */ -- GitLab From 6831e342160b8319801291aeb2ad8d5164176b25 Mon Sep 17 00:00:00 2001 From: Nicolas Le Bayon Date: Wed, 6 Mar 2019 15:12:16 +0000 Subject: [PATCH 0435/1121] i2c: i2c-stm32f7: Fix SDADEL minimum formula commit c86da50cfd840edf223a242580913692acddbcf6 upstream. It conforms with Reference Manual I2C timing section. Fixes: aeb068c57214 ("i2c: i2c-stm32f7: add driver") Signed-off-by: Nicolas Le Bayon Signed-off-by: Bich Hemon Reviewed-by: Pierre-Yves MORDRET Signed-off-by: Wolfram Sang Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-stm32f7.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c index 124f9b1cf1b0..d8cbe149925b 100644 --- a/drivers/i2c/busses/i2c-stm32f7.c +++ b/drivers/i2c/busses/i2c-stm32f7.c @@ -340,7 +340,7 @@ static int stm32f7_i2c_compute_timing(struct stm32f7_i2c_dev *i2c_dev, STM32F7_I2C_ANALOG_FILTER_DELAY_MAX : 0); dnf_delay = setup->dnf * i2cclk; - sdadel_min = setup->fall_time - i2c_specs[setup->speed].hddat_min - + sdadel_min = i2c_specs[setup->speed].hddat_min + setup->fall_time - af_delay_min - (setup->dnf + 3) * i2cclk; sdadel_max = i2c_specs[setup->speed].vddat_max - setup->rise_time - -- GitLab From 111d60355189bf9ad126fd19950b8ea7a664f3dd Mon Sep 17 00:00:00 2001 From: Jacopo Mondi Date: Fri, 29 Dec 2017 07:22:26 -0500 Subject: [PATCH 0436/1121] media: v4l2: i2c: ov7670: Fix PLL bypass register values commit 61da76beef1e4f0b6ba7be4f8d0cf0dac7ce1f55 upstream. The following commits: commit f6dd927f34d6 ("[media] media: ov7670: calculate framerate properly for ov7675") commit 04ee6d92047e ("[media] media: ov7670: add possibility to bypass pll for ov7675") introduced the ability to bypass PLL multiplier and use input clock (xvclk) as pixel clock output frequency for ov7675 sensor. PLL is bypassed using register DBLV[7:6], according to ov7670 and ov7675 sensor manuals. Macros used to set DBLV register seem wrong in the driver, as their values do not match what reported in the datasheet. Fix by changing DBLV_* macros to use bits [7:6] and set bits [3:0] to default 0x0a reserved value (according to datasheets). While at there, remove a write to DBLV register in "ov7675_set_framerate()" that over-writes the previous one to the same register that takes "info->pll_bypass" flag into account instead of setting PLL multiplier to 4x unconditionally. And, while at there, since "info->pll_bypass" is only used in set/get_framerate() functions used by ov7675 only, it is not necessary to check for the device id at probe time to make sure that when using ov7670 "info->pll_bypass" is set to false. Fixes: f6dd927f34d6 ("[media] media: ov7670: calculate framerate properly for ov7675") Signed-off-by: Jacopo Mondi Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- drivers/media/i2c/ov7670.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c index 39ff73a6a807..6925749864a8 100644 --- a/drivers/media/i2c/ov7670.c +++ b/drivers/media/i2c/ov7670.c @@ -158,10 +158,10 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); #define REG_GFIX 0x69 /* Fix gain control */ #define REG_DBLV 0x6b /* PLL control an debugging */ -#define DBLV_BYPASS 0x00 /* Bypass PLL */ -#define DBLV_X4 0x01 /* clock x4 */ -#define DBLV_X6 0x10 /* clock x6 */ -#define DBLV_X8 0x11 /* clock x8 */ +#define DBLV_BYPASS 0x0a /* Bypass PLL */ +#define DBLV_X4 0x4a /* clock x4 */ +#define DBLV_X6 0x8a /* clock x6 */ +#define DBLV_X8 0xca /* clock x8 */ #define REG_REG76 0x76 /* OV's name */ #define R76_BLKPCOR 0x80 /* Black pixel correction enable */ @@ -837,7 +837,7 @@ static int ov7675_set_framerate(struct v4l2_subdev *sd, if (ret < 0) return ret; - return ov7670_write(sd, REG_DBLV, DBLV_X4); + return 0; } static void ov7670_get_framerate_legacy(struct v4l2_subdev *sd, @@ -1601,11 +1601,7 @@ static int ov7670_probe(struct i2c_client *client, if (config->clock_speed) info->clock_speed = config->clock_speed; - /* - * It should be allowed for ov7670 too when it is migrated to - * the new frame rate formula. - */ - if (config->pll_bypass && id->driver_data != MODEL_OV7670) + if (config->pll_bypass) info->pll_bypass = true; if (config->pclk_hb_disable) -- GitLab From 843807167cfac7f763853709c4fd00b08a232a79 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 18 Apr 2019 17:50:48 -0700 Subject: [PATCH 0437/1121] mm/kmemleak.c: fix unused-function warning commit dce5b0bdeec61bdbee56121ceb1d014151d5cab1 upstream. The only references outside of the #ifdef have been removed, so now we get a warning in non-SMP configurations: mm/kmemleak.c:1404:13: error: unused function 'scan_large_block' [-Werror,-Wunused-function] Add a new #ifdef around it. Link: http://lkml.kernel.org/r/20190416123148.3502045-1-arnd@arndb.de Fixes: 298a32b13208 ("kmemleak: powerpc: skip scanning holes in the .bss section") Signed-off-by: Arnd Bergmann Acked-by: Catalin Marinas Cc: Vincent Whitchurch Cc: Michael Ellerman Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Cc: Nobuhiro Iwamatsu Signed-off-by: Greg Kroah-Hartman --- mm/kmemleak.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mm/kmemleak.c b/mm/kmemleak.c index 337be9aacb7a..71ba1c7f8892 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c @@ -1364,6 +1364,7 @@ static void scan_block(void *_start, void *_end, /* * Scan a large memory block in MAX_SCAN_SIZE chunks to reduce the latency. */ +#ifdef CONFIG_SMP static void scan_large_block(void *start, void *end) { void *next; @@ -1375,6 +1376,7 @@ static void scan_large_block(void *start, void *end) cond_resched(); } } +#endif /* * Scan a memory block corresponding to a kmemleak_object. A condition is -- GitLab From b4677bbb658d54ad29c8122d61bdcc0f878030b1 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 8 May 2019 07:20:54 +0200 Subject: [PATCH 0438/1121] Linux 4.14.117 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7dcaffff08a3..efe716372985 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 4 PATCHLEVEL = 14 -SUBLEVEL = 116 +SUBLEVEL = 117 EXTRAVERSION = NAME = Petit Gorille -- GitLab From 58ab6e8c44d9d905e65b696b729fbe1e1067346d Mon Sep 17 00:00:00 2001 From: Tony Lijo Jose Date: Thu, 9 May 2019 10:47:02 +0530 Subject: [PATCH 0439/1121] msm: camera: csiphy: correct DPHY bring up sequence Modify/Add register address/Value for dphy bring up sequence. Change-Id: I570f73be658f2a3a6bb4ac1e362f5f0b46c4e558 Signed-off-by: Tony Lijo Jose --- .../cam_csiphy/include/cam_csiphy_1_2_hwreg.h | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h index 67653e81fde1..edde07091d9e 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h @@ -21,7 +21,7 @@ struct csiphy_reg_parms_t csiphy_v1_2 = { .mipi_csiphy_glbl_irq_cmd_addr = 0x828, .csiphy_common_array_size = 6, .csiphy_reset_array_size = 5, - .csiphy_2ph_config_array_size = 21, + .csiphy_2ph_config_array_size = 22, .csiphy_3ph_config_array_size = 38, .csiphy_2ph_clock_lane = 0x1, .csiphy_2ph_combo_ck_ln = 0x10, @@ -78,10 +78,11 @@ csiphy_reg_t csiphy_2ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { {0x0000, 0x91, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0004, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0020, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0008, 0x04, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x0008, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, {0x000c, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x0010, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0038, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, }, { {0x0730, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, @@ -105,6 +106,7 @@ csiphy_reg_t csiphy_2ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { {0x070c, 0xFF, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0710, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0738, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, }, { {0x0230, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, @@ -128,6 +130,7 @@ csiphy_reg_t csiphy_2ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { {0x020c, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x0210, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0238, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, }, { {0x0430, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, @@ -151,6 +154,7 @@ csiphy_reg_t csiphy_2ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { {0x040c, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x0410, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0438, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, }, { {0x0630, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, @@ -174,6 +178,7 @@ csiphy_reg_t csiphy_2ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { {0x060c, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x0610, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0638, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, }, }; @@ -197,10 +202,11 @@ struct csiphy_reg_t {0x0000, 0x91, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0004, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0020, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0008, 0x04, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x0008, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, {0x000c, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x0010, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0038, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x00, 0x00, CSIPHY_DNP_PARAMS}, }, { {0x0730, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, @@ -224,6 +230,7 @@ struct csiphy_reg_t {0x070c, 0xFF, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0710, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0738, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x00, 0x00, CSIPHY_DNP_PARAMS}, }, { {0x0230, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, @@ -247,6 +254,7 @@ struct csiphy_reg_t {0x020c, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x0210, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0238, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x00, 0x00, CSIPHY_DNP_PARAMS}, }, { {0x0430, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, @@ -270,6 +278,7 @@ struct csiphy_reg_t {0x040c, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x0410, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0438, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x00, 0x00, CSIPHY_DNP_PARAMS}, }, { {0x0630, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, @@ -293,6 +302,7 @@ struct csiphy_reg_t {0x060c, 0xFF, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0610, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0638, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x00, 0x00, CSIPHY_DNP_PARAMS}, }, }; -- GitLab From 4b7d967d9718afc26a6f37788105b0febec87d04 Mon Sep 17 00:00:00 2001 From: Raja Mallik Date: Mon, 8 Apr 2019 15:17:41 +0530 Subject: [PATCH 0440/1121] msm: camera: isp: Prevent out of bounds read Add checks for OOB Read in new CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG_V2 When command buffers are passed from userspace in the form of generic blobs, the size must be validated to prevent out of bounds read. Change-Id: Ic604c7466cf4735abe010c6134b6e4a7f7ff6b59 Signed-off-by: Raja Mallik --- .../cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c index 5f23e87d1c3f..2a248e19c3da 100644 --- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c @@ -3709,10 +3709,33 @@ static int cam_isp_packet_generic_blob_handler(void *user_data, } break; case CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG_V2: { - struct cam_isp_bw_config_ab *bw_config_ab = - (struct cam_isp_bw_config_ab *)blob_data; + struct cam_isp_bw_config_ab *bw_config_ab; + struct cam_isp_prepare_hw_update_data *prepare_hw_data; + if (blob_size < sizeof(struct cam_isp_bw_config_ab)) { + CAM_ERR(CAM_ISP, "Invalid blob size %u", blob_size); + return -EINVAL; + } + + bw_config_ab = (struct cam_isp_bw_config_ab *)blob_data; + + if (bw_config_ab->num_rdi > CAM_IFE_RDI_NUM_MAX) { + CAM_ERR(CAM_ISP, "Invalid num_rdi %u in bw config ab", + bw_config_ab->num_rdi); + return -EINVAL; + } + + if (blob_size < (sizeof(uint32_t) * 2 + + (bw_config_ab->num_rdi + 2) + * sizeof(struct cam_isp_bw_vote))) { + CAM_ERR(CAM_ISP, "Invalid blob size %u expected %u", + blob_size, + sizeof(uint32_t) * 2 + + (bw_config_ab->num_rdi + 2) + * sizeof(struct cam_isp_bw_vote)); + return -EINVAL; + } CAM_DBG(CAM_ISP, "AB L:%lld R:%lld usage_type %d", bw_config_ab->left_pix_vote_ab, bw_config_ab->right_pix_vote_ab, -- GitLab From 4835252d4c0fa0099b011ed942c188506671da42 Mon Sep 17 00:00:00 2001 From: Mangalaram ARCHANA Date: Thu, 25 Apr 2019 14:33:27 +0530 Subject: [PATCH 0441/1121] msm: camera: icp: Mapping fw error numbers with error names Printing ICP error names based on error type. Change-Id: Id282d60e0d31982c912113dcd78c868008e5ddef Signed-off-by: Mangalaram ARCHANA --- .../msm/camera/cam_icp/fw_inc/hfi_sys_defs.h | 23 ++++- .../icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c | 97 +++++++++++++++++-- 2 files changed, 109 insertions(+), 11 deletions(-) diff --git a/drivers/media/platform/msm/camera/cam_icp/fw_inc/hfi_sys_defs.h b/drivers/media/platform/msm/camera/cam_icp/fw_inc/hfi_sys_defs.h index 311886ffd6da..d60a25e8b925 100644 --- a/drivers/media/platform/msm/camera/cam_icp/fw_inc/hfi_sys_defs.h +++ b/drivers/media/platform/msm/camera/cam_icp/fw_inc/hfi_sys_defs.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -215,6 +215,27 @@ #define HFI_DEV_VERSION_MAX 0x5 +/* General errors and HFI Specific errors. */ +enum hfi_errors { + CAMERAICP_SUCCESS, + CAMERAICP_EFAILED, + CAMERAICP_ENOMEMORY, + CAMERAICP_EBADSTATE, + CAMERAICP_EBADPARM, + CAMERAICP_EBADITEM, + CAMERAICP_EINVALIDFORMAT, + CAMERAICP_EUNSUPPORTED, + CAMERAICP_EOUTOFBOUND, + CAMERAICP_ETIMEDOUT, + CAMERAICP_EABORTED, + CAMERAICP_EHWVIOLATION, + CAMERAICP_ECDMERROR, + CAMERAICP_HFI_ERR_COMMAND_SIZE = 1000, + CAMERAICP_HFI_ERR_MESSAGE_SIZE, + CAMERAICP_HFI_QUEUE_EMPTY, + CAMERAICP_HFI_QUEUE_FULL, +}; + /** * start of sys command packet types * These commands are used to get system level information diff --git a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c index 0f4d07716e01..f7ea8111d95a 100644 --- a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c +++ b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c @@ -1563,7 +1563,69 @@ static int cam_icp_mgr_handle_frame_process(uint32_t *msg_ptr, int flag) return 0; } +static const char *cam_icp_error_handle_id_to_type( + uint32_t error_handle) +{ + const char *name = NULL; + switch (error_handle) { + case CAMERAICP_SUCCESS: + name = "SUCCESS"; + break; + case CAMERAICP_EFAILED: + name = "EFAILED"; + break; + case CAMERAICP_ENOMEMORY: + name = "ENOMEMORY"; + break; + case CAMERAICP_EBADSTATE: + name = "EBADSTATE"; + break; + case CAMERAICP_EBADPARM: + name = "EBADPARM"; + break; + case CAMERAICP_EBADITEM: + name = "EBADITEM"; + break; + case CAMERAICP_EINVALIDFORMAT: + name = "EINVALIDFORMAT"; + break; + case CAMERAICP_EUNSUPPORTED: + name = "EUNSUPPORTED"; + break; + case CAMERAICP_EOUTOFBOUND: + name = "EOUTOFBOUND"; + break; + case CAMERAICP_ETIMEDOUT: + name = "ETIMEDOUT"; + break; + case CAMERAICP_EABORTED: + name = "EABORTED"; + break; + case CAMERAICP_EHWVIOLATION: + name = "EHWVIOLATION"; + break; + case CAMERAICP_ECDMERROR: + name = "ECDMERROR"; + break; + case CAMERAICP_HFI_ERR_COMMAND_SIZE: + name = "HFI_ERR_COMMAND_SIZE"; + break; + case CAMERAICP_HFI_ERR_MESSAGE_SIZE: + name = "HFI_ERR_MESSAGE_SIZE"; + break; + case CAMERAICP_HFI_QUEUE_EMPTY: + name = "HFI_QUEUE_EMPTY"; + break; + case CAMERAICP_HFI_QUEUE_FULL: + name = "HFI_QUEUE_FULL"; + break; + default: + name = NULL; + break; + } + return name; +} static int cam_icp_mgr_process_msg_frame_process(uint32_t *msg_ptr) { struct hfi_msg_ipebps_async_ack *ioconfig_ack = NULL; @@ -1576,8 +1638,11 @@ static int cam_icp_mgr_process_msg_frame_process(uint32_t *msg_ptr) ioconfig_ack = (struct hfi_msg_ipebps_async_ack *)msg_ptr; if (ioconfig_ack->err_type != HFI_ERR_SYS_NONE) { - CAM_ERR(CAM_ICP, "failed with error : %u", - ioconfig_ack->err_type); + CAM_ERR(CAM_ICP, + "failed with err_no= [%u] err_type= [%s]", + ioconfig_ack->err_type, + cam_icp_error_handle_id_to_type( + ioconfig_ack->err_type)); cam_icp_mgr_handle_frame_process(msg_ptr, ICP_FRAME_PROCESS_FAILURE); return -EIO; @@ -1617,8 +1682,12 @@ static int cam_icp_mgr_process_msg_config_io(uint32_t *msg_ptr) ipe_config_ack = (struct hfi_msg_ipe_config *)(ioconfig_ack->msg_data); if (ipe_config_ack->rc) { - CAM_ERR(CAM_ICP, "rc = %d err = %u", - ipe_config_ack->rc, ioconfig_ack->err_type); + CAM_ERR(CAM_ICP, "rc = %d failed with\n" + "err_no = [%u] err_type = [%s]", + ipe_config_ack->rc, + ioconfig_ack->err_type, + cam_icp_error_handle_id_to_type( + ioconfig_ack->err_type)); return -EIO; } ctx_data = (struct cam_icp_hw_ctx_data *) @@ -1783,9 +1852,13 @@ static int cam_icp_mgr_process_direct_ack_msg(uint32_t *msg_ptr) (struct cam_icp_hw_ctx_data *)ioconfig_ack->user_data1; if (ctx_data->state != CAM_ICP_CTX_STATE_FREE) complete(&ctx_data->wait_complete); - CAM_DBG(CAM_ICP, - "received IPE/BPS MAP ACK:ctx_state =%d err_status =%u", - ctx_data->state, ioconfig_ack->err_type); + CAM_DBG(CAM_ICP, "received IPE/BPS\n" + "MAP ACK:ctx_state =%d\n" + "failed with err_no = [%u] err_type = [%s]", + ctx_data->state, + ioconfig_ack->err_type, + cam_icp_error_handle_id_to_type( + ioconfig_ack->err_type)); break; case HFI_IPEBPS_CMD_OPCODE_MEM_UNMAP: ioconfig_ack = (struct hfi_msg_ipebps_async_ack *)msg_ptr; @@ -1793,9 +1866,13 @@ static int cam_icp_mgr_process_direct_ack_msg(uint32_t *msg_ptr) (struct cam_icp_hw_ctx_data *)ioconfig_ack->user_data1; if (ctx_data->state != CAM_ICP_CTX_STATE_FREE) complete(&ctx_data->wait_complete); - CAM_DBG(CAM_ICP, - "received IPE/BPS UNMAP ACK:ctx_state =%d err_status =%u", - ctx_data->state, ioconfig_ack->err_type); + CAM_DBG(CAM_ICP, + "received IPE/BPS UNMAP ACK:ctx_state =%d\n" + "failed with err_no = [%u] err_type = [%s]", + ctx_data->state, + ioconfig_ack->err_type, + cam_icp_error_handle_id_to_type( + ioconfig_ack->err_type)); break; default: CAM_ERR(CAM_ICP, "Invalid opcode : %u", -- GitLab From 835cdfa53ce2fe0b4fedc51c08b5e93d047bf891 Mon Sep 17 00:00:00 2001 From: Depeng Shao Date: Fri, 10 May 2019 16:29:31 +0800 Subject: [PATCH 0442/1121] msm: camera: reqmgr: Fix CRM shift one req issue Check if current link is faster than sync link before check if current link is ready, then we don't need to skip sync link sof if current link is faster than sync link. And, skip sync link next SOF just link and sync link ready status is different to avoid skiping needed SOF. Change-Id: I92145bde28680538833d6d2472f200622202327a Signed-off-by: Depeng Shao --- .../msm/camera/cam_req_mgr/cam_req_mgr_core.c | 42 ++++++++++++------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c index 80521ea69deb..32dfba3fe80a 100644 --- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c +++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c @@ -893,6 +893,7 @@ static int __cam_req_mgr_check_sync_req_is_ready( int64_t req_id = 0; int sync_slot_idx = 0, sync_rd_idx = 0, rc = 0; int32_t sync_num_slots = 0; + bool ready = true, sync_ready = true; if (!link->sync_link) { CAM_ERR(CAM_CRM, "Sync link null"); @@ -921,17 +922,7 @@ static int __cam_req_mgr_check_sync_req_is_ready( CAM_DBG(CAM_CRM, "Skip Process Req: %lld on link: %x", req_id, link->link_hdl); - link->sync_link_sof_skip = true; - return rc; - } - - rc = __cam_req_mgr_check_link_is_ready(link, slot->idx, true); - if (rc) { - CAM_DBG(CAM_CRM, - "Req: %lld [My link] not ready on link: %x, rc=%d", - req_id, link->link_hdl, rc); - link->sync_link_sof_skip = true; - return rc; + ready = false; } sync_slot_idx = __cam_req_mgr_find_slot_for_req( @@ -939,8 +930,7 @@ static int __cam_req_mgr_check_sync_req_is_ready( if (sync_slot_idx == -1) { CAM_DBG(CAM_CRM, "Req: %lld not found on link: %x [other link]", req_id, sync_link->link_hdl); - link->sync_link_sof_skip = true; - return -EINVAL; + sync_ready = false; } sync_rd_idx = sync_link->req.in_q->rd_idx; @@ -956,14 +946,38 @@ static int __cam_req_mgr_check_sync_req_is_ready( return -EAGAIN; } + rc = __cam_req_mgr_check_link_is_ready(link, slot->idx, true); + if (rc) { + CAM_DBG(CAM_CRM, + "Req: %lld [My link] not ready on link: %x, rc=%d", + req_id, link->link_hdl, rc); + ready = false; + } + rc = __cam_req_mgr_check_link_is_ready(sync_link, sync_slot_idx, true); if (rc && (sync_link->req.in_q->slot[sync_slot_idx].status != CRM_SLOT_STATUS_REQ_APPLIED)) { CAM_DBG(CAM_CRM, "Req: %lld not ready on [other link] link: %x, rc=%d", req_id, sync_link->link_hdl, rc); + sync_ready = false; + } + + /* + * If both of them are ready or not ready, then just + * skip this sof and don't skip sync link next SOF. + */ + if (sync_ready != ready) { + CAM_DBG(CAM_CRM, + "Req: %lld ready %d sync_ready %d, ignore sync link next SOF", + req_id, ready, sync_ready); link->sync_link_sof_skip = true; - return rc; + return -EINVAL; + } else if (ready == false) { + CAM_DBG(CAM_CRM, + "Req: %lld not ready on link: %x", + req_id, link->link_hdl); + return -EINVAL; } CAM_DBG(CAM_REQ, -- GitLab From 724b1b8ef2cab61079d23e679309343bc63e9840 Mon Sep 17 00:00:00 2001 From: Tejas Prajapati Date: Wed, 8 May 2019 16:26:45 +0530 Subject: [PATCH 0443/1121] msm: camera: fd: Remove duplicate "qcom,fd501" property Remove the duplicate dt property for fd hardware. Change-Id: Iac2a096560695f10ae977d392a2f995479c7a1da Signed-off-by: Tejas Prajapati --- .../msm/camera/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_dev.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_dev.c b/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_dev.c index 8a84c0ee7e99..083041c21dff 100644 --- a/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_dev.c +++ b/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -206,10 +206,6 @@ static const struct of_device_id cam_fd_hw_dt_match[] = { .compatible = "qcom,fd501", .data = &cam_fd_wrapper200_core501_info, }, - { - .compatible = "qcom,fd501", - .data = &cam_fd_wrapper200_core501_info, - }, {} }; MODULE_DEVICE_TABLE(of, cam_fd_hw_dt_match); -- GitLab From 5dfa2308bfe1403db72763887c9a1a96dbec29a3 Mon Sep 17 00:00:00 2001 From: Rishabh Jain Date: Fri, 3 May 2019 19:42:43 +0530 Subject: [PATCH 0444/1121] ARM: dts: msm: Increase camnoc bw margin for sdmmagpie Increase camnoc axi bandwidth margin from 10 to 20. Change-Id: I7491dbe32cb7cc405e9f26cee1e90f35befe2f78 Signed-off-by: Rishabh Jain --- arch/arm64/boot/dts/qcom/sdmmagpie-camera.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdmmagpie-camera.dtsi b/arch/arm64/boot/dts/qcom/sdmmagpie-camera.dtsi index a280fbf08889..b773dd748a87 100644 --- a/arch/arm64/boot/dts/qcom/sdmmagpie-camera.dtsi +++ b/arch/arm64/boot/dts/qcom/sdmmagpie-camera.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1070,7 +1070,7 @@ "svs_l1", "nominal", "turbo"; control-camnoc-axi-clk; camnoc-bus-width = <32>; - camnoc-axi-clk-bw-margin-perc = <10>; + camnoc-axi-clk-bw-margin-perc = <20>; qcom,msm-bus,name = "cam_ahb"; qcom,msm-bus,num-cases = <6>; qcom,msm-bus,num-paths = <1>; -- GitLab From bca410086067f6d17bb4b1fbea148d7d8f09b499 Mon Sep 17 00:00:00 2001 From: hangtian Date: Wed, 22 May 2019 13:19:09 +0800 Subject: [PATCH 0445/1121] defconfig: qcs405: Enable ath10k pci driver for besera Enable ath10k pci driver for besera. Change-Id: Ia48d90db38db428357b72edd777b3abf20a71f9e CRs-Fixed: 2457330 Signed-off-by: hangtian --- arch/arm64/configs/vendor/qcs405-perf_defconfig | 8 +++++++- arch/arm64/configs/vendor/qcs405_defconfig | 7 +++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/arch/arm64/configs/vendor/qcs405-perf_defconfig b/arch/arm64/configs/vendor/qcs405-perf_defconfig index 3d966ec2f295..3660fbdde05a 100644 --- a/arch/arm64/configs/vendor/qcs405-perf_defconfig +++ b/arch/arm64/configs/vendor/qcs405-perf_defconfig @@ -21,7 +21,6 @@ CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set # CONFIG_PID_NS is not set CONFIG_DEFAULT_USE_ENERGY_AWARE=y -CONFIG_RELAY=y CONFIG_BLK_DEV_INITRD=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_KALLSYMS_ALL=y @@ -208,6 +207,9 @@ CONFIG_BT=y CONFIG_MSM_BT_POWER=y CONFIG_CFG80211=y CONFIG_CFG80211_INTERNAL_REGDB=y +CONFIG_MAC80211=m +CONFIG_MAC80211_RC_MINSTREL_VHT=y +CONFIG_MAC80211_DEBUGFS=y CONFIG_RFKILL=y CONFIG_NTAG_NQ=y CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y @@ -260,6 +262,10 @@ CONFIG_PPP_ASYNC=y CONFIG_PPP_SYNC_TTY=y CONFIG_USB_USBNET=y CONFIG_USB_NET_SMSC75XX=y +CONFIG_ATH10K=m +CONFIG_ATH10K_PCI=m +CONFIG_ATH10K_DEBUG=y +CONFIG_ATH10K_DEBUGFS=y CONFIG_WCNSS_MEM_PRE_ALLOC=y CONFIG_CLD_LL_CORE=y CONFIG_INPUT_EVDEV=y diff --git a/arch/arm64/configs/vendor/qcs405_defconfig b/arch/arm64/configs/vendor/qcs405_defconfig index 80b997bb0b83..17f65b8db147 100644 --- a/arch/arm64/configs/vendor/qcs405_defconfig +++ b/arch/arm64/configs/vendor/qcs405_defconfig @@ -213,6 +213,9 @@ CONFIG_BT=y CONFIG_MSM_BT_POWER=y CONFIG_CFG80211=y CONFIG_CFG80211_INTERNAL_REGDB=y +CONFIG_MAC80211=m +CONFIG_MAC80211_RC_MINSTREL_VHT=y +CONFIG_MAC80211_DEBUGFS=y CONFIG_RFKILL=y CONFIG_NTAG_NQ=y CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y @@ -265,6 +268,10 @@ CONFIG_PPP_ASYNC=y CONFIG_PPP_SYNC_TTY=y CONFIG_USB_USBNET=y CONFIG_USB_NET_SMSC75XX=y +CONFIG_ATH10K=m +CONFIG_ATH10K_PCI=m +CONFIG_ATH10K_DEBUG=y +CONFIG_ATH10K_DEBUGFS=y CONFIG_WCNSS_MEM_PRE_ALLOC=y CONFIG_CLD_LL_CORE=y CONFIG_INPUT_EVDEV=y -- GitLab From 2cf1b502bb95e3945710cc03e2585283e2b74cd4 Mon Sep 17 00:00:00 2001 From: Mangalaram ARCHANA Date: Tue, 21 May 2019 09:22:55 +0530 Subject: [PATCH 0446/1121] msm: camera: crm: Increase the device handles to 128 Increasing the device handles to 128 to support more pipelines. Change-Id: Id0322cba095091e6168d8541d432628d8422a641 Signed-off-by: Mangalaram ARCHANA --- .../msm/camera/cam_req_mgr/cam_req_mgr_core.c | 160 +++++++++++++++--- .../msm/camera/cam_req_mgr/cam_req_mgr_core.h | 7 +- .../msm/camera/cam_req_mgr/cam_req_mgr_dev.c | 37 +++- include/uapi/media/cam_req_mgr.h | 16 ++ 4 files changed, 191 insertions(+), 29 deletions(-) diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c index 35aa9072b646..a2d03a0abb35 100644 --- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c +++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c @@ -2364,7 +2364,7 @@ static struct cam_req_mgr_crm_cb cam_req_mgr_ops = { * */ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, - struct cam_req_mgr_link_info *link_info) + struct cam_req_mgr_ver_info *link_info) { int rc = 0, i = 0; struct cam_req_mgr_core_dev_link_setup link_data; @@ -2372,10 +2372,16 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, struct cam_req_mgr_req_tbl *pd_tbl; enum cam_pipeline_delay max_delay; uint32_t subscribe_event = 0; - - if (link_info->num_devices > CAM_REQ_MGR_MAX_HANDLES) - return -EPERM; - + if (link_info->version == VERSION_1) { + if (link_info->u.link_info_v1.num_devices > + CAM_REQ_MGR_MAX_HANDLES) + return -EPERM; + } + else if (link_info->version == VERSION_2) { + if (link_info->u.link_info_v2.num_devices > + CAM_REQ_MGR_MAX_HANDLES_V2) + return -EPERM; + } mutex_init(&link->req.lock); CAM_DBG(CAM_CRM, "LOCK_DBG in_q lock %pK", &link->req.lock); link->req.num_tbl = 0; @@ -2385,11 +2391,12 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, return rc; max_delay = CAM_PIPELINE_DELAY_0; - for (i = 0; i < link_info->num_devices; i++) { + for (i = 0; i < link_info->u.link_info_v1.num_devices; i++) { dev = &link->l_dev[i]; /* Using dev hdl, get ops ptr to communicate with device */ dev->ops = (struct cam_req_mgr_kmd_ops *) - cam_get_device_ops(link_info->dev_hdls[i]); + cam_get_device_ops( + link_info->u.link_info_v1.dev_hdls[i]); if (!dev->ops || !dev->ops->get_dev_info || !dev->ops->link_setup) { @@ -2397,7 +2404,7 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, rc = -ENXIO; goto error; } - dev->dev_hdl = link_info->dev_hdls[i]; + dev->dev_hdl = link_info->u.link_info_v1.dev_hdls[i]; dev->parent = (void *)link; dev->dev_info.dev_hdl = dev->dev_hdl; rc = dev->ops->get_dev_info(&dev->dev_info); @@ -2406,7 +2413,8 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, CAM_DBG(CAM_CRM, "%x: connected: %s, id %d, delay %d, trigger %x", - link_info->session_hdl, dev->dev_info.name, + link_info->u.link_info_v1.session_hdl, + dev->dev_info.name, dev->dev_info.dev_id, dev->dev_info.p_delay, dev->dev_info.trigger); if (rc < 0 || @@ -2418,7 +2426,7 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, goto error; } else { CAM_DBG(CAM_CRM, "%x: connected: %s, delay %d", - link_info->session_hdl, + link_info->u.link_info_v1.session_hdl, dev->dev_info.name, dev->dev_info.p_delay); if (dev->dev_info.p_delay > max_delay) @@ -2435,7 +2443,7 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, link_data.max_delay = max_delay; link_data.subscribe_event = subscribe_event; - for (i = 0; i < link_info->num_devices; i++) { + for (i = 0; i < link_info->u.link_info_v1.num_devices; i++) { dev = &link->l_dev[i]; link_data.dev_hdl = dev->dev_hdl; @@ -2478,7 +2486,7 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, if (link->max_delay < dev->dev_info.p_delay) link->max_delay = dev->dev_info.p_delay; } - link->num_devs = link_info->num_devices; + link->num_devs = link_info->u.link_info_v1.num_devices; /* Assign id for pd tables */ __cam_req_mgr_tbl_set_id(link->req.l_tbl, &link->req); @@ -2636,7 +2644,115 @@ int cam_req_mgr_destroy_session( return rc; } -int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info) +int cam_req_mgr_link(struct cam_req_mgr_ver_info *link_info) +{ + int rc = 0; + int wq_flag = 0; + char buf[128]; + struct cam_create_dev_hdl root_dev; + struct cam_req_mgr_core_session *cam_session; + struct cam_req_mgr_core_link *link; + + if (!link_info) { + CAM_DBG(CAM_CRM, "NULL pointer"); + return -EINVAL; + } + if (link_info->u.link_info_v1.num_devices > CAM_REQ_MGR_MAX_HANDLES) { + CAM_ERR(CAM_CRM, "Invalid num devices %d", + link_info->u.link_info_v1.num_devices); + return -EINVAL; + } + + mutex_lock(&g_crm_core_dev->crm_lock); + + /* session hdl's priv data is cam session struct */ + cam_session = (struct cam_req_mgr_core_session *) + cam_get_device_priv(link_info->u.link_info_v1.session_hdl); + if (!cam_session) { + CAM_DBG(CAM_CRM, "NULL pointer"); + mutex_unlock(&g_crm_core_dev->crm_lock); + return -EINVAL; + } + + /* Allocate link struct and map it with session's request queue */ + link = __cam_req_mgr_reserve_link(cam_session); + if (!link) { + CAM_ERR(CAM_CRM, "failed to reserve new link"); + mutex_unlock(&g_crm_core_dev->crm_lock); + return -EINVAL; + } + CAM_DBG(CAM_CRM, "link reserved %pK %x", link, link->link_hdl); + + memset(&root_dev, 0, sizeof(struct cam_create_dev_hdl)); + root_dev.session_hdl = link_info->u.link_info_v1.session_hdl; + root_dev.priv = (void *)link; + + mutex_lock(&link->lock); + /* Create unique dev handle for link */ + link->link_hdl = cam_create_device_hdl(&root_dev); + if (link->link_hdl < 0) { + CAM_ERR(CAM_CRM, + "Insufficient memory to create new device handle"); + rc = link->link_hdl; + goto link_hdl_fail; + } + link_info->u.link_info_v1.link_hdl = link->link_hdl; + link->last_flush_id = 0; + + /* Allocate memory to hold data of all linked devs */ + rc = __cam_req_mgr_create_subdevs(&link->l_dev, + link_info->u.link_info_v1.num_devices); + if (rc < 0) { + CAM_ERR(CAM_CRM, + "Insufficient memory to create new crm subdevs"); + goto create_subdev_failed; + } + + /* Using device ops query connected devs, prepare request tables */ + rc = __cam_req_mgr_setup_link_info(link, link_info); + if (rc < 0) + goto setup_failed; + + spin_lock_bh(&link->link_state_spin_lock); + link->state = CAM_CRM_LINK_STATE_READY; + spin_unlock_bh(&link->link_state_spin_lock); + + /* Create worker for current link */ + snprintf(buf, sizeof(buf), "%x-%x", + link_info->u.link_info_v1.session_hdl, link->link_hdl); + wq_flag = CAM_WORKQ_FLAG_HIGH_PRIORITY | CAM_WORKQ_FLAG_SERIAL; + rc = cam_req_mgr_workq_create(buf, CRM_WORKQ_NUM_TASKS, + &link->workq, CRM_WORKQ_USAGE_NON_IRQ, wq_flag); + if (rc < 0) { + CAM_ERR(CAM_CRM, "FATAL: unable to create worker"); + __cam_req_mgr_destroy_link_info(link); + goto setup_failed; + } + + /* Assign payload to workqueue tasks */ + rc = __cam_req_mgr_setup_payload(link->workq); + if (rc < 0) { + __cam_req_mgr_destroy_link_info(link); + cam_req_mgr_workq_destroy(&link->workq); + goto setup_failed; + } + + mutex_unlock(&link->lock); + mutex_unlock(&g_crm_core_dev->crm_lock); + return rc; +setup_failed: + __cam_req_mgr_destroy_subdev(link->l_dev); +create_subdev_failed: + cam_destroy_device_hdl(link->link_hdl); + link_info->u.link_info_v1.link_hdl = -1; +link_hdl_fail: + mutex_unlock(&link->lock); + __cam_req_mgr_unreserve_link(cam_session, link); + mutex_unlock(&g_crm_core_dev->crm_lock); + return rc; +} + +int cam_req_mgr_link_v2(struct cam_req_mgr_ver_info *link_info) { int rc = 0; int wq_flag = 0; @@ -2649,9 +2765,10 @@ int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info) CAM_DBG(CAM_CRM, "NULL pointer"); return -EINVAL; } - if (link_info->num_devices > CAM_REQ_MGR_MAX_HANDLES) { + if (link_info->u.link_info_v2.num_devices > + CAM_REQ_MGR_MAX_HANDLES_V2) { CAM_ERR(CAM_CRM, "Invalid num devices %d", - link_info->num_devices); + link_info->u.link_info_v2.num_devices); return -EINVAL; } @@ -2659,7 +2776,7 @@ int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info) /* session hdl's priv data is cam session struct */ cam_session = (struct cam_req_mgr_core_session *) - cam_get_device_priv(link_info->session_hdl); + cam_get_device_priv(link_info->u.link_info_v2.session_hdl); if (!cam_session) { CAM_DBG(CAM_CRM, "NULL pointer"); mutex_unlock(&g_crm_core_dev->crm_lock); @@ -2676,7 +2793,7 @@ int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info) CAM_DBG(CAM_CRM, "link reserved %pK %x", link, link->link_hdl); memset(&root_dev, 0, sizeof(struct cam_create_dev_hdl)); - root_dev.session_hdl = link_info->session_hdl; + root_dev.session_hdl = link_info->u.link_info_v2.session_hdl; root_dev.priv = (void *)link; mutex_lock(&link->lock); @@ -2688,12 +2805,12 @@ int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info) rc = link->link_hdl; goto link_hdl_fail; } - link_info->link_hdl = link->link_hdl; + link_info->u.link_info_v2.link_hdl = link->link_hdl; link->last_flush_id = 0; /* Allocate memory to hold data of all linked devs */ rc = __cam_req_mgr_create_subdevs(&link->l_dev, - link_info->num_devices); + link_info->u.link_info_v2.num_devices); if (rc < 0) { CAM_ERR(CAM_CRM, "Insufficient memory to create new crm subdevs"); @@ -2711,7 +2828,7 @@ int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info) /* Create worker for current link */ snprintf(buf, sizeof(buf), "%x-%x", - link_info->session_hdl, link->link_hdl); + link_info->u.link_info_v2.session_hdl, link->link_hdl); wq_flag = CAM_WORKQ_FLAG_HIGH_PRIORITY | CAM_WORKQ_FLAG_SERIAL; rc = cam_req_mgr_workq_create(buf, CRM_WORKQ_NUM_TASKS, &link->workq, CRM_WORKQ_USAGE_NON_IRQ, wq_flag); @@ -2736,7 +2853,7 @@ int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info) __cam_req_mgr_destroy_subdev(link->l_dev); create_subdev_failed: cam_destroy_device_hdl(link->link_hdl); - link_info->link_hdl = -1; + link_info->u.link_info_v2.link_hdl = -1; link_hdl_fail: mutex_unlock(&link->lock); __cam_req_mgr_unreserve_link(cam_session, link); @@ -2744,6 +2861,7 @@ int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info) return rc; } + int cam_req_mgr_unlink(struct cam_req_mgr_unlink_info *unlink_info) { int rc = 0; diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.h b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.h index ff522fad6996..7bd04c137ed9 100644 --- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.h +++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.h @@ -36,6 +36,9 @@ #define MAXIMUM_LINKS_PER_SESSION 4 +#define VERSION_1 1 +#define VERSION_2 2 + /** * enum crm_workq_task_type * @codes: to identify which type of task is present @@ -412,7 +415,9 @@ int cam_req_mgr_destroy_session(struct cam_req_mgr_session_info *ses_info); * a unique link handle for the link and is specific to a * session. Returns link handle */ -int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info); +int cam_req_mgr_link(struct cam_req_mgr_ver_info *link_info); +int cam_req_mgr_link_v2(struct cam_req_mgr_ver_info *link_info); + /** * cam_req_mgr_unlink() diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_dev.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_dev.c index 5cf1d844f5e2..31607ac6391f 100644 --- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_dev.c +++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -268,27 +268,50 @@ static long cam_private_ioctl(struct file *file, void *fh, break; case CAM_REQ_MGR_LINK: { - struct cam_req_mgr_link_info link_info; + struct cam_req_mgr_ver_info ver_info; - if (k_ioctl->size != sizeof(link_info)) + if (k_ioctl->size != sizeof(ver_info.u.link_info_v1)) return -EINVAL; - if (copy_from_user(&link_info, + if (copy_from_user(&ver_info.u.link_info_v1, u64_to_user_ptr(k_ioctl->handle), sizeof(struct cam_req_mgr_link_info))) { return -EFAULT; } - - rc = cam_req_mgr_link(&link_info); + ver_info.version = VERSION_1; + rc = cam_req_mgr_link(&ver_info); if (!rc) if (copy_to_user( u64_to_user_ptr(k_ioctl->handle), - &link_info, + &ver_info.u.link_info_v1, sizeof(struct cam_req_mgr_link_info))) rc = -EFAULT; } break; + case CAM_REQ_MGR_LINK_V2: { + struct cam_req_mgr_ver_info ver_info; + + if (k_ioctl->size != sizeof(ver_info.u.link_info_v2)) + return -EINVAL; + + if (copy_from_user(&ver_info.u.link_info_v2, + u64_to_user_ptr(k_ioctl->handle), + sizeof(struct cam_req_mgr_link_info_v2))) { + return -EFAULT; + } + ver_info.version = VERSION_2; + rc = cam_req_mgr_link_v2(&ver_info); + if (!rc) + if (copy_to_user( + u64_to_user_ptr(k_ioctl->handle), + &ver_info.u.link_info_v2, + sizeof(struct + cam_req_mgr_link_info_v2))) + rc = -EFAULT; + } + break; + case CAM_REQ_MGR_UNLINK: { struct cam_req_mgr_unlink_info unlink_info; diff --git a/include/uapi/media/cam_req_mgr.h b/include/uapi/media/cam_req_mgr.h index b903078dccbd..9b9f97bd50d5 100644 --- a/include/uapi/media/cam_req_mgr.h +++ b/include/uapi/media/cam_req_mgr.h @@ -35,6 +35,7 @@ * It includes both session and device handles */ #define CAM_REQ_MGR_MAX_HANDLES 64 +#define CAM_REQ_MGR_MAX_HANDLES_V2 128 #define MAX_LINKS_PER_SESSION 2 /* V4L event type which user space will subscribe to */ @@ -121,6 +122,20 @@ struct cam_req_mgr_link_info { int32_t link_hdl; }; +struct cam_req_mgr_link_info_v2 { + int32_t session_hdl; + uint32_t num_devices; + int32_t dev_hdls[CAM_REQ_MGR_MAX_HANDLES_V2]; + int32_t link_hdl; +}; + +struct cam_req_mgr_ver_info { + uint32_t version; + union { + struct cam_req_mgr_link_info link_info_v1; + struct cam_req_mgr_link_info_v2 link_info_v2; + } u; +}; /** * struct cam_req_mgr_unlink_info * @session_hdl: input param - session handle @@ -230,6 +245,7 @@ struct cam_req_mgr_link_control { #define CAM_REQ_MGR_RELEASE_BUF (CAM_COMMON_OPCODE_MAX + 11) #define CAM_REQ_MGR_CACHE_OPS (CAM_COMMON_OPCODE_MAX + 12) #define CAM_REQ_MGR_LINK_CONTROL (CAM_COMMON_OPCODE_MAX + 13) +#define CAM_REQ_MGR_LINK_V2 (CAM_COMMON_OPCODE_MAX + 14) /* end of cam_req_mgr opcodes */ #define CAM_MEM_FLAG_HW_READ_WRITE (1<<0) -- GitLab From 10d45d06e60b8a743bf57f8896419da0763ee078 Mon Sep 17 00:00:00 2001 From: Diptanshu Jamgade Date: Fri, 24 May 2019 14:59:02 +0530 Subject: [PATCH 0447/1121] clk: qcom: Add HALT_DELAY for gpu_cc_cx_gfx3d_clk for SM6150 CBCR for gpu_cc_cx_ahb_clk does not toggle according to the clock on/off status. Hence, add HALT_DELAY to stop polling for clock_off bit. Also, update the parent of cx_gfx3d_clk from gpu_cc_gx_gfx3d_clk_src to gpu_cc_gx_gfx_clk as the RCG enable HW signal is tied to this clock. Change-Id: I75f447627e294b45e2316624729fb403850d2a3e Signed-off-by: Diptanshu Jamgade --- drivers/clk/qcom/gpucc-sm6150.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/qcom/gpucc-sm6150.c b/drivers/clk/qcom/gpucc-sm6150.c index 08b95c2c4720..aa6fd4f4fc49 100644 --- a/drivers/clk/qcom/gpucc-sm6150.c +++ b/drivers/clk/qcom/gpucc-sm6150.c @@ -296,14 +296,14 @@ static struct clk_branch gpu_cc_cx_apb_clk = { static struct clk_branch gpu_cc_cx_gfx3d_clk = { .halt_reg = 0x10a4, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_DELAY, .clkr = { .enable_reg = 0x10a4, .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gpu_cc_cx_gfx3d_clk", .parent_names = (const char *[]){ - "gpu_cc_gx_gfx3d_clk_src", + "gpu_cc_gx_gfx3d_clk", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, -- GitLab From 720fdba3ddd600ff43f47c5bcf10b7f35ec52392 Mon Sep 17 00:00:00 2001 From: Diptanshu Jamgade Date: Fri, 24 May 2019 15:49:14 +0530 Subject: [PATCH 0448/1121] clk: qcom: Update parent of gpu_cc_cx_gfx3d_clk for Trinket Update the parent of gpu_cc_cx_gfx3d_clk from gpu_cc_gx_gfx3d_clk_src to gpu_cc_gx_gfx_clk as the RCG enable HW signal is tied to this clock. Change-Id: Ie2c38c538942b03a6baf330f28f82668a81b710e Signed-off-by: Diptanshu Jamgade --- drivers/clk/qcom/gpucc-trinket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/qcom/gpucc-trinket.c b/drivers/clk/qcom/gpucc-trinket.c index 15f037af0344..e07d4a9e3f2b 100644 --- a/drivers/clk/qcom/gpucc-trinket.c +++ b/drivers/clk/qcom/gpucc-trinket.c @@ -259,7 +259,7 @@ static struct clk_branch gpu_cc_cx_gfx3d_clk = { .hw.init = &(struct clk_init_data){ .name = "gpu_cc_cx_gfx3d_clk", .parent_names = (const char *[]){ - "gpu_cc_gx_gfx3d_clk_src", + "gpu_cc_gx_gfx3d_clk", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, -- GitLab From 1cfaf527a42cab59e8c7a6715b01991ca8cc22c0 Mon Sep 17 00:00:00 2001 From: Jigarkumar Zala Date: Thu, 16 May 2019 01:56:43 -0700 Subject: [PATCH 0449/1121] msm: camera: cci: Add rd_done to handle read done operation Currently reset_complete and rd_done operation is flagged with same irq handler reset_complete. Sometime complete on reset_complete also been catched by wait for read done operation, which allows to perform wrong operations for read done. This sceneraio generates wrong operation which includes, rd_underflow/rd_done. This change adds rd_done attributes to differentiate the operation. Also, there is a race condition for cci device ref count, when multiple submodules try to do cci_init parallely, reference count will be out of sync. This change adds mutex for reference count as well as to be the ref_count in sync. This change also adds some irq error mask to identify errors for debuggind purpose. Change-Id: I52aec8246cf4d1beef41b195adfa468d7c5192d0 Signed-off-by: Jigarkumar Zala --- .../cam_sensor_module/cam_cci/cam_cci_core.c | 16 ++-- .../cam_sensor_module/cam_cci/cam_cci_dev.c | 58 ++++++++++----- .../cam_sensor_module/cam_cci/cam_cci_dev.h | 73 ++++++++++--------- .../cam_sensor_module/cam_cci/cam_cci_hwreg.h | 8 +- .../cam_sensor_module/cam_cci/cam_cci_soc.c | 12 ++- 5 files changed, 105 insertions(+), 62 deletions(-) diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c index ed88282737c0..a06a4c6c6339 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1094,7 +1094,7 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd, * RD_DONE exclusively. */ rem_jiffies = wait_for_completion_timeout( - &cci_dev->cci_master_info[master].reset_complete, + &cci_dev->cci_master_info[master].rd_done, CCI_TIMEOUT); if (!rem_jiffies) { rc = -ETIMEDOUT; @@ -1275,10 +1275,11 @@ static int32_t cam_cci_read(struct v4l2_subdev *sd, val = 1 << ((master * 2) + queue); cam_io_w_mb(val, base + CCI_QUEUE_START_ADDR); CAM_DBG(CAM_CCI, - "waiting_for_rd_done [exp_words: %d]", exp_words); + "waiting_for_rd_done [exp_words: %d]", + ((read_cfg->num_byte / 4) + 1)); rc = wait_for_completion_timeout( - &cci_dev->cci_master_info[master].reset_complete, CCI_TIMEOUT); + &cci_dev->cci_master_info[master].rd_done, CCI_TIMEOUT); if (rc <= 0) { #ifdef DUMP_CCI_REGISTERS cam_cci_dump_registers(cci_dev, master, queue); @@ -1692,14 +1693,19 @@ int32_t cam_cci_core_cfg(struct v4l2_subdev *sd, struct cam_cci_ctrl *cci_ctrl) { int32_t rc = 0; - + struct cci_device *cci_dev = v4l2_get_subdevdata(sd); CAM_DBG(CAM_CCI, "cmd %d", cci_ctrl->cmd); + switch (cci_ctrl->cmd) { case MSM_CCI_INIT: + mutex_lock(&cci_dev->init_mutex); rc = cam_cci_init(sd, cci_ctrl); + mutex_unlock(&cci_dev->init_mutex); break; case MSM_CCI_RELEASE: + mutex_lock(&cci_dev->init_mutex); rc = cam_cci_release(sd); + mutex_unlock(&cci_dev->init_mutex); break; case MSM_CCI_I2C_READ: rc = cam_cci_read_bytes(sd, cci_ctrl); diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.c index 6ac042c83604..69b5af002610 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -71,20 +71,26 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) irq_status0 = cam_io_r_mb(base + CCI_IRQ_STATUS_0_ADDR); irq_status1 = cam_io_r_mb(base + CCI_IRQ_STATUS_1_ADDR); + CAM_DBG(CAM_CCI, "BASE: %pK", base); CAM_DBG(CAM_CCI, "irq0:%x irq1:%x", irq_status0, irq_status1); if (irq_status0 & CCI_IRQ_STATUS_0_RST_DONE_ACK_BMSK) { + struct cam_cci_master_info *cci_master_info; if (cci_dev->cci_master_info[MASTER_0].reset_pending == TRUE) { + cci_master_info = &cci_dev->cci_master_info[MASTER_0]; cci_dev->cci_master_info[MASTER_0].reset_pending = FALSE; - complete( - &cci_dev->cci_master_info[MASTER_0].reset_complete); + if (!cci_master_info->status) + complete(&cci_master_info->reset_complete); + cci_master_info->status = 0; } if (cci_dev->cci_master_info[MASTER_1].reset_pending == TRUE) { + cci_master_info = &cci_dev->cci_master_info[MASTER_1]; cci_dev->cci_master_info[MASTER_1].reset_pending = FALSE; - complete( - &cci_dev->cci_master_info[MASTER_1].reset_complete); + if (!cci_master_info->status) + complete(&cci_master_info->reset_complete); + cci_master_info->status = 0; } } @@ -93,7 +99,7 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) cci_dev->cci_master_info[MASTER_0].status = 0; rd_done_th_assert = true; complete(&cci_dev->cci_master_info[MASTER_0].th_complete); - complete(&cci_dev->cci_master_info[MASTER_0].reset_complete); + complete(&cci_dev->cci_master_info[MASTER_0].rd_done); } if ((irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK) && (!rd_done_th_assert)) { @@ -102,7 +108,7 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) if (cci_dev->is_burst_read) complete( &cci_dev->cci_master_info[MASTER_0].th_complete); - complete(&cci_dev->cci_master_info[MASTER_0].reset_complete); + complete(&cci_dev->cci_master_info[MASTER_0].rd_done); } if ((irq_status1 & CCI_IRQ_STATUS_1_I2C_M0_RD_THRESHOLD) && (!rd_done_th_assert)) { @@ -149,7 +155,7 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) cci_dev->cci_master_info[MASTER_1].status = 0; rd_done_th_assert = true; complete(&cci_dev->cci_master_info[MASTER_1].th_complete); - complete(&cci_dev->cci_master_info[MASTER_1].reset_complete); + complete(&cci_dev->cci_master_info[MASTER_1].rd_done); } if ((irq_status0 & CCI_IRQ_STATUS_0_I2C_M1_RD_DONE_BMSK) && (!rd_done_th_assert)) { @@ -158,7 +164,7 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) if (cci_dev->is_burst_read) complete( &cci_dev->cci_master_info[MASTER_1].th_complete); - complete(&cci_dev->cci_master_info[MASTER_1].reset_complete); + complete(&cci_dev->cci_master_info[MASTER_1].rd_done); } if ((irq_status1 & CCI_IRQ_STATUS_1_I2C_M1_RD_THRESHOLD) && (!rd_done_th_assert)) { @@ -217,16 +223,33 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) } if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_ERROR_BMSK) { cci_dev->cci_master_info[MASTER_0].status = -EINVAL; - cam_io_w_mb(CCI_M0_HALT_REQ_RMSK, - base + CCI_HALT_REQ_ADDR); - CAM_DBG(CAM_CCI, "MASTER_0 error 0x%x", irq_status0); + if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_NACK_ERROR_BMSK) + CAM_ERR(CAM_CCI, "Base:%pK, M0 NACK ERROR: 0x%x", + base, irq_status0); + if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_ERROR_BMSK) + CAM_ERR(CAM_CCI, + "Base:%pK, M0 QUEUE_OVER/UNDER_FLOW OR CMD ERR: 0x%x", + base, irq_status0); + if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_RD_ERROR_BMSK) + CAM_ERR(CAM_CCI, + "Base: %pK, M0 RD_OVER/UNDER_FLOW ERROR: 0x%x", + base, irq_status0); + cam_io_w_mb(CCI_M0_HALT_REQ_RMSK, base + CCI_HALT_REQ_ADDR); } if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M1_ERROR_BMSK) { cci_dev->cci_master_info[MASTER_1].status = -EINVAL; - cam_io_w_mb(CCI_M1_HALT_REQ_RMSK, - base + CCI_HALT_REQ_ADDR); - CAM_DBG(CAM_CCI, "MASTER_1 error 0x%x", irq_status0); - + if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_NACK_ERROR_BMSK) + CAM_ERR(CAM_CCI, "Base:%pK, M1 NACK ERROR: 0x%x", + base, irq_status0); + if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_ERROR_BMSK) + CAM_ERR(CAM_CCI, + "Base:%pK, M1 QUEUE_OVER_UNDER_FLOW OR CMD ERROR:0x%x", + base, irq_status0); + if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_RD_ERROR_BMSK) + CAM_ERR(CAM_CCI, + "Base:%pK, M1 RD_OVER/UNDER_FLOW ERROR: 0x%x", + base, irq_status0); + cam_io_w_mb(CCI_M1_HALT_REQ_RMSK, base + CCI_HALT_REQ_ADDR); } cam_io_w_mb(irq_status0, base + CCI_IRQ_CLEAR_0_ADDR); @@ -402,7 +425,8 @@ static int cam_cci_platform_probe(struct platform_device *pdev) } g_cci_subdev[soc_info->index] = &new_cci_dev->v4l2_dev_str.sd; - CAM_ERR(CAM_CCI, "Device Type :%d", soc_info->index); + mutex_init(&(new_cci_dev->init_mutex)); + CAM_INFO(CAM_CCI, "Device Type :%d", soc_info->index); cam_register_subdev_fops(&cci_v4l2_subdev_fops); cci_v4l2_subdev_fops.unlocked_ioctl = cam_cci_subdev_fops_ioctl; diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.h index 83c935b52885..2e4c032cb322 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.h +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -140,6 +140,7 @@ struct cam_cci_master_info { uint8_t reset_pending; struct mutex mutex; struct completion reset_complete; + struct completion rd_done; struct completion th_complete; struct mutex mutex_q[NUM_QUEUES]; struct completion report_q[NUM_QUEUES]; @@ -172,40 +173,41 @@ enum cam_cci_state_t { /** * struct cci_device - * @pdev: Platform device - * @subdev: V4L2 sub device - * @base: Base address of CCI device - * @hw_version: Hardware version - * @ref_count: Reference Count - * @cci_state: CCI state machine - * @num_clk: Number of CCI clock - * @cci_clk: CCI clock structure - * @cci_clk_info: CCI clock information - * @cam_cci_i2c_queue_info: CCI queue information - * @i2c_freq_mode: I2C frequency of operations - * @cci_clk_params: CCI hw clk params - * @cci_gpio_tbl: CCI GPIO table - * @cci_gpio_tbl_size: GPIO table size - * @cci_pinctrl: Pinctrl structure - * @cci_pinctrl_status: CCI pinctrl status - * @cci_clk_src: CCI clk src rate - * @cci_vreg: CCI regulator structure - * @cci_reg_ptr: CCI individual regulator structure - * @regulator_count: Regulator count - * @support_seq_write: - * Set this flag when sequential write is enabled - * @write_wq: Work queue structure - * @valid_sync: Is it a valid sync with CSID - * @v4l2_dev_str: V4L2 device structure - * @cci_wait_sync_cfg: CCI sync config - * @cycles_per_us: Cycles per micro sec - * @payload_size: CCI packet payload size - * @irq_status1: Store irq_status1 to be cleared after - * draining FIFO buffer for burst read - * @lock_status: to protect changes to irq_status1 - * @is_burst_read: Flag to determine if we are performing - * a burst read operation or not - * @irqs_disabled: Mask for IRQs that are disabled + * @pdev: Platform device + * @subdev: V4L2 sub device + * @base: Base address of CCI device + * @hw_version: Hardware version + * @ref_count: Reference Count + * @cci_state: CCI state machine + * @num_clk: Number of CCI clock + * @cci_clk: CCI clock structure + * @cci_clk_info: CCI clock information + * @cam_cci_i2c_queue_info: CCI queue information + * @i2c_freq_mode: I2C frequency of operations + * @cci_clk_params: CCI hw clk params + * @cci_gpio_tbl: CCI GPIO table + * @cci_gpio_tbl_size: GPIO table size + * @cci_pinctrl: Pinctrl structure + * @cci_pinctrl_status: CCI pinctrl status + * @cci_clk_src: CCI clk src rate + * @cci_vreg: CCI regulator structure + * @cci_reg_ptr: CCI individual regulator structure + * @regulator_count: Regulator count + * @support_seq_write: Set this flag when sequential write is enabled + * @write_wq: Work queue structure + * @valid_sync: Is it a valid sync with CSID + * @v4l2_dev_str: V4L2 device structure + * @cci_wait_sync_cfg: CCI sync config + * @cycles_per_us: Cycles per micro sec + * @payload_size: CCI packet payload size + * @irq_status1: Store irq_status1 to be cleared after + * draining FIFO buffer for burst read + * @lock_status: to protect changes to irq_status1 + * @is_burst_read: Flag to determine if we are performing + * a burst read operation or not + * @irqs_disabled: Mask for IRQs that are disabled + * @init_mutex: Mutex for maintaining refcount for attached + * devices to cci during init/deinit. */ struct cci_device { struct v4l2_subdev subdev; @@ -234,6 +236,7 @@ struct cci_device { spinlock_t lock_status; bool is_burst_read; uint32_t irqs_disabled; + struct mutex init_mutex; }; enum cam_cci_i2c_cmd_type { diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_hwreg.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_hwreg.h index 027a0501dcae..ead18afc77ad 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_hwreg.h +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_hwreg.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2015, 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -61,6 +61,12 @@ #define CCI_IRQ_STATUS_0_I2C_M0_Q0_REPORT_BMSK 0x10 #define CCI_IRQ_STATUS_0_I2C_M0_ERROR_BMSK 0x18000EE6 #define CCI_IRQ_STATUS_0_I2C_M1_ERROR_BMSK 0x60EE6000 +#define CCI_IRQ_STATUS_0_I2C_M0_NACK_ERROR_BMSK 0x18000000 +#define CCI_IRQ_STATUS_0_I2C_M1_NACK_ERROR_BMSK 0x60000000 +#define CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_ERROR_BMSK 0xEE0 +#define CCI_IRQ_STATUS_0_I2C_M1_Q0Q1_ERROR_BMSK 0xEE0000 +#define CCI_IRQ_STATUS_0_I2C_M0_RD_ERROR_BMSK 0x6 +#define CCI_IRQ_STATUS_0_I2C_M1_RD_ERROR_BMSK 0x6000 #define CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK 0x1 #define CCI_IRQ_STATUS_1_I2C_M0_RD_THRESHOLD 0x10000 #define CCI_IRQ_STATUS_1_I2C_M0_RD_PAUSE 0x20000 diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_soc.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_soc.c index fa290c0b982c..0181a4d8e2ff 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_soc.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_soc.c @@ -19,7 +19,7 @@ int cam_cci_init(struct v4l2_subdev *sd, uint8_t i = 0, j = 0; int32_t rc = 0; struct cci_device *cci_dev; - enum cci_i2c_master_t master = MASTER_0; + enum cci_i2c_master_t master = c_ctrl->cci_info->cci_i2c_master; struct cam_ahb_vote ahb_vote; struct cam_axi_vote axi_vote; struct cam_hw_soc_info *soc_info = NULL; @@ -47,7 +47,6 @@ int cam_cci_init(struct v4l2_subdev *sd, if (cci_dev->ref_count++) { CAM_DBG(CAM_CCI, "ref_count %d", cci_dev->ref_count); - master = c_ctrl->cci_info->cci_i2c_master; CAM_DBG(CAM_CCI, "master %d", master); if (master < MASTER_MAX && master >= 0) { mutex_lock(&cci_dev->cci_master_info[master].mutex); @@ -55,6 +54,8 @@ int cam_cci_init(struct v4l2_subdev *sd, /* Re-initialize the completion */ reinit_completion( &cci_dev->cci_master_info[master].reset_complete); + reinit_completion( + &cci_dev->cci_master_info[master].rd_done); for (i = 0; i < NUM_QUEUES; i++) reinit_completion( &cci_dev->cci_master_info[master].report_q[i]); @@ -93,6 +94,7 @@ int cam_cci_init(struct v4l2_subdev *sd, /* Re-initialize the completion */ reinit_completion(&cci_dev->cci_master_info[master].reset_complete); + reinit_completion(&cci_dev->cci_master_info[master].rd_done); for (i = 0; i < NUM_QUEUES; i++) reinit_completion( &cci_dev->cci_master_info[master].report_q[i]); @@ -128,12 +130,12 @@ int cam_cci_init(struct v4l2_subdev *sd, } } - cci_dev->cci_master_info[MASTER_0].reset_pending = TRUE; + cci_dev->cci_master_info[master].reset_pending = TRUE; cam_io_w_mb(CCI_RESET_CMD_RMSK, base + CCI_RESET_CMD_ADDR); cam_io_w_mb(0x1, base + CCI_RESET_CMD_ADDR); rc = wait_for_completion_timeout( - &cci_dev->cci_master_info[MASTER_0].reset_complete, + &cci_dev->cci_master_info[master].reset_complete, CCI_TIMEOUT); if (rc <= 0) { CAM_ERR(CAM_CCI, "wait_for_completion_timeout"); @@ -205,6 +207,8 @@ static void cam_cci_init_cci_params(struct cci_device *new_cci_dev) &new_cci_dev->cci_master_info[i].reset_complete); init_completion( &new_cci_dev->cci_master_info[i].th_complete); + init_completion( + &new_cci_dev->cci_master_info[i].rd_done); for (j = 0; j < NUM_QUEUES; j++) { mutex_init(&new_cci_dev->cci_master_info[i].mutex_q[j]); -- GitLab From afe0cb8ced985dc7e7dd0fc3c17792f906eaaa98 Mon Sep 17 00:00:00 2001 From: Narender Ankam Date: Thu, 18 Apr 2019 14:27:11 +0530 Subject: [PATCH 0450/1121] ARM: msm: dts: disable USB Type-C analog audio switch for QCS610 As there is no DP support, disable USB Type-C analog audio switch for QCS610 IOT target. Change-Id: Iea1205ce97107ae9ceec9d62eb7d4b27510aeeb5 Signed-off-by: Narender Ankam --- arch/arm64/boot/dts/qcom/qcs610-iot.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/qcs610-iot.dtsi b/arch/arm64/boot/dts/qcom/qcs610-iot.dtsi index 4b1df9e53cb9..2db2d687671d 100644 --- a/arch/arm64/boot/dts/qcom/qcs610-iot.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs610-iot.dtsi @@ -28,6 +28,10 @@ #include "smb1390.dtsi" }; +&fsa4480 { + status = "disabled"; +}; + &pm6150l_gpios { key_vol_up { key_vol_up_default: key_vol_up_default { -- GitLab From 6f58caae21910a0700592a9acf12d7f6dda2e7bc Mon Sep 17 00:00:00 2001 From: Maria Yu Date: Wed, 29 May 2019 12:30:47 +0800 Subject: [PATCH 0451/1121] sched: fair: Add strict skip buddy support Skip buddy i.e task called yield() is always skipped and the next entity is selected to run irrespective of the unfairness. Change-Id: Ia9b9fbe46917152b58dc6406c718eb1cfb3b0fb2 Signed-off-by: Maria Yu --- kernel/sched/fair.c | 3 ++- kernel/sched/features.h | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 9c68ee82be70..ec7fc2a74918 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -4247,7 +4247,8 @@ pick_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *curr) second = curr; } - if (second && wakeup_preempt_entity(second, left) < 1) + if (second && (sched_feat(STRICT_SKIP_BUDDY) || + wakeup_preempt_entity(second, left) < 1)) se = second; } diff --git a/kernel/sched/features.h b/kernel/sched/features.h index 68c92b6709e9..96636034bb2a 100644 --- a/kernel/sched/features.h +++ b/kernel/sched/features.h @@ -26,6 +26,12 @@ SCHED_FEAT(NEXT_BUDDY, false) */ SCHED_FEAT(LAST_BUDDY, true) +/* + * skip buddy i.e task called yield() is always skipped and the + * next entity is selected to run irrespective of the vruntime + */ +SCHED_FEAT(STRICT_SKIP_BUDDY, true) + /* * Consider buddies to be cache hot, decreases the likelyness of a * cache buddy being migrated away, increases cache locality. -- GitLab From 0f64100456af12a5b90ae21d0f93fe1159fe94ce Mon Sep 17 00:00:00 2001 From: Sujeev Dias Date: Fri, 15 Feb 2019 17:18:18 -0800 Subject: [PATCH 0452/1121] mhi: core: allow clients to independently disable bus or device lpm Provide clients ability disable low power modes for link and/or external modem low power modes. CRs-Fixed: 2418347 Change-Id: I45ad7f43c6bea75ff65f883f9ccda9a0c11fa2aa Signed-off-by: Sujeev Dias --- drivers/bus/mhi/core/mhi_init.c | 108 ++++++++++++++++-- drivers/bus/mhi/core/mhi_internal.h | 2 + drivers/bus/mhi/core/mhi_pm.c | 88 +++++++++++--- drivers/bus/mhi/devices/mhi_netdev.c | 4 +- .../platform/msm/ipa/ipa_v3/ipa_mhi_proxy.c | 6 +- drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c | 4 +- include/linux/mhi.h | 23 ++-- 7 files changed, 195 insertions(+), 40 deletions(-) diff --git a/drivers/bus/mhi/core/mhi_init.c b/drivers/bus/mhi/core/mhi_init.c index 98464b3165db..89c1b1de57e9 100644 --- a/drivers/bus/mhi/core/mhi_init.c +++ b/drivers/bus/mhi/core/mhi_init.c @@ -79,6 +79,95 @@ const char *to_mhi_pm_state_str(enum MHI_PM_STATE state) return mhi_pm_state_str[index]; } +static ssize_t bus_vote_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct mhi_device *mhi_dev = to_mhi_device(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", + atomic_read(&mhi_dev->bus_vote)); +} + +static ssize_t bus_vote_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct mhi_device *mhi_dev = to_mhi_device(dev); + int ret = -EINVAL; + + if (sysfs_streq(buf, "get")) { + ret = mhi_device_get_sync(mhi_dev, MHI_VOTE_BUS); + } else if (sysfs_streq(buf, "put")) { + mhi_device_put(mhi_dev, MHI_VOTE_BUS); + ret = 0; + } + + return ret ? ret : count; +} +static DEVICE_ATTR_RW(bus_vote); + +static ssize_t device_vote_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct mhi_device *mhi_dev = to_mhi_device(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", + atomic_read(&mhi_dev->dev_vote)); +} + +static ssize_t device_vote_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct mhi_device *mhi_dev = to_mhi_device(dev); + int ret = -EINVAL; + + if (sysfs_streq(buf, "get")) { + ret = mhi_device_get_sync(mhi_dev, MHI_VOTE_DEVICE); + } else if (sysfs_streq(buf, "put")) { + mhi_device_put(mhi_dev, MHI_VOTE_DEVICE); + ret = 0; + } + + return ret ? ret : count; +} +static DEVICE_ATTR_RW(device_vote); + +static struct attribute *mhi_vote_attrs[] = { + &dev_attr_bus_vote.attr, + &dev_attr_device_vote.attr, + NULL, +}; + +static const struct attribute_group mhi_vote_group = { + .attrs = mhi_vote_attrs, +}; + +int mhi_create_vote_sysfs(struct mhi_controller *mhi_cntrl) +{ + return sysfs_create_group(&mhi_cntrl->mhi_dev->dev.kobj, + &mhi_vote_group); +} + +void mhi_destroy_vote_sysfs(struct mhi_controller *mhi_cntrl) +{ + struct mhi_device *mhi_dev = mhi_cntrl->mhi_dev; + + sysfs_remove_group(&mhi_dev->dev.kobj, &mhi_vote_group); + + /* relinquish any pending votes for device */ + while (atomic_read(&mhi_dev->dev_vote)) + mhi_device_put(mhi_dev, MHI_VOTE_DEVICE); + + /* remove pending votes for the bus */ + while (atomic_read(&mhi_dev->bus_vote)) + mhi_device_put(mhi_dev, MHI_VOTE_BUS); +} + /* MHI protocol require transfer ring to be aligned to ring length */ static int mhi_alloc_aligned_ring(struct mhi_controller *mhi_cntrl, struct mhi_ring *ring, @@ -1400,7 +1489,7 @@ static int mhi_driver_probe(struct device *dev) int ret; /* bring device out of lpm */ - ret = mhi_device_get_sync(mhi_dev); + ret = mhi_device_get_sync(mhi_dev, MHI_VOTE_DEVICE); if (ret) return ret; @@ -1448,7 +1537,7 @@ static int mhi_driver_probe(struct device *dev) mhi_prepare_for_transfer(mhi_dev); exit_probe: - mhi_device_put(mhi_dev); + mhi_device_put(mhi_dev, MHI_VOTE_DEVICE); return ret; } @@ -1523,11 +1612,13 @@ static int mhi_driver_remove(struct device *dev) if (mhi_cntrl->tsync_dev == mhi_dev) mhi_cntrl->tsync_dev = NULL; - /* relinquish any pending votes */ - read_lock_bh(&mhi_cntrl->pm_lock); - while (atomic_read(&mhi_dev->dev_wake)) - mhi_device_put(mhi_dev); - read_unlock_bh(&mhi_cntrl->pm_lock); + /* relinquish any pending votes for device */ + while (atomic_read(&mhi_dev->dev_vote)) + mhi_device_put(mhi_dev, MHI_VOTE_DEVICE); + + /* remove pending votes for the bus */ + while (atomic_read(&mhi_dev->bus_vote)) + mhi_device_put(mhi_dev, MHI_VOTE_BUS); return 0; } @@ -1571,7 +1662,8 @@ struct mhi_device *mhi_alloc_device(struct mhi_controller *mhi_cntrl) mhi_dev->bus = mhi_cntrl->bus; mhi_dev->slot = mhi_cntrl->slot; mhi_dev->mtu = MHI_MAX_MTU; - atomic_set(&mhi_dev->dev_wake, 0); + atomic_set(&mhi_dev->dev_vote, 0); + atomic_set(&mhi_dev->bus_vote, 0); return mhi_dev; } diff --git a/drivers/bus/mhi/core/mhi_internal.h b/drivers/bus/mhi/core/mhi_internal.h index 5da0feab0eab..b0a30bea682f 100644 --- a/drivers/bus/mhi/core/mhi_internal.h +++ b/drivers/bus/mhi/core/mhi_internal.h @@ -753,6 +753,8 @@ int mhi_get_capability_offset(struct mhi_controller *mhi_cntrl, u32 capability, int mhi_init_timesync(struct mhi_controller *mhi_cntrl); int mhi_create_timesync_sysfs(struct mhi_controller *mhi_cntrl); void mhi_destroy_timesync(struct mhi_controller *mhi_cntrl); +int mhi_create_vote_sysfs(struct mhi_controller *mhi_cntrl); +void mhi_destroy_vote_sysfs(struct mhi_controller *mhi_cntrl); /* memory allocation methods */ static inline void *mhi_alloc_coherent(struct mhi_controller *mhi_cntrl, diff --git a/drivers/bus/mhi/core/mhi_pm.c b/drivers/bus/mhi/core/mhi_pm.c index b7b56f35f41e..4bf440efe1bd 100644 --- a/drivers/bus/mhi/core/mhi_pm.c +++ b/drivers/bus/mhi/core/mhi_pm.c @@ -492,6 +492,9 @@ static int mhi_pm_mission_mode_transition(struct mhi_controller *mhi_cntrl) /* add supported devices */ mhi_create_devices(mhi_cntrl); + /* setup sysfs nodes for userspace votes */ + mhi_create_vote_sysfs(mhi_cntrl); + ret = 0; read_lock_bh(&mhi_cntrl->pm_lock); @@ -590,6 +593,9 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl, MHI_LOG("Finish resetting channels\n"); + /* remove support for userspace votes */ + mhi_destroy_vote_sysfs(mhi_cntrl); + MHI_LOG("Waiting for all pending threads to complete\n"); wake_up_all(&mhi_cntrl->state_event); flush_work(&mhi_cntrl->st_worker); @@ -925,6 +931,7 @@ int mhi_pm_suspend(struct mhi_controller *mhi_cntrl) int ret; enum MHI_PM_STATE new_state; struct mhi_chan *itr, *tmp; + struct mhi_device *mhi_dev = mhi_cntrl->mhi_dev; if (mhi_cntrl->pm_state == MHI_PM_DISABLE) return -EINVAL; @@ -932,9 +939,10 @@ int mhi_pm_suspend(struct mhi_controller *mhi_cntrl) if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) return -EIO; - /* do a quick check to see if any pending data, then exit */ + /* do a quick check to see if any pending votes to keep us busy */ if (atomic_read(&mhi_cntrl->dev_wake) || - atomic_read(&mhi_cntrl->pending_pkts)) { + atomic_read(&mhi_cntrl->pending_pkts) || + atomic_read(&mhi_dev->bus_vote)) { MHI_VERB("Busy, aborting M3\n"); return -EBUSY; } @@ -961,9 +969,13 @@ int mhi_pm_suspend(struct mhi_controller *mhi_cntrl) write_lock_irq(&mhi_cntrl->pm_lock); - /* we're asserting wake so count would be @ least 1 */ + /* + * Check the votes once more to see if we should abort + * suepend. We're asserting wake so count would be @ least 1 + */ if (atomic_read(&mhi_cntrl->dev_wake) > 1 || - atomic_read(&mhi_cntrl->pending_pkts)) { + atomic_read(&mhi_cntrl->pending_pkts) || + atomic_read(&mhi_dev->bus_vote)) { MHI_VERB("Busy, aborting M3\n"); write_unlock_irq(&mhi_cntrl->pm_lock); ret = -EBUSY; @@ -1117,38 +1129,78 @@ int __mhi_device_get_sync(struct mhi_controller *mhi_cntrl) return 0; } -void mhi_device_get(struct mhi_device *mhi_dev) +void mhi_device_get(struct mhi_device *mhi_dev, int vote) { struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; - atomic_inc(&mhi_dev->dev_wake); - read_lock_bh(&mhi_cntrl->pm_lock); - mhi_cntrl->wake_get(mhi_cntrl, true); - read_unlock_bh(&mhi_cntrl->pm_lock); + if (vote & MHI_VOTE_DEVICE) { + read_lock_bh(&mhi_cntrl->pm_lock); + mhi_cntrl->wake_get(mhi_cntrl, true); + read_unlock_bh(&mhi_cntrl->pm_lock); + atomic_inc(&mhi_dev->dev_vote); + } + + if (vote & MHI_VOTE_BUS) { + mhi_cntrl->runtime_get(mhi_cntrl, mhi_cntrl->priv_data); + atomic_inc(&mhi_dev->bus_vote); + } } EXPORT_SYMBOL(mhi_device_get); -int mhi_device_get_sync(struct mhi_device *mhi_dev) +int mhi_device_get_sync(struct mhi_device *mhi_dev, int vote) { struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; int ret; + /* + * regardless of any vote we will bring device out lpm and assert + * device wake + */ ret = __mhi_device_get_sync(mhi_cntrl); - if (!ret) - atomic_inc(&mhi_dev->dev_wake); + if (ret) + return ret; - return ret; + if (vote & MHI_VOTE_DEVICE) { + atomic_inc(&mhi_dev->dev_vote); + } else { + /* client did not requested device vote so de-assert dev_wake */ + read_lock_bh(&mhi_cntrl->pm_lock); + mhi_cntrl->wake_put(mhi_cntrl, false); + read_unlock_bh(&mhi_cntrl->pm_lock); + } + + if (vote & MHI_VOTE_BUS) { + mhi_cntrl->runtime_get(mhi_cntrl, mhi_cntrl->priv_data); + atomic_inc(&mhi_dev->bus_vote); + } + + return 0; } EXPORT_SYMBOL(mhi_device_get_sync); -void mhi_device_put(struct mhi_device *mhi_dev) +void mhi_device_put(struct mhi_device *mhi_dev, int vote) { struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; - atomic_dec(&mhi_dev->dev_wake); - read_lock_bh(&mhi_cntrl->pm_lock); - mhi_cntrl->wake_put(mhi_cntrl, false); - read_unlock_bh(&mhi_cntrl->pm_lock); + if (vote & MHI_VOTE_DEVICE) { + atomic_dec(&mhi_dev->dev_vote); + read_lock_bh(&mhi_cntrl->pm_lock); + mhi_cntrl->wake_put(mhi_cntrl, false); + read_unlock_bh(&mhi_cntrl->pm_lock); + } + + if (vote & MHI_VOTE_BUS) { + atomic_dec(&mhi_dev->bus_vote); + mhi_cntrl->runtime_put(mhi_cntrl, mhi_cntrl->priv_data); + + /* + * if counts reach 0, clients release all votes + * send idle cb to to attempt suspend + */ + if (!atomic_read(&mhi_dev->bus_vote)) + mhi_cntrl->status_cb(mhi_cntrl, mhi_cntrl->priv_data, + MHI_CB_IDLE); + } } EXPORT_SYMBOL(mhi_device_put); diff --git a/drivers/bus/mhi/devices/mhi_netdev.c b/drivers/bus/mhi/devices/mhi_netdev.c index 485d9d430860..d32a5f482f36 100644 --- a/drivers/bus/mhi/devices/mhi_netdev.c +++ b/drivers/bus/mhi/devices/mhi_netdev.c @@ -465,12 +465,12 @@ static int mhi_netdev_ioctl_extended(struct net_device *dev, struct ifreq *ifr) /* Request to enable LPM */ MSG_VERB("Enable MHI LPM"); mhi_netdev->wake--; - mhi_device_put(mhi_dev); + mhi_device_put(mhi_dev, MHI_VOTE_DEVICE); } else if (!ext_cmd.u.data && !mhi_netdev->wake) { /* Request to disable LPM */ MSG_VERB("Disable MHI LPM"); mhi_netdev->wake++; - mhi_device_get(mhi_dev); + mhi_device_get(mhi_dev, MHI_VOTE_DEVICE); } break; default: diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_mhi_proxy.c b/drivers/platform/msm/ipa/ipa_v3/ipa_mhi_proxy.c index 0b46190e35f3..a2f38e5a56c7 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_mhi_proxy.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_mhi_proxy.c @@ -655,7 +655,7 @@ struct ipa_mhi_clk_vote_resp_msg_v01 * executed from mhi context. */ if (vote) { - ret = mhi_device_get_sync(imp_ctx->md.mhi_dev); + ret = mhi_device_get_sync(imp_ctx->md.mhi_dev, MHI_VOTE_BUS); if (ret) { IMP_ERR("mhi_sync_get failed %d\n", ret); resp->resp.result = IPA_QMI_RESULT_FAILURE_V01; @@ -669,7 +669,7 @@ struct ipa_mhi_clk_vote_resp_msg_v01 return resp; } } else { - mhi_device_put(imp_ctx->md.mhi_dev); + mhi_device_put(imp_ctx->md.mhi_dev, MHI_VOTE_BUS); } mutex_lock(&imp_ctx->mutex); @@ -729,7 +729,7 @@ static void imp_mhi_shutdown(void) false); } if (imp_ctx->lpm_disabled) { - mhi_device_put(imp_ctx->md.mhi_dev); + mhi_device_put(imp_ctx->md.mhi_dev, MHI_VOTE_BUS); imp_ctx->lpm_disabled = false; } diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c b/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c index f9e79b6ddeff..38454745f276 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c @@ -1327,7 +1327,7 @@ static int ipa_mpm_vote_unvote_pcie_clk(enum ipa_mpm_clk_vote_type vote, if (vote == CLK_ON) { result = mhi_device_get_sync( - ipa_mpm_ctx->md[probe_id].mhi_dev); + ipa_mpm_ctx->md[probe_id].mhi_dev, MHI_VOTE_BUS); if (result) { IPA_MPM_ERR("mhi_sync_get failed for probe_id %d\n", result, probe_id); @@ -1345,7 +1345,7 @@ static int ipa_mpm_vote_unvote_pcie_clk(enum ipa_mpm_clk_vote_type vote, probe_id); ipa_assert(); } - mhi_device_put(ipa_mpm_ctx->md[probe_id].mhi_dev); + mhi_device_put(ipa_mpm_ctx->md[probe_id].mhi_dev, MHI_VOTE_BUS); IPA_MPM_DBG("probe_id %d PCIE clock off\n", probe_id); atomic_dec(&ipa_mpm_ctx->md[probe_id].clk_cnt.pcie_clk_cnt); atomic_dec(&ipa_mpm_ctx->pcie_clk_total_cnt); diff --git a/include/linux/mhi.h b/include/linux/mhi.h index 240653216dcd..0c2bf340ce14 100644 --- a/include/linux/mhi.h +++ b/include/linux/mhi.h @@ -114,6 +114,9 @@ enum mhi_dev_state { MHI_STATE_MAX, }; +#define MHI_VOTE_BUS BIT(0) /* do not disable the bus */ +#define MHI_VOTE_DEVICE BIT(1) /* prevent mhi device from entering lpm */ + /** * struct image_info - firmware and rddm table table * @mhi_buf - Contain device firmware and rddm table @@ -309,6 +312,8 @@ struct mhi_controller { * @ul_chan_id: MHI channel id for UL transfer * @dl_chan_id: MHI channel id for DL transfer * @tiocm: Device current terminal settings + * @dev_vote: Keep external device in active state + * @bus_vote: Keep physical bus (pci, spi) in active state * @priv: Driver private data */ struct mhi_device { @@ -328,7 +333,8 @@ struct mhi_device { struct mhi_controller *mhi_cntrl; struct mhi_chan *ul_chan; struct mhi_chan *dl_chan; - atomic_t dev_wake; + atomic_t dev_vote; + atomic_t bus_vote; enum mhi_device_type dev_type; void *priv_data; int (*ul_xfer)(struct mhi_device *, struct mhi_chan *, void *, @@ -467,26 +473,29 @@ int mhi_device_configure(struct mhi_device *mhi_div, int elements); /** - * mhi_device_get - disable all low power modes + * mhi_device_get - disable low power modes * Only disables lpm, does not immediately exit low power mode * if controller already in a low power mode * @mhi_dev: Device associated with the channels + * @vote: requested vote (bus, device or both) */ -void mhi_device_get(struct mhi_device *mhi_dev); +void mhi_device_get(struct mhi_device *mhi_dev, int vote); /** - * mhi_device_get_sync - disable all low power modes - * Synchronously disable all low power, exit low power mode if + * mhi_device_get_sync - disable low power modes + * Synchronously disable device & or bus low power, exit low power mode if * controller already in a low power state * @mhi_dev: Device associated with the channels + * @vote: requested vote (bus, device or both) */ -int mhi_device_get_sync(struct mhi_device *mhi_dev); +int mhi_device_get_sync(struct mhi_device *mhi_dev, int vote); /** * mhi_device_put - re-enable low power modes * @mhi_dev: Device associated with the channels + * @vote: vote to remove */ -void mhi_device_put(struct mhi_device *mhi_dev); +void mhi_device_put(struct mhi_device *mhi_dev, int vote); /** * mhi_prepare_for_transfer - setup channel for data transfer -- GitLab From f591118b1ccce2740480cda88d74f0f91305ae0b Mon Sep 17 00:00:00 2001 From: Prakasha Nayak Date: Mon, 20 May 2019 13:47:48 +0530 Subject: [PATCH 0453/1121] msm: camera: cpas: Check the HW state before accessing register Check the hardware state before accessing registers and add mutex lock to prevent unclocked access Change-Id: I624614ea3b469c354dfbdc9ab6110c34664592b4 Signed-off-by: Prakasha Nayak --- .../msm/camera/cam_cpas/cpas_top/cam_cpastop_hw.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/msm/camera/cam_cpas/cpas_top/cam_cpastop_hw.c b/drivers/media/platform/msm/camera/cam_cpas/cpas_top/cam_cpastop_hw.c index aa970f83424d..a21803ee5945 100644 --- a/drivers/media/platform/msm/camera/cam_cpas/cpas_top/cam_cpastop_hw.c +++ b/drivers/media/platform/msm/camera/cam_cpas/cpas_top/cam_cpastop_hw.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -406,6 +406,12 @@ static void cam_cpastop_work(struct work_struct *work) return; } + mutex_lock(&cpas_hw->hw_mutex); + if (cpas_hw->hw_state == CAM_HW_STATE_POWER_DOWN) { + CAM_ERR(CAM_CPAS, "CPAS CORE is off"); + mutex_unlock(&cpas_hw->hw_mutex); + return; + } for (i = 0; i < camnoc_info->irq_err_size; i++) { if ((payload->irq_status & camnoc_info->irq_err[i].sbm_port) && (camnoc_info->irq_err[i].enable)) { @@ -451,6 +457,7 @@ static void cam_cpastop_work(struct work_struct *work) ~camnoc_info->irq_err[i].sbm_port; } } + mutex_unlock(&cpas_hw->hw_mutex); atomic_dec(&cpas_core->irq_count); wake_up(&cpas_core->irq_count_wq); CAM_DBG(CAM_CPAS, "irq_count=%d\n", atomic_read(&cpas_core->irq_count)); -- GitLab From de0cfd8614397ca13806e69145f956014aa0b151 Mon Sep 17 00:00:00 2001 From: Alok Pandey Date: Mon, 3 Jun 2019 10:32:06 +0530 Subject: [PATCH 0454/1121] msm: camera: mem: print error value In case of map IOCTL failure, print error number and fd. Change-Id: Iab6088a0461d7c12694e31e5d03ba61d10ace80a Signed-off-by: Alok Pandey --- drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr.c index 53de02a3a20f..dfdabd96703a 100644 --- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr.c +++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr.c @@ -779,7 +779,8 @@ int cam_mem_mgr_map(struct cam_mem_mgr_map_cmd *cmd) dmabuf = dma_buf_get(cmd->fd); if (IS_ERR_OR_NULL((void *)(dmabuf))) { - CAM_ERR(CAM_MEM, "Failed to import dma_buf fd"); + CAM_ERR(CAM_MEM, "Failed to import dma_buf fd %d, rc %d", + cmd->fd, (IS_ERR(dmabuf) ? PTR_ERR(dmabuf) : 0)); return -EINVAL; } -- GitLab From 1824ac8ea80fc5f10941b99975340e0973c071d7 Mon Sep 17 00:00:00 2001 From: Gaurav Jindal Date: Thu, 9 May 2019 15:06:09 +0530 Subject: [PATCH 0455/1121] msm: camera: mem: Mutex before cpu_begin_access & cpu_end_access In corner cases, a possibility lies that ion buffer is getting freed and simultaneously cpu_begin_access or cpu_end_access is called on another cpu. If the buffer gets freed before dereferencing, device will crash. It protects the tbl.bufq[idx] with tbl.bufq[idx].q_lock. This will prevent the parallel access of the same buffer. Change-Id: I9e04486b5ee815b0880ccc704065182811db59cc Signed-off-by: Gaurav Jindal --- .../msm/camera/cam_req_mgr/cam_mem_mgr.c | 63 +++++++++++++------ 1 file changed, 45 insertions(+), 18 deletions(-) diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr.c index 53de02a3a20f..3ffa9e8a2951 100644 --- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr.c +++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr.c @@ -251,33 +251,50 @@ int cam_mem_get_cpu_buf(int32_t buf_handle, uintptr_t *vaddr_ptr, size_t *len) if (idx >= CAM_MEM_BUFQ_MAX || idx <= 0) return -EINVAL; - if (!tbl.bufq[idx].active) - return -EPERM; + mutex_lock(&tbl.bufq[idx].q_lock); + if (!tbl.bufq[idx].active) { + CAM_ERR(CAM_MEM, "idx: %d not active", idx); + rc = -EPERM; + goto end; + } - if (buf_handle != tbl.bufq[idx].buf_handle) - return -EINVAL; + if (buf_handle != tbl.bufq[idx].buf_handle) { + CAM_ERR(CAM_MEM, "idx: %d Invalid buf handle %d", + idx, buf_handle); + rc = -EINVAL; + goto end; + } - if (!(tbl.bufq[idx].flags & CAM_MEM_FLAG_KMD_ACCESS)) - return -EINVAL; + if (!(tbl.bufq[idx].flags & CAM_MEM_FLAG_KMD_ACCESS)) { + CAM_ERR(CAM_MEM, "idx: %d Invalid flag 0x%x", + idx, tbl.bufq[idx].flags); + rc = -EINVAL; + goto end; + } if (tbl.bufq[idx].kmdvaddr) { dmabuf = tbl.bufq[idx].dma_buf; if (!dmabuf) { CAM_ERR(CAM_MEM, "Invalid DMA buffer pointer"); - return -EINVAL; + rc = -EINVAL; + goto end; } rc = dma_buf_begin_cpu_access(dmabuf, DMA_BIDIRECTIONAL); if (rc) { CAM_ERR(CAM_MEM, "dma begin access failed rc=%d", rc); - return rc; + goto end; } } else { - return -EINVAL; + CAM_ERR(CAM_MEM, "Invalid kmdvaddr"); + rc = -EINVAL; + goto end; } *vaddr_ptr = tbl.bufq[idx].kmdvaddr; *len = tbl.bufq[idx].len; +end: + mutex_unlock(&tbl.bufq[idx].q_lock); return rc; } EXPORT_SYMBOL(cam_mem_get_cpu_buf); @@ -300,30 +317,38 @@ int cam_mem_put_cpu_buf(int32_t buf_handle) if (idx >= CAM_MEM_BUFQ_MAX || idx <= 0) return -EINVAL; - if (!tbl.bufq[idx].active) - return -EPERM; + mutex_lock(&tbl.bufq[idx].q_lock); + if (!tbl.bufq[idx].active) { + CAM_ERR(CAM_MEM, "idx: %d not active", idx); + rc = -EPERM; + goto end; + } - if (buf_handle != tbl.bufq[idx].buf_handle) - return -EINVAL; + if (buf_handle != tbl.bufq[idx].buf_handle) { + CAM_ERR(CAM_MEM, "idx: %d Invalid buf handle %d", + idx, buf_handle); + rc = -EINVAL; + goto end; + } dmabuf = tbl.bufq[idx].dma_buf; if (!dmabuf) { CAM_ERR(CAM_CRM, "Invalid DMA buffer pointer"); - return -EINVAL; + rc = -EINVAL; + goto end; } if ((tbl.bufq[idx].flags & CAM_MEM_FLAG_KMD_ACCESS) && (tbl.bufq[idx].kmdvaddr)) { rc = dma_buf_end_cpu_access(dmabuf, DMA_BIDIRECTIONAL); - if (rc) { + if (rc) CAM_ERR(CAM_MEM, "dma begin access failed rc=%d", rc); - return rc; - } } else { CAM_ERR(CAM_MEM, "Invalid buf flag"); rc = -EINVAL; } - +end: + mutex_unlock(&tbl.bufq[idx].q_lock); return rc; } EXPORT_SYMBOL(cam_mem_put_cpu_buf); @@ -953,6 +978,7 @@ static int cam_mem_mgr_cleanup_table(void) tbl.bufq[i].num_hdl = 0; tbl.bufq[i].dma_buf = NULL; tbl.bufq[i].active = false; + tbl.bufq[i].kmdvaddr = 0; mutex_unlock(&tbl.bufq[i].q_lock); mutex_destroy(&tbl.bufq[i].q_lock); } @@ -1051,6 +1077,7 @@ static int cam_mem_util_unmap(int32_t idx, tbl.bufq[idx].len = 0; tbl.bufq[idx].num_hdl = 0; tbl.bufq[idx].active = false; + tbl.bufq[idx].kmdvaddr = 0; mutex_unlock(&tbl.bufq[idx].q_lock); mutex_destroy(&tbl.bufq[idx].q_lock); clear_bit(idx, tbl.bitmap); -- GitLab From 5fcc58b1bd545deb6801887de02d6fd34aa37bb7 Mon Sep 17 00:00:00 2001 From: Prakasha Nayak Date: Wed, 29 May 2019 16:00:45 +0530 Subject: [PATCH 0456/1121] msm: camera: icp: Prevent out of bound access in acquire In ICP during acquire, no of output resource can change from usespace. Change in no of output resource after the memory allocation may result in out of bound access. This can be avoided by checking value of no of output resource during the allocation to the value copied from userspace after allocation. Change-Id: Ife0a96bd61fad0ad0481af01734fc4cff68baf5a Signed-off-by: Prakasha Nayak --- .../msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c index 6383b80efdd4..51422dac5725 100644 --- a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c +++ b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c @@ -4690,6 +4690,13 @@ static int cam_icp_get_acquire_info(struct cam_icp_hw_mgr *hw_mgr, return -EFAULT; } + /* To make sure num_out_res is same as allocated */ + if (ctx_data->icp_dev_acquire_info->num_out_res != + icp_dev_acquire_info.num_out_res) { + CAM_ERR(CAM_ICP, "num_out_res got changed"); + return -EFAULT; + } + CAM_DBG(CAM_ICP, "%x %x %x %x %x %x %x", ctx_data->icp_dev_acquire_info->dev_type, ctx_data->icp_dev_acquire_info->in_res.format, -- GitLab From 1efa9848fdbea0114ec4d1cf3f86f77e3c1e50c6 Mon Sep 17 00:00:00 2001 From: Tejas Prajapati Date: Fri, 19 Apr 2019 13:21:22 +0530 Subject: [PATCH 0457/1121] ARM: dts: msm: Increasing shared mem region size for SM6150 and sdmmagpie Increase shared memory region for ICP context bank from 100 to 150MB. The extra 50MB is compensated from the I/O region. Change-Id: I18fc6b33421a810e909a1b7679e351f5ee7d38c1 Signed-off-by: Tejas Prajapati --- arch/arm64/boot/dts/qcom/sdmmagpie-camera.dtsi | 12 ++++++------ arch/arm64/boot/dts/qcom/sm6150-camera.dtsi | 14 +++++++------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdmmagpie-camera.dtsi b/arch/arm64/boot/dts/qcom/sdmmagpie-camera.dtsi index b773dd748a87..bdfc630e5127 100644 --- a/arch/arm64/boot/dts/qcom/sdmmagpie-camera.dtsi +++ b/arch/arm64/boot/dts/qcom/sdmmagpie-camera.dtsi @@ -409,10 +409,10 @@ }; iova-mem-region-shared { - /* Shared region is 100MB long */ + /* Shared region is 150MB long */ iova-region-name = "shared"; iova-region-start = <0x7400000>; - iova-region-len = <0x6400000>; + iova-region-len = <0x9600000>; iova-region-id = <0x1>; status = "ok"; }; @@ -420,7 +420,7 @@ iova-mem-region-secondary-heap { /* Secondary heap region is 1MB long */ iova-region-name = "secheap"; - iova-region-start = <0xd800000>; + iova-region-start = <0x10A00000>; iova-region-len = <0x100000>; iova-region-id = <0x4>; status = "ok"; @@ -429,8 +429,8 @@ iova-mem-region-io { /* IO region is approximately 3 GB */ iova-region-name = "io"; - iova-region-start = <0xda00000>; - iova-region-len = <0xace00000>; + iova-region-start = <0x10C00000>; + iova-region-len = <0xA9C00000>; iova-region-id = <0x3>; status = "ok"; }; @@ -438,7 +438,7 @@ iova-mem-qdss-region { /* QDSS region is appropriate 1MB */ iova-region-name = "qdss"; - iova-region-start = <0xd900000>; + iova-region-start = <0x10B00000>; iova-region-len = <0x100000>; iova-region-id = <0x5>; qdss-phy-addr = <0x16790000>; diff --git a/arch/arm64/boot/dts/qcom/sm6150-camera.dtsi b/arch/arm64/boot/dts/qcom/sm6150-camera.dtsi index feeb01c194bc..df9bf2c3a626 100644 --- a/arch/arm64/boot/dts/qcom/sm6150-camera.dtsi +++ b/arch/arm64/boot/dts/qcom/sm6150-camera.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -318,10 +318,10 @@ }; iova-mem-region-shared { - /* Shared region is 100MB long */ + /* Shared region is 150MB long */ iova-region-name = "shared"; iova-region-start = <0x7400000>; - iova-region-len = <0x6400000>; + iova-region-len = <0x9600000>; iova-region-id = <0x1>; iova-granularity = <0x15>; status = "ok"; @@ -330,7 +330,7 @@ iova-mem-region-secondary-heap { /* Secondary heap region is 1MB long */ iova-region-name = "secheap"; - iova-region-start = <0xd800000>; + iova-region-start = <0x10A00000>; iova-region-len = <0x100000>; iova-region-id = <0x4>; status = "ok"; @@ -339,8 +339,8 @@ iova-mem-region-io { /* IO region is approximately 3 GB */ iova-region-name = "io"; - iova-region-start = <0xd911000>; - iova-region-len = <0xd26ef000>; + iova-region-start = <0x10B11000>; + iova-region-len = <0xCF4EF000>; iova-region-id = <0x3>; status = "ok"; }; @@ -348,7 +348,7 @@ iova-mem-qdss-region { /* qdss region is approximately 64K */ iova-region-name = "qdss"; - iova-region-start = <0xd900000>; + iova-region-start = <0x10B00000>; iova-region-len = <0x10000>; iova-region-id = <0x5>; qdss-phy-addr = <0x16790000>; -- GitLab From 54862ee56a6d49e8cb993190d6a33e923f1cd623 Mon Sep 17 00:00:00 2001 From: Rajesh Kemisetti Date: Mon, 3 Jun 2019 17:37:32 +0530 Subject: [PATCH 0458/1121] msm: kgsl: Add GPU_RBBM_GBIF_CLIENT_QOS_CNTL to powerup register list GPU_RBBM_GBIF_CLIENT_QOS_CNTL register is getting updated for every wake up sequence but not retained across IFPC. Add this register to powerup register list so as to restore its value across IFPC. Change-Id: I3fe15ad43af1f0f1adc49764e749bb89e4cf8a65 Signed-off-by: Rajesh Kemisetti --- drivers/gpu/msm/adreno_a6xx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/msm/adreno_a6xx.c b/drivers/gpu/msm/adreno_a6xx.c index 9385bf5e1daa..e25df1e44b4a 100644 --- a/drivers/gpu/msm/adreno_a6xx.c +++ b/drivers/gpu/msm/adreno_a6xx.c @@ -427,6 +427,7 @@ static struct reg_list_pair { /* IFPC only static powerup restore list */ static struct reg_list_pair a6xx_ifpc_pwrup_reglist[] = { { A6XX_RBBM_VBIF_CLIENT_QOS_CNTL, 0x0 }, + { A6XX_RBBM_GBIF_CLIENT_QOS_CNTL, 0x0 }, { A6XX_CP_CHICKEN_DBG, 0x0 }, { A6XX_CP_DBG_ECO_CNTL, 0x0 }, { A6XX_CP_PROTECT_CNTL, 0x0 }, -- GitLab From 0d99716c7f8d1a885bc48d4dc588358868a8dd13 Mon Sep 17 00:00:00 2001 From: Rama Krishna Phani A Date: Mon, 3 Jun 2019 20:08:41 +0530 Subject: [PATCH 0459/1121] defconfig: qcs405: enable MHI host stack for qcs405 MHI host driver allows users to communicate to MHI compatible devices over PCIe bus. Change-Id: Ic434e8203a6819b0836c98b0ad4b4f52f6dc09c1 Signed-off-by: Rama Krishna Phani A --- arch/arm64/configs/vendor/qcs405-perf_defconfig | 4 ++++ arch/arm64/configs/vendor/qcs405_defconfig | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/arch/arm64/configs/vendor/qcs405-perf_defconfig b/arch/arm64/configs/vendor/qcs405-perf_defconfig index 3d966ec2f295..0eda3cad0a25 100644 --- a/arch/arm64/configs/vendor/qcs405-perf_defconfig +++ b/arch/arm64/configs/vendor/qcs405-perf_defconfig @@ -213,6 +213,10 @@ CONFIG_NTAG_NQ=y CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y CONFIG_DMA_CMA=y +CONFIG_MHI_BUS=y +CONFIG_MHI_QCOM=y +CONFIG_MHI_NETDEV=y +CONFIG_MHI_UCI=y CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_BLOCK=y diff --git a/arch/arm64/configs/vendor/qcs405_defconfig b/arch/arm64/configs/vendor/qcs405_defconfig index 80b997bb0b83..9f800210a5d9 100644 --- a/arch/arm64/configs/vendor/qcs405_defconfig +++ b/arch/arm64/configs/vendor/qcs405_defconfig @@ -218,6 +218,11 @@ CONFIG_NTAG_NQ=y CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y CONFIG_DMA_CMA=y +CONFIG_MHI_BUS=y +CONFIG_MHI_DEBUG=y +CONFIG_MHI_QCOM=y +CONFIG_MHI_NETDEV=y +CONFIG_MHI_UCI=y CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_BLOCK=y -- GitLab From 5d7259610c9042b0c9cb360ecec7f6fca0e592b1 Mon Sep 17 00:00:00 2001 From: Deepak Kumar Date: Mon, 3 Jun 2019 14:55:54 +0530 Subject: [PATCH 0460/1121] msm: kgsl: Ensure that thermal power level restrictions are enforced Add checks to make sure thermal power level restrictions are enforced and power level is always within thermal min and max limit. Currently, thermal limits are breached in cases where GPU min_pwrlevel and max_pwrlevel sysfs entries are updated by performance daemon to maintain performance and thermal mitigation kicks in at same time. Change-Id: Id3f0c2d878588633398d20d43223b26ec292b98e Signed-off-by: Deepak Kumar --- drivers/gpu/msm/kgsl_pwrctrl.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c index eac0933e4f4c..8d651cf31718 100644 --- a/drivers/gpu/msm/kgsl_pwrctrl.c +++ b/drivers/gpu/msm/kgsl_pwrctrl.c @@ -178,6 +178,12 @@ static unsigned int _adjust_pwrlevel(struct kgsl_pwrctrl *pwr, int level, pwr->thermal_pwrlevel_floor, pwr->min_pwrlevel); + /* Ensure that max/min pwrlevels are within thermal max/min limits */ + max_pwrlevel = min_t(unsigned int, max_pwrlevel, + pwr->thermal_pwrlevel_floor); + min_pwrlevel = max_t(unsigned int, min_pwrlevel, + pwr->thermal_pwrlevel); + switch (pwrc->type) { case KGSL_CONSTRAINT_PWRLEVEL: { switch (pwrc->sub_type) { -- GitLab From 3b0c9e07aca2b45fa6703f0e2c03be84866f68a8 Mon Sep 17 00:00:00 2001 From: Ravikishore Pampana Date: Tue, 7 May 2019 19:19:58 +0530 Subject: [PATCH 0461/1121] msm: camera: isp: Add support for initial frame drop Initial frame drop is required for some sensors. User space provide the number of frames need to drop through blob command buffer. If initial frame drop is provided, CSID driver enable the SOF irq at csid path start. For every SOF IRQ, count will be incremented and if it reaches the init frame drop number then configure path control registers to start the path at frame boundary. For dual ife usecase, first RDI frame need to drop as pix frame will be dropped for csid synchronization. Change-Id: I615c9f03a7387329214fa6d2fc12e8578a665593 Signed-off-by: Ravikishore Pampana --- .../cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c | 47 +++ .../isp_hw/ife_csid_hw/cam_ife_csid_core.c | 281 ++++++++++++++++-- .../isp_hw/ife_csid_hw/cam_ife_csid_core.h | 15 + .../isp_hw/include/cam_ife_csid_hw_intf.h | 3 +- include/uapi/media/cam_isp.h | 11 + 5 files changed, 338 insertions(+), 19 deletions(-) diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c index 2a248e19c3da..a228df5f9cd7 100644 --- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c @@ -3575,6 +3575,38 @@ void fill_res_bitmap(uint32_t resource_type, unsigned long *res_bitmap) } } +static int cam_isp_blob_init_frame_drop( + struct cam_isp_init_frame_drop_config *frame_drop_cfg, + struct cam_hw_prepare_update_args *prepare) +{ + struct cam_ife_hw_mgr_ctx *ctx = NULL; + struct cam_ife_hw_mgr_res *hw_mgr_res; + struct cam_hw_intf *hw_intf; + uint32_t hw_idx = UINT_MAX; + uint32_t i; + int rc = 0; + + ctx = prepare->ctxt_to_hw_map; + list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid, list) { + for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { + if (!hw_mgr_res->hw_res[i]) + continue; + + hw_intf = hw_mgr_res->hw_res[i]->hw_intf; + if (hw_intf->hw_idx == hw_idx) + continue; + + rc = hw_intf->hw_ops.process_cmd(hw_intf->hw_priv, + CAM_IFE_CSID_SET_INIT_FRAME_DROP, + frame_drop_cfg, + sizeof( + struct cam_isp_init_frame_drop_config *)); + hw_idx = hw_intf->hw_idx; + } + } + return rc; +} + static int cam_isp_packet_generic_blob_handler(void *user_data, uint32_t blob_type, uint32_t blob_size, uint8_t *blob_data) { @@ -3820,7 +3852,22 @@ static int cam_isp_packet_generic_blob_handler(void *user_data, CAM_ERR(CAM_ISP, "FS Update Failed rc: %d", rc); } break; + case CAM_ISP_GENERIC_BLOB_TYPE_INIT_FRAME_DROP: { + struct cam_isp_init_frame_drop_config *frame_drop_cfg = + (struct cam_isp_init_frame_drop_config *)blob_data; + + if (blob_size < sizeof(struct cam_isp_init_frame_drop_config)) { + CAM_ERR(CAM_ISP, "Invalid blob size %u expected %u", + blob_size, + sizeof(struct cam_isp_init_frame_drop_config)); + return -EINVAL; + } + rc = cam_isp_blob_init_frame_drop(frame_drop_cfg, prepare); + if (rc) + CAM_ERR(CAM_ISP, "Init Frame drop Update Failed"); + } + break; default: CAM_WARN(CAM_ISP, "Invalid blob type %d", blob_type); break; diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c index ea0b01f39523..f4b91a4d844a 100644 --- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c +++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c @@ -468,6 +468,9 @@ static int cam_ife_csid_global_reset(struct cam_ife_csid_hw *csid_hw) csid_hw->hw_intf->hw_idx, val); csid_hw->error_irq_count = 0; + for (i = 0 ; i < CAM_IFE_PIX_PATH_RES_MAX; i++) + csid_hw->res_sof_cnt[i] = 0; + return rc; } @@ -838,7 +841,6 @@ static int cam_ife_csid_cid_reserve(struct cam_ife_csid_hw *csid_hw, return rc; } - static int cam_ife_csid_path_reserve(struct cam_ife_csid_hw *csid_hw, struct cam_csid_hw_reserve_resource_args *reserve) { @@ -953,7 +955,7 @@ static int cam_ife_csid_path_reserve(struct cam_ife_csid_hw *csid_hw, path_data->height = reserve->in_port->height; path_data->start_line = reserve->in_port->line_start; path_data->end_line = reserve->in_port->line_stop; - + path_data->usage_type = reserve->in_port->usage_type; /* Enable RDI crop for single ife use case only */ switch (reserve->res_id) { case CAM_IFE_PIX_PATH_RES_RDI_0: @@ -1120,6 +1122,7 @@ static int cam_ife_csid_enable_hw(struct cam_ife_csid_hw *csid_hw) static int cam_ife_csid_disable_hw(struct cam_ife_csid_hw *csid_hw) { int rc = -EINVAL; + uint32_t i; struct cam_hw_soc_info *soc_info; const struct cam_ife_csid_reg_offset *csid_reg; unsigned long flags; @@ -1160,12 +1163,95 @@ static int cam_ife_csid_disable_hw(struct cam_ife_csid_hw *csid_hw) spin_lock_irqsave(&csid_hw->lock_state, flags); csid_hw->device_enabled = 0; spin_unlock_irqrestore(&csid_hw->lock_state, flags); + for (i = 0; i < CAM_IFE_PIX_PATH_RES_MAX; i++) + csid_hw->res_sof_cnt[i] = 0; + csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN; csid_hw->error_irq_count = 0; return rc; } +static int cam_ife_csid_check_path_active(struct cam_ife_csid_hw *csid_hw) +{ + struct cam_hw_soc_info *soc_info; + const struct cam_ife_csid_reg_offset *csid_reg; + uint32_t i, path_status = 1; + + csid_reg = csid_hw->csid_info->csid_reg; + soc_info = &csid_hw->hw_info->soc_info; + + /* check the IPP path status */ + if (csid_reg->cmn_reg->num_pix) { + path_status = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csid_reg->ipp_reg->csid_pxl_status_addr); + CAM_DBG(CAM_ISP, "CSID:%d IPP path status:%d", + csid_hw->hw_intf->hw_idx, path_status); + /* if status is 0 then it is active */ + if (!path_status) + goto end; + } + + if (csid_reg->cmn_reg->num_ppp) { + path_status = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csid_reg->ppp_reg->csid_pxl_status_addr); + CAM_DBG(CAM_ISP, "CSID:%d PPP path status:%d", + csid_hw->hw_intf->hw_idx, path_status); + /* if status is 0 then it is active */ + if (!path_status) + goto end; + } + + /* Check the RDI path status */ + for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) { + path_status = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csid_reg->rdi_reg[i]->csid_rdi_status_addr); + CAM_DBG(CAM_ISP, "CSID:%d RDI:%d path status:%d", + csid_hw->hw_intf->hw_idx, i, path_status); + /* if status is 0 then it is active */ + if (!path_status) + goto end; + } + +end: + return path_status; +} + +static void cam_ife_csid_reset_init_frame_drop( + struct cam_ife_csid_hw *csid_hw) +{ + const struct cam_ife_csid_reg_offset *csid_reg; + uint32_t i = 0; + + /* + * Reset CSID init frame drop value only if all resources are + * released + */ + csid_reg = csid_hw->csid_info->csid_reg; + if (csid_reg->cmn_reg->num_pix) { + if (csid_hw->ipp_res.res_state != + CAM_ISP_RESOURCE_STATE_AVAILABLE) + goto end; + } + + if (csid_reg->cmn_reg->num_ppp) { + if (csid_hw->ppp_res.res_state != + CAM_ISP_RESOURCE_STATE_AVAILABLE) + goto end; + } + + for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) { + if (csid_hw->rdi_res[i].res_state != + CAM_ISP_RESOURCE_STATE_AVAILABLE) + goto end; + } + + /* All CSID resources are available reset the init frame drop */ + csid_hw->init_frame_drop = 0; +end: + return; + +} static int cam_ife_csid_tpg_start(struct cam_ife_csid_hw *csid_hw, struct cam_isp_resource_node *res) @@ -1725,7 +1811,7 @@ static int cam_ife_csid_enable_pxl_path( struct cam_ife_csid_path_cfg *path_data; const struct cam_ife_csid_pxl_reg_offset *pxl_reg = NULL; bool is_ipp; - uint32_t val = 0; + uint32_t val = 0, path_status; path_data = (struct cam_ife_csid_path_cfg *) res->res_priv; csid_reg = csid_hw->csid_info->csid_reg; @@ -1768,14 +1854,15 @@ static int cam_ife_csid_enable_pxl_path( /* Default is internal halt mode */ val = 0; - /* - * Resume at frame boundary if Master or No Sync. - * Slave will get resume command from Master. - */ - if (path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER || - path_data->sync_mode == CAM_ISP_HW_SYNC_NONE) - val |= CAM_CSID_RESUME_AT_FRAME_BOUNDARY; - + /* Resume at frame boundary */ + path_status = cam_ife_csid_check_path_active(csid_hw); + if (!csid_hw->init_frame_drop || + (csid_hw->init_frame_drop && !path_status)) { + CAM_DBG(CAM_ISP, "start pixel path"); + if (path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER || + path_data->sync_mode == CAM_ISP_HW_SYNC_NONE) + val |= CAM_CSID_RESUME_AT_FRAME_BOUNDARY; + } cam_io_w_mb(val, soc_info->reg_map[0].mem_base + pxl_reg->csid_pxl_ctrl_addr); @@ -1789,8 +1876,10 @@ static int cam_ife_csid_enable_pxl_path( if (pxl_reg->ccif_violation_en) val |= CSID_PATH_ERROR_CCIF_VIOLATION; - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ) + if ((csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ) || + (csid_hw->init_frame_drop && path_status)) val |= CSID_PATH_INFO_INPUT_SOF; + if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ) val |= CSID_PATH_INFO_INPUT_EOF; @@ -2087,8 +2176,10 @@ static int cam_ife_csid_enable_rdi_path( { const struct cam_ife_csid_reg_offset *csid_reg; struct cam_hw_soc_info *soc_info; - uint32_t id, val; + struct cam_ife_csid_path_cfg *path_data; + uint32_t id, val, path_status; + path_data = (struct cam_ife_csid_path_cfg *) res->res_priv; csid_reg = csid_hw->csid_info->csid_reg; soc_info = &csid_hw->hw_info->soc_info; id = res->res_id; @@ -2103,19 +2194,28 @@ static int cam_ife_csid_enable_rdi_path( return -EINVAL; } - /*resume at frame boundary */ - cam_io_w_mb(CAM_CSID_RESUME_AT_FRAME_BOUNDARY, - soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr); + if (path_data->usage_type) + path_data->init_frame_drop = csid_hw->init_frame_drop + 1; + /*resume at frame boundary */ + path_status = cam_ife_csid_check_path_active(csid_hw); + if (!path_data->init_frame_drop || + (path_data->init_frame_drop && !path_status)) { + CAM_DBG(CAM_ISP, "Start RDI:%d path", id); + cam_io_w_mb(CAM_CSID_RESUME_AT_FRAME_BOUNDARY, + soc_info->reg_map[0].mem_base + + csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr); + } /* Enable the required RDI interrupts */ val = CSID_PATH_INFO_RST_DONE | CSID_PATH_ERROR_FIFO_OVERFLOW; if (csid_reg->rdi_reg[id]->ccif_violation_en) val |= CSID_PATH_ERROR_CCIF_VIOLATION; - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ) + if ((csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ) || + (path_data->init_frame_drop && path_status)) val |= CSID_PATH_INFO_INPUT_SOF; + if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ) val |= CSID_PATH_INFO_INPUT_EOF; @@ -2375,6 +2475,19 @@ static int cam_ife_csid_set_csid_debug(struct cam_ife_csid_hw *csid_hw, return 0; } +static int cam_ife_csid_set_init_frame_drop(struct cam_ife_csid_hw *csid_hw, + void *cmd_args) +{ + struct cam_isp_init_frame_drop_config *frame_drop_cfg; + + frame_drop_cfg = (struct cam_isp_init_frame_drop_config *) cmd_args; + csid_hw->init_frame_drop = frame_drop_cfg->init_frame_drop; + CAM_DBG(CAM_ISP, "CSID:%d set init frame drop:%d", + csid_hw->hw_intf->hw_idx, csid_hw->init_frame_drop); + + return 0; +} + static int cam_ife_csid_get_hw_caps(void *hw_priv, void *get_hw_cap_args, uint32_t arg_size) { @@ -2551,6 +2664,7 @@ static int cam_ife_csid_release(void *hw_priv, break; case CAM_ISP_RESOURCE_PIX_PATH: res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE; + cam_ife_csid_reset_init_frame_drop(csid_hw); break; default: CAM_ERR(CAM_ISP, "CSID:%d Invalid res type:%d res id%d", @@ -3016,6 +3130,9 @@ static int cam_ife_csid_process_cmd(void *hw_priv, case CAM_ISP_HW_CMD_CSID_CLOCK_UPDATE: rc = cam_ife_csid_set_csid_clock(csid_hw, cmd_args); break; + case CAM_IFE_CSID_SET_INIT_FRAME_DROP: + rc = cam_ife_csid_set_init_frame_drop(csid_hw, cmd_args); + break; default: CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d", csid_hw->hw_intf->hw_idx, cmd_type); @@ -3033,6 +3150,9 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data) struct cam_hw_soc_info *soc_info; const struct cam_ife_csid_reg_offset *csid_reg; const struct cam_ife_csid_csi2_rx_reg_offset *csi2_reg; + struct cam_ife_csid_path_cfg *path_data; + const struct cam_ife_csid_pxl_reg_offset *pxl_reg; + const struct cam_ife_csid_rdi_reg_offset *rdi_reg; uint32_t i, irq_status_top, irq_status_rx, irq_status_ipp = 0; uint32_t irq_status_rdi[4] = {0, 0, 0, 0}; uint32_t val, irq_status_ppp = 0; @@ -3264,6 +3384,53 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data) csid_hw->irq_debug_cnt++; } + if ((irq_status_ipp & CSID_PATH_INFO_INPUT_SOF) && + (csid_hw->init_frame_drop) && + (csid_hw->ipp_res.res_state == + CAM_ISP_RESOURCE_STATE_STREAMING)) { + csid_hw->res_sof_cnt[CAM_IFE_PIX_PATH_RES_IPP]++; + CAM_DBG(CAM_ISP, + "CSID:%d IPP SOF cnt:%d init_frame_drop:%d", + csid_hw->hw_intf->hw_idx, + csid_hw->res_sof_cnt[CAM_IFE_PIX_PATH_RES_IPP], + csid_hw->init_frame_drop); + if (csid_hw->res_sof_cnt[CAM_IFE_PIX_PATH_RES_IPP] == + csid_hw->init_frame_drop) { + pxl_reg = csid_reg->ipp_reg; + path_data = csid_hw->ipp_res.res_priv; + if (path_data->sync_mode == + CAM_ISP_HW_SYNC_MASTER) { + val = cam_io_r_mb( + soc_info->reg_map[0].mem_base + + pxl_reg->csid_pxl_ctrl_addr); + + val |= + CAM_CSID_RESUME_AT_FRAME_BOUNDARY; + cam_io_w_mb(val, + soc_info->reg_map[0].mem_base + + pxl_reg->csid_pxl_ctrl_addr); + + } else if (path_data->sync_mode == + CAM_ISP_HW_SYNC_NONE) { + cam_io_w_mb( + CAM_CSID_RESUME_AT_FRAME_BOUNDARY, + soc_info->reg_map[0].mem_base + + pxl_reg->csid_pxl_ctrl_addr); + } + + if (!(csid_hw->csid_debug & + CSID_DEBUG_ENABLE_SOF_IRQ)) { + val = cam_io_r_mb( + soc_info->reg_map[0].mem_base + + pxl_reg->csid_pxl_irq_mask_addr); + val &= ~(CSID_PATH_INFO_INPUT_SOF); + cam_io_w_mb(val, + soc_info->reg_map[0].mem_base + + pxl_reg->csid_pxl_irq_mask_addr); + } + } + } + if ((irq_status_ipp & CSID_PATH_INFO_INPUT_EOF) && (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ)) CAM_INFO_RATE_LIMIT(CAM_ISP, "CSID:%d IPP EOF received", @@ -3299,6 +3466,52 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data) csid_hw->irq_debug_cnt++; } + if ((irq_status_ppp & CSID_PATH_INFO_INPUT_SOF) && + (csid_hw->init_frame_drop) && + (csid_hw->ppp_res.res_state == + CAM_ISP_RESOURCE_STATE_STREAMING)) { + csid_hw->res_sof_cnt[CAM_IFE_PIX_PATH_RES_PPP]++; + CAM_DBG(CAM_ISP, + "CSID:%d PPP SOF cnt:%d init_frame_drop:%d", + csid_hw->hw_intf->hw_idx, + csid_hw->res_sof_cnt[CAM_IFE_PIX_PATH_RES_PPP], + csid_hw->init_frame_drop); + if (csid_hw->res_sof_cnt[CAM_IFE_PIX_PATH_RES_PPP] == + csid_hw->init_frame_drop) { + path_data = csid_hw->ppp_res.res_priv; + pxl_reg = csid_reg->ppp_reg; + if (path_data->sync_mode == + CAM_ISP_HW_SYNC_MASTER) { + val = cam_io_r_mb( + soc_info->reg_map[0].mem_base + + pxl_reg->csid_pxl_ctrl_addr); + + val |= + CAM_CSID_RESUME_AT_FRAME_BOUNDARY; + cam_io_w_mb(val, + soc_info->reg_map[0].mem_base + + pxl_reg->csid_pxl_ctrl_addr); + } else if (path_data->sync_mode == + CAM_ISP_HW_SYNC_NONE) { + cam_io_w_mb( + CAM_CSID_RESUME_AT_FRAME_BOUNDARY, + soc_info->reg_map[0].mem_base + + pxl_reg->csid_pxl_ctrl_addr); + } + + if (!(csid_hw->csid_debug & + CSID_DEBUG_ENABLE_SOF_IRQ)) { + val = cam_io_r_mb( + soc_info->reg_map[0].mem_base + + pxl_reg->csid_pxl_irq_mask_addr); + val &= ~(CSID_PATH_INFO_INPUT_SOF); + cam_io_w_mb(val, + soc_info->reg_map[0].mem_base + + pxl_reg->csid_pxl_irq_mask_addr); + } + } + } + if ((irq_status_ppp & CSID_PATH_INFO_INPUT_EOF) && (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ)) CAM_INFO_RATE_LIMIT(CAM_ISP, "CSID:%d PPP EOF received", @@ -3319,6 +3532,9 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data) } for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) { + path_data = (struct cam_ife_csid_path_cfg *) + csid_hw->rdi_res[i].res_priv; + rdi_reg = csid_reg->rdi_reg[i]; if (irq_status_rdi[i] & BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) { complete(&csid_hw->csid_rdin_complete[i]); @@ -3332,6 +3548,35 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data) csid_hw->irq_debug_cnt++; } + if ((irq_status_rdi[i] & CSID_PATH_INFO_INPUT_SOF) && + (path_data->init_frame_drop) && + (csid_hw->rdi_res[i].res_state == + CAM_ISP_RESOURCE_STATE_STREAMING)) { + csid_hw->res_sof_cnt[i]++; + CAM_DBG(CAM_ISP, + "CSID:%d RDI:%d SOF cnt:%d init_frame_drop:%d", + csid_hw->hw_intf->hw_idx, i, + csid_hw->res_sof_cnt[i], + path_data->init_frame_drop); + if (csid_hw->res_sof_cnt[i] == + path_data->init_frame_drop) { + cam_io_w_mb(CAM_CSID_RESUME_AT_FRAME_BOUNDARY, + soc_info->reg_map[0].mem_base + + rdi_reg->csid_rdi_ctrl_addr); + + if (!(csid_hw->csid_debug & + CSID_DEBUG_ENABLE_SOF_IRQ)) { + val = cam_io_r_mb( + soc_info->reg_map[0].mem_base + + rdi_reg->csid_rdi_irq_mask_addr); + val &= ~(CSID_PATH_INFO_INPUT_SOF); + cam_io_w_mb(val, + soc_info->reg_map[0].mem_base + + rdi_reg->csid_rdi_irq_mask_addr); + } + } + } + if ((irq_status_rdi[i] & CSID_PATH_INFO_INPUT_EOF) && (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ)) CAM_INFO_RATE_LIMIT(CAM_ISP, diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h index 3a093d205f59..600deb245f32 100644 --- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h +++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h @@ -419,6 +419,9 @@ struct cam_ife_csid_cid_data { * @master_idx: For Slave reservation, Give master IFE instance Index. * Slave will synchronize with master Start and stop operations * @clk_rate Clock rate + * @usage_type Usage type ie dual or single ife usecase + * @init_frame_drop init frame drop value. In dual ife case rdi need to drop one + * more frame than pix. * */ struct cam_ife_csid_path_cfg { @@ -437,6 +440,8 @@ struct cam_ife_csid_path_cfg { enum cam_isp_hw_sync_mode sync_mode; uint32_t master_idx; uint64_t clk_rate; + uint32_t usage_type; + uint32_t init_frame_drop; }; /** @@ -468,6 +473,13 @@ struct cam_ife_csid_path_cfg { * @irq_debug_cnt: Counter to track sof irq's when above flag is set. * @error_irq_count Error IRQ count, if continuous error irq comes * need to stop the CSID and mask interrupts. + * @device_enabled Device enabled will set once CSID powered on and + * initial configuration are done. + * @lock_state csid spin lock + * @dual_usage usage type, dual ife or single ife + * @init_frame_drop Initial frame drop number + * @res_sof_cnt path resource sof count value. it used for initial + * frame drop * */ struct cam_ife_csid_hw { @@ -496,6 +508,9 @@ struct cam_ife_csid_hw { uint32_t error_irq_count; uint32_t device_enabled; spinlock_t lock_state; + uint32_t dual_usage; + uint32_t init_frame_drop; + uint32_t res_sof_cnt[CAM_IFE_PIX_PATH_RES_MAX]; }; int cam_ife_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf, diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h index 58818fbecf67..0c45bd1268b9 100644 --- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h +++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -157,6 +157,7 @@ enum cam_ife_csid_cmd_type { CAM_IFE_CSID_CMD_GET_TIME_STAMP, CAM_IFE_CSID_SET_CSID_DEBUG, CAM_IFE_CSID_SOF_IRQ_DEBUG, + CAM_IFE_CSID_SET_INIT_FRAME_DROP, CAM_IFE_CSID_CMD_MAX, }; diff --git a/include/uapi/media/cam_isp.h b/include/uapi/media/cam_isp.h index de32a61b539c..68e8446f1585 100644 --- a/include/uapi/media/cam_isp.h +++ b/include/uapi/media/cam_isp.h @@ -91,6 +91,7 @@ #define CAM_ISP_GENERIC_BLOB_TYPE_CSID_CLOCK_CONFIG 4 #define CAM_ISP_GENERIC_BLOB_TYPE_FE_CONFIG 5 #define CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG_V2 6 +#define CAM_ISP_GENERIC_BLOB_TYPE_INIT_FRAME_DROP 10 /* Per Path Usage Data */ #define CAM_ISP_USAGE_INVALID 0 @@ -500,4 +501,14 @@ struct cam_isp_acquire_hw_info { #define CAM_ISP_ACQUIRE_OUT_SIZE_VER0 sizeof(struct cam_isp_out_port_info) +/** + * struct cam_isp_init_frame_drop_config - init frame drop configuration + * + * @init_frame_drop: Initial number of frames needs to drop + */ + +struct cam_isp_init_frame_drop_config { + uint32_t init_frame_drop; +} __attribute__((packed)); + #endif /* __UAPI_CAM_ISP_H__ */ -- GitLab From 21690279bf48fcce72ff86566b5fcc197c41faae Mon Sep 17 00:00:00 2001 From: Mangalaram ARCHANA Date: Thu, 9 May 2019 10:09:04 +0530 Subject: [PATCH 0462/1121] msm: camera: Adding device type to track device handles Adding device type for each driver to track how many device handles are created and freed. Change-Id: I97bae8c3d816ce0a6764731f1efb275fd5df09fb Signed-off-by: Mangalaram ARCHANA --- .../msm/camera/cam_core/cam_context_utils.c | 2 +- .../msm/camera/cam_isp/cam_isp_context.c | 2 +- .../msm/camera/cam_req_mgr/cam_req_mgr_core.c | 2 +- .../msm/camera/cam_req_mgr/cam_req_mgr_util.c | 20 ++++++++++++++++++- .../msm/camera/cam_req_mgr/cam_req_mgr_util.h | 4 +++- .../cam_actuator/cam_actuator_core.c | 4 ++-- .../cam_csiphy/cam_csiphy_core.c | 2 +- .../cam_eeprom/cam_eeprom_core.c | 2 +- .../cam_flash/cam_flash_dev.c | 2 +- .../cam_sensor_module/cam_ois/cam_ois_core.c | 4 ++-- .../cam_sensor/cam_sensor_core.c | 2 +- 11 files changed, 33 insertions(+), 13 deletions(-) diff --git a/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c b/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c index f79af9b0c71f..427632667b80 100644 --- a/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c +++ b/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c @@ -578,7 +578,7 @@ int32_t cam_context_acquire_dev_to_hw(struct cam_context *ctx, req_hdl_param.media_entity_flag = 0; req_hdl_param.priv = ctx; req_hdl_param.ops = ctx->crm_ctx_intf; - + req_hdl_param.dev_id = ctx->dev_id; ctx->dev_hdl = cam_create_device_hdl(&req_hdl_param); if (ctx->dev_hdl <= 0) { rc = -EFAULT; diff --git a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c index 43e08611cd18..0078d61050b9 100644 --- a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c +++ b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c @@ -2875,7 +2875,7 @@ static int __cam_isp_ctx_acquire_dev_in_available(struct cam_context *ctx, req_hdl_param.media_entity_flag = 0; req_hdl_param.ops = ctx->crm_ctx_intf; req_hdl_param.priv = ctx; - + req_hdl_param.dev_id = CAM_ISP; CAM_DBG(CAM_ISP, "get device handle form bridge"); ctx->dev_hdl = cam_create_device_hdl(&req_hdl_param); if (ctx->dev_hdl <= 0) { diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c index c902bd3efeea..b0ae4e999377 100644 --- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c +++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c @@ -2700,7 +2700,7 @@ int cam_req_mgr_link(struct cam_req_mgr_ver_info *link_info) memset(&root_dev, 0, sizeof(struct cam_create_dev_hdl)); root_dev.session_hdl = link_info->u.link_info_v1.session_hdl; root_dev.priv = (void *)link; - + root_dev.dev_id = CAM_CRM; mutex_lock(&link->lock); /* Create unique dev handle for link */ link->link_hdl = cam_create_device_hdl(&root_dev); diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_util.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_util.c index dda04f8e5164..d531fdcf388b 100644 --- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_util.c +++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_util.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -128,6 +128,21 @@ static int32_t cam_get_free_handle_index(void) return idx; } +void cam_dump_tbl_info(void) +{ + int i; + + for (i = 0; i < CAM_REQ_MGR_MAX_HANDLES; i++) + CAM_INFO(CAM_CRM, "session_hdl=%x hdl_value=%x\n" + "type=%d state=%d dev_id=%lld", + hdl_tbl->hdl[i].session_hdl, + hdl_tbl->hdl[i].hdl_value, + hdl_tbl->hdl[i].type, + hdl_tbl->hdl[i].state, + hdl_tbl->hdl[i].dev_id); + +} + int32_t cam_create_session_hdl(void *priv) { int idx; @@ -144,6 +159,7 @@ int32_t cam_create_session_hdl(void *priv) idx = cam_get_free_handle_index(); if (idx < 0) { CAM_ERR(CAM_CRM, "Unable to create session handle"); + cam_dump_tbl_info(); spin_unlock_bh(&hdl_tbl_lock); return idx; } @@ -177,6 +193,7 @@ int32_t cam_create_device_hdl(struct cam_create_dev_hdl *hdl_data) idx = cam_get_free_handle_index(); if (idx < 0) { CAM_ERR(CAM_CRM, "Unable to create device handle"); + cam_dump_tbl_info(); spin_unlock_bh(&hdl_tbl_lock); return idx; } @@ -189,6 +206,7 @@ int32_t cam_create_device_hdl(struct cam_create_dev_hdl *hdl_data) hdl_tbl->hdl[idx].state = HDL_ACTIVE; hdl_tbl->hdl[idx].priv = hdl_data->priv; hdl_tbl->hdl[idx].ops = hdl_data->ops; + hdl_tbl->hdl[idx].dev_id = hdl_data->dev_id; spin_unlock_bh(&hdl_tbl_lock); pr_debug("%s: handle = %x", __func__, handle); diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_util.h b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_util.h index 7b8e3e601ed8..50d6f309da15 100644 --- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_util.h +++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_util.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -50,6 +50,7 @@ struct handle { uint32_t hdl_value; enum hdl_type type; enum hdl_state state; + uint64_t dev_id; void *ops; void *priv; }; @@ -80,6 +81,7 @@ struct cam_create_dev_hdl { int32_t v4l2_sub_dev_flag; int32_t media_entity_flag; int32_t reserved; + uint64_t dev_id; void *ops; void *priv; }; diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c index f6f562c79093..3bdc0f5e0b9f 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -786,7 +786,7 @@ int32_t cam_actuator_driver_cmd(struct cam_actuator_ctrl_t *a_ctrl, bridge_params.v4l2_sub_dev_flag = 0; bridge_params.media_entity_flag = 0; bridge_params.priv = a_ctrl; - + bridge_params.dev_id = CAM_ACTUATOR; actuator_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); a_ctrl->bridge_intf.device_hdl = actuator_acq_dev.device_handle; diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c index 5304b463f7ab..57f0d0b58288 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c @@ -725,7 +725,7 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, bridge_params.v4l2_sub_dev_flag = 0; bridge_params.media_entity_flag = 0; bridge_params.priv = csiphy_dev; - + bridge_params.dev_id = CAM_CSIPHY; if (csiphy_acq_params.combo_mode >= 2) { CAM_ERR(CAM_CSIPHY, "Invalid combo_mode %d", csiphy_acq_params.combo_mode); diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c index faece709dea4..08b7a1620e90 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c @@ -356,7 +356,7 @@ static int32_t cam_eeprom_get_dev_handle(struct cam_eeprom_ctrl_t *e_ctrl, bridge_params.v4l2_sub_dev_flag = 0; bridge_params.media_entity_flag = 0; bridge_params.priv = e_ctrl; - + bridge_params.dev_id = CAM_EEPROM; eeprom_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); e_ctrl->bridge_intf.device_hdl = eeprom_acq_dev.device_handle; diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.c index 1a0edb8d4d02..f4c9d254df7c 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.c @@ -71,7 +71,7 @@ static int32_t cam_flash_driver_cmd(struct cam_flash_ctrl *fctrl, bridge_params.v4l2_sub_dev_flag = 0; bridge_params.media_entity_flag = 0; bridge_params.priv = fctrl; - + bridge_params.dev_id = CAM_FLASH; flash_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); fctrl->bridge_intf.device_hdl = diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c index 8f8ddca8c668..937c46ab5033 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -90,7 +90,7 @@ static int cam_ois_get_dev_handle(struct cam_ois_ctrl_t *o_ctrl, bridge_params.v4l2_sub_dev_flag = 0; bridge_params.media_entity_flag = 0; bridge_params.priv = o_ctrl; - + bridge_params.dev_id = CAM_OIS; ois_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); o_ctrl->bridge_intf.device_hdl = ois_acq_dev.device_handle; diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c index 7c44aaa4ccec..36db52249f47 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c @@ -776,7 +776,7 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl, bridge_params.v4l2_sub_dev_flag = 0; bridge_params.media_entity_flag = 0; bridge_params.priv = s_ctrl; - + bridge_params.dev_id = CAM_SENSOR; sensor_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); s_ctrl->bridge_intf.device_hdl = sensor_acq_dev.device_handle; -- GitLab From b1beed57e76a802aa43d9a651d3227bdf7b14068 Mon Sep 17 00:00:00 2001 From: Sumalatha Malothu Date: Fri, 10 May 2019 16:27:27 +0530 Subject: [PATCH 0463/1121] msm: camera: Send topology and stream status to TZ In secure camera mode, publish topology and stream start and stop events to TZ for it to reset the modules, which adds to the security of the data. Change-Id: If7f4b85199e628846a1a416530f43ad4afa786ac Signed-off-by: Vijay kumar Tumati Signed-off-by: Shadul Shaikh Signed-off-by: Sumalatha Malothu --- .../msm/camera_v2/sensor/csid/msm_csid.c | 143 +++++++++++++++++- include/media/msm_cam_sensor.h | 4 + include/uapi/media/msm_cam_sensor.h | 2 + include/uapi/media/msm_camera.h | 3 + include/uapi/media/msm_camsensor_sdk.h | 4 + 5 files changed, 152 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c index e77c98efc11d..851bb261ca1b 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c +++ b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c @@ -62,7 +62,14 @@ #define SOF_DEBUG_DISABLE 0 #define SCM_SVC_CAMERASS 0x18 -#define SECURE_SYSCALL_ID 0x6 +#define SECURE_SYSCALL_ID 0x7 +#define TOPOLOGY_SYSCALL_ID 0x8 +#define STREAM_NOTIF_SYSCALL_ID 0x9 + +#define CSIPHY_0_LANES_MASK 0x000f +#define CSIPHY_1_LANES_MASK 0x00f0 +#define CSIPHY_2_LANES_MASK 0x0f00 +#define CSIPHY_3_LANES_MASK 0xf000 #define TRUE 1 #define FALSE 0 @@ -73,6 +80,13 @@ #undef CDBG #define CDBG(fmt, args...) pr_debug(fmt, ##args) +static const uint32_t CSIPHY_LANES_MASKS[] = { + CSIPHY_0_LANES_MASK, + CSIPHY_1_LANES_MASK, + CSIPHY_2_LANES_MASK, + CSIPHY_3_LANES_MASK, +}; + static struct camera_vreg_t csid_vreg_info[] = { {"qcom,mipi-csi-vdd", 0, 0, 12000}, }; @@ -340,6 +354,63 @@ static bool msm_csid_find_max_clk_rate(struct csid_device *csid_dev) } return ret; } + +static int msm_csid_seccam_send_topology(struct csid_device *csid_dev, + struct msm_camera_csid_params *csid_params) +{ + void __iomem *csidbase; + struct scm_desc desc = {0}; + + csidbase = csid_dev->base; + if (!csidbase || !csid_params) { + pr_err("%s:%d csidbase %pK, csid params %pK\n", __func__, + __LINE__, csidbase, csid_params); + return -EINVAL; + } + + desc.arginfo = SCM_ARGS(2, SCM_VAL, SCM_VAL); + desc.args[0] = csid_params->phy_sel; + desc.args[1] = csid_params->topology; + + CDBG("phy_sel %d, topology %d\n", + csid_params->phy_sel, csid_params->topology); + if (scm_call2(SCM_SIP_FNID(SCM_SVC_CAMERASS, + TOPOLOGY_SYSCALL_ID), &desc)) { + pr_err("%s:%d scm call to hypervisor failed\n", + __func__, __LINE__); + return -EINVAL; + } + return 0; +} + +static int msm_csid_seccam_reset_pipeline(struct csid_device *csid_dev, + struct msm_camera_csid_params *csid_params) +{ + void __iomem *csidbase; + struct scm_desc desc = {0}; + + csidbase = csid_dev->base; + if (!csidbase || !csid_params) { + pr_err("%s:%d csidbase %pK, csid params %pK\n", __func__, + __LINE__, csidbase, csid_params); + return -EINVAL; + } + + desc.arginfo = SCM_ARGS(2, SCM_VAL, SCM_VAL); + desc.args[0] = csid_params->phy_sel; + desc.args[1] = csid_params->is_streamon; + + CDBG("phy_sel %d, is_streamon %d\n", + csid_params->phy_sel, csid_params->is_streamon); + if (scm_call2(SCM_SIP_FNID(SCM_SVC_CAMERASS, + STREAM_NOTIF_SYSCALL_ID), &desc)) { + pr_err("%s:%d scm call to hypervisor failed\n", + __func__, __LINE__); + return -EINVAL; + } + return 0; +} + static int msm_csid_config(struct csid_device *csid_dev, struct msm_camera_csid_params *csid_params) { @@ -377,17 +448,19 @@ static int msm_csid_config(struct csid_device *csid_dev, desc.arginfo = SCM_ARGS(2, SCM_VAL, SCM_VAL); desc.args[0] = csid_params->is_secure; - desc.args[1] = csid_params->phy_sel; + desc.args[1] = CSIPHY_LANES_MASKS[csid_params->phy_sel]; CDBG("phy_sel : %d, secure : %d\n", csid_params->phy_sel, csid_params->is_secure); + + msm_camera_tz_clear_tzbsp_status(); + if (scm_call2(SCM_SIP_FNID(SCM_SVC_CAMERASS, SECURE_SYSCALL_ID), &desc)) { pr_err("%s:%d scm call to hypervisor failed\n", __func__, __LINE__); return -EINVAL; } - msm_camera_tz_clear_tzbsp_status(); } csid_dev->csid_lane_cnt = csid_params->lane_cnt; @@ -757,7 +830,8 @@ static int msm_csid_release(struct csid_device *csid_dev) desc.arginfo = SCM_ARGS(2, SCM_VAL, SCM_VAL); desc.args[0] = 0; - desc.args[1] = csid_dev->current_csid_params.phy_sel; + desc.args[1] = CSIPHY_LANES_MASKS[ + csid_dev->current_csid_params.phy_sel]; if (scm_call2(SCM_SIP_FNID(SCM_SVC_CAMERASS, SECURE_SYSCALL_ID), &desc)) { @@ -886,6 +960,32 @@ static int32_t msm_csid_cmd(struct csid_device *csid_dev, void *arg) kfree(csid_params.lut_params.vc_cfg[i]); break; } + case CSID_SECCAM_TOPOLOGY: { + struct msm_camera_csid_params csid_params; + + if (copy_from_user(&csid_params, + (void __user *)cdata->cfg.csid_params, + sizeof(struct msm_camera_csid_params))) { + pr_err("%s: %d failed\n", __func__, __LINE__); + rc = -EFAULT; + break; + } + rc = msm_csid_seccam_send_topology(csid_dev, &csid_params); + break; + } + case CSID_SECCAM_RESET: { + struct msm_camera_csid_params csid_params; + + if (copy_from_user(&csid_params, + (void __user *)cdata->cfg.csid_params, + sizeof(struct msm_camera_csid_params))) { + pr_err("%s: %d failed\n", __func__, __LINE__); + rc = -EFAULT; + break; + } + rc = msm_csid_seccam_reset_pipeline(csid_dev, &csid_params); + break; + } case CSID_RELEASE: rc = msm_csid_release(csid_dev); break; @@ -1058,6 +1158,41 @@ static int32_t msm_csid_cmd32(struct csid_device *csid_dev, void *arg) } break; } + case CSID_SECCAM_TOPOLOGY: { + struct msm_camera_csid_params csid_params; + struct msm_camera_csid_params32 csid_params32; + + if (copy_from_user(&csid_params32, + (void __user *)compat_ptr(arg32->cfg.csid_params), + sizeof(struct msm_camera_csid_params32))) { + pr_err("%s: %d failed\n", __func__, __LINE__); + rc = -EFAULT; + break; + } + + csid_params.topology = csid_params32.topology; + csid_params.phy_sel = csid_params32.phy_sel; + + rc = msm_csid_seccam_send_topology(csid_dev, &csid_params); + break; + } + case CSID_SECCAM_RESET: { + struct msm_camera_csid_params csid_params; + struct msm_camera_csid_params32 csid_params32; + + if (copy_from_user(&csid_params32, + (void __user *)compat_ptr(arg32->cfg.csid_params), + sizeof(struct msm_camera_csid_params32))) { + pr_err("%s: %d failed\n", __func__, __LINE__); + rc = -EFAULT; + break; + } + + csid_params.is_streamon = csid_params32.is_streamon; + csid_params.phy_sel = csid_params32.phy_sel; + rc = msm_csid_seccam_reset_pipeline(csid_dev, &csid_params); + break; + } case CSID_RELEASE: rc = msm_csid_release(csid_dev); break; diff --git a/include/media/msm_cam_sensor.h b/include/media/msm_cam_sensor.h index 599b8d0361e7..e7ade838a541 100644 --- a/include/media/msm_cam_sensor.h +++ b/include/media/msm_cam_sensor.h @@ -18,6 +18,8 @@ #include +#define SECURE_CAM_RST_MODULES + #ifdef CONFIG_COMPAT struct msm_sensor_power_setting32 { @@ -85,6 +87,8 @@ struct msm_camera_csid_params32 { struct msm_camera_csid_lut_params32 lut_params; uint8_t csi_3p_sel; uint8_t is_secure; + uint32_t topology; + uint8_t is_streamon; }; struct msm_camera_csi2_params32 { diff --git a/include/uapi/media/msm_cam_sensor.h b/include/uapi/media/msm_cam_sensor.h index 18276f5c27e1..4a86e1f3084e 100644 --- a/include/uapi/media/msm_cam_sensor.h +++ b/include/uapi/media/msm_cam_sensor.h @@ -155,6 +155,8 @@ enum csid_cfg_type_t { CSID_CFG, CSID_TESTMODE_CFG, CSID_RELEASE, + CSID_SECCAM_TOPOLOGY, + CSID_SECCAM_RESET, }; enum csiphy_cfg_type_t { diff --git a/include/uapi/media/msm_camera.h b/include/uapi/media/msm_camera.h index 224ef9cdc3f9..13dd801678d0 100644 --- a/include/uapi/media/msm_camera.h +++ b/include/uapi/media/msm_camera.h @@ -1367,6 +1367,7 @@ struct msm_camera_csid_params { uint8_t lane_cnt; uint16_t lane_assign; uint8_t phy_sel; + uint32_t topology; struct msm_camera_csid_lut_params lut_params; }; @@ -1411,6 +1412,8 @@ struct csic_cfg_data { enum csid_cfg_type_t { CSID_INIT, CSID_CFG, + CSID_SECCAM_TOPOLOGY, + CSID_SECCAM_RESET, }; struct csid_cfg_data { diff --git a/include/uapi/media/msm_camsensor_sdk.h b/include/uapi/media/msm_camsensor_sdk.h index 082a83e386c6..b5ff07592ad9 100644 --- a/include/uapi/media/msm_camsensor_sdk.h +++ b/include/uapi/media/msm_camsensor_sdk.h @@ -54,6 +54,8 @@ #define SECURE_CAMERA +#define SECURE_CAM_RST_MODULES + enum msm_sensor_camera_id_t { CAMERA_0, CAMERA_1, @@ -355,6 +357,8 @@ struct msm_camera_csid_params { struct msm_camera_csid_lut_params lut_params; unsigned char csi_3p_sel; unsigned char is_secure; + uint32_t topology; + unsigned char is_streamon; }; struct msm_camera_csid_testmode_parms { -- GitLab From 781c7ae0225b6429cb62a0aace5b492d4488deef Mon Sep 17 00:00:00 2001 From: Ravikishore Pampana Date: Fri, 24 May 2019 17:03:18 +0530 Subject: [PATCH 0464/1121] msm: camera: smmu: Set smmu non fatal flag true Set the non fatal flag true during the iommu domain attributes configuration. Change-Id: I109f7e7f7d3af036f057da0134d5a3e320c43cb9 Signed-off-by: Ravikishore Pampana --- drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.c b/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.c index 19f410393f9b..ae0b531a9169 100644 --- a/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.c +++ b/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.c @@ -189,7 +189,7 @@ static struct cam_iommu_cb_set iommu_cb_set; static struct dentry *smmu_dentry; -static bool smmu_fatal_flag; +static bool smmu_fatal_flag = true; static enum dma_data_direction cam_smmu_translate_dir( enum cam_smmu_map_dir dir); -- GitLab From e1cf8dfcfa0128bf214bb3c8c0cccd88ceb90e68 Mon Sep 17 00:00:00 2001 From: Anirudh Ghayal Date: Tue, 4 Jun 2019 14:20:12 +0530 Subject: [PATCH 0465/1121] power: qpnp-smb5: Do not use ibatt based termination for QG PMICs On QG based targets, the charger makes the conversion request for IBATT and determines when to terminate rather than sniffing the IBATT as on PM8150B. Hence, enable this ibatt based charger termination only for PM8150B(FG). Change-Id: I294edce1b424e8175002d4924856461fb3ef0aab Signed-off-by: Anirudh Ghayal --- drivers/power/supply/qcom/qpnp-smb5.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/power/supply/qcom/qpnp-smb5.c b/drivers/power/supply/qcom/qpnp-smb5.c index b958ca579dfc..b441dee44876 100644 --- a/drivers/power/supply/qcom/qpnp-smb5.c +++ b/drivers/power/supply/qcom/qpnp-smb5.c @@ -2251,13 +2251,15 @@ static int smb5_configure_iterm_thresholds(struct smb5 *chip) switch (chip->dt.term_current_src) { case ITERM_SRC_ADC: - rc = smblib_masked_write(chg, CHGR_ADC_TERM_CFG_REG, - TERM_BASED_ON_SYNC_CONV_OR_SAMPLE_CNT, - TERM_BASED_ON_SAMPLE_CNT); - if (rc < 0) { - dev_err(chg->dev, "Couldn't configure ADC_ITERM_CFG rc=%d\n", - rc); - return rc; + if (chip->chg.smb_version == PM8150B_SUBTYPE) { + rc = smblib_masked_write(chg, CHGR_ADC_TERM_CFG_REG, + TERM_BASED_ON_SYNC_CONV_OR_SAMPLE_CNT, + TERM_BASED_ON_SAMPLE_CNT); + if (rc < 0) { + dev_err(chg->dev, "Couldn't configure ADC_ITERM_CFG rc=%d\n", + rc); + return rc; + } } rc = smb5_configure_iterm_thresholds_adc(chip); break; -- GitLab From dbf3709f0ba2e39634d27ff05877efee79338459 Mon Sep 17 00:00:00 2001 From: Raghavendra Kakarla Date: Tue, 4 Jun 2019 12:12:54 +0530 Subject: [PATCH 0466/1121] ARM: dts: msm: Disable RSC mailbox controller device display Remove mailbox controller device nodes for display subsystem. Change-Id: Ie53852f2d62fe24f39962471c489b02dfce06029 Signed-off-by: Raghavendra Kakarla --- arch/arm64/boot/dts/qcom/atoll-rumi.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/atoll-rumi.dtsi b/arch/arm64/boot/dts/qcom/atoll-rumi.dtsi index 84e7518cf79b..521632604db2 100644 --- a/arch/arm64/boot/dts/qcom/atoll-rumi.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll-rumi.dtsi @@ -23,4 +23,8 @@ wdog: qcom,wdt@17c10000{ status = "disabled"; }; + + disp_rsc: mailbox@af20000 { + status = "disabled"; + }; }; -- GitLab From c4a67effeb3ed1699527bae8c07e537b746f346c Mon Sep 17 00:00:00 2001 From: Mangalaram ARCHANA Date: Fri, 31 May 2019 12:01:37 +0530 Subject: [PATCH 0467/1121] msm: camera: crm: Increasing the device handles to 128 In triple camera usecase dev_handles usage is more than 64.Based on usecase switching dev_handles from 64 to 128. Change-Id: I0d21866ba0bc4abfe78941e191688773441ce03f Signed-off-by: Mangalaram ARCHANA --- .../msm/camera/cam_req_mgr/cam_req_mgr_core.c | 65 +++++++++++++------ 1 file changed, 46 insertions(+), 19 deletions(-) diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c index c902bd3efeea..0e9a03a7bbe0 100644 --- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c +++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c @@ -2380,7 +2380,7 @@ static struct cam_req_mgr_crm_cb cam_req_mgr_ops = { static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, struct cam_req_mgr_ver_info *link_info) { - int rc = 0, i = 0; + int rc = 0, i = 0, num_devices = 0; struct cam_req_mgr_core_dev_link_setup link_data; struct cam_req_mgr_connected_device *dev; struct cam_req_mgr_req_tbl *pd_tbl; @@ -2405,12 +2405,21 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, return rc; max_delay = CAM_PIPELINE_DELAY_0; - for (i = 0; i < link_info->u.link_info_v1.num_devices; i++) { + if (link_info->version == VERSION_1) + num_devices = link_info->u.link_info_v1.num_devices; + else if (link_info->version == VERSION_2) + num_devices = link_info->u.link_info_v2.num_devices; + for (i = 0; i < num_devices; i++) { dev = &link->l_dev[i]; /* Using dev hdl, get ops ptr to communicate with device */ - dev->ops = (struct cam_req_mgr_kmd_ops *) - cam_get_device_ops( - link_info->u.link_info_v1.dev_hdls[i]); + if (link_info->version == VERSION_1) + dev->ops = (struct cam_req_mgr_kmd_ops *) + cam_get_device_ops( + link_info->u.link_info_v1.dev_hdls[i]); + else if (link_info->version == VERSION_2) + dev->ops = (struct cam_req_mgr_kmd_ops *) + cam_get_device_ops( + link_info->u.link_info_v2.dev_hdls[i]); if (!dev->ops || !dev->ops->get_dev_info || !dev->ops->link_setup) { @@ -2418,19 +2427,29 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, rc = -ENXIO; goto error; } - dev->dev_hdl = link_info->u.link_info_v1.dev_hdls[i]; + if (link_info->version == VERSION_1) + dev->dev_hdl = link_info->u.link_info_v1.dev_hdls[i]; + else if (link_info->version == VERSION_2) + dev->dev_hdl = link_info->u.link_info_v2.dev_hdls[i]; dev->parent = (void *)link; dev->dev_info.dev_hdl = dev->dev_hdl; rc = dev->ops->get_dev_info(&dev->dev_info); trace_cam_req_mgr_connect_device(link, &dev->dev_info); - - CAM_DBG(CAM_CRM, - "%x: connected: %s, id %d, delay %d, trigger %x", - link_info->u.link_info_v1.session_hdl, - dev->dev_info.name, - dev->dev_info.dev_id, dev->dev_info.p_delay, - dev->dev_info.trigger); + if (link_info->version == VERSION_1) + CAM_DBG(CAM_CRM, + "%x: connected: %s, id %d, delay %d, trigger %x", + link_info->u.link_info_v1.session_hdl, + dev->dev_info.name, + dev->dev_info.dev_id, dev->dev_info.p_delay, + dev->dev_info.trigger); + else if (link_info->version == VERSION_2) + CAM_DBG(CAM_CRM, + "%x: connected: %s, id %d, delay %d, trigger %x", + link_info->u.link_info_v2.session_hdl, + dev->dev_info.name, + dev->dev_info.dev_id, dev->dev_info.p_delay, + dev->dev_info.trigger); if (rc < 0 || dev->dev_info.p_delay >= CAM_PIPELINE_DELAY_MAX || @@ -2439,10 +2458,18 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, CAM_ERR(CAM_CRM, "get device info failed"); goto error; } else { - CAM_DBG(CAM_CRM, "%x: connected: %s, delay %d", - link_info->u.link_info_v1.session_hdl, - dev->dev_info.name, - dev->dev_info.p_delay); + if (link_info->version == VERSION_1) { + CAM_DBG(CAM_CRM, "%x: connected: %s, delay %d", + link_info->u.link_info_v1.session_hdl, + dev->dev_info.name, + dev->dev_info.p_delay); + } + else if (link_info->version == VERSION_2) { + CAM_DBG(CAM_CRM, "%x: connected: %s, delay %d", + link_info->u.link_info_v2.session_hdl, + dev->dev_info.name, + dev->dev_info.p_delay); + } if (dev->dev_info.p_delay > max_delay) max_delay = dev->dev_info.p_delay; @@ -2457,7 +2484,7 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, link_data.max_delay = max_delay; link_data.subscribe_event = subscribe_event; - for (i = 0; i < link_info->u.link_info_v1.num_devices; i++) { + for (i = 0; i < num_devices; i++) { dev = &link->l_dev[i]; link_data.dev_hdl = dev->dev_hdl; @@ -2500,7 +2527,7 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, if (link->max_delay < dev->dev_info.p_delay) link->max_delay = dev->dev_info.p_delay; } - link->num_devs = link_info->u.link_info_v1.num_devices; + link->num_devs = num_devices; /* Assign id for pd tables */ __cam_req_mgr_tbl_set_id(link->req.l_tbl, &link->req); -- GitLab From fcb7563351091377b4ab5a4739280ce33b8c7244 Mon Sep 17 00:00:00 2001 From: Patrick Daly Date: Tue, 5 Mar 2019 19:12:38 -0800 Subject: [PATCH 0468/1121] soc: qcom: mem-offline: Check return value from mbox_send_msg properly mbox_send_msg returns a value >= 0 on success, and a negative value on failure. Change-Id: I9fe56d5fddda0d6abb8dd5eb95743f12adac9eef Signed-off-by: Patrick Daly Signed-off-by: Charan Teja Reddy --- drivers/soc/qcom/mem-offline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/soc/qcom/mem-offline.c b/drivers/soc/qcom/mem-offline.c index 8c967a5919e0..6e720ee93f6a 100644 --- a/drivers/soc/qcom/mem-offline.c +++ b/drivers/soc/qcom/mem-offline.c @@ -170,7 +170,7 @@ static int aop_send_msg(unsigned long addr, bool online) pkt.size = MAX_LEN; pkt.data = mbox_msg; - return mbox_send_message(mailbox.mbox, &pkt); + return (mbox_send_message(mailbox.mbox, &pkt) < 0); } static int send_msg(struct memory_notify *mn, bool online) -- GitLab From 40d18910ca9ccb4cefc34d5dece661a804ea2911 Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Wed, 29 May 2019 15:00:36 +0530 Subject: [PATCH 0469/1121] msm: vidc: Reset AXI CBCR register during hardware hung During video hardware CPUSS hung, it is recommended to reset the V-NOC module. Ensure that the V-NOC module is reset for all types of system errors from firmware by calling reset on AXI registers using clock reset api's. AXI registers needs to be reset only for specific soc architecture which powers video noc module from different rails. Adding the check based on hardware version to limit the register programming. Change-Id: I586b989cb356543c440fcaf1ef34483ac92fc53d Signed-off-by: Manikanta Kanamarlapudi --- drivers/media/platform/msm/vidc/venus_hfi.c | 57 +++++++++++++++++++-- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c index 3125794ea183..3b1b3398f796 100644 --- a/drivers/media/platform/msm/vidc/venus_hfi.c +++ b/drivers/media/platform/msm/vidc/venus_hfi.c @@ -46,6 +46,8 @@ #define REG_ADDR_OFFSET_BITMASK 0x000FFFFF #define QDSS_IOVA_START 0x80001000 +#define VERSION_HANA (0x5 << 28 | 0x10 << 16) + static struct hal_device_data hal_ctxt; #define TZBSP_MEM_PROTECT_VIDEO_VAR 0x8 @@ -3976,6 +3978,42 @@ static inline int __prepare_ahb2axi_bridge(struct venus_hfi_device *device) return 0; } +static inline int __unprepare_ahb2axi_bridge(struct venus_hfi_device *device, + u32 version) +{ + int rc; + + if (!device) { + dprintk(VIDC_ERR, "NULL device\n"); + return -EINVAL; + } + + /* reset axi0 and axi1 as needed only for specific video hardware */ + version &= ~GENMASK(15, 0); + if (version != VERSION_HANA) + return -EINVAL; + + dprintk(VIDC_ERR, + "reset axi cbcr to recover\n"); + + rc = __handle_reset_clk(device->res, ASSERT); + if (rc) { + dprintk(VIDC_ERR, "failed to assert reset clocks\n"); + return rc; + } + + /* wait for deassert */ + usleep_range(150, 250); + + rc = __handle_reset_clk(device->res, DEASSERT); + if (rc) { + dprintk(VIDC_ERR, "failed to deassert reset clocks\n"); + return rc; + } + + return 0; +} + static inline int __prepare_enable_clks(struct venus_hfi_device *device) { struct clock_info *cl = NULL, *cl_fail = NULL; @@ -4715,8 +4753,10 @@ static int __venus_power_on(struct venus_hfi_device *device) return rc; } -static void __venus_power_off(struct venus_hfi_device *device) +static void __venus_power_off(struct venus_hfi_device *device, bool axi_reset) { + u32 version; + if (!device->power_enabled) return; @@ -4724,7 +4764,14 @@ static void __venus_power_off(struct venus_hfi_device *device) disable_irq_nosync(device->hal_data->irq); device->intr_status = 0; + if (axi_reset) + version = __read_register(device, VIDC_WRAPPER_HW_VERSION); + __disable_unprepare_clks(device); + + if (axi_reset) + __unprepare_ahb2axi_bridge(device, version); + if (__disable_regulators(device)) dprintk(VIDC_WARN, "Failed to disable regulators\n"); @@ -4759,7 +4806,7 @@ static inline int __suspend(struct venus_hfi_device *device) __disable_subcaches(device); - __venus_power_off(device); + __venus_power_off(device, false); dprintk(VIDC_PROF, "Venus power off\n"); return rc; @@ -4834,7 +4881,7 @@ static inline int __resume(struct venus_hfi_device *device) err_reset_core: __tzbsp_set_video_state(TZBSP_VIDEO_STATE_SUSPEND); err_set_video_state: - __venus_power_off(device); + __venus_power_off(device, false); err_venus_power_on: dprintk(VIDC_ERR, "Failed to resume from power collapse\n"); return rc; @@ -4893,7 +4940,7 @@ static int __load_fw(struct venus_hfi_device *device) subsystem_put(device->resources.fw.cookie); device->resources.fw.cookie = NULL; fail_load_fw: - __venus_power_off(device); + __venus_power_off(device, true); fail_venus_power_on: fail_init_pkt: __deinit_resources(device); @@ -4914,7 +4961,7 @@ static void __unload_fw(struct venus_hfi_device *device) __vote_buses(device, NULL, 0); subsystem_put(device->resources.fw.cookie); __interface_queues_release(device); - __venus_power_off(device); + __venus_power_off(device, true); device->resources.fw.cookie = NULL; __deinit_resources(device); -- GitLab From 14a93c98347627c1d44246222c192829198c5c9b Mon Sep 17 00:00:00 2001 From: "Jinesh K. Jayakumar" Date: Fri, 17 May 2019 16:23:11 -0400 Subject: [PATCH 0470/1121] ARM: dts: msm: Update AQC moderation for peak throughput Tune moderation parameters for AQC and GSI Rx/Tx channels to achieve peak throughput. Change-Id: If24f40ca59f267e2188c8af8a6229f53a6c49781 Signed-off-by: Jinesh K. Jayakumar --- arch/arm64/boot/dts/qcom/sdxprairie-aqc.dtsi | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdxprairie-aqc.dtsi b/arch/arm64/boot/dts/qcom/sdxprairie-aqc.dtsi index cff05a19192f..ff0802a715b8 100644 --- a/arch/arm64/boot/dts/qcom/sdxprairie-aqc.dtsi +++ b/arch/arm64/boot/dts/qcom/sdxprairie-aqc.dtsi @@ -53,14 +53,21 @@ qcom,rx-proxy = <&atd_proxy_host>, <&atd_proxy_uc>; + qcom,rx-proxy-mode = "counter"; - qcom,rx-gsi-mod-count = <20>; - qcom,rx-gsi-mod-timer = <1>; + qcom,rx-ring-size = <4096>; + qcom,rx-buff-size = <2048>; + qcom,rx-int-mod-usecs = <64>; - qcom,tx-gsi-mod-count = <20>; - qcom,tx-gsi-mod-timer = <1>; + qcom,rx-gsi-mod-pc = <10>; + qcom,rx-gsi-mod-timer = <32>; - qcom,rx-mod-usecs = <30>; + qcom,tx-ring-size = <4096>; + qcom,tx-buff-size = <2048>; + qcom,tx-wrb-mod-pc = <25>; + + qcom,tx-gsi-mod-pc = <10>; + qcom,tx-gsi-mod-timer = <32>; qcom,use-pci-direct; -- GitLab From 77811940976813878ed014575aa2352897264e9c Mon Sep 17 00:00:00 2001 From: Shaoqing Liu Date: Fri, 22 Feb 2019 17:08:40 +0800 Subject: [PATCH 0471/1121] ARM: dts: msm: Add ipcb tgu node for sdxprairie Add ipcb tgu node for sdxprairie. Change-Id: Id418b2c62b97d9e4cfe2dce19bd9eae82fb819b3 Signed-off-by: Shaoqing Liu --- .../boot/dts/qcom/sdxprairie-coresight.dtsi | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdxprairie-coresight.dtsi b/arch/arm64/boot/dts/qcom/sdxprairie-coresight.dtsi index 9db702bb4d68..049fad807e9c 100644 --- a/arch/arm64/boot/dts/qcom/sdxprairie-coresight.dtsi +++ b/arch/arm64/boot/dts/qcom/sdxprairie-coresight.dtsi @@ -1158,6 +1158,22 @@ }; + ipcb_tgu: tgu@6b0c000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x000bb999>; + reg = <0x06b0c000 0x1000>; + reg-names = "tgu-base"; + tgu-steps = <3>; + tgu-conditions = <4>; + tgu-regs = <4>; + tgu-timer-counters = <8>; + + coresight-name = "coresight-tgu-ipcb"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + cti0_swao:cti@6b04000 { compatible = "arm,primecell"; arm,primecell-periphid = <0x0003b966>; -- GitLab From 33c1cdcbfee1ef14e437e72cd145bc9e74824536 Mon Sep 17 00:00:00 2001 From: "Jinesh K. Jayakumar" Date: Tue, 28 May 2019 16:01:32 -0400 Subject: [PATCH 0472/1121] net: aquantia: Save PCI config space during suspend callback MSM PCI bus driver disables PCIe link during regular suspend. Save PCI config space during AQC suspend callback so that the PCI framework will not attempt to save config space during late suspend. Change-Id: I3dd43a080958a43fa5a602c85e557cd7f8caef82 Signed-off-by: Jinesh K. Jayakumar --- drivers/net/ethernet/aquantia/atlantic-fwd/atl_main.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/ethernet/aquantia/atlantic-fwd/atl_main.c b/drivers/net/ethernet/aquantia/atlantic-fwd/atl_main.c index 30ade8c2e6bd..d3ec2bffebfe 100644 --- a/drivers/net/ethernet/aquantia/atlantic-fwd/atl_main.c +++ b/drivers/net/ethernet/aquantia/atlantic-fwd/atl_main.c @@ -490,7 +490,10 @@ static int atl_suspend_common(struct device *dev, bool deep) atl_dev_err("Enable WoL failed: %d\n", -ret); } + pci_save_state(pdev); pci_disable_device(pdev); + pci_set_power_state(pdev, PCI_D3hot); + __clear_bit(ATL_ST_ENABLED, &nic->state); rtnl_unlock(); @@ -516,6 +519,9 @@ static int atl_resume_common(struct device *dev, bool deep) rtnl_lock(); + pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); + ret = pci_enable_device_mem(pdev); if (ret) goto exit; -- GitLab From 9089218741d3a556e9a2c45743b46190b7807619 Mon Sep 17 00:00:00 2001 From: "Jinesh K. Jayakumar" Date: Tue, 4 Jun 2019 21:07:15 -0400 Subject: [PATCH 0473/1121] net: aquantia: Re-initialize fwd rings on driver resume Enable support for re-initializing forward rings during system resume. Change-Id: I8850a2b675a9a8efb21038871982017de830e535 Signed-off-by: Jinesh K. Jayakumar --- .../aquantia/atlantic-fwd/atl_common.h | 5 + .../ethernet/aquantia/atlantic-fwd/atl_fwd.c | 97 +++++++++++++++---- .../ethernet/aquantia/atlantic-fwd/atl_fwd.h | 1 + .../ethernet/aquantia/atlantic-fwd/atl_main.c | 4 + 4 files changed, 90 insertions(+), 17 deletions(-) diff --git a/drivers/net/ethernet/aquantia/atlantic-fwd/atl_common.h b/drivers/net/ethernet/aquantia/atlantic-fwd/atl_common.h index cddbeccc2459..a3dfebf9c00c 100644 --- a/drivers/net/ethernet/aquantia/atlantic-fwd/atl_common.h +++ b/drivers/net/ethernet/aquantia/atlantic-fwd/atl_common.h @@ -384,6 +384,11 @@ int atl_update_eth_stats(struct atl_nic *nic); void atl_adjust_eth_stats(struct atl_ether_stats *stats, struct atl_ether_stats *base, bool add); void atl_fwd_release_rings(struct atl_nic *nic); +#ifdef CONFIG_ATLFWD_FWD +int atl_fwd_resume_rings(struct atl_nic *nic); +#else +static inline int atl_fwd_resume_rings(struct atl_nic *nic) { return 0; } +#endif int atl_get_lpi_timer(struct atl_nic *nic, uint32_t *lpi_delay); int atl_mdio_hwsem_get(struct atl_hw *hw); void atl_mdio_hwsem_put(struct atl_hw *hw); diff --git a/drivers/net/ethernet/aquantia/atlantic-fwd/atl_fwd.c b/drivers/net/ethernet/aquantia/atlantic-fwd/atl_fwd.c index 019bec332d22..bf04d22de15f 100644 --- a/drivers/net/ethernet/aquantia/atlantic-fwd/atl_fwd.c +++ b/drivers/net/ethernet/aquantia/atlantic-fwd/atl_fwd.c @@ -593,12 +593,47 @@ void atl_fwd_release_event(struct atl_fwd_event *evt) } EXPORT_SYMBOL(atl_fwd_release_event); -int atl_fwd_request_event(struct atl_fwd_event *evt) +static int atl_fwd_init_event(struct atl_fwd_event *evt) { struct atl_fwd_ring *ring = evt->ring; int dir_tx = atl_fwd_ring_tx(ring); struct atl_nic *nic = ring->nic; struct atl_hw *hw = &nic->hw; + bool tx_wb = !!(evt->flags & ATL_FWD_EVT_TXWB); + int idx; + int ret; + + if (tx_wb) { + struct atl_hw_ring *hwring = &ring->hw; + + atl_write(hw, ATL_TX_RING_HEAD_WB_LSW(hwring), + evt->tx_head_wrb); + atl_write(hw, ATL_TX_RING_HEAD_WB_MSW(hwring), + upper_32_bits(evt->tx_head_wrb)); + return 0; + } + + idx = evt->idx; + + ret = atl_fwd_set_msix_vec(nic, evt); + if (ret) + return ret; + + atl_set_intr_bits(&nic->hw, ring->idx, + dir_tx ? -1 : idx, + dir_tx ? idx : -1); + + atl_write_bit(hw, ATL_INTR_AUTO_CLEAR, idx, 1); + atl_write_bit(hw, ATL_INTR_AUTO_MASK, idx, + !!(evt->flags & ATL_FWD_EVT_AUTOMASK)); + + return 0; +} + +int atl_fwd_request_event(struct atl_fwd_event *evt) +{ + struct atl_fwd_ring *ring = evt->ring; + struct atl_nic *nic = ring->nic; unsigned long *map = &nic->fwd.msi_map; bool tx_wb = !!(evt->flags & ATL_FWD_EVT_TXWB); int idx; @@ -631,13 +666,9 @@ int atl_fwd_request_event(struct atl_fwd_event *evt) ring->evt = evt; if (tx_wb) { - struct atl_hw_ring *hwring = &ring->hw; - - atl_write(hw, ATL_TX_RING_HEAD_WB_LSW(hwring), - evt->tx_head_wrb); - atl_write(hw, ATL_TX_RING_HEAD_WB_MSW(hwring), - upper_32_bits(evt->tx_head_wrb)); - return 0; + ret = atl_fwd_init_event(evt); + if (ret) + goto fail; } idx = find_next_zero_bit(map, ATL_NUM_MSI_VECS, ATL_FWD_MSI_BASE); @@ -649,20 +680,12 @@ int atl_fwd_request_event(struct atl_fwd_event *evt) evt->idx = idx; - ret = atl_fwd_set_msix_vec(nic, evt); + ret = atl_fwd_init_event(evt); if (ret) goto fail; __set_bit(idx, map); - atl_set_intr_bits(&nic->hw, ring->idx, - dir_tx ? -1 : idx, - dir_tx ? idx : -1); - - atl_write_bit(hw, ATL_INTR_AUTO_CLEAR, idx, 1); - atl_write_bit(hw, ATL_INTR_AUTO_MASK, idx, - !!(evt->flags & ATL_FWD_EVT_AUTOMASK)); - return 0; fail: @@ -681,10 +704,12 @@ int atl_fwd_enable_event(struct atl_fwd_event *evt) return -EINVAL; atl_write_bit(hw, ATL_TX_RING_CTL(&ring->hw), 28, 1); + ring->state |= ATL_FWR_ST_EVT_ENABLED; return 0; } atl_intr_enable(hw, BIT(evt->idx)); + ring->state |= ATL_FWR_ST_EVT_ENABLED; return 0; } EXPORT_SYMBOL(atl_fwd_enable_event); @@ -699,10 +724,12 @@ int atl_fwd_disable_event(struct atl_fwd_event *evt) return -EINVAL; atl_write_bit(hw, ATL_TX_RING_CTL(&ring->hw), 28, 0); + ring->state &= ~ATL_FWR_ST_EVT_ENABLED; return 0; } atl_intr_disable(hw, BIT(evt->idx)); + ring->state &= ~ATL_FWR_ST_EVT_ENABLED; return 0; } EXPORT_SYMBOL(atl_fwd_disable_event); @@ -721,3 +748,39 @@ int atl_fwd_transmit_skb(struct net_device *ndev, struct sk_buff *skb) } EXPORT_SYMBOL(atl_fwd_transmit_skb); +int atl_fwd_resume_rings(struct atl_nic *nic) +{ + struct atl_fwd_ring **rings = nic->fwd.rings[0]; + int i; + int ret; + + for (i = 0; i < ATL_NUM_FWD_RINGS * 2; i++) { + struct atl_fwd_ring *ring = rings[i]; + + if (!ring) + continue; + + atl_fwd_init_ring(ring); + + if (ring->evt) { + ret = atl_fwd_init_event(ring->evt); + if (ret) + return ret; + + if (ring->state & ATL_FWR_ST_EVT_ENABLED) { + ret = atl_fwd_enable_event(ring->evt); + if (ret) + return ret; + } + } + + if (ring->state & ATL_FWR_ST_ENABLED) { + ret = atl_fwd_enable_ring(ring); + if (ret) + return ret; + } + } + + return 0; +} + diff --git a/drivers/net/ethernet/aquantia/atlantic-fwd/atl_fwd.h b/drivers/net/ethernet/aquantia/atlantic-fwd/atl_fwd.h index d348fc03b082..05c3e21e0592 100644 --- a/drivers/net/ethernet/aquantia/atlantic-fwd/atl_fwd.h +++ b/drivers/net/ethernet/aquantia/atlantic-fwd/atl_fwd.h @@ -364,6 +364,7 @@ int atl_fwd_transmit_skb(struct net_device *ndev, struct sk_buff *skb); enum atl_fwd_ring_state { ATL_FWR_ST_ENABLED = BIT(0), + ATL_FWR_ST_EVT_ENABLED = BIT(1), }; #endif diff --git a/drivers/net/ethernet/aquantia/atlantic-fwd/atl_main.c b/drivers/net/ethernet/aquantia/atlantic-fwd/atl_main.c index d3ec2bffebfe..531aa9d9b4fe 100644 --- a/drivers/net/ethernet/aquantia/atlantic-fwd/atl_main.c +++ b/drivers/net/ethernet/aquantia/atlantic-fwd/atl_main.c @@ -546,6 +546,10 @@ static int atl_resume_common(struct device *dev, bool deep) if (ret) goto exit; + ret = atl_fwd_resume_rings(nic); + if (ret) + goto exit; + netif_device_attach(nic->ndev); exit: -- GitLab From db26814565eab0f062ffea1b595cda497c87f213 Mon Sep 17 00:00:00 2001 From: "Jinesh K. Jayakumar" Date: Tue, 4 Jun 2019 21:08:55 -0400 Subject: [PATCH 0474/1121] msm: ipa: Reset GSI channel before gsi_dealloc_channel() call GSI channel enters STOPPED state when gsi_stop_channel() is called instead of ALLOCATED state. Call gsi_reset_channel() before gsi_dealloc_channel() to change channel state to ALLOCATED. Change-Id: Icfaf03483c4a90317f9a5e6150ad2951d3bc0aaf Signed-off-by: Jinesh K. Jayakumar --- drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_gsi.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_gsi.c b/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_gsi.c index ebdc5a297e58..8f3983dd7c7d 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_gsi.c +++ b/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_gsi.c @@ -222,6 +222,14 @@ int ipa_eth_gsi_dealloc(struct ipa_eth_channel *ch) } if (ep_ctx->gsi_chan_hdl != ~0) { + gsi_rc = gsi_reset_channel(ep_ctx->gsi_chan_hdl); + if (gsi_rc != GSI_STATUS_SUCCESS) { + ipa_eth_dev_err(ch->eth_dev, + "Failed to reset channel %u", + ep_ctx->gsi_chan_hdl); + return gsi_rc; + } + gsi_rc = gsi_dealloc_channel(ep_ctx->gsi_chan_hdl); if (gsi_rc != GSI_STATUS_SUCCESS) { ipa_eth_dev_err(ch->eth_dev, -- GitLab From 68b09de0675925a3a7c7b20d14ec87f2afbd0ac3 Mon Sep 17 00:00:00 2001 From: Jilai Wang Date: Tue, 4 Jun 2019 15:24:54 -0400 Subject: [PATCH 0475/1121] msm: npu: Limit one client to load network This change is to limit only one client to be able to load network. Change-Id: I081b068044e29c0198f46a62481e675abdf89dbe Signed-off-by: Jilai Wang --- drivers/media/platform/msm/npu/npu_mgr.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/media/platform/msm/npu/npu_mgr.c b/drivers/media/platform/msm/npu/npu_mgr.c index 7e8a9c3f591b..be008f73946e 100644 --- a/drivers/media/platform/msm/npu/npu_mgr.c +++ b/drivers/media/platform/msm/npu/npu_mgr.c @@ -579,6 +579,17 @@ static struct npu_network *alloc_network(struct npu_host_ctx *ctx, WARN_ON(!mutex_is_locked(&ctx->lock)); + for (i = 0; i < MAX_LOADED_NETWORK; i++) { + if ((network->id != 0) && + (network->client != client)) { + pr_err("NPU is used by other client now\n"); + return NULL; + } + + network++; + } + + network = ctx->networks; for (i = 0; i < MAX_LOADED_NETWORK; i++) { if (network->id == 0) break; -- GitLab From 15b2a5428b4fc5b2a90e74f82b2f1c03bc9130c2 Mon Sep 17 00:00:00 2001 From: "Thomas (Wonyoung) Yun" Date: Wed, 3 Apr 2019 17:48:54 -0400 Subject: [PATCH 0476/1121] msm: kgsl: Avoid unnecessary GMU reinitialization In case of some error cases that the hibernation does not complete successfully and system goes to recover without cutting power, we should not force GMU to initialize again. Check the GMU hardware status to determine if it is the case. Change-Id: I2b548d7001927095b7700d6df7ee3738820c3833 Signed-off-by: Thomas (Wonyoung) Yun --- drivers/gpu/msm/adreno.c | 15 +++-- drivers/gpu/msm/adreno_a6xx_gmu.c | 95 ++++++++++++++++++++++--------- drivers/gpu/msm/kgsl_gmu.c | 19 +++++++ drivers/gpu/msm/kgsl_gmu.h | 4 ++ drivers/gpu/msm/kgsl_gmu_core.c | 13 ++++- drivers/gpu/msm/kgsl_gmu_core.h | 5 +- 6 files changed, 115 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index 63c6b5154706..b81f7934f1db 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -4046,12 +4046,6 @@ static int adreno_suspend_device(struct kgsl_device *device, if (gpudev->zap_shader_unload != NULL) gpudev->zap_shader_unload(adreno_dev); - if (gmu_core_isenabled(device)) { - clear_bit(GMU_BOOT_INIT_DONE, &device->gmu_core.flags); - clear_bit(GMU_RSCC_SLEEP_SEQ_DONE, - &device->gmu_core.flags); - } - if (gpudev->secure_pt_hibernate != NULL) ret = gpudev->secure_pt_hibernate(adreno_dev); } @@ -4080,6 +4074,15 @@ static int adreno_resume_device(struct kgsl_device *device, if (ret) return ret; } + + if (gmu_core_isenabled(device)) { + if (!gmu_core_is_initialized(device)) { + clear_bit(GMU_BOOT_INIT_DONE, + &device->gmu_core.flags); + clear_bit(GMU_RSCC_SLEEP_SEQ_DONE, + &device->gmu_core.flags); + } + } } if (device->state == KGSL_STATE_SUSPEND) diff --git a/drivers/gpu/msm/adreno_a6xx_gmu.c b/drivers/gpu/msm/adreno_a6xx_gmu.c index 28cf1812d2ac..b5f5ca3e70fd 100644 --- a/drivers/gpu/msm/adreno_a6xx_gmu.c +++ b/drivers/gpu/msm/adreno_a6xx_gmu.c @@ -71,6 +71,8 @@ static const unsigned int a6xx_gmu_registers[] = { #define RSC_CMD_OFFSET 2 #define PDC_CMD_OFFSET 4 +#define PDC_ENABLE_REG_VALUE 0x80000001 + static void _regwrite(void __iomem *regbase, unsigned int offsetwords, unsigned int value) { @@ -80,17 +82,11 @@ static void _regwrite(void __iomem *regbase, __raw_writel(value, reg); } -/* - * _load_gmu_rpmh_ucode() - Load the ucode into the GPU PDC/RSC blocks - * PDC and RSC execute GPU power on/off RPMh sequence - * @device: Pointer to KGSL device - */ -static int _load_gmu_rpmh_ucode(struct kgsl_device *device) +static int _map_pdc_iomem(struct kgsl_device *device) { struct gmu_device *gmu = KGSL_GMU_DEVICE(device); struct adreno_device *adreno_dev = ADRENO_DEVICE(device); struct resource *res_pdc, *res_cfg, *res_seq; - void __iomem *cfg = NULL, *seq = NULL; unsigned int cfg_offset, seq_offset; /* Offsets from the base PDC (if no PDC subsections in the DTSI) */ @@ -125,31 +121,59 @@ static int _load_gmu_rpmh_ucode(struct kgsl_device *device) * Map the starting address for pdc_cfg programming. If the pdc_cfg * resource is not available use an offset from the base PDC resource. */ - if (res_cfg) - cfg = ioremap(res_cfg->start, resource_size(res_cfg)); - else if (res_pdc) - cfg = ioremap(res_pdc->start + cfg_offset, 0x10000); - - if (!cfg) { - dev_err(&gmu->pdev->dev, "Failed to map PDC CFG\n"); - return -ENODEV; + if (gmu->pdc_cfg_base == NULL) { + if (res_cfg) + gmu->pdc_cfg_base = devm_ioremap(&gmu->pdev->dev, + res_cfg->start, resource_size(res_cfg)); + else if (res_pdc) + gmu->pdc_cfg_base = devm_ioremap(&gmu->pdev->dev, + res_pdc->start + cfg_offset, 0x10000); + + if (gmu->pdc_cfg_base == NULL) { + dev_err(&gmu->pdev->dev, "Failed to map PDC CFG\n"); + return -ENODEV; + } } /* * Map the starting address for pdc_seq programming. If the pdc_seq * resource is not available use an offset from the base PDC resource. */ - if (res_seq) - seq = ioremap(res_seq->start, resource_size(res_seq)); - else if (res_pdc) - seq = ioremap(res_pdc->start + seq_offset, 0x10000); - - if (!seq) { - dev_err(&gmu->pdev->dev, "Failed to map PDC SEQ\n"); - iounmap(cfg); - return -ENODEV; + if (gmu->pdc_seq_base == NULL) { + if (res_seq) + gmu->pdc_seq_base = devm_ioremap(&gmu->pdev->dev, + res_seq->start, resource_size(res_seq)); + else if (res_pdc) + gmu->pdc_seq_base = devm_ioremap(&gmu->pdev->dev, + res_pdc->start + seq_offset, 0x10000); + + if (gmu->pdc_seq_base == NULL) { + dev_err(&gmu->pdev->dev, "Failed to map PDC SEQ\n"); + return -ENODEV; + } } + return 0; +} + +/* + * _load_gmu_rpmh_ucode() - Load the ucode into the GPU PDC/RSC blocks + * PDC and RSC execute GPU power on/off RPMh sequence + * @device: Pointer to KGSL device + */ +static int _load_gmu_rpmh_ucode(struct kgsl_device *device) +{ + struct gmu_device *gmu = KGSL_GMU_DEVICE(device); + struct adreno_device *adreno_dev = ADRENO_DEVICE(device); + void __iomem *cfg, *seq; + int ret = _map_pdc_iomem(device); + + if (ret) + return ret; + + cfg = gmu->pdc_cfg_base; + seq = gmu->pdc_seq_base; + /* Disable SDE clock gating */ gmu_core_regwrite(device, A6XX_GPU_RSCC_RSC_STATUS0_DRV0, BIT(24)); @@ -238,14 +262,11 @@ static int _load_gmu_rpmh_ucode(struct kgsl_device *device) /* Setup GPU PDC */ _regwrite(cfg, PDC_GPU_SEQ_START_ADDR, 0); - _regwrite(cfg, PDC_GPU_ENABLE_PDC, 0x80000001); + _regwrite(cfg, PDC_GPU_ENABLE_PDC, PDC_ENABLE_REG_VALUE); /* ensure no writes happen before the uCode is fully written */ wmb(); - iounmap(seq); - iounmap(cfg); - return 0; } @@ -1597,6 +1618,23 @@ static int a6xx_gmu_wait_for_active_transition( return -ETIMEDOUT; } +static bool a6xx_gmu_is_initialized(struct adreno_device *adreno_dev) +{ + struct kgsl_device *device = KGSL_DEVICE(adreno_dev); + struct gmu_device *gmu = KGSL_GMU_DEVICE(device); + u32 val; + + if (_map_pdc_iomem(device)) + return false; + + val = __raw_readl(gmu->pdc_cfg_base + (PDC_GPU_ENABLE_PDC << 2)); + + /* ensure this read operation is done before the next one */ + rmb(); + + return (val == PDC_ENABLE_REG_VALUE); +} + struct gmu_dev_ops adreno_a6xx_gmudev = { .load_firmware = a6xx_gmu_load_firmware, .oob_set = a6xx_gmu_oob_set, @@ -1613,6 +1651,7 @@ struct gmu_dev_ops adreno_a6xx_gmudev = { .ifpc_show = a6xx_gmu_ifpc_show, .snapshot = a6xx_gmu_snapshot, .wait_for_active_transition = a6xx_gmu_wait_for_active_transition, + .is_initialized = a6xx_gmu_is_initialized, .gmu2host_intr_mask = HFI_IRQ_MASK, .gmu_ao_intr_mask = GMU_AO_INT_MASK, }; diff --git a/drivers/gpu/msm/kgsl_gmu.c b/drivers/gpu/msm/kgsl_gmu.c index 41cb7d75242f..f962952c6594 100644 --- a/drivers/gpu/msm/kgsl_gmu.c +++ b/drivers/gpu/msm/kgsl_gmu.c @@ -1851,6 +1851,24 @@ static bool gmu_regulator_isenabled(struct kgsl_device *device) return (gmu->gx_gdsc && regulator_is_enabled(gmu->gx_gdsc)); } +static bool gmu_is_initialized(struct kgsl_device *device) +{ + struct adreno_device *adreno_dev = ADRENO_DEVICE(device); + struct gmu_dev_ops *gmu_dev_ops = GMU_DEVICE_OPS(device); + struct gmu_device *gmu = KGSL_GMU_DEVICE(device); + bool ret; + + gmu_enable_gdsc(gmu); + gmu_enable_clks(device); + + ret = gmu_dev_ops->is_initialized(adreno_dev); + + gmu_disable_clks(device); + gmu_disable_gdsc(gmu); + + return ret; +} + struct gmu_core_ops gmu_ops = { .probe = gmu_probe, .remove = gmu_remove, @@ -1861,4 +1879,5 @@ struct gmu_core_ops gmu_ops = { .regulator_isenabled = gmu_regulator_isenabled, .suspend = gmu_suspend, .acd_set = gmu_acd_set, + .is_initialized = gmu_is_initialized, }; diff --git a/drivers/gpu/msm/kgsl_gmu.h b/drivers/gpu/msm/kgsl_gmu.h index 24d5f547fb7e..56eee96ab65e 100644 --- a/drivers/gpu/msm/kgsl_gmu.h +++ b/drivers/gpu/msm/kgsl_gmu.h @@ -161,6 +161,8 @@ struct kgsl_mailbox { * @idle_level: Minimal GPU idle power level * @fault_count: GMU fault count * @mailbox: Messages to AOP for ACD enable/disable go through this + * @pdc_cfg_base: Base address of PDC cfg registers + * @pdc_seq_base: Base address of PDC seq registers */ struct gmu_device { unsigned int ver; @@ -196,6 +198,8 @@ struct gmu_device { unsigned int idle_level; unsigned int fault_count; struct kgsl_mailbox mailbox; + void __iomem *pdc_cfg_base; + void __iomem *pdc_seq_base; }; struct gmu_memdesc *gmu_get_memdesc(unsigned int addr, unsigned int size); diff --git a/drivers/gpu/msm/kgsl_gmu_core.c b/drivers/gpu/msm/kgsl_gmu_core.c index 6e98bb5eead1..f4303743e688 100644 --- a/drivers/gpu/msm/kgsl_gmu_core.c +++ b/drivers/gpu/msm/kgsl_gmu_core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -258,3 +258,14 @@ void gmu_core_regrmw(struct kgsl_device *device, val &= ~mask; gmu_core_regwrite(device, offsetwords, val | bits); } + +bool gmu_core_is_initialized(struct kgsl_device *device) +{ + struct gmu_core_ops *gmu_core_ops = GMU_CORE_OPS(device); + + if (gmu_core_ops && gmu_core_ops->is_initialized) + return gmu_core_ops->is_initialized(device); + + return false; +} + diff --git a/drivers/gpu/msm/kgsl_gmu_core.h b/drivers/gpu/msm/kgsl_gmu_core.h index 52395b76b995..fb8382fb74ee 100644 --- a/drivers/gpu/msm/kgsl_gmu_core.h +++ b/drivers/gpu/msm/kgsl_gmu_core.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -134,6 +134,7 @@ struct gmu_core_ops { bool (*regulator_isenabled)(struct kgsl_device *device); int (*suspend)(struct kgsl_device *device); int (*acd_set)(struct kgsl_device *device, unsigned int val); + bool (*is_initialized)(struct kgsl_device *device); }; struct gmu_dev_ops { @@ -159,6 +160,7 @@ struct gmu_dev_ops { void (*snapshot)(struct adreno_device *, struct kgsl_snapshot *); void (*halt_execution)(struct kgsl_device *device); int (*wait_for_active_transition)(struct adreno_device *adreno_dev); + bool (*is_initialized)(struct adreno_device *adreno_dev); const unsigned int gmu2host_intr_mask; const unsigned int gmu_ao_intr_mask; }; @@ -212,4 +214,5 @@ void gmu_core_regwrite(struct kgsl_device *device, unsigned int offsetwords, void gmu_core_regrmw(struct kgsl_device *device, unsigned int offsetwords, unsigned int mask, unsigned int bits); const char *gmu_core_oob_type_str(enum oob_request req); +bool gmu_core_is_initialized(struct kgsl_device *device); #endif /* __KGSL_GMU_CORE_H */ -- GitLab From 44f331a21798726b828645b64fddd0368cbed0e3 Mon Sep 17 00:00:00 2001 From: "Thomas (Wonyoung) Yun" Date: Wed, 3 Apr 2019 17:57:56 -0400 Subject: [PATCH 0477/1121] msm: kgsl: Redo adreno governor tz init after hibernation Re-initialize adreno freq table to TZ when resuming from hibernation, since TZ is not aware of hibernation. Change-Id: Ia01be44521b9f79c5595510e9a777102ce223e25 Signed-off-by: Thomas (Wonyoung) Yun --- drivers/devfreq/governor_msm_adreno_tz.c | 31 ++++++++++++++++++++++++ drivers/gpu/msm/adreno.c | 7 ++++++ include/linux/msm_adreno_devfreq.h | 9 +++++++ 3 files changed, 47 insertions(+) diff --git a/drivers/devfreq/governor_msm_adreno_tz.c b/drivers/devfreq/governor_msm_adreno_tz.c index 779c37836ff3..9c4cce1e9656 100644 --- a/drivers/devfreq/governor_msm_adreno_tz.c +++ b/drivers/devfreq/governor_msm_adreno_tz.c @@ -519,6 +519,37 @@ static int tz_handler(struct devfreq *devfreq, unsigned int event, void *data) return result; } +int msm_adreno_devfreq_init_tz(struct devfreq *devfreq) +{ + struct devfreq_msm_adreno_tz_data *priv; + unsigned int tz_pwrlevels[MSM_ADRENO_MAX_PWRLEVELS + 1]; + int i, out = 1, ret; + unsigned int version; + + if (!devfreq) + return -EINVAL; + + priv = devfreq->data; + + if (devfreq->profile->max_state < MSM_ADRENO_MAX_PWRLEVELS) { + for (i = 0; i < devfreq->profile->max_state; i++) + tz_pwrlevels[out++] = devfreq->profile->freq_table[i]; + tz_pwrlevels[0] = i; + } else { + pr_err(TAG "tz_pwrlevels[] is too short\n"); + return -EINVAL; + } + + ret = tz_init(priv, tz_pwrlevels, sizeof(tz_pwrlevels), &version, + sizeof(version)); + if (ret != 0 || version > MAX_TZ_VERSION) { + pr_err(TAG "tz_init failed\n"); + return ret ? ret : -EINVAL; + } + + return 0; +} +EXPORT_SYMBOL(msm_adreno_devfreq_init_tz); static struct devfreq_governor msm_adreno_tz = { .name = "msm-adreno-tz", diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index b81f7934f1db..37d79a71779d 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -4083,6 +4083,13 @@ static int adreno_resume_device(struct kgsl_device *device, &device->gmu_core.flags); } } + + if (device->pwrscale.devfreqptr) { + ret = msm_adreno_devfreq_init_tz( + device->pwrscale.devfreqptr); + if (ret) + return ret; + } } if (device->state == KGSL_STATE_SUSPEND) diff --git a/include/linux/msm_adreno_devfreq.h b/include/linux/msm_adreno_devfreq.h index c99beecf3cf2..4976ce78bd6c 100644 --- a/include/linux/msm_adreno_devfreq.h +++ b/include/linux/msm_adreno_devfreq.h @@ -79,4 +79,13 @@ int devfreq_vbif_update_bw(unsigned long ib, unsigned long ab); int devfreq_vbif_register_callback(void *callback); #endif +#ifdef CONFIG_DEVFREQ_GOV_QCOM_ADRENO_TZ +int msm_adreno_devfreq_init_tz(struct devfreq *devfreq); +#else +static inline int msm_adreno_devfreq_init_tz(struct devfreq *devfreq) +{ + return 0; +} +#endif + #endif -- GitLab From 5588888870f425ccfde1bc286b501d5a25a4ea0a Mon Sep 17 00:00:00 2001 From: Skylar Chang Date: Mon, 3 Jun 2019 11:12:05 -0700 Subject: [PATCH 0478/1121] dtsi: add ipa_pm exception list Add the ipa_pm exception list for ODL/DPL clients to change the ipa-hw clock-voting for PCIE modem. Change-Id: Id469e9e74bf86ac66418485be3ffd544301c5d0a Signed-off-by: Skylar Chang --- arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi b/arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi index 78505248b54c..6a0172d89d1f 100644 --- a/arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi @@ -119,6 +119,8 @@ qcom,testbus-collection-on-crash; qcom,non-tn-collection-on-crash; qcom,secure-debug-check-action = <0>; + qcom,scaling-exceptions = "USB DPL", "0", "600", + "1000", "ODL", "0", "600", "1000"; }; qcom,ipa_fws { -- GitLab From 2e7632df8f659e4912f4fe11dcc566b3f63e2d8f Mon Sep 17 00:00:00 2001 From: "Jinesh K. Jayakumar" Date: Thu, 6 Jun 2019 14:27:48 -0400 Subject: [PATCH 0479/1121] msm: ipa: Fix kconfig dependency for AQC offload driver Add missing kconfig dependency from AQC_IPA_PROXY_* choice to AQC_IPA option. Change-Id: I853119bdb40dd6422effbf50dc38237f12536fb6 Signed-off-by: Jinesh K. Jayakumar --- drivers/platform/msm/ipa/ipa_v3/ethernet/aquantia/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/platform/msm/ipa/ipa_v3/ethernet/aquantia/Kconfig b/drivers/platform/msm/ipa/ipa_v3/ethernet/aquantia/Kconfig index 8fdbbbc475bd..b1abbc2db8f6 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ethernet/aquantia/Kconfig +++ b/drivers/platform/msm/ipa/ipa_v3/ethernet/aquantia/Kconfig @@ -11,6 +11,7 @@ config AQC_IPA choice prompt "Default Rx Interrupt Proxy Method" + depends on AQC_IPA default AQC_IPA_PROXY_HOST config AQC_IPA_PROXY_UC -- GitLab From b741b1ab8ea4a69f3a7adc238071e52ad774ab3e Mon Sep 17 00:00:00 2001 From: "Jinesh K. Jayakumar" Date: Thu, 6 Jun 2019 15:46:45 -0400 Subject: [PATCH 0480/1121] defconfig: sdxprairie: Disable AQC IPA offload driver Disable AQC IPA offload driver until we enable support for IPA offload sub-system API v2 in the offload driver. Change-Id: I3516ecb8b7176b1143b0fb451e3796d6ad3835ee Signed-off-by: Jinesh K. Jayakumar --- arch/arm/configs/vendor/sdxprairie-perf_defconfig | 2 -- arch/arm/configs/vendor/sdxprairie_defconfig | 3 --- 2 files changed, 5 deletions(-) diff --git a/arch/arm/configs/vendor/sdxprairie-perf_defconfig b/arch/arm/configs/vendor/sdxprairie-perf_defconfig index d629857a60fe..8b95fa0ade4f 100644 --- a/arch/arm/configs/vendor/sdxprairie-perf_defconfig +++ b/arch/arm/configs/vendor/sdxprairie-perf_defconfig @@ -352,8 +352,6 @@ CONFIG_MSM_MHI_DEV=y CONFIG_IPA3=y CONFIG_IPA_WDI_UNIFIED_API=y CONFIG_IPA_ETH=y -CONFIG_AQC_IPA=y -CONFIG_AQC_IPA_PROXY_UC=y CONFIG_RMNET_IPA3=y CONFIG_ECM_IPA=y CONFIG_RNDIS_IPA=y diff --git a/arch/arm/configs/vendor/sdxprairie_defconfig b/arch/arm/configs/vendor/sdxprairie_defconfig index 04b5b0310ce4..e25428a5892c 100644 --- a/arch/arm/configs/vendor/sdxprairie_defconfig +++ b/arch/arm/configs/vendor/sdxprairie_defconfig @@ -356,9 +356,6 @@ CONFIG_IPA_DEBUG=y CONFIG_IPA_WDI_UNIFIED_API=y CONFIG_IPA_ETH=y CONFIG_IPA_ETH_DEBUG=y -CONFIG_AQC_IPA=y -CONFIG_AQC_IPA_PROXY_UC=y -CONFIG_AQC_IPA_DEBUG=y CONFIG_RMNET_IPA3=y CONFIG_ECM_IPA=y CONFIG_RNDIS_IPA=y -- GitLab From 0f39dc7fd4cee73fd13d149f2ee9f9fa6bece7a6 Mon Sep 17 00:00:00 2001 From: "Jinesh K. Jayakumar" Date: Thu, 16 May 2019 15:36:16 -0400 Subject: [PATCH 0481/1121] msm: ipa: Add support for memory allocator in offload sub-system Add support for offload and network drivers to use custom memory allocators for allocating channel and descriptor memory. Change-Id: I764d96fa80222e6bae14a30240fc45d60b2691a1 Signed-off-by: Jinesh K. Jayakumar --- .../aquantia/atlantic-fwd/atl_qcom_ipa.c | 221 +++- .../platform/msm/ipa/ipa_v3/ethernet/Makefile | 1 + .../msm/ipa/ipa_v3/ethernet/ipa_eth.c | 44 +- .../msm/ipa/ipa_v3/ethernet/ipa_eth_bus.c | 2 + .../msm/ipa/ipa_v3/ethernet/ipa_eth_ep.c | 204 ++-- .../msm/ipa/ipa_v3/ethernet/ipa_eth_i.h | 16 +- .../msm/ipa/ipa_v3/ethernet/ipa_eth_net.c | 1060 +++++++++++++++++ .../msm/ipa/ipa_v3/ethernet/ipa_eth_offload.c | 25 +- include/linux/ipa_eth.h | 403 +++++-- 9 files changed, 1746 insertions(+), 230 deletions(-) create mode 100644 drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_net.c diff --git a/drivers/net/ethernet/aquantia/atlantic-fwd/atl_qcom_ipa.c b/drivers/net/ethernet/aquantia/atlantic-fwd/atl_qcom_ipa.c index 230c2bbbd15a..586d7c2335d0 100644 --- a/drivers/net/ethernet/aquantia/atlantic-fwd/atl_qcom_ipa.c +++ b/drivers/net/ethernet/aquantia/atlantic-fwd/atl_qcom_ipa.c @@ -14,28 +14,99 @@ #include #include + +#define IPA_ETH_NET_DRIVER #include #include "atl_fwd.h" #include "atl_qcom_ipa.h" -#define ATL_IPA_DEFAULT_RING_SZ 128 -#define ATL_IPA_DEFAULT_BUFF_SZ 2048 - static inline struct atl_fwd_ring *CH_RING(struct ipa_eth_channel *ch) { return (struct atl_fwd_ring *)(ch->nd_priv); } +static void *atl_ipa_dma_alloc(struct device *dev, size_t size, + dma_addr_t *daddr, gfp_t gfp, + struct ipa_eth_dma_allocator *dma_allocator) +{ + struct atl_nic *nic = (struct atl_nic *)dev_get_drvdata(dev); + struct ipa_eth_device *eth_dev = nic->fwd.private; + struct ipa_eth_resource mem; + + if (dma_allocator->alloc(eth_dev, size, gfp, &mem)) + return NULL; + + if (daddr) + *daddr = mem.daddr; + + return mem.vaddr; +} + +static void atl_ipa_dma_free(void *buf, struct device *dev, size_t size, + dma_addr_t daddr, + struct ipa_eth_dma_allocator *dma_allocator) +{ + struct atl_nic *nic = (struct atl_nic *)dev_get_drvdata(dev); + struct ipa_eth_device *eth_dev = nic->fwd.private; + struct ipa_eth_resource mem = { + .size = size, + .vaddr = buf, + .daddr = daddr, + }; + + return dma_allocator->free(eth_dev, &mem); +} + +static void *atl_ipa_alloc_descs(struct device *dev, size_t size, + dma_addr_t *daddr, gfp_t gfp, + struct atl_fwd_mem_ops *ops) +{ + struct ipa_eth_channel *ch = ops->private; + + return atl_ipa_dma_alloc(dev, size, daddr, gfp, + ch->mem_params.desc.allocator); +} + +static void *atl_ipa_alloc_buf(struct device *dev, size_t size, + dma_addr_t *daddr, gfp_t gfp, + struct atl_fwd_mem_ops *ops) +{ + struct ipa_eth_channel *ch = ops->private; + + return atl_ipa_dma_alloc(dev, size, daddr, gfp, + ch->mem_params.buff.allocator); +} + +static void atl_ipa_free_descs(void *buf, struct device *dev, size_t size, + dma_addr_t daddr, struct atl_fwd_mem_ops *ops) +{ + struct ipa_eth_channel *ch = ops->private; + + return atl_ipa_dma_free(buf, dev, size, daddr, + ch->mem_params.desc.allocator); +} + +static void atl_ipa_free_buf(void *buf, struct device *dev, size_t size, + dma_addr_t daddr, struct atl_fwd_mem_ops *ops) +{ + struct ipa_eth_channel *ch = ops->private; + + return atl_ipa_dma_free(buf, dev, size, daddr, + ch->mem_params.desc.allocator); +} + static int atl_ipa_open_device(struct ipa_eth_device *eth_dev) { struct atl_nic *nic = (struct atl_nic *)dev_get_drvdata(eth_dev->dev); if (!nic || !nic->ndev) { - dev_err(eth_dev->dev, "Invalid atl_nic"); + dev_err(eth_dev->dev, "Invalid atl_nic\n"); return -ENODEV; } + nic->fwd.private = eth_dev; + /* atl specific init, ref counting go here */ eth_dev->nd_priv = nic; @@ -46,17 +117,48 @@ static int atl_ipa_open_device(struct ipa_eth_device *eth_dev) static void atl_ipa_close_device(struct ipa_eth_device *eth_dev) { + struct atl_nic *nic = eth_dev->nd_priv; + + nic->fwd.private = NULL; + eth_dev->nd_priv = NULL; eth_dev->net_dev = NULL; } static struct ipa_eth_channel *atl_ipa_request_channel( struct ipa_eth_device *eth_dev, enum ipa_eth_channel_dir dir, - unsigned long features, unsigned long events) + unsigned long events, unsigned long features, + const struct ipa_eth_channel_mem_params *mem_params) { struct atl_fwd_ring *ring = NULL; enum atl_fwd_ring_flags ring_flags = 0; struct ipa_eth_channel *channel = NULL; + struct atl_fwd_mem_ops *mem_ops = NULL; + struct ipa_eth_channel_mem *desc_mem = NULL; + struct ipa_eth_channel_mem *buff_mem = NULL; + size_t desc_count; + size_t buff_size; + + channel = + ipa_eth_net_alloc_channel(eth_dev, dir, + events, features, mem_params); + if (!channel) { + dev_err(eth_dev->dev, "Failed to alloc ipa eth channel\n"); + goto err_channel; + } + + desc_count = channel->mem_params.desc.count; + buff_size = channel->mem_params.buff.size; + + mem_ops = kzalloc(sizeof(*mem_ops), GFP_KERNEL); + if (!mem_ops) + goto err_mem_ops; + + mem_ops->alloc_descs = atl_ipa_alloc_descs; + mem_ops->alloc_buf = atl_ipa_alloc_buf; + mem_ops->free_descs = atl_ipa_free_descs; + mem_ops->free_buf = atl_ipa_free_buf; + mem_ops->private = channel; switch (dir) { case IPA_ETH_DIR_RX: @@ -65,67 +167,92 @@ static struct ipa_eth_channel *atl_ipa_request_channel( ring_flags |= ATL_FWR_TX; break; default: - dev_err(eth_dev->dev, "Unsupported direction %d", dir); - return NULL; + dev_err(eth_dev->dev, "Unsupported direction %d\n", dir); + goto err_dir; } ring_flags |= ATL_FWR_ALLOC_BUFS; ring_flags |= ATL_FWR_CONTIG_BUFS; ring = atl_fwd_request_ring(eth_dev->net_dev, ring_flags, - ATL_IPA_DEFAULT_RING_SZ, - ATL_IPA_DEFAULT_BUFF_SZ, 1, NULL); + desc_count, buff_size, 1, mem_ops); if (IS_ERR_OR_NULL(ring)) { - dev_err(eth_dev->dev, "Request ring failed"); - goto err_exit; + dev_err(eth_dev->dev, "Request ring failed\n"); + goto err_ring; } - channel = kzalloc(sizeof(*channel), GFP_KERNEL); - if (!channel) - goto err_exit; - - channel->events = 0; - channel->features = 0; - channel->direction = dir; + channel->nd_priv = ring; channel->queue = ring->idx; - channel->desc_size = 16; - channel->desc_count = ring->hw.size; - channel->desc_mem.size = channel->desc_size * channel->desc_count; + desc_mem = kzalloc(sizeof(*desc_mem), GFP_KERNEL); + if (!desc_mem) + goto err_desc_mem; - channel->desc_mem.vaddr = ring->hw.descs; - channel->desc_mem.daddr = ring->hw.daddr; - channel->desc_mem.paddr = - page_to_phys(vmalloc_to_page(channel->desc_mem.vaddr)); + channel->mem_params.desc.size = 16; + channel->mem_params.desc.count = ring->hw.size; - channel->buff_size = ATL_IPA_DEFAULT_BUFF_SZ; - channel->buff_count = channel->desc_count; - channel->buff_mem.size = channel->buff_size * channel->buff_count; + desc_mem->mem.size = + channel->mem_params.desc.size * channel->mem_params.desc.count; + desc_mem->mem.vaddr = ring->hw.descs; + desc_mem->mem.daddr = ring->hw.daddr; + desc_mem->mem.paddr = channel->mem_params.desc.allocator->paddr( + eth_dev, desc_mem->mem.vaddr); - channel->buff_mem.vaddr = (void *)ring->bufs->vaddr_vec; - channel->buff_mem.daddr = ring->bufs->daddr_vec_base; - channel->buff_mem.paddr = virt_to_phys((void *)ring->bufs->vaddr_vec); + buff_mem = kzalloc(sizeof(*buff_mem), GFP_KERNEL); + if (!buff_mem) + goto err_buff_mem; - channel->eth_dev = eth_dev; - channel->nd_priv = ring; + channel->mem_params.buff.size = buff_size; + channel->mem_params.buff.count = channel->mem_params.desc.count; - return channel; + buff_mem->mem.size = + channel->mem_params.buff.size * channel->mem_params.buff.count; + buff_mem->mem.vaddr = (void *)ring->bufs->vaddr_vec; + buff_mem->mem.daddr = ring->bufs->daddr_vec_base; + buff_mem->mem.paddr = channel->mem_params.buff.allocator->paddr( + eth_dev, buff_mem->mem.vaddr); -err_exit: - kzfree(channel); + list_add(&desc_mem->mem_list_entry, &channel->desc_mem); + list_add(&buff_mem->mem_list_entry, &channel->buff_mem); - if (!IS_ERR_OR_NULL(ring)) { - atl_fwd_release_ring(ring); - ring = NULL; - } + return channel; +err_buff_mem: + kzfree(desc_mem); +err_desc_mem: + atl_fwd_release_ring(ring); +err_ring: +err_dir: + if (mem_ops) + kzfree(mem_ops); +err_mem_ops: + ipa_eth_net_free_channel(channel); +err_channel: return NULL; } static void atl_ipa_release_channel(struct ipa_eth_channel *ch) { - atl_fwd_release_ring(CH_RING(ch)); - kzfree(ch); + struct ipa_eth_channel_mem *mem, *tmp; + struct atl_fwd_ring *ring = CH_RING(ch); + struct atl_fwd_mem_ops *mem_ops = ring->mem_ops; + + atl_fwd_release_ring(ring); + + if (mem_ops) + kzfree(mem_ops); + + list_for_each_entry_safe(mem, tmp, &ch->desc_mem, mem_list_entry) { + list_del(&mem->mem_list_entry); + kzfree(mem); + } + + list_for_each_entry_safe(mem, tmp, &ch->buff_mem, mem_list_entry) { + list_del(&mem->mem_list_entry); + kzfree(mem); + } + + ipa_eth_net_free_channel(ch); } static int atl_ipa_enable_channel(struct ipa_eth_channel *ch) @@ -153,7 +280,7 @@ static int atl_ipa_request_event(struct ipa_eth_channel *ch, case IPA_ETH_DEV_EV_RX_INT: if (ch->direction != IPA_ETH_DIR_RX) { dev_err(eth_dev->dev, - "Rx interrupt requested on incorrect channel"); + "Rx interrupt requested on tx channel\n"); return -EFAULT; } @@ -166,7 +293,7 @@ static int atl_ipa_request_event(struct ipa_eth_channel *ch, case IPA_ETH_DEV_EV_TX_INT: if (ch->direction != IPA_ETH_DIR_TX) { dev_err(eth_dev->dev, - "Tx interrupt requested on incorrect channel"); + "Tx interrupt requested on rx channel\n"); return -EFAULT; } @@ -179,7 +306,7 @@ static int atl_ipa_request_event(struct ipa_eth_channel *ch, case IPA_ETH_DEV_EV_TX_PTR: if (ch->direction != IPA_ETH_DIR_TX) { dev_err(eth_dev->dev, - "Tx ptr wrb requested on incorrect channel"); + "Tx ptr wrb requested on rx channel\n"); return -EFAULT; } @@ -190,7 +317,7 @@ static int atl_ipa_request_event(struct ipa_eth_channel *ch, break; default: - dev_err(eth_dev->dev, "Unsupported event requested"); + dev_err(eth_dev->dev, "Unsupported event requested\n"); return -ENODEV; } @@ -226,7 +353,7 @@ static void atl_ipa_release_event(struct ipa_eth_channel *ch, break; default: - dev_err(eth_dev->dev, "Unsupported event for release"); + dev_err(eth_dev->dev, "Unsupported event for release\n"); return; } diff --git a/drivers/platform/msm/ipa/ipa_v3/ethernet/Makefile b/drivers/platform/msm/ipa/ipa_v3/ethernet/Makefile index ea66a4d6df39..7bb1bf9430b0 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ethernet/Makefile +++ b/drivers/platform/msm/ipa/ipa_v3/ethernet/Makefile @@ -6,6 +6,7 @@ ipa-eth-y := \ ipa_eth.o \ ipa_eth_ep.o \ ipa_eth_gsi.o \ + ipa_eth_net.o \ ipa_eth_offload.o \ ipa_eth_pci.o \ ipa_eth_pm.o \ diff --git a/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth.c b/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth.c index 09e2d7c06ba1..0405b09a24ba 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth.c +++ b/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth.c @@ -244,7 +244,9 @@ static void __ipa_eth_refresh_device(struct work_struct *work) if (initable(eth_dev)) { if (eth_dev->of_state == IPA_ETH_OF_ST_DEINITED) { + IPA_ACTIVE_CLIENTS_INC_SIMPLE(); (void) ipa_eth_init_device(eth_dev); + IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); if (eth_dev->of_state != IPA_ETH_OF_ST_INITED) { ipa_eth_dev_err(eth_dev, @@ -255,7 +257,9 @@ static void __ipa_eth_refresh_device(struct work_struct *work) } if (startable(eth_dev)) { + IPA_ACTIVE_CLIENTS_INC_SIMPLE(); (void) ipa_eth_start_device(eth_dev); + IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); if (eth_dev->of_state != IPA_ETH_OF_ST_STARTED) { ipa_eth_dev_err(eth_dev, "Failed to start device"); @@ -269,7 +273,9 @@ static void __ipa_eth_refresh_device(struct work_struct *work) ipa_eth_dev_log(eth_dev, "Start is disallowed for the device"); if (eth_dev->of_state == IPA_ETH_OF_ST_STARTED) { + IPA_ACTIVE_CLIENTS_INC_SIMPLE(); ipa_eth_stop_device(eth_dev); + IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); if (eth_dev->of_state != IPA_ETH_OF_ST_INITED) { ipa_eth_dev_err(eth_dev, @@ -282,7 +288,9 @@ static void __ipa_eth_refresh_device(struct work_struct *work) if (!initable(eth_dev)) { ipa_eth_dev_log(eth_dev, "Init is disallowed for the device"); + IPA_ACTIVE_CLIENTS_INC_SIMPLE(); ipa_eth_deinit_device(eth_dev); + IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); if (eth_dev->of_state != IPA_ETH_OF_ST_DEINITED) { ipa_eth_dev_err(eth_dev, "Failed to deinit device"); @@ -382,18 +390,6 @@ static void ipa_eth_ipa_ready_cb(void *data) ipa_eth_refresh_devices(); } -struct ipa_eth_device *ipa_eth_find_device(struct device *dev) -{ - struct ipa_eth_device *eth_dev; - - list_for_each_entry(eth_dev, &ipa_eth_devices, device_list) { - if (eth_dev->dev == dev) - return eth_dev; - } - - return NULL; -} - static ssize_t ipa_eth_dev_write_init(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) @@ -626,6 +622,8 @@ static void ipa_eth_unpair_devices(struct ipa_eth_offload_driver *od) int ipa_eth_register_device(struct ipa_eth_device *eth_dev) { + int rc; + if (!eth_dev->dev) { ipa_eth_dev_err(eth_dev, "Device is NULL"); return -EINVAL; @@ -640,8 +638,23 @@ int ipa_eth_register_device(struct ipa_eth_device *eth_dev) eth_dev->pm_handle = IPA_PM_MAX_CLIENTS; INIT_WORK(ð_dev->refresh, __ipa_eth_refresh_device); + INIT_LIST_HEAD(ð_dev->rx_channels); + INIT_LIST_HEAD(ð_dev->tx_channels); + eth_dev->init = eth_dev->start = !ipa_eth_noauto; + rc = ipa_eth_net_open_device(eth_dev); + if (rc) { + ipa_eth_dev_err(eth_dev, "Failed to open network device"); + return rc; + } + + if (!eth_dev->net_dev) { + ipa_eth_dev_err(eth_dev, "Netdev info is missing"); + ipa_eth_net_close_device(eth_dev); + return -EFAULT; + } + mutex_lock(&ipa_eth_devices_lock); list_add(ð_dev->device_list, &ipa_eth_devices); @@ -661,10 +674,11 @@ void ipa_eth_unregister_device(struct ipa_eth_device *eth_dev) __ipa_eth_unpair_device(eth_dev); list_del(ð_dev->device_list); - - ipa_eth_dev_log(eth_dev, "Unregistered device"); + ipa_eth_net_close_device(eth_dev); mutex_unlock(&ipa_eth_devices_lock); + + ipa_eth_dev_log(eth_dev, "Unregistered device"); } static phys_addr_t ipa_eth_vmalloc_to_pa(void *vaddr) @@ -979,7 +993,7 @@ void *ipa_eth_get_ipc_logbuf_dbg(void) } EXPORT_SYMBOL(ipa_eth_get_ipc_logbuf_dbg); -#define IPA_ETH_IPC_LOG_PAGES 50 +#define IPA_ETH_IPC_LOG_PAGES 128 static int ipa_eth_ipc_log_init(void) { diff --git a/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_bus.c b/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_bus.c index eaccf5ee28a0..b41a7a81936d 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_bus.c +++ b/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_bus.c @@ -10,6 +10,8 @@ * GNU General Public License for more details. */ +#include + #include "ipa_eth_i.h" static bool ipa_eth_bus_is_ready; diff --git a/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_ep.c b/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_ep.c index a75970d2f6be..d497214e2193 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_ep.c +++ b/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_ep.c @@ -131,7 +131,7 @@ int ipa_eth_ep_init_headers(struct ipa_eth_device *eth_dev) { int rc = 0; bool vlan_mode; - const size_t num_hdrs = 2; // one each for IPv4 and IPv6 + const size_t num_hdrs = 2; /* one each for IPv4 and IPv6 */ size_t hdr_alloc_sz = sizeof(struct ipa_ioc_add_hdr) + num_hdrs * sizeof(struct ipa_hdr_add); struct ipa_hdr_add *hdr_v4 = NULL; @@ -156,7 +156,7 @@ int ipa_eth_ep_init_headers(struct ipa_eth_device *eth_dev) hdrs->commit = 1; hdrs->num_hdrs = num_hdrs; - // Initialize IPv4 headers + /* Initialize IPv4 headers */ snprintf(hdr_v4->name, sizeof(hdr_v4->name), "%s_ipv4", eth_dev->net_dev->name); @@ -165,7 +165,7 @@ int ipa_eth_ep_init_headers(struct ipa_eth_device *eth_dev) else ipa_eth_init_vlan_header_v4(eth_dev, hdr_v4); - // Initialize IPv6 headers + /* Initialize IPv6 headers */ snprintf(hdr_v6->name, sizeof(hdr_v6->name), "%s_ipv6", eth_dev->net_dev->name); @@ -184,10 +184,11 @@ int ipa_eth_ep_init_headers(struct ipa_eth_device *eth_dev) } static void ipa_eth_ep_init_tx_props_v4(struct ipa_eth_device *eth_dev, - struct ipa_ioc_tx_intf_prop *props) + struct ipa_eth_channel *ch, + struct ipa_ioc_tx_intf_prop *props) { props->ip = IPA_IP_v4; - props->dst_pipe = eth_dev->ch_tx->ipa_client; + props->dst_pipe = ch->ipa_client; props->hdr_l2_type = IPA_HDR_L2_ETHERNET_II; snprintf(props->hdr_name, sizeof(props->hdr_name), "%s_ipv4", @@ -196,10 +197,11 @@ static void ipa_eth_ep_init_tx_props_v4(struct ipa_eth_device *eth_dev, } static void ipa_eth_ep_init_tx_props_v6(struct ipa_eth_device *eth_dev, - struct ipa_ioc_tx_intf_prop *props) + struct ipa_eth_channel *ch, + struct ipa_ioc_tx_intf_prop *props) { props->ip = IPA_IP_v6; - props->dst_pipe = eth_dev->ch_tx->ipa_client; + props->dst_pipe = ch->ipa_client; props->hdr_l2_type = IPA_HDR_L2_ETHERNET_II; snprintf(props->hdr_name, sizeof(props->hdr_name), "%s_ipv6", @@ -207,25 +209,79 @@ static void ipa_eth_ep_init_tx_props_v6(struct ipa_eth_device *eth_dev, } static void ipa_eth_ep_init_rx_props_v4(struct ipa_eth_device *eth_dev, - struct ipa_ioc_rx_intf_prop *props) + struct ipa_eth_channel *ch, + struct ipa_ioc_rx_intf_prop *props) { props->ip = IPA_IP_v4; - props->src_pipe = eth_dev->ch_rx->ipa_client; + props->src_pipe = ch->ipa_client; props->hdr_l2_type = IPA_HDR_L2_ETHERNET_II; - - // TODO: what about attrib? } static void ipa_eth_ep_init_rx_props_v6(struct ipa_eth_device *eth_dev, - struct ipa_ioc_rx_intf_prop *props) + struct ipa_eth_channel *ch, + struct ipa_ioc_rx_intf_prop *props) { props->ip = IPA_IP_v6; - props->src_pipe = eth_dev->ch_rx->ipa_client; + props->src_pipe = ch->ipa_client; props->hdr_l2_type = IPA_HDR_L2_ETHERNET_II; +} + +static int ipa_eth_ep_init_tx_intf(struct ipa_eth_device *eth_dev, + struct ipa_tx_intf *tx_intf) +{ + u32 num_props; + struct list_head *l; + struct ipa_eth_channel *ch; + + num_props = 0; + list_for_each(l, ð_dev->tx_channels) + num_props += 2; /* one each for IPv4 and IPv6 */ + + tx_intf->prop = kcalloc(num_props, sizeof(*tx_intf->prop), GFP_KERNEL); + if (!tx_intf->prop) { + ipa_eth_dev_err(eth_dev, "Failed to alloc tx props"); + return -ENOMEM; + } + + tx_intf->num_props = 0; + list_for_each_entry(ch, ð_dev->tx_channels, channel_list) { + ipa_eth_ep_init_tx_props_v4(eth_dev, ch, + &tx_intf->prop[tx_intf->num_props++]); + ipa_eth_ep_init_tx_props_v6(eth_dev, ch, + &tx_intf->prop[tx_intf->num_props++]); + } - // TODO: what about attrib? + return 0; +} + +static int ipa_eth_ep_init_rx_intf(struct ipa_eth_device *eth_dev, + struct ipa_rx_intf *rx_intf) +{ + u32 num_props; + struct list_head *l; + struct ipa_eth_channel *ch; + + num_props = 0; + list_for_each(l, ð_dev->rx_channels) + num_props += 2; /* one each for IPv4 and IPv6 */ + + rx_intf->prop = kcalloc(num_props, sizeof(*rx_intf->prop), GFP_KERNEL); + if (!rx_intf->prop) { + ipa_eth_dev_err(eth_dev, "Failed to alloc rx props"); + return -ENOMEM; + } + + rx_intf->num_props = 0; + list_for_each_entry(ch, ð_dev->rx_channels, channel_list) { + ipa_eth_ep_init_rx_props_v4(eth_dev, ch, + &rx_intf->prop[rx_intf->num_props++]); + ipa_eth_ep_init_rx_props_v6(eth_dev, ch, + &rx_intf->prop[rx_intf->num_props++]); + } + + return 0; } /** @@ -240,27 +296,28 @@ static void ipa_eth_ep_init_rx_props_v6(struct ipa_eth_device *eth_dev, */ int ipa_eth_ep_register_interface(struct ipa_eth_device *eth_dev) { + int rc; struct ipa_tx_intf tx_intf; struct ipa_rx_intf rx_intf; - const size_t num_props = 2; // one each for IPv4 and IPv6 - struct ipa_ioc_tx_intf_prop tx_props[num_props]; - struct ipa_ioc_rx_intf_prop rx_props[num_props]; - memset(&tx_props, 0, sizeof(tx_props)); - ipa_eth_ep_init_tx_props_v4(eth_dev, &tx_props[0]); - ipa_eth_ep_init_tx_props_v6(eth_dev, &tx_props[1]); + memset(&tx_intf, 0, sizeof(tx_intf)); + memset(&rx_intf, 0, sizeof(rx_intf)); - tx_intf.num_props = num_props; - tx_intf.prop = tx_props; + rc = ipa_eth_ep_init_tx_intf(eth_dev, &tx_intf); + if (rc) + goto free_and_exit; + + rc = ipa_eth_ep_init_rx_intf(eth_dev, &rx_intf); + if (rc) + goto free_and_exit; - memset(&rx_props, 0, sizeof(rx_props)); - ipa_eth_ep_init_rx_props_v4(eth_dev, &rx_props[0]); - ipa_eth_ep_init_rx_props_v6(eth_dev, &rx_props[1]); + rc = ipa_register_intf(eth_dev->net_dev->name, &tx_intf, &rx_intf); - rx_intf.num_props = num_props; - rx_intf.prop = rx_props; +free_and_exit: + kzfree(tx_intf.prop); + kzfree(rx_intf.prop); - return ipa_register_intf(eth_dev->net_dev->name, &tx_intf, &rx_intf); + return rc; } /** @@ -274,44 +331,16 @@ int ipa_eth_ep_unregister_interface(struct ipa_eth_device *eth_dev) } /** - * ipa_eth_ep_init - Initialize IPA endpoint for a channel - * @ch: Channel for which EP need to be initialized - * - * Return: 0 on success, negative errno otherwise + * ipa_eth_ep_init_ctx - Initialize IPA endpoint context for a channel + * @ch: Channel for which EP ctx need to be initialized + * @vlan_mode: true if VLAN mode is enabled for the EP */ -int ipa_eth_ep_init(struct ipa_eth_channel *ch) +void ipa_eth_ep_init_ctx(struct ipa_eth_channel *ch, bool vlan_mode) { - int rc = 0; - bool vlan_mode; - const bool client_prod = IPA_CLIENT_IS_PROD(ch->ipa_client); - const int ep_num = ipa_get_ep_mapping(ch->ipa_client); - - struct ipa3_ep_context *ep_ctx = NULL; - - if (ep_num == IPA_EP_NOT_ALLOCATED) { - ipa_eth_dev_err(ch->eth_dev, - "Could not determine EP number for client %d", - ch->ipa_client); - rc = -EFAULT; - goto err_exit; - } - - ch->ipa_ep_num = ep_num; - - rc = ipa3_is_vlan_mode(IPA_VLAN_IF_ETH, &vlan_mode); - if (rc) { - ipa_eth_dev_err(ch->eth_dev, - "Could not determine IPA VLAN mode"); - goto err_exit; - } + struct ipa3_ep_context *ep_ctx = &ipa3_ctx->ep[ch->ipa_ep_num]; - ep_ctx = &ipa3_ctx->ep[ep_num]; - if (ep_ctx->valid) { - ipa_eth_dev_err(ch->eth_dev, - "EP context is already initialiazed"); - rc = -EEXIST; - goto err_exit; - } + if (ep_ctx->valid) + return; memset(ep_ctx, 0, offsetof(typeof(*ep_ctx), sys)); @@ -320,30 +349,57 @@ int ipa_eth_ep_init(struct ipa_eth_channel *ch) ep_ctx->client_notify = ipa_ep_client_notifier; ep_ctx->priv = ch; - ep_ctx->cfg.nat.nat_en = client_prod ? IPA_SRC_NAT : IPA_BYPASS_NAT; + ep_ctx->cfg.nat.nat_en = IPA_CLIENT_IS_PROD(ch->ipa_client) ? + IPA_SRC_NAT : IPA_BYPASS_NAT; ep_ctx->cfg.hdr.hdr_len = vlan_mode ? VLAN_ETH_HLEN : ETH_HLEN; - ep_ctx->cfg.mode.mode = IPA_BASIC; +} + +/** + * ipa_eth_ep_deinit_ctx - Deinitialize IPA endpoint context for a channel + * @ch: Channel for which EP ctx need to be deinitialized + */ +void ipa_eth_ep_deinit_ctx(struct ipa_eth_channel *ch) +{ + struct ipa3_ep_context *ep_ctx = &ipa3_ctx->ep[ch->ipa_ep_num]; -#ifdef IPA_ETH_DMA_MODE - if (IPA_ETH_CH_IS_RX(ch)) { - ep_ctx->cfg.mode.mode = IPA_DMA; - ep_ctx->cfg.mode.dst = IPA_CLIENT_AQC_ETHERNET_CONS; + if (!ep_ctx->valid) + return; + + ep_ctx->valid = false; + + memset(ep_ctx, 0, offsetof(typeof(*ep_ctx), sys)); +} + +/** + * ipa_eth_ep_init - Initialize IPA endpoint for a channel + * @ch: Channel for which EP need to be initialized + * + * Return: 0 on success, negative errno otherwise + */ +int ipa_eth_ep_init(struct ipa_eth_channel *ch) +{ + int rc = 0; + struct ipa3_ep_context *ep_ctx = NULL; + + ep_ctx = &ipa3_ctx->ep[ch->ipa_ep_num]; + if (!ep_ctx->valid) { + ipa_eth_dev_bug(ch->eth_dev, "EP context is not initialiazed"); + return -EFAULT; } -#endif IPA_ACTIVE_CLIENTS_INC_SIMPLE(); - rc = ipa3_cfg_ep(ep_num, &ep_ctx->cfg); + rc = ipa3_cfg_ep(ch->ipa_ep_num, &ep_ctx->cfg); if (rc) { ipa_eth_dev_err(ch->eth_dev, - "Failed to configure EP %d", ep_num); + "Failed to configure EP %d", ch->ipa_ep_num); IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); goto err_exit; } - if (IPA_ETH_CH_IS_RX(ch)) - ipa3_install_dflt_flt_rules(ep_num); + if (IPA_CLIENT_IS_PROD(ch->ipa_client)) + ipa3_install_dflt_flt_rules(ch->ipa_ep_num); IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); diff --git a/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_i.h b/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_i.h index 5f431f08da9f..1c63fc92e4d2 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_i.h @@ -13,7 +13,8 @@ #ifndef _IPA_ETH_I_H_ #define _IPA_ETH_I_H_ -#include +#define IPA_ETH_NET_DRIVER +#define IPA_ETH_OFFLOAD_DRIVER #include #include "../ipa_i.h" @@ -97,6 +98,14 @@ struct ipa_eth_bus { extern struct ipa_eth_bus ipa_eth_pci_bus; +struct ipa_eth_cb_map_param { + bool map; + bool sym; + int iommu_prot; + enum dma_data_direction dma_dir; + const struct ipa_smmu_cb_ctx *cb_ctx; +}; + int ipa_eth_register_device(struct ipa_eth_device *eth_dev); void ipa_eth_unregister_device(struct ipa_eth_device *eth_dev); @@ -137,9 +146,14 @@ int ipa_eth_offload_deinit(struct ipa_eth_device *eth_dev); int ipa_eth_offload_start(struct ipa_eth_device *eth_dev); int ipa_eth_offload_stop(struct ipa_eth_device *eth_dev); +int ipa_eth_net_open_device(struct ipa_eth_device *eth_dev); +void ipa_eth_net_close_device(struct ipa_eth_device *eth_dev); + int ipa_eth_ep_init_headers(struct ipa_eth_device *eth_dev); int ipa_eth_ep_register_interface(struct ipa_eth_device *eth_dev); int ipa_eth_ep_unregister_interface(struct ipa_eth_device *eth_dev); +void ipa_eth_ep_init_ctx(struct ipa_eth_channel *ch, bool vlan_mode); +void ipa_eth_ep_deinit_ctx(struct ipa_eth_channel *ch); int ipa_eth_pm_register(struct ipa_eth_device *eth_dev); int ipa_eth_pm_unregister(struct ipa_eth_device *eth_dev); diff --git a/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_net.c b/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_net.c new file mode 100644 index 000000000000..1e993936abe9 --- /dev/null +++ b/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_net.c @@ -0,0 +1,1060 @@ +/* Copyright (c) 2019 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "ipa_eth_i.h" + +#define ipa_eth_nd_op(eth_dev, op, args...) (eth_dev->nd->ops->op(args)) + +int ipa_eth_net_open_device(struct ipa_eth_device *eth_dev) +{ + return ipa_eth_nd_op(eth_dev, open_device, eth_dev); +} + +void ipa_eth_net_close_device(struct ipa_eth_device *eth_dev) +{ + return ipa_eth_nd_op(eth_dev, close_device, eth_dev); +} + +static phys_addr_t ipa_eth_dma_pgaddr(struct ipa_eth_device *eth_dev, + const void *vaddr) +{ + return page_to_phys(vmalloc_to_page(vaddr)); +} + +static phys_addr_t ipa_eth_dma_paddr(struct ipa_eth_device *eth_dev, + const void *vaddr) +{ + return ipa_eth_dma_pgaddr(eth_dev, vaddr) | + ((phys_addr_t)vaddr & ~PAGE_MASK); +} + +static int ipa_eth_dma_alloc(struct ipa_eth_device *eth_dev, + size_t size, gfp_t gfp, struct ipa_eth_resource *mem) +{ + if (!eth_dev || !eth_dev->dev) { + ipa_eth_dev_err(eth_dev, "eth_dev is invalid"); + return -EFAULT; + } + + if (!mem) { + ipa_eth_dev_err(eth_dev, "Missing mem parameter"); + return -EINVAL; + } + + memset(mem, 0, sizeof(*mem)); + + mem->vaddr = dma_alloc_coherent(eth_dev->dev, size, &mem->daddr, gfp); + if (!mem->vaddr) { + ipa_eth_dev_err(eth_dev, + "Failed to allocate memory of size %zu", size); + return -ENOMEM; + } + + mem->size = size; + mem->paddr = ipa_eth_dma_paddr(eth_dev, mem->vaddr); + + ipa_eth_dev_log(eth_dev, + "Allocated memory of size %zu at [%pK,%pad,%pap]", + mem->size, mem->vaddr, &mem->daddr, &mem->paddr); + + return 0; +} + +static void ipa_eth_dma_free(struct ipa_eth_device *eth_dev, + struct ipa_eth_resource *mem) +{ + dma_free_coherent(eth_dev->dev, mem->size, mem->vaddr, mem->daddr); +} + +static size_t ipa_eth_dma_walk(struct ipa_eth_device *eth_dev, + const struct ipa_eth_resource *mem, + ipa_eth_mem_it_t it, void *arg) +{ + struct ipa_eth_resource cmem = { + .size = PAGE_SIZE, + .vaddr = (void *) rounddown((unsigned long) mem->vaddr, + PAGE_SIZE), + .daddr = rounddown(mem->daddr, PAGE_SIZE), + }; + + if ((mem->daddr - cmem.daddr) != (mem->vaddr - cmem.vaddr)) { + ipa_eth_dev_err(eth_dev, + "Alignment mismatch between daddr and addr"); + return 0; + } + + if (cmem.daddr != mem->daddr) + ipa_eth_dev_dbg(eth_dev, "Daddr %pad is realigned to %pad", + mem->daddr, &cmem.daddr); + + if (cmem.vaddr != mem->vaddr) + ipa_eth_dev_dbg(eth_dev, "Vaddr %pK is realigned to %pK", + mem->vaddr, cmem.vaddr); + + while (cmem.vaddr < (mem->vaddr + mem->size)) { + cmem.paddr = ipa_eth_dma_paddr(eth_dev, cmem.vaddr); + + if (it(eth_dev, &cmem, arg)) { + ipa_eth_dev_err(eth_dev, + "Remap failed for page at [%pK,%pad,%pap]", + cmem.vaddr, &cmem.daddr, &cmem.paddr); + break; + } + + cmem.vaddr += PAGE_SIZE; + cmem.daddr += PAGE_SIZE; + } + + return clamp_val(cmem.vaddr, mem->vaddr, mem->vaddr + mem->size) - + mem->vaddr; +} + +static struct ipa_eth_dma_allocator default_dma_allocator = { + .name = "ipa_eth_dma_alloc_coherent", + .paddr = ipa_eth_dma_paddr, + .alloc = ipa_eth_dma_alloc, + .free = ipa_eth_dma_free, + .walk = ipa_eth_dma_walk, +}; + +static int ipa_eth_net_process_skb(struct ipa_eth_channel *ch, + struct sk_buff *skb) +{ + if (likely(IPA_ETH_CH_IS_RX(ch))) + return ipa_eth_net_receive_skb(ch->eth_dev, skb); + else + return ipa_eth_net_transmit_skb(ch->eth_dev, skb); +} + +static enum ipa_smmu_cb_type ipa_eth_hw_to_cb_type( + struct ipa_eth_channel *ch, + enum ipa_eth_hw_type hw_type) +{ + enum ipa_smmu_cb_type cb_type = IPA_SMMU_CB_MAX; + + switch (hw_type) { + case IPA_ETH_HW_UC: + cb_type = IPA_SMMU_CB_UC; + break; + + case IPA_ETH_HW_GSI: + case IPA_ETH_HW_IPA: /* All current ethernet client EPs uses GSI CB */ + cb_type = IPA_SMMU_CB_AP; + break; + + default: + ipa_eth_bug("Unknown Eth CB type %d", hw_type); + break; + } + + return cb_type; +} + +static struct ipa_smmu_cb_ctx *ipa_eth_get_smmu_ctx( + enum ipa_smmu_cb_type cb_type) +{ + struct ipa_smmu_cb_ctx *cb; + + if (cb_type >= IPA_SMMU_CB_MAX) + return NULL; + + cb = ipa3_get_smmu_ctx(cb_type); + + if (!cb || !cb->valid) + return NULL; + + return cb; +} + +static int ipa_eth_hw_to_cb_map_one(struct ipa_eth_channel *ch, + enum ipa_eth_hw_type hw_type, + struct ipa_eth_hw_map_param *hw_map_param, + enum ipa_smmu_cb_type cb_type, + struct ipa_eth_cb_map_param *cb_map_param) +{ + struct ipa_smmu_cb_ctx *cb_ctx = ipa_eth_get_smmu_ctx(cb_type); + + if (!cb_ctx) { + ipa_eth_dev_err(ch->eth_dev, + "Failed to get smmu ctx for hw type %d", + hw_type); + return -EFAULT; + } + + /* One CB can be shared between multiple HW. Make sure the parameters + * for CB are aggregated to a common denominator. + */ + cb_map_param->map = cb_map_param->map || hw_map_param->map; + cb_map_param->sym = cb_map_param->sym || hw_map_param->sym; + cb_map_param->iommu_prot |= hw_map_param->read ? IOMMU_READ : 0; + cb_map_param->iommu_prot |= hw_map_param->write ? IOMMU_WRITE : 0; + + switch (cb_map_param->iommu_prot) { + case IOMMU_READ: + cb_map_param->dma_dir = DMA_TO_DEVICE; + break; + case IOMMU_WRITE: + cb_map_param->dma_dir = DMA_FROM_DEVICE; + break; + case 0: + cb_map_param->dma_dir = DMA_NONE; + break; + default: + cb_map_param->dma_dir = DMA_BIDIRECTIONAL; + break; + } + + cb_map_param->cb_ctx = cb_ctx; + + return 0; +} + +/** + * ipa_eth_hw_to_cb_map() - Translate memory mapping parameters from IPA + * hardware types to context bank types + * @ch: Channel to which the parameters belong + * @hw_map_params: Mapping parameters for various hardware types + * @cb_map_params: Translated mapping parameters output for context banks + * + * Return: 0 if successful, non-zero otherwise + */ +static int ipa_eth_hw_to_cb_map(struct ipa_eth_channel *ch, + struct ipa_eth_hw_map_param *hw_map_params, + struct ipa_eth_cb_map_param *cb_map_params) +{ + int rc; + enum ipa_eth_hw_type hw_type; + + for (hw_type = 0; hw_type < IPA_ETH_HW_MAX; hw_type++) { + enum ipa_smmu_cb_type cb_type = + ipa_eth_hw_to_cb_type(ch, hw_type); + + rc = ipa_eth_hw_to_cb_map_one(ch, + hw_type, &hw_map_params[hw_type], + cb_type, &cb_map_params[cb_type]); + if (rc) { + ipa_eth_dev_err(ch->eth_dev, + "Failed to convert from hw to cb map params"); + return rc; + } + } + + return 0; +} + +static int ipa_eth_cb_mapper_sym(struct ipa_eth_device *eth_dev, + const struct ipa_eth_resource *cmem, void *arg) +{ + int rc; + struct ipa_eth_cb_map_param *cb_map_param = arg; + const struct ipa_smmu_cb_ctx *cb_ctx = cb_map_param->cb_ctx; + + if (!cb_map_param->map) { + ipa_eth_dev_bug(eth_dev, "CB map is not enabled"); + return -EFAULT; + } + + if (!cmem->size) { + ipa_eth_dev_bug(eth_dev, "Requested CB mapping of size 0"); + return -EINVAL; + } + + rc = ipa3_iommu_map(cb_ctx->mapping->domain, + cmem->daddr, cmem->paddr, cmem->size, cb_map_param->iommu_prot); + if (rc) { + ipa_eth_dev_err(eth_dev, + "Failed to map %zu bytes into CB %s at [%pK,%pad,%pap]", + cmem->size, cb_ctx->iommu->name, + cmem->vaddr, &cmem->daddr, &cmem->paddr); + } + + return rc; +} + +static int ipa_eth_cb_unmapper_sym(struct ipa_eth_device *eth_dev, + const struct ipa_eth_resource *cmem, void *arg) +{ + size_t size; + struct ipa_eth_cb_map_param *cb_map_param = arg; + const struct ipa_smmu_cb_ctx *cb_ctx = cb_map_param->cb_ctx; + + if (!cmem->size) { + ipa_eth_dev_err(eth_dev, "Requested CB unmapping of size 0"); + return -EINVAL; + } + + size = iommu_unmap(cb_ctx->mapping->domain, cmem->daddr, cmem->size); + if (size != cmem->size) { + ipa_eth_dev_err(eth_dev, + "Failed to unmap %zu bytes in domain %s at daddr %pad", + cmem->size, dev_name(cb_ctx->dev), &cmem->daddr); + return -EFAULT; + } + + return 0; +} + +static size_t ipa_eth_net_remap(struct ipa_eth_device *eth_dev, + const struct ipa_eth_resource *mem, + struct ipa_eth_dma_allocator *allocator, + ipa_eth_mem_it_t map_op, + struct ipa_eth_cb_map_param *cb_map_param) +{ + return allocator->walk(eth_dev, mem, map_op, cb_map_param); +} + +/** + * ipa_eth_net_cb_map_sym() - Symmetrically map a channel memory to a given IPA + * SMMU context bank + * @eth_dev: Device to which the channel memory belong + * @ch_mem: Channel memory that need to be mapped + * @allocator: Allocator used for allocating the channel memory + * @cb_type: IPA SMMU context bank to which to map the memory + * @cb_map_param: Parameters for mapping memory to the given context bank + * + * Symmetric mapping creates the same DADDR->PADDR memory mapping in the + * given IPA context bank as in the original channel memory @ch_mem. Use this + * API if any of the IPA hardware need to use the same IO virtual address as + * the network device. + * + * Return: 0 on successful mapping to the given @cb_type, non-zero otherwise. + */ +static int ipa_eth_net_cb_map_sym(struct ipa_eth_device *eth_dev, + struct ipa_eth_channel_mem *ch_mem, + struct ipa_eth_dma_allocator *allocator, + enum ipa_smmu_cb_type cb_type, + struct ipa_eth_cb_map_param *cb_map_param) +{ + size_t size; + struct ipa_eth_resource *cb_mem = &ch_mem->cb_mem[cb_type]; + const struct ipa_smmu_cb_ctx *cb_ctx = cb_map_param->cb_ctx; + + if (!ch_mem->mem.daddr) { + ipa_eth_dev_err(eth_dev, + "Symmetric mapping requires a valid DMA address"); + return -EFAULT; + } + + ipa_eth_dev_log(eth_dev, + "Mapping %zu bytes into domain %s at [%pK,%pad,%pap]", + ch_mem->mem.size, dev_name(cb_ctx->dev), + ch_mem->mem.vaddr, &ch_mem->mem.daddr, &ch_mem->mem.paddr); + + size = ipa_eth_net_remap(eth_dev, &ch_mem->mem, allocator, + ipa_eth_cb_mapper_sym, cb_map_param); + if (size != ch_mem->mem.size) { + /* Unmap any partially mapped memory */ + struct ipa_eth_resource unmap_mem = { + .size = size, + .vaddr = ch_mem->mem.vaddr, + .daddr = ch_mem->mem.daddr, + .paddr = ch_mem->mem.paddr, + }; + + ipa_eth_dev_err(eth_dev, + "Failed to map %zu bytes to domain %s, undo mapping", + ch_mem->mem.size - size, dev_name(cb_ctx->dev)); + + (void) ipa_eth_net_remap(eth_dev, &unmap_mem, allocator, + ipa_eth_cb_unmapper_sym, cb_map_param); + + return -EFAULT; + } + + *cb_mem = ch_mem->mem; + + ipa_eth_dev_log(eth_dev, + "Mapped %zu bytes into domain %s at [%pK,%pad,%pap]", + cb_mem->size, dev_name(cb_ctx->dev), + cb_mem->vaddr, &cb_mem->daddr, &cb_mem->paddr); + + return 0; +} + +/** + * ipa_eth_net_cb_map_asym() - Map a channel memory to a context bank, not + * necessarily using the same IO virtual address + * @eth_dev: Device to which the channel memory belong + * @ch_mem: Channel memory that need to be mapped + * @allocator: Allocator used for allocating the channel memory + * @cb_type: IPA SMMU context bank to which to map the memory + * @cb_map_param: Parameters for mapping memory to the given context bank + * + * Use this API if symmetric mapping is not required for a channel memory. See + * ipa_eth_net_cb_map_sym() for more details on symmetric mapping. + * + * Note that since assymmetric mapping uses dma_map_single(), it can only be + * used to map memory that was allocated using kmalloc(). Memory allocated from + * vmalloc region (like dma_alloc_coherent() on ARM targets) can not be mapped + * again using this API. + * + * Return: 0 on success, non-zero otherwise + */ +static int ipa_eth_net_cb_map_asym(struct ipa_eth_device *eth_dev, + struct ipa_eth_channel_mem *ch_mem, + struct ipa_eth_dma_allocator *allocator, + enum ipa_smmu_cb_type cb_type, + struct ipa_eth_cb_map_param *cb_map_param) +{ + struct ipa_eth_resource *cb_mem = &ch_mem->cb_mem[cb_type]; + const struct ipa_smmu_cb_ctx *cb_ctx = cb_map_param->cb_ctx; + + if (is_vmalloc_addr(ch_mem->mem.vaddr)) { + ipa_eth_dev_err(eth_dev, + "Asymmetric mapping cannot use vmalloc address"); + return -EFAULT; + } + + ipa_eth_dev_log(eth_dev, + "Mapping %zu bytes into device %s from [%pK,%pad,%pap]", + ch_mem->mem.size, dev_name(cb_ctx->dev), + ch_mem->mem.vaddr, &ch_mem->mem.daddr, &ch_mem->mem.paddr); + + *cb_mem = ch_mem->mem; + + cb_mem->daddr = dma_map_single(cb_ctx->dev, + ch_mem->mem.vaddr, ch_mem->mem.size, + cb_map_param->dma_dir); + if (dma_mapping_error(cb_ctx->dev, cb_mem->daddr)) { + cb_mem->size = 0; + ipa_eth_dev_err(eth_dev, "Failed to map buffer to device %s", + dev_name(cb_ctx->dev)); + return -EFAULT; + } + + ipa_eth_dev_log(eth_dev, + "Mapped %zu bytes into device %s at [%pK,%pad,%pap]", + cb_mem->size, dev_name(cb_ctx->dev), + cb_mem->vaddr, &cb_mem->daddr, &cb_mem->paddr); + + return 0; +} + +static int ipa_eth_net_cb_map_one(struct ipa_eth_device *eth_dev, + struct ipa_eth_channel_mem *ch_mem, + struct ipa_eth_dma_allocator *allocator, + enum ipa_smmu_cb_type cb_type, + struct ipa_eth_cb_map_param *cb_map_param) +{ + if (cb_map_param->sym) + return ipa_eth_net_cb_map_sym( + eth_dev, ch_mem, allocator, cb_type, cb_map_param); + else + return ipa_eth_net_cb_map_asym( + eth_dev, ch_mem, allocator, cb_type, cb_map_param); +} + +static void ipa_eth_net_cb_unmap_sym(struct ipa_eth_device *eth_dev, + struct ipa_eth_channel_mem *ch_mem, + struct ipa_eth_dma_allocator *allocator, + enum ipa_smmu_cb_type cb_type, + struct ipa_eth_cb_map_param *cb_map_param) +{ + struct ipa_eth_resource *cb_mem = &ch_mem->cb_mem[cb_type]; + const struct ipa_smmu_cb_ctx *cb_ctx = cb_map_param->cb_ctx; + + if (!cb_mem->size) + return; + + ipa_eth_dev_log(eth_dev, + "Unmapping %zu bytes in domain %s from daddr %pad", + cb_mem->size, dev_name(cb_ctx->dev), &cb_mem->daddr); + + (void) ipa_eth_net_remap(eth_dev, &ch_mem->mem, allocator, + ipa_eth_cb_unmapper_sym, cb_map_param); + + ipa_eth_dev_log(eth_dev, + "Unmapped %zu bytes in domain %s from daddr %pad", + cb_mem->size, dev_name(cb_ctx->dev), &cb_mem->daddr); + + cb_mem->size = 0; +} + +static void ipa_eth_net_cb_unmap_asym(struct ipa_eth_device *eth_dev, + struct ipa_eth_channel_mem *ch_mem, + struct ipa_eth_dma_allocator *allocator, + enum ipa_smmu_cb_type cb_type, + struct ipa_eth_cb_map_param *cb_map_param) +{ + struct ipa_eth_resource *cb_mem = &ch_mem->cb_mem[cb_type]; + const struct ipa_smmu_cb_ctx *cb_ctx = cb_map_param->cb_ctx; + + if (!cb_mem->size) + return; + + ipa_eth_dev_log(eth_dev, + "Unmapping %zu bytes in device %s from daddr %pad", + cb_mem->size, dev_name(cb_ctx->dev), &cb_mem->daddr); + + dma_unmap_single(cb_ctx->dev, cb_mem->daddr, cb_mem->size, + cb_map_param->dma_dir); + + ipa_eth_dev_log(eth_dev, + "Unmapped %zu bytes in device %s from daddr %pad", + cb_mem->size, dev_name(cb_ctx->dev), &cb_mem->daddr); + + cb_mem->size = 0; +} + +static void ipa_eth_net_cb_unmap_one(struct ipa_eth_device *eth_dev, + struct ipa_eth_channel_mem *ch_mem, + struct ipa_eth_dma_allocator *allocator, + enum ipa_smmu_cb_type cb_type, + struct ipa_eth_cb_map_param *cb_map_param) +{ + if (cb_map_param->sym) + return ipa_eth_net_cb_unmap_sym( + eth_dev, ch_mem, allocator, cb_type, cb_map_param); + else + return ipa_eth_net_cb_unmap_asym( + eth_dev, ch_mem, allocator, cb_type, cb_map_param); +} + +/** + * ipa_eth_net_cb_unmap_ch_mem() - Unmap one channel memory from one of more + * IPA context banks + * @eth_dev: Device to which the channel memory belong + * @ch_mem: Channel memory that need to be unmapped + * @allocator: Allocator used for allocating the channel memory + * @cb_map_params: Mapping parameters for all known IPA context banks + * + * Use this API to unmap a channel memory from various IPA context banks that + * was previously mapped using ipa_eth_net_cb_map_ch_mem(). + */ +static void ipa_eth_net_cb_unmap_ch_mem(struct ipa_eth_device *eth_dev, + struct ipa_eth_channel_mem *ch_mem, + struct ipa_eth_dma_allocator *allocator, + struct ipa_eth_cb_map_param *cb_map_params) +{ + enum ipa_smmu_cb_type cb_type; + + if (!ch_mem->cb_mem) + return; + + for (cb_type = 0; cb_type < IPA_SMMU_CB_MAX; cb_type++) { + if (!cb_map_params[cb_type].map) + continue; + + ipa_eth_net_cb_unmap_one(eth_dev, ch_mem, allocator, + cb_type, &cb_map_params[cb_type]); + } + + kfree(ch_mem->cb_mem); + ch_mem->cb_mem = NULL; +} + +/** + * ipa_eth_net_cb_map_ch_mem() - Map one channel memory to one or more IPA + * context banks + * @eth_dev: Device to which the channel memory belong + * @ch_mem: Channel memory that need to be mapped + * @allocator: Allocator used for allocating the channel memory + * @cb_map_params: Mapping parameters for all known IPA context banks + * + * Return: 0 on success, non-zero otherwise + */ +static int ipa_eth_net_cb_map_ch_mem(struct ipa_eth_device *eth_dev, + struct ipa_eth_channel_mem *ch_mem, + struct ipa_eth_dma_allocator *allocator, + struct ipa_eth_cb_map_param *cb_map_params) +{ + int rc; + enum ipa_smmu_cb_type cb_type; + + if (ch_mem->cb_mem) { + ipa_eth_dev_err(eth_dev, "CB mem is already initialized"); + return -EEXIST; + } + + ch_mem->cb_mem = kzalloc(sizeof(*ch_mem->cb_mem) * IPA_SMMU_CB_MAX, + GFP_KERNEL); + if (!ch_mem->cb_mem) { + ipa_eth_dev_err(eth_dev, "Failed to alloc CB mem resource"); + return -ENOMEM; + } + + for (cb_type = 0; cb_type < IPA_SMMU_CB_MAX; cb_type++) { + if (!cb_map_params[cb_type].map) + continue; + + rc = ipa_eth_net_cb_map_one(eth_dev, ch_mem, allocator, + cb_type, &cb_map_params[cb_type]); + if (rc) + goto err_map; + } + + return 0; + +err_map: + ipa_eth_net_cb_unmap_ch_mem(eth_dev, ch_mem, allocator, cb_map_params); + return -ENOMEM; +} + +/** + * ipa_eth_net_hw_unmap_desc_mem() - Unmap all descriptor memory from various + * IPA hardware types + * @eth_dev: Device to which the channel belong + * @ch: Channel whose descriptor memory need to be unmapped + * + * Use this API to unmap any descriptor memory previously mapped to any of the + * IPA hardware types. + */ +static void ipa_eth_net_hw_unmap_desc_mem(struct ipa_eth_device *eth_dev, + struct ipa_eth_channel *ch) +{ + int rc; + struct ipa_eth_channel_mem *ch_mem; + struct ipa_eth_cb_map_param cb_map_params[IPA_SMMU_CB_MAX]; + + memset(cb_map_params, 0, sizeof(cb_map_params)); + + rc = ipa_eth_hw_to_cb_map(ch, + ch->mem_params.desc.hw_map_params, cb_map_params); + if (rc) { + ipa_eth_dev_err(eth_dev, + "Failed to convert map params from hw to cb"); + return; + } + + list_for_each_entry(ch_mem, &ch->desc_mem, mem_list_entry) { + ipa_eth_net_cb_unmap_ch_mem(eth_dev, ch_mem, + ch->mem_params.desc.allocator, cb_map_params); + } +} + +/** + * ipa_eth_net_hw_map_desc_mem() - Map all descriptor memory to various IPA + * hadware types + * @eth_dev: Device to which the channel belong + * @ch: Channel from which the descriptor memory need to be mapped + * + * The API uses hardware mapping parameters listed in hw_map_params[] of struct + * ipa_eth_desc_params to determine how the mapping need to be perfomed. The + * actual SMMU context banks used by each hardware type is determined by using + * the ipa_eth_hw_to_cb_map() API. + * + * Return: 0 on success, non-zero otherwise + */ +static int ipa_eth_net_hw_map_desc_mem(struct ipa_eth_device *eth_dev, + struct ipa_eth_channel *ch) +{ + int rc; + struct ipa_eth_channel_mem *ch_mem; + struct ipa_eth_cb_map_param cb_map_params[IPA_SMMU_CB_MAX]; + + memset(cb_map_params, 0, sizeof(cb_map_params)); + + rc = ipa_eth_hw_to_cb_map(ch, + ch->mem_params.desc.hw_map_params, cb_map_params); + if (rc) { + ipa_eth_dev_err(eth_dev, + "Failed to convert map params from hw to cb"); + return rc; + } + + list_for_each_entry(ch_mem, &ch->desc_mem, mem_list_entry) { + rc = ipa_eth_net_cb_map_ch_mem(eth_dev, ch_mem, + ch->mem_params.desc.allocator, cb_map_params); + if (rc) + goto err_map; + } + + return 0; + +err_map: + ipa_eth_net_hw_unmap_desc_mem(eth_dev, ch); + return rc; +} + +/** + * ipa_eth_net_hw_unmap_buff_mem() - Unmap all buffer memory from various IPA + * hardware types + * @eth_dev: Device to which the channel belong + * @ch: Channel whose buffer memory need to be unmapped + * + * Use this API to unmap any buffer memory previously mapped to any of the IPA + * hardware types. + */ +static void ipa_eth_net_hw_unmap_buff_mem(struct ipa_eth_device *eth_dev, + struct ipa_eth_channel *ch) +{ + int rc; + struct ipa_eth_channel_mem *ch_mem; + struct ipa_eth_cb_map_param cb_map_params[IPA_SMMU_CB_MAX]; + + memset(cb_map_params, 0, sizeof(cb_map_params)); + + rc = ipa_eth_hw_to_cb_map(ch, + ch->mem_params.buff.hw_map_params, cb_map_params); + if (rc) { + ipa_eth_dev_err(eth_dev, + "Failed to convert map params from hw to cb"); + return; + } + + list_for_each_entry(ch_mem, &ch->buff_mem, mem_list_entry) { + ipa_eth_net_cb_unmap_ch_mem(eth_dev, ch_mem, + ch->mem_params.buff.allocator, cb_map_params); + } +} + +/** + * ipa_eth_net_hw_map_buff_mem() - Map all buffer memory to various IPA hadware + * types + * @eth_dev: Device to which the channel belong + * @ch: Channel from which the buffer memory need to be mapped + * + * The API uses hardware mapping parameters listed in hw_map_params[] of struct + * ipa_eth_buff_params to determine how the mapping need to be perfomed. The + * actual SMMU context banks used by each hardware type is determined by using + * the ipa_eth_hw_to_cb_map() API. + * + * Return: 0 on success, non-zero otherwise + */ +static int ipa_eth_net_hw_map_buff_mem(struct ipa_eth_device *eth_dev, + struct ipa_eth_channel *ch) +{ + int rc; + struct ipa_eth_channel_mem *ch_mem; + struct ipa_eth_cb_map_param cb_map_params[IPA_SMMU_CB_MAX]; + + memset(cb_map_params, 0, sizeof(cb_map_params)); + + rc = ipa_eth_hw_to_cb_map(ch, + ch->mem_params.buff.hw_map_params, cb_map_params); + if (rc) { + ipa_eth_dev_err(eth_dev, + "Failed to convert map params from hw to cb"); + return rc; + } + + list_for_each_entry(ch_mem, &ch->buff_mem, mem_list_entry) { + rc = ipa_eth_net_cb_map_ch_mem(eth_dev, ch_mem, + ch->mem_params.buff.allocator, cb_map_params); + if (rc) + goto err_map; + } + + return 0; + +err_map: + ipa_eth_net_hw_unmap_buff_mem(eth_dev, ch); + return rc; +} + +/** + * ipa_eth_net_hw_map_channel() - Map all the channel memory to various IPA + * hardware types + * @eth_dev: Device to which the channel belong + * @ch: Channel whose memory need to be mapped + * + * Return: 0 if successful, non-zero otherwise + */ +static int ipa_eth_net_hw_map_channel(struct ipa_eth_device *eth_dev, + struct ipa_eth_channel *ch) +{ + int rc; + + rc = ipa_eth_net_hw_map_desc_mem(eth_dev, ch); + if (rc) + return rc; + + rc = ipa_eth_net_hw_map_buff_mem(eth_dev, ch); + if (rc) { + ipa_eth_net_hw_unmap_desc_mem(eth_dev, ch); + return rc; + } + + return 0; +} + +/** + * ipa_eth_net_cb_unmap_channel() - Unmap channel descriptor and buffer memory + * from IPA CBs + * @eth_dev: Ethernet device + * @ch: Ethernet device channel + */ +static void ipa_eth_net_hw_unmap_channel(struct ipa_eth_device *eth_dev, + struct ipa_eth_channel *ch) +{ + ipa_eth_net_hw_unmap_desc_mem(eth_dev, ch); + ipa_eth_net_hw_unmap_buff_mem(eth_dev, ch); +} + +/** + * ipa_eth_net_alloc_channel() - Allocate and initialize ipa_eth_channel + * @eth_dev: Ethernet device + * @dir: Channel direction + * @events: Supported events + * @featues: Supported features + * @mem_params: Channel memory allocation parameters + * + * This API is expected to be called by network driver .request_channel() + * callback implementation. + * + * Return: Pointer to the allocated ipa_eth_channel, NULL if the allocation + * fails + */ +struct ipa_eth_channel *ipa_eth_net_alloc_channel( + struct ipa_eth_device *eth_dev, enum ipa_eth_channel_dir dir, + unsigned long events, unsigned long features, + const struct ipa_eth_channel_mem_params *mem_params) +{ + struct ipa_eth_channel *channel; + + if (!mem_params) { + ipa_eth_dev_err(eth_dev, "Missing channel mem params"); + return NULL; + } + + channel = kzalloc(sizeof(*channel), GFP_KERNEL); + if (!channel) + return NULL; + + channel->eth_dev = eth_dev; + channel->direction = dir; + channel->events = events; + channel->features = features; + + channel->mem_params = *mem_params; + + INIT_LIST_HEAD(&channel->desc_mem); + INIT_LIST_HEAD(&channel->buff_mem); + + return channel; +} +EXPORT_SYMBOL(ipa_eth_net_alloc_channel); + +/** + * ipa_eth_net_free_channel() - Deallocate an ipa_eth_channel previously + * allocated by ipa_eth_net_alloc_channel() + * @channel: Channel to be deallocated + */ +void ipa_eth_net_free_channel(struct ipa_eth_channel *channel) +{ + struct ipa_eth_device *eth_dev = channel->eth_dev; + + if (!list_empty(&channel->desc_mem)) + ipa_eth_dev_bug(eth_dev, "Descriptor memory still in use"); + + if (!list_empty(&channel->desc_mem)) + ipa_eth_dev_bug(eth_dev, "Buffer memory still in use"); + + kzfree(channel); +} +EXPORT_SYMBOL(ipa_eth_net_free_channel); + + +/** + * ipa_eth_net_request_channel() - Request a channel from network device to be + * used for a specific end-point + * @eth_dev: Ethernet device + * @ipa_client: IPA EP client enum that also determines the channel direction + * @events: Refer documentation of ipa_eth_net_ops.request_channel() + * @features: Refer documentation of ipa_eth_net_ops.request_channel() + * @mem_params: Refer documentation of ipa_eth_net_ops.request_channel() + * + * Offload drivers should use this API in order to invoke the network driver API + * ipa_eth_net_ops.request_channel(). The function also initializes EP context + * and maps channel memory to various IPA SMMU context banks. + * + * Return: Allocated channel if the allocation succeeds. NULL otherwise. + */ +struct ipa_eth_channel *ipa_eth_net_request_channel( + struct ipa_eth_device *eth_dev, enum ipa_client_type ipa_client, + unsigned long events, unsigned long features, + const struct ipa_eth_channel_mem_params *mem_params) +{ + int rc; + bool vlan_mode; + int ipa_ep_num; + struct ipa_eth_channel *ch; + enum ipa_eth_channel_dir dir; + struct ipa_eth_channel_mem_params params; + struct ipa3_ep_context *ep_ctx = NULL; + + if (!mem_params) { + ipa_eth_dev_err(eth_dev, "Missing channel mem params"); + return NULL; + } + + params = *mem_params; + + if (!params.desc.allocator) + params.desc.allocator = &default_dma_allocator; + + if (!params.buff.allocator) + params.buff.allocator = &default_dma_allocator; + + dir = IPA_CLIENT_IS_PROD(ipa_client) ? IPA_ETH_DIR_RX : IPA_ETH_DIR_TX; + + ipa_ep_num = ipa_get_ep_mapping(ipa_client); + if (ipa_ep_num == IPA_EP_NOT_ALLOCATED) { + ipa_eth_dev_err(eth_dev, + "Could not determine EP number for client %d", + ipa_client); + return NULL; + } + + ep_ctx = &ipa3_ctx->ep[ipa_ep_num]; + if (ep_ctx->valid) { + ipa_eth_dev_err(eth_dev, + "EP context is already initialiazed"); + return NULL; + } + + rc = ipa3_is_vlan_mode(IPA_VLAN_IF_ETH, &vlan_mode); + if (rc) { + ipa_eth_dev_err(eth_dev, + "Could not determine IPA VLAN mode"); + return NULL; + } + + ch = ipa_eth_nd_op(eth_dev, request_channel, + eth_dev, dir, events, features, ¶ms); + if (IS_ERR_OR_NULL(ch)) { + ipa_eth_dev_err(eth_dev, + "Failed to request channel from net driver %s", + eth_dev->nd->name); + return ch; + } + + ch->ipa_ep_num = ipa_ep_num; + ch->ipa_client = ipa_client; + ch->process_skb = ipa_eth_net_process_skb; + ch->eth_dev = eth_dev; + + if (ipa_eth_net_hw_map_channel(eth_dev, ch)) { + ipa_eth_dev_err(eth_dev, + "Failed to map channel memory to IPA CBs"); + ipa_eth_nd_op(eth_dev, release_channel, ch); + return NULL; + } + + ipa_eth_ep_init_ctx(ch, vlan_mode); + + if (dir == IPA_ETH_CH_DIR_RX) + list_add(&ch->channel_list, ð_dev->rx_channels); + else + list_add(&ch->channel_list, ð_dev->tx_channels); + + return ch; +} +EXPORT_SYMBOL(ipa_eth_net_request_channel); + +/** + * ipa_eth_net_release_channel() - Releases a channel presiously allocated using + * ipa_eth_net_request_channel() + * @ch: Channel to be released + */ +void ipa_eth_net_release_channel(struct ipa_eth_channel *ch) +{ + list_del(&ch->channel_list); + ipa_eth_ep_deinit_ctx(ch); + ipa_eth_net_hw_unmap_channel(ch->eth_dev, ch); + return ipa_eth_nd_op(ch->eth_dev, release_channel, ch); +} +EXPORT_SYMBOL(ipa_eth_net_release_channel); + +int ipa_eth_net_enable_channel(struct ipa_eth_channel *ch) +{ + return ipa_eth_nd_op(ch->eth_dev, enable_channel, ch); +} +EXPORT_SYMBOL(ipa_eth_net_enable_channel); + +int ipa_eth_net_disable_channel(struct ipa_eth_channel *ch) +{ + return ipa_eth_nd_op(ch->eth_dev, disable_channel, ch); +} +EXPORT_SYMBOL(ipa_eth_net_disable_channel); + +int ipa_eth_net_request_event(struct ipa_eth_channel *ch, unsigned long event, + phys_addr_t addr, u64 data) +{ + return ipa_eth_nd_op(ch->eth_dev, request_event, ch, event, addr, data); +} +EXPORT_SYMBOL(ipa_eth_net_request_event); + +void ipa_eth_net_release_event(struct ipa_eth_channel *ch, unsigned long event) +{ + return ipa_eth_nd_op(ch->eth_dev, release_event, ch, event); +} +EXPORT_SYMBOL(ipa_eth_net_release_event); + +int ipa_eth_net_enable_event(struct ipa_eth_channel *ch, unsigned long event) +{ + return ipa_eth_nd_op(ch->eth_dev, enable_event, ch, event); +} +EXPORT_SYMBOL(ipa_eth_net_enable_event); + +int ipa_eth_net_disable_event(struct ipa_eth_channel *ch, unsigned long event) +{ + return ipa_eth_nd_op(ch->eth_dev, disable_event, ch, event); +} +EXPORT_SYMBOL(ipa_eth_net_disable_event); + +int ipa_eth_net_moderate_event(struct ipa_eth_channel *ch, unsigned long event, + u64 min_count, u64 max_count, + u64 min_usecs, u64 max_usecs) +{ + return ipa_eth_nd_op(ch->eth_dev, moderate_event, ch, event, + min_count, max_count, min_usecs, max_usecs); +} +EXPORT_SYMBOL(ipa_eth_net_moderate_event); + +int ipa_eth_net_receive_skb(struct ipa_eth_device *eth_dev, + struct sk_buff *skb) +{ + return ipa_eth_nd_op(eth_dev, receive_skb, eth_dev, skb); +} +EXPORT_SYMBOL(ipa_eth_net_receive_skb); + +int ipa_eth_net_transmit_skb(struct ipa_eth_device *eth_dev, + struct sk_buff *skb) +{ + return ipa_eth_nd_op(eth_dev, transmit_skb, eth_dev, skb); +} +EXPORT_SYMBOL(ipa_eth_net_transmit_skb); + +/** + * ipa_eth_net_ch_to_cb_mem() - Provides memory mapping of a specific channel + * memory on an IPA hardware type + * @ch: Channel to which the memory belong + * @ch_mem: Channel memory whose hardware mapping need to be found out + * @hw_type: Hardware for which the mapping need to be determined + * + * The SMMU context bank used by each hw_type could vary based on channel. Use + * this API to correctly identify the context bank and the mapping made for the + * channel memory to it. + * + * Return: Memory mapping info for the given @hw_type if a mapping was + * previously made via one of ipa_eth_net_*() APIs. NULL if no mapping + * was made before to the context bank associated with a @hw_type. + */ +struct ipa_eth_resource *ipa_eth_net_ch_to_cb_mem( + struct ipa_eth_channel *ch, + struct ipa_eth_channel_mem *ch_mem, + enum ipa_eth_hw_type hw_type) +{ + struct ipa_eth_resource *cb_mem; + enum ipa_smmu_cb_type cb_type = ipa_eth_hw_to_cb_type(ch, hw_type); + + if (ch_mem->cb_mem == NULL || cb_type >= IPA_SMMU_CB_MAX) + return NULL; + + cb_mem = &ch_mem->cb_mem[cb_type]; + if (!cb_mem->size) + return NULL; + + return cb_mem; +} +EXPORT_SYMBOL(ipa_eth_net_ch_to_cb_mem); diff --git a/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_offload.c b/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_offload.c index b4ce9439efe3..faebc82bf256 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_offload.c +++ b/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_offload.c @@ -112,7 +112,7 @@ int ipa_eth_offload_stop(struct ipa_eth_device *eth_dev) static int __try_pair_device(struct ipa_eth_device *eth_dev, struct ipa_eth_offload_driver *od) { - int rc = od->bus_ops->probe(eth_dev); + int rc = od->ops->pair(eth_dev); if (rc) { ipa_eth_dev_dbg(eth_dev, @@ -122,19 +122,9 @@ static int __try_pair_device(struct ipa_eth_device *eth_dev, } ipa_eth_dev_log(eth_dev, - "Offload driver %s successfully probed device from %s", + "Offload driver %s is paired with device from %s", od->name, eth_dev->nd->name); - if (!eth_dev->net_dev) { - ipa_eth_dev_err(eth_dev, - "Offload driver %s did not fill net_dev field", - od->name); - - od->bus_ops->remove(eth_dev); - - return -EFAULT; - } - eth_dev->od = od; ipa_eth_dev_log(eth_dev, @@ -182,12 +172,7 @@ void ipa_eth_offload_unpair_device(struct ipa_eth_device *eth_dev) eth_dev->od = NULL; - if (od->bus_ops->remove) - od->bus_ops->remove(eth_dev); - else - ipa_eth_dev_dbg(eth_dev, - "Bus remove is unsupported by the offload driver %s", - od->name); + od->ops->unpair(eth_dev); } int ipa_eth_offload_register_driver(struct ipa_eth_offload_driver *od) @@ -197,8 +182,8 @@ int ipa_eth_offload_register_driver(struct ipa_eth_offload_driver *od) return -EINVAL; } - if (!od->bus_ops || !od->bus_ops->probe || !od->bus_ops->remove) { - ipa_eth_err("Bus ops missing for offload driver %s", od->name); + if (!od->ops || !od->ops->pair || !od->ops->unpair) { + ipa_eth_err("Pair ops missing for offload driver %s", od->name); return -EINVAL; } diff --git a/include/linux/ipa_eth.h b/include/linux/ipa_eth.h index 58e34e5dcebf..15fcf3d3f6d4 100644 --- a/include/linux/ipa_eth.h +++ b/include/linux/ipa_eth.h @@ -26,7 +26,21 @@ #include #include -#define IPA_ETH_API_VER 1 +/** + * API Version Changes + * --------------------------------------------------------------------------- + * 1 - Initial version + * 2 - API separation for use by network and offload drivers + * - New ipa_eth_net_*() APIs offer safer interface for offload + * drivers to call into ipa_eth_net_ops + * - ipa_eth_net_ops.request_channel() to accept additional + * memory allocation params, including custom memory allocator + * defined via struct ipa_eth_dma_allocator interface + * - probe() and remove() offload bus ops are replaced by pair() + * and unpair() callbacks respectively + */ + +#define IPA_ETH_API_VER 2 /** * enum ipa_eth_dev_features - Features supported by an ethernet device or @@ -147,22 +161,216 @@ struct ipa_eth_resource { void *vaddr; dma_addr_t daddr; phys_addr_t paddr; +}; + +/** + * ipa_eth_mem_it_t() - Callback used by the ipa_eth_dma_allocator.walk() as it + * iterates through each contiguous chunk of memory + * @eth_dev: Device to which the memory belong + * @cmem: Contigous mapping. If cmem->paddr is NULL, it could be determined from + * ipa_eth_dma_allocator.paddr(cmem->vaddr) + * @arg: Private argument passed to ipa_eth_dma_allocator.walk() that can hold + * necessary context required by the iterator + * + * See &struct ipa_eth_dma_allocator for more details. + */ +typedef int (*ipa_eth_mem_it_t)(struct ipa_eth_device *eth_dev, + const struct ipa_eth_resource *cmem, void *arg); + +/** + * struct ipa_eth_dma_allocator - Custom DMA memory allocator interface + * @name: Name of the allocator + */ +struct ipa_eth_dma_allocator { + const char *name; + + /** + * .paddr() - Convert a virtual address previously allocated by this + * ipa_eth_dma_allocator, to physical address + * @eth_dev: Device which owns the memory + * @vaddr: Kernel mapped address of the resource + * + * Return: Physical address of @vaddr + */ + phys_addr_t (*paddr)(struct ipa_eth_device *eth_dev, + const void *vaddr); + + /** + * .alloc() - Allocates DMA memory for a given device + * @eth_dev: Device which will own the memory. Note that @eth_dev->dev + * should be a valid struct device pointer. + * @size: Minimum number of bytes to allocate + * @gfp: Kernel GFP_* flags to use, if the allocator supports it + * @mem: Memory info if the allocation was successful. @mem->paddr may + * be NUll or not valid, use ipa_eth_dma_allocator.paddr() to get + * the correct physical address for a page of virtual address. + * + * This API callback is typically called by the network driver to + * allocate memory for descriptor rings, buffers, etc. Any memory + * allocated by this callback should be traversable by the .remap() + * API callback implementation. + * + * Return: 0 on success, non-zero otherwise + */ + int (*alloc)(struct ipa_eth_device *eth_dev, size_t size, gfp_t gfp, + struct ipa_eth_resource *mem); + + /** + * .free() - Free a memory previously allocated using .alloc() API + * @eth_dev: Device which owns the memory + * @mem: Memory info + * + * This API callback is typically called by the network driver to free + * memory resources associated with descriptor rings, buffers, etc. once + * their associated hardware queues are stopped. + */ + void (*free)(struct ipa_eth_device *eth_dev, + struct ipa_eth_resource *mem); + + /** + * .walk() - Iterates over memory previously allocated by .alloc() + * @eth_dev: Device which owns the memory + * @mem: Allocated memory that need to be iterated over + * @it: Iterator that is invoked for each chunk (typically PAGE_SIZE) + * of memory + * @arg: Private argument passed to @it for each invocation + * + * This API is expected to iterate over pieces of an allocated memory + * for typical purposes remapping to additional peripherals, and later + * unmapping from them. .walk() is responsible to invoke the iterator + * @it for each mappable region within an allocated space, which is + * typically page sized. + * + * Iteration is expected to stop either when the page walk completes or + * when any of the @it() invocations return failure. Iterator can add + * additional checks for memory alignments, addressability, etc. that + * can also fail. In any case, the API is expected to return the number + * of bytes (<= mem->size) from the given memory that was successfully + * iterated. Although the API may re-align memory regions while invoking + * the iterator, it should still return only the number of bytes of the + * original memory that was successfully iterated. + * + * .walk() API could be used for any purpose of iteration, not limited + * to memory mapping and unmapping. Implementation of the API should be + * flexible for generalized use-cases. Caller of this API should always + * check for the return value against @mem->size to make sure if the + * intended operation was successful, and explicitly revert any partial + * operation. Ex, + * + * mapped_bytes = alctr->walk(dev, mem_region, iommu_mapper, map_ctx); + * if (mapped_bytes != mem_region->size) { + * struct ipa_eth_resource unmap_region = *mem_region; + * unmap_region.size = mapped_bytes; + * alctr->walk(dev, unmap_region, smmu_map, ctx); + * return -ENOMEM; + * } + * + * Return: the number of bytes in @mem that were successfully iterated + */ + size_t (*walk)(struct ipa_eth_device *eth_dev, + const struct ipa_eth_resource *mem, + ipa_eth_mem_it_t it, void *arg); +}; + +/** + * enum ipa_eth_hw_type - Types of hardware used in an offload path + * @IPA_ETH_HW_UC: IPA uC + * @IPA_ETH_HW_GSI: GSI + * @IPA_ETH_HW_IPA: IPA hardware/endpoint + */ +enum ipa_eth_hw_type { + IPA_ETH_HW_UC, + IPA_ETH_HW_GSI, + IPA_ETH_HW_IPA, + IPA_ETH_HW_MAX, +}; + +/** + * struct ipa_eth_hw_map_param - Params for mapping memory to IPA hardware + * @map: If true, perform mapping of memory to the given hardware + * @sym: If true, performs symmetric mapping where IO virtual address (IOVA) + * used is the same as the one used on original device. + * @read: Memory should be readable by hardware + * @write: Memory should be writable by hardware + */ +struct ipa_eth_hw_map_param { + bool map; + bool sym; + bool read; + bool write; +}; + +/** + * struct ipa_eth_desc_params - Params for allocating descriptor memory + * @size: Size of each descriptor. This field is usually filled in by the + * network driver. + * @count: Number of descriptors to be allocated + * @allocator: DMA allocator to be used for IO memory allocation and mapping + * @hw_map_params: Info on memory mapping requirements to IPA CBs + */ +struct ipa_eth_desc_params { + size_t size; + size_t count; + struct ipa_eth_dma_allocator *allocator; + struct ipa_eth_hw_map_param hw_map_params[IPA_ETH_HW_MAX]; +}; + +/** + * struct ipa_eth_buff_params - Params for allocating buffer memory + * @size: Size of data buffer associated with a descriptor + * @count: Number of buffers. This ield is usually filled in by the network + * driver and is typically the same value as descriptor count. + * @allocator: DMA allocator to be used for IO memory allocation and mapping + * @maps: Info on memory mapping requirements to IPA CBs + */ +struct ipa_eth_buff_params { + size_t size; + size_t count; + struct ipa_eth_dma_allocator *allocator; + struct ipa_eth_hw_map_param hw_map_params[IPA_ETH_HW_MAX]; +}; + +/** + * struct ipa_eth_channel_mem_params - Params for various channel memory + * @desc: Descriptor memory parameters + * @buff: Buffer memory parameters + */ +struct ipa_eth_channel_mem_params { + struct ipa_eth_desc_params desc; + struct ipa_eth_buff_params buff; +}; + +/** + * struct ipa_eth_channel_mem - Represents a piece of memory used by the + * network device channel for descriptrors, buffers, etc. + * @mem_list_entry: list entry in either of ipa_eth_channel.desc_mem or + * ipa_eth_channel.buff_mem + * @mem: Memory mapping info as used by the network device/driver + * @cb_mem: Memory mapping info as used by each of IPA context banks. When a + * mapping is present, cb_mem[cb_type].size would be non-zero. + */ +struct ipa_eth_channel_mem { + struct list_head mem_list_entry; + + struct ipa_eth_resource mem; +/* private: for internal use by offload sub-system */ + struct ipa_eth_resource *cb_mem; }; /** * struct ipa_eth_channel - Represents a network device channel + * @channel_list: list entry in either of ipa_eth_device.rx_channels or + * ipa_eth_device.tx_channels * @nd_priv: Private field for use by network driver * @events: Events supported by the channel * @features: Features enabled in the channel * @direction: Channel direction + * @mem_params: Channel memory params filled in collectively by Offload driver, + * Network driver and Offload sub-system * @queue: Network device queue/ring number - * @desc_size: Size of each descriptor - * @desc_count: Number of descriptors in the ring - * @desc_mem: Descriptor ring memory base - * @buff_size: Size of each data buffer - * @buff_count: Number of data buffers - * @buff_mem: Data buffer memory base + * @desc_mem: Descriptor ring memory list + * @buff_mem: Data buffer memory list * @od_priv: Private field for use by offload driver * @eth_dev: Associated ipa_eth_device * @ipa_client: IPA client type enum to be used for the channel @@ -176,22 +384,19 @@ struct ipa_eth_resource { * into IPA */ struct ipa_eth_channel { + struct list_head channel_list; + /* fields managed by network driver */ void *nd_priv; unsigned long events; unsigned long features; enum ipa_eth_channel_dir direction; + struct ipa_eth_channel_mem_params mem_params; int queue; - - u16 desc_size; - u32 desc_count; - struct ipa_eth_resource desc_mem; - - u16 buff_size; - u32 buff_count; - struct ipa_eth_resource buff_mem; + struct list_head desc_mem; + struct list_head buff_mem; /* fields managed by offload driver */ void *od_priv; @@ -215,13 +420,13 @@ struct ipa_eth_channel { /** * struct ipa_eth_device - Represents an ethernet device + * @device_list: Entry in the global offload device list + * @bus_device_list: Entry in the per-bus offload device list * @net_dev: Netdev registered by the network driver * @nd_priv: Private field for use by network driver - * @ch_rx: Rx channel allocated for the offload path - * @ch_tx: Tx channel allocated for the offload path * @od_priv: Private field for use by offload driver - * @device_list: Entry in the global offload device list - * @bus_device_list: Entry in the per-bus offload device list + * @rx_channels: Rx channels allocated for the offload path + * @tx_channels: Tx channels allocated for the offload path * @of_state: Offload state of the device * @dev: Pointer to struct device * @nd: IPA offload net driver associated with the device @@ -238,18 +443,19 @@ struct ipa_eth_channel { * @refresh: Work struct used to perform device refresh */ struct ipa_eth_device { + struct list_head device_list; + struct list_head bus_device_list; + /* fields managed by the network driver */ struct net_device *net_dev; void *nd_priv; /* fields managed by offload driver */ - struct ipa_eth_channel *ch_rx; - struct ipa_eth_channel *ch_tx; void *od_priv; /* fields managed by offload subsystem */ - struct list_head device_list; - struct list_head bus_device_list; + struct list_head rx_channels; + struct list_head tx_channels; enum ipa_eth_offload_state of_state; @@ -272,16 +478,27 @@ struct ipa_eth_device { struct work_struct refresh; }; +#ifdef IPA_ETH_NET_DRIVER + /** * struct ipa_eth_net_ops - Network device operations required for IPA offload */ struct ipa_eth_net_ops { /** - * .open_device() - Initialize the network device if needed before - * channels and events are configured. + * .open_device() - Initialize the network device if needed and fill in + * @eth_dev->net_dev field * @eth_dev: Device to initialize * - * Typically this is API is functionally equivalent to .ndo_open() + * Some network perform complete device initialization only in driver + * .ndo_open(). Offload sub-system may try to use the network hardware + * for offload path even before .ndo_open() is called. .open_device() is + * expected to perform all device initialization that may be required + * to make the hardware functional for offload path, irrespective of + * whether .ndo_open() gets called. + * + * Once the device is initialized, .open_device() should initialize the + * @eth_dev->net_dev field with the driver struct net_device pointer + * before returning. * * Return: 0 on success, negative errno otherwise */ @@ -302,7 +519,7 @@ struct ipa_eth_net_ops { void (*close_device)(struct ipa_eth_device *eth_dev); /** - * .request_channel() - Allocate a channel/ring for IPA offload data + * .request_channel() - Request a channel/ring for IPA offload data * path to use * @eth_dev: Device from which to allocate channel * @dir: Requested channel direction @@ -310,6 +527,11 @@ struct ipa_eth_net_ops { * more IPA_ETH_DEV_EV_* flags. * @features: Device featured requested for the channel. Value is zero * or more IPA_ETH_DEV_F_* feature flags. + * @mem_params: Channel memory parameters. Values to be passed in is + * specific to the network driver. This info is typically + * passed on to ipa_eth_net_alloc_channel() which will + * memcpy() the contents to mem_params inside the + * ipa_eth_channel that is returned back. * * Arguments @dir, @features and @events are used to inform the network * driver about the capabilities of the offload subsystem/driver. The @@ -319,14 +541,17 @@ struct ipa_eth_net_ops { * allocated capability set is acceptable for data path operation. * * The allocated channel is expected to be in disabled state with no - * events allocated or enabled. + * events allocated or enabled. It is recommended to use the offload + * sub-system API ipa_eth_net_alloc_channel() for allocating the + * ipa_eth_channel object. * * Return: Channel object pointer, or NULL if the channel allocation * failed */ struct ipa_eth_channel * (*request_channel)( struct ipa_eth_device *eth_dev, enum ipa_eth_channel_dir dir, - unsigned long events, unsigned long features); + unsigned long events, unsigned long features, + const struct ipa_eth_channel_mem_params *mem_params); /** * .release_channel() - Free a channel/ring previously allocated using @@ -498,51 +723,15 @@ struct ipa_eth_net_driver { int ipa_eth_register_net_driver(struct ipa_eth_net_driver *nd); void ipa_eth_unregister_net_driver(struct ipa_eth_net_driver *nd); -/** - * struct ipa_eth_bus_ops - Offload driver callbacks for bus operations - * - * These APIS are implemented by the offload driver for receiving bus level - * notifications like probe, remove, suspend, resume, etc. - */ -struct ipa_eth_bus_ops { - /** - * .probe() - Probe new device for offload ability - * @eth_dev: Device being probed - * - * This API is implemented by the offload driver and called immediately - * after the network driver (PCI/plaform) probe. Offload driver is - * expected to check if the device is compatible with the driver and - * that the driver has enough offload resources for offloading the - * device to IPA. - * - * The API implementation can expect the eth_dev->dev and eth_dev->nd - * to have been already initialized by the offload subsystem. The API - * is expected to perform at least the following: - * - * 1. Ensure the device is compatible with the offload driver. For - * plaform drivers, the .compatible DT property could be used while - * PCI IDs could be used for matching with a PCI device. - * 2. If multiple network devices of the same type can be managed by the - * offload driver, it may attempt to pair @eth_dev with an available - * resource set for a single instance. - * 3. Initialize the network device, typically by calling open_device() - * callback provided by the network driver. - * - * Return: 0 on success, negative errno otherwise - */ - int (*probe)(struct ipa_eth_device *eth_dev); +struct ipa_eth_channel *ipa_eth_net_alloc_channel( + struct ipa_eth_device *eth_dev, enum ipa_eth_channel_dir dir, + unsigned long events, unsigned long features, + const struct ipa_eth_channel_mem_params *mem_params); +void ipa_eth_net_free_channel(struct ipa_eth_channel *channel); - /** - * .remove() - Handle device removal - * @eth_dev: Device being removed - * - * The API implementation should assume the device to be no more - * physically connected. - */ - void (*remove)(struct ipa_eth_device *eth_dev); +#endif /* IPA_ETH_NET_DRIVER */ - /* dev_pm_ops go here */ -}; +#ifdef IPA_ETH_OFFLOAD_DRIVER /** * struct ipa_eth_offload_link_stats - Stats for each link within an @@ -578,6 +767,46 @@ struct ipa_eth_offload_stats { * struct ipa_eth_offload_ops - Offload operations provided by an offload driver */ struct ipa_eth_offload_ops { + /** + * .pair() - Pair a new device, if compatible, with the offload driver + * @eth_dev: Device to pair with the offload driver + * + * This API is called by offload sub-system in order to pair an ethernet + * device with the offload driver. Typically this API is called soon + * after the device probe is completed and registered with the offload + * sub-system. When the API is called, offload driver is expected to + * check if the device is compatible with the driver and that the driver + * has enough offload resources for offloading the device to IPA. + * + * The API implementation can expect the eth_dev->dev to have been + * already initialized by the offload subsystem, from which a bus + * specific device pointer (pci_dev, platform_device, etc.) can be + * derived. The API is expected to perform at least the following: + * + * 1. Ensure the device is compatible with the offload driver. For + * plaform drivers, the .compatible DT property could be used while + * PCI IDs could be used for matching with a PCI device. + * 2. If multiple network devices of the same type can be managed by the + * offload driver, it may attempt to pair @eth_dev with an available + * resource set for a single instance. + * + * Return: 0 on success, negative errno otherwise + */ + int (*pair)(struct ipa_eth_device *eth_dev); + + /** + * .unpair() - Unpair a device from the offload driver + * @eth_dev: Device to unpair + * + * Unpairing the device from offload driver should make sure that all + * resources allocated for the device are freed and the data path is + * stopped and deinitialized, and device is readied for removal. The + * implementation should be able to handle plug-n-play devices by not + * assuming the device to be connected anymore to the bus/system when + * this API is called. + */ + void (*unpair)(struct ipa_eth_device *eth_dev); + /** * .init_tx() - Initialize offload path in Tx direction * @@ -667,7 +896,6 @@ struct ipa_eth_offload_driver { struct bus_type *bus; struct ipa_eth_offload_ops *ops; - struct ipa_eth_bus_ops *bus_ops; struct dentry *debugfs; }; @@ -675,6 +903,33 @@ struct ipa_eth_offload_driver { int ipa_eth_register_offload_driver(struct ipa_eth_offload_driver *od); void ipa_eth_unregister_offload_driver(struct ipa_eth_offload_driver *od); +struct ipa_eth_channel *ipa_eth_net_request_channel( + struct ipa_eth_device *eth_dev, enum ipa_client_type ipa_client, + unsigned long events, unsigned long features, + const struct ipa_eth_channel_mem_params *mem_params); +void ipa_eth_net_release_channel(struct ipa_eth_channel *ch); +int ipa_eth_net_enable_channel(struct ipa_eth_channel *ch); +int ipa_eth_net_disable_channel(struct ipa_eth_channel *ch); + +int ipa_eth_net_request_event(struct ipa_eth_channel *ch, unsigned long event, + phys_addr_t addr, u64 data); +void ipa_eth_net_release_event(struct ipa_eth_channel *ch, unsigned long event); +int ipa_eth_net_enable_event(struct ipa_eth_channel *ch, unsigned long event); +int ipa_eth_net_disable_event(struct ipa_eth_channel *ch, unsigned long event); +int ipa_eth_net_moderate_event(struct ipa_eth_channel *ch, unsigned long event, + u64 min_count, u64 max_count, + u64 min_usecs, u64 max_usecs); + +int ipa_eth_net_receive_skb(struct ipa_eth_device *eth_dev, + struct sk_buff *skb); +int ipa_eth_net_transmit_skb(struct ipa_eth_device *eth_dev, + struct sk_buff *skb); + +struct ipa_eth_resource *ipa_eth_net_ch_to_cb_mem( + struct ipa_eth_channel *ch, + struct ipa_eth_channel_mem *ch_mem, + enum ipa_eth_hw_type hw_type); + int ipa_eth_ep_init(struct ipa_eth_channel *ch); int ipa_eth_ep_start(struct ipa_eth_channel *ch); int ipa_eth_ep_stop(struct ipa_eth_channel *ch); @@ -736,6 +991,8 @@ int ipa_eth_uc_iommu_vamap(dma_addr_t daddr, void *vaddr, size_t size, int prot, bool split); int ipa_eth_uc_iommu_unmap(dma_addr_t daddr, size_t size, bool split); +#endif /* IPA_ETH_OFFLOAD_DRIVER */ + /* IPC logging interface */ #define ipa_eth_ipc_do_log(ipcbuf, fmt, args...) \ -- GitLab From 63b496bd853c9067f76fe834f102db8d1100775e Mon Sep 17 00:00:00 2001 From: "Jinesh K. Jayakumar" Date: Thu, 6 Jun 2019 15:50:04 -0400 Subject: [PATCH 0482/1121] defconfig: sdxprairie: Enable AQC IPA offload driver Enable AQC IPA offload driver and its dependencies. Change-Id: Ie1f3c3784b85377bb7d0cf45dabc6a3e3d605f27 Signed-off-by: Jinesh K. Jayakumar --- arch/arm/configs/vendor/sdxprairie-perf_defconfig | 2 ++ arch/arm/configs/vendor/sdxprairie_defconfig | 3 +++ 2 files changed, 5 insertions(+) diff --git a/arch/arm/configs/vendor/sdxprairie-perf_defconfig b/arch/arm/configs/vendor/sdxprairie-perf_defconfig index 8b95fa0ade4f..d629857a60fe 100644 --- a/arch/arm/configs/vendor/sdxprairie-perf_defconfig +++ b/arch/arm/configs/vendor/sdxprairie-perf_defconfig @@ -352,6 +352,8 @@ CONFIG_MSM_MHI_DEV=y CONFIG_IPA3=y CONFIG_IPA_WDI_UNIFIED_API=y CONFIG_IPA_ETH=y +CONFIG_AQC_IPA=y +CONFIG_AQC_IPA_PROXY_UC=y CONFIG_RMNET_IPA3=y CONFIG_ECM_IPA=y CONFIG_RNDIS_IPA=y diff --git a/arch/arm/configs/vendor/sdxprairie_defconfig b/arch/arm/configs/vendor/sdxprairie_defconfig index e25428a5892c..04b5b0310ce4 100644 --- a/arch/arm/configs/vendor/sdxprairie_defconfig +++ b/arch/arm/configs/vendor/sdxprairie_defconfig @@ -356,6 +356,9 @@ CONFIG_IPA_DEBUG=y CONFIG_IPA_WDI_UNIFIED_API=y CONFIG_IPA_ETH=y CONFIG_IPA_ETH_DEBUG=y +CONFIG_AQC_IPA=y +CONFIG_AQC_IPA_PROXY_UC=y +CONFIG_AQC_IPA_DEBUG=y CONFIG_RMNET_IPA3=y CONFIG_ECM_IPA=y CONFIG_RNDIS_IPA=y -- GitLab From ccc5e484dc127884d903b034de0fde4003a461d2 Mon Sep 17 00:00:00 2001 From: Raghavendra Rao Ananta Date: Tue, 18 Dec 2018 11:06:31 -0800 Subject: [PATCH 0483/1121] esoc: Convert the boot fail configurations to IOCTLs Currently the external modem's boot fail configurations, boot_fail_action and n_pon_tries, are set via module parameters. Convert it to an IOCTL so that a registered user-space application has control over the configurations. Change-Id: Iaf412b873fa452b99811a50e7ae886cc49cfcf81 Signed-off-by: Raghavendra Rao Ananta --- drivers/esoc/esoc-mdm-drv.c | 83 +++++++++++++++++++++++++--------- drivers/esoc/esoc.h | 4 ++ drivers/esoc/esoc_dev.c | 6 +++ include/uapi/linux/esoc_ctrl.h | 13 ++++++ 4 files changed, 84 insertions(+), 22 deletions(-) diff --git a/drivers/esoc/esoc-mdm-drv.c b/drivers/esoc/esoc-mdm-drv.c index 1645d10bd781..353bcfe2114f 100644 --- a/drivers/esoc/esoc-mdm-drv.c +++ b/drivers/esoc/esoc-mdm-drv.c @@ -20,25 +20,11 @@ #include "mdm-dbg.h" /* Default number of powerup trial requests per session */ -#define ESOC_DEF_PON_REQ 2 -static unsigned int n_pon_tries = ESOC_DEF_PON_REQ; -module_param(n_pon_tries, uint, 0644); -MODULE_PARM_DESC(n_pon_tries, -"Number of power-on retrials allowed upon boot failure"); - -enum esoc_boot_fail_action { - BOOT_FAIL_ACTION_RETRY, - BOOT_FAIL_ACTION_COLD_RESET, - BOOT_FAIL_ACTION_SHUTDOWN, - BOOT_FAIL_ACTION_PANIC, - BOOT_FAIL_ACTION_NOP, - BOOT_FAIL_ACTION_S3_RESET, -}; +#define ESOC_DEF_PON_REQ 3 + +#define ESOC_MAX_PON_TRIES 5 -static unsigned int boot_fail_action = BOOT_FAIL_ACTION_PANIC; -module_param(boot_fail_action, uint, 0644); -MODULE_PARM_DESC(boot_fail_action, -"Actions: 0:Retry PON; 1:Cold reset; 2:Power-down; 3:APQ Panic; 4:No action"); +#define BOOT_FAIL_ACTION_DEF BOOT_FAIL_ACTION_PANIC enum esoc_pon_state { PON_INIT, @@ -70,14 +56,58 @@ struct mdm_drv { struct work_struct ssr_work; struct notifier_block esoc_restart; struct mutex poff_lock; + atomic_t boot_fail_action; + atomic_t n_pon_tries; }; #define to_mdm_drv(d) container_of(d, struct mdm_drv, cmd_eng) -#define S3_RESET_DELAY_MS 2100 +#define S3_RESET_DELAY_MS 2000 static void esoc_client_link_power_off(struct esoc_clink *esoc_clink, unsigned int flags); +int esoc_set_boot_fail_action(struct esoc_clink *esoc_clink, u32 action) +{ + struct mdm_drv *mdm_drv = esoc_get_drv_data(esoc_clink); + + if (action >= BOOT_FAIL_ACTION_LAST) { + esoc_mdm_log("Unknown boot fail action requested: %u\n", + action); + return -EINVAL; + } + + if (!mdm_drv) { + esoc_mdm_log("esoc-mdm driver not present\n"); + return -EAGAIN; + } + + atomic_set(&mdm_drv->boot_fail_action, action); + esoc_mdm_log("Boot fail action configured to %u\n", action); + + return 0; +} + +int esoc_set_n_pon_tries(struct esoc_clink *esoc_clink, u32 n_tries) +{ + struct mdm_drv *mdm_drv = esoc_get_drv_data(esoc_clink); + + if (n_tries > ESOC_MAX_PON_TRIES) { + esoc_mdm_log( + "Num PON tries requested (%u) is over the limit: %u\n", + n_tries, ESOC_MAX_PON_TRIES); + } + + if (!mdm_drv) { + esoc_mdm_log("esoc-mdm driver not present\n"); + return -EAGAIN; + } + + atomic_set(&mdm_drv->n_pon_tries, n_tries); + esoc_mdm_log("Num PON tries configured to %u\n", n_tries); + + return 0; +} + static int esoc_msm_restart_handler(struct notifier_block *nb, unsigned long action, void *data) { @@ -327,8 +357,15 @@ static void mdm_subsys_retry_powerup_cleanup(struct esoc_clink *esoc_clink, static int mdm_handle_boot_fail(struct esoc_clink *esoc_clink, u8 *pon_trial) { struct mdm_ctrl *mdm = get_esoc_clink_data(esoc_clink); + struct mdm_drv *mdm_drv = esoc_get_drv_data(esoc_clink); + + if (*pon_trial == atomic_read(&mdm_drv->n_pon_tries)) { + esoc_mdm_log("Reached max. number of boot trials\n"); + atomic_set(&mdm_drv->boot_fail_action, + BOOT_FAIL_ACTION_PANIC); + } - switch (boot_fail_action) { + switch (atomic_read(&mdm_drv->boot_fail_action)) { case BOOT_FAIL_ACTION_RETRY: mdm_subsys_retry_powerup_cleanup(esoc_clink, 0); esoc_mdm_log("Request to retry a warm reset\n"); @@ -382,7 +419,7 @@ static int mdm_subsys_powerup(const struct subsys_desc *crashed_subsys) struct mdm_drv *mdm_drv = esoc_get_drv_data(esoc_clink); const struct esoc_clink_ops * const clink_ops = esoc_clink->clink_ops; int timeout = INT_MAX; - u8 pon_trial = 1; + u8 pon_trial = 0; esoc_mdm_log("Powerup request from SSR\n"); @@ -456,7 +493,7 @@ static int mdm_subsys_powerup(const struct subsys_desc *crashed_subsys) } else if (mdm_drv->pon_state == PON_SUCCESS) { break; } - } while (pon_trial <= n_pon_tries); + } while (pon_trial <= atomic_read(&mdm_drv->n_pon_tries)); return 0; } @@ -528,6 +565,8 @@ int esoc_ssr_probe(struct esoc_clink *esoc_clink, struct esoc_drv *drv) mdm_drv->esoc_clink = esoc_clink; mdm_drv->mode = PWR_OFF; mdm_drv->pon_state = PON_INIT; + atomic_set(&mdm_drv->boot_fail_action, BOOT_FAIL_ACTION_DEF); + atomic_set(&mdm_drv->n_pon_tries, ESOC_DEF_PON_REQ); mdm_drv->esoc_restart.notifier_call = esoc_msm_restart_handler; ret = register_reboot_notifier(&mdm_drv->esoc_restart); if (ret) diff --git a/drivers/esoc/esoc.h b/drivers/esoc/esoc.h index 81dd0dfe1cad..46403c371698 100644 --- a/drivers/esoc/esoc.h +++ b/drivers/esoc/esoc.h @@ -193,3 +193,7 @@ static inline void notify_esoc_clients(struct esoc_clink *esoc_clink, bool esoc_req_eng_enabled(struct esoc_clink *esoc_clink); bool esoc_cmd_eng_enabled(struct esoc_clink *esoc_clink); #endif + +/* Modem boot fail actions */ +int esoc_set_boot_fail_action(struct esoc_clink *esoc_clink, u32 action); +int esoc_set_n_pon_tries(struct esoc_clink *esoc_clink, u32 n_tries); diff --git a/drivers/esoc/esoc_dev.c b/drivers/esoc/esoc_dev.c index 6777627daee5..bd3929074eea 100644 --- a/drivers/esoc/esoc_dev.c +++ b/drivers/esoc/esoc_dev.c @@ -330,6 +330,12 @@ static long esoc_dev_ioctl(struct file *file, unsigned int cmd, return err; case ESOC_GET_LINK_ID: return esoc_get_link_id(esoc_clink, arg); + case ESOC_SET_BOOT_FAIL_ACT: + get_user(esoc_cmd, (u32 __user *) arg); + return esoc_set_boot_fail_action(esoc_clink, esoc_cmd); + case ESOC_SET_N_PON_TRIES: + get_user(esoc_cmd, (u32 __user *) arg); + return esoc_set_n_pon_tries(esoc_clink, esoc_cmd); default: return -EINVAL; }; diff --git a/include/uapi/linux/esoc_ctrl.h b/include/uapi/linux/esoc_ctrl.h index 9761aa1ae3b0..631fa449c386 100644 --- a/include/uapi/linux/esoc_ctrl.h +++ b/include/uapi/linux/esoc_ctrl.h @@ -14,12 +14,25 @@ #define ESOC_REG_REQ_ENG _IO(ESOC_CODE, 7) #define ESOC_REG_CMD_ENG _IO(ESOC_CODE, 8) #define ESOC_GET_LINK_ID _IOWR(ESOC_CODE, 9, __u64) +#define ESOC_SET_BOOT_FAIL_ACT _IOW(ESOC_CODE, 10, unsigned int) +#define ESOC_SET_N_PON_TRIES _IOW(ESOC_CODE, 11, unsigned int) #define ESOC_REQ_SEND_SHUTDOWN ESOC_REQ_SEND_SHUTDOWN #define ESOC_REQ_CRASH_SHUTDOWN ESOC_REQ_CRASH_SHUTDOWN #define ESOC_PON_RETRY ESOC_PON_RETRY +#define ESOC_BOOT_FAIL_ACTION #define ESOC_LINK_ID +enum esoc_boot_fail_action { + BOOT_FAIL_ACTION_RETRY, + BOOT_FAIL_ACTION_COLD_RESET, + BOOT_FAIL_ACTION_SHUTDOWN, + BOOT_FAIL_ACTION_PANIC, + BOOT_FAIL_ACTION_NOP, + BOOT_FAIL_ACTION_S3_RESET, + BOOT_FAIL_ACTION_LAST, +}; + enum esoc_evt { ESOC_RUN_STATE = 0x1, ESOC_UNEXPECTED_RESET, -- GitLab From 02fbd6a6c5bb089b04e0a143155b789a57a14dcb Mon Sep 17 00:00:00 2001 From: Prakruthi Deepak Heragu Date: Mon, 29 Apr 2019 11:14:53 -0700 Subject: [PATCH 0484/1121] ARM: dts: msm: Add support for CPE on sdxprairie Add device tree files to support CPE on sdxprairie target. Change-Id: I8388468706cc68e895950e1c7e035c1ac3139727 Signed-off-by: Prakruthi Deepak Heragu --- arch/arm64/boot/dts/qcom/Makefile | 2 ++ .../boot/dts/qcom/sdxprairie-cdp-cpe.dts | 24 +++++++++++++++++++ .../boot/dts/qcom/sdxprairie-cdp-cpe.dtsi | 18 ++++++++++++++ .../boot/dts/qcom/sdxprairie-mtp-cpe.dts | 24 +++++++++++++++++++ .../boot/dts/qcom/sdxprairie-mtp-cpe.dtsi | 18 ++++++++++++++ 5 files changed, 86 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/sdxprairie-cdp-cpe.dts create mode 100644 arch/arm64/boot/dts/qcom/sdxprairie-cdp-cpe.dtsi create mode 100644 arch/arm64/boot/dts/qcom/sdxprairie-mtp-cpe.dts create mode 100644 arch/arm64/boot/dts/qcom/sdxprairie-mtp-cpe.dtsi diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index 1450e40b1bb3..61fd9d0296e1 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -256,6 +256,8 @@ dtb-$(CONFIG_ARCH_SDXPRAIRIE) += sdxprairie-rumi.dtb \ sdxprairie-dsda-cdp.dtb \ sdxprairie-mtp.dtb \ sdxprairie-pcie-ep-mtp.dtb \ + sdxprairie-mtp-cpe.dtb \ + sdxprairie-cdp-cpe.dtb \ sdxprairie-cdp-256.dtb \ sdxprairie-mtp-256.dtb \ sdxprairie-mtp-aqc.dtb \ diff --git a/arch/arm64/boot/dts/qcom/sdxprairie-cdp-cpe.dts b/arch/arm64/boot/dts/qcom/sdxprairie-cdp-cpe.dts new file mode 100644 index 000000000000..3db0c8850552 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sdxprairie-cdp-cpe.dts @@ -0,0 +1,24 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "sdxprairie-cdp-cpe.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. SDXPRAIRIE CDP (CPE)"; + compatible = "qcom,sdxprairie-cdp", + "qcom,sdxprairie", "qcom,cdp"; + qcom,board-id = <0x5010001 0x0>; +}; + + diff --git a/arch/arm64/boot/dts/qcom/sdxprairie-cdp-cpe.dtsi b/arch/arm64/boot/dts/qcom/sdxprairie-cdp-cpe.dtsi new file mode 100644 index 000000000000..f4f6843b16e4 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sdxprairie-cdp-cpe.dtsi @@ -0,0 +1,18 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "sdxprairie.dtsi" +#include "sdxprairie-cdp.dtsi" + +&qnand_1 { + status = "ok"; +}; diff --git a/arch/arm64/boot/dts/qcom/sdxprairie-mtp-cpe.dts b/arch/arm64/boot/dts/qcom/sdxprairie-mtp-cpe.dts new file mode 100644 index 000000000000..1c15d85d8afa --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sdxprairie-mtp-cpe.dts @@ -0,0 +1,24 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "sdxprairie-mtp-cpe.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. SDXPRAIRIE MTP (CPE)"; + compatible = "qcom,sdxprairie-mtp", + "qcom,sdxprairie", "qcom,mtp"; + qcom,board-id = <0x7010008 0x0>; +}; + + diff --git a/arch/arm64/boot/dts/qcom/sdxprairie-mtp-cpe.dtsi b/arch/arm64/boot/dts/qcom/sdxprairie-mtp-cpe.dtsi new file mode 100644 index 000000000000..007fd6c7faee --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sdxprairie-mtp-cpe.dtsi @@ -0,0 +1,18 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "sdxprairie.dtsi" +#include "sdxprairie-mtp.dtsi" + +&qnand_1 { + status = "ok"; +}; -- GitLab From 3362b949b9ccabe6c47abbd3ba474998f35a38ed Mon Sep 17 00:00:00 2001 From: Chandana Kishori Chiluveru Date: Fri, 19 Apr 2019 12:51:26 +0530 Subject: [PATCH 0485/1121] ARM: dts: msm: Add dtsi entries of USB for ATOLL Add support for USB for ATOLL target. Change-Id: I7b1c4d51fd24ada97eda93b946262e0ccd91a74f Signed-off-by: Chandana Kishori Chiluveru --- arch/arm64/boot/dts/qcom/atoll-rumi.dtsi | 31 ++++++ arch/arm64/boot/dts/qcom/atoll-usb.dtsi | 130 +++++++++++++++++++++++ arch/arm64/boot/dts/qcom/atoll.dtsi | 1 + 3 files changed, 162 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/atoll-usb.dtsi diff --git a/arch/arm64/boot/dts/qcom/atoll-rumi.dtsi b/arch/arm64/boot/dts/qcom/atoll-rumi.dtsi index 84e7518cf79b..8a60f298d9d0 100644 --- a/arch/arm64/boot/dts/qcom/atoll-rumi.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll-rumi.dtsi @@ -20,7 +20,38 @@ clock-frequency = <1000000>; }; + usb_emu_phy: usb_emu_phy@a720000 { + compatible = "qcom,usb-emu-phy"; + reg = <0x0a720000 0x9500>, + <0x0a6f8800 0x100>; + reg-names = "base", "qcratch_base"; + + qcom,emu-init-seq = <0xfff0 0x4 + 0xfff3 0x4 + 0x40 0x4 + 0xfff3 0x4 + 0xfff0 0x4 + 0x100000 0x20 + 0x0 0x20 + 0x1a0 0x20 + 0x100000 0x3c + 0x0 0x3c + 0x10060 0x3c + 0x0 0x4>; + }; + + usb_nop_phy: usb_nop_phy { + compatible = "usb-nop-xceiv"; + }; + wdog: qcom,wdt@17c10000{ status = "disabled"; }; }; + +&usb0 { + dwc3@a600000 { + usb-phy = <&usb_emu_phy>, <&usb_nop_phy>; + maximum-speed = "high-speed"; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/atoll-usb.dtsi b/arch/arm64/boot/dts/qcom/atoll-usb.dtsi new file mode 100644 index 000000000000..1dc6626553fc --- /dev/null +++ b/arch/arm64/boot/dts/qcom/atoll-usb.dtsi @@ -0,0 +1,130 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include + +&soc { + usb0: ssusb@a600000 { + compatible = "qcom,dwc-usb3-msm"; + reg = <0x0a600000 0x100000>; + reg-names = "core_base"; + + iommus = <&apps_smmu 0x540 0x0>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + interrupts = <0 489 0>, <0 130 0>, <0 486 0>, <0 488 0>; + interrupt-names = "dp_hs_phy_irq", "pwr_event_irq", + "ss_phy_irq", "dm_hs_phy_irq"; + USB3_GDSC-supply = <&usb30_prim_gdsc>; + qcom,use-pdc-interrupts; + + clocks = <&clock_gcc GCC_USB30_PRIM_MASTER_CLK>, + <&clock_gcc GCC_CFG_NOC_USB3_PRIM_AXI_CLK>, + <&clock_gcc GCC_AGGRE_USB3_PRIM_AXI_CLK>, + <&clock_gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>, + <&clock_gcc GCC_USB30_PRIM_SLEEP_CLK>, + <&clock_gcc GCC_USB3_PRIM_CLKREF_CLK>; + clock-names = "core_clk", "iface_clk", "bus_aggr_clk", + "utmi_clk", "sleep_clk", "xo"; + + resets = <&clock_gcc GCC_USB30_PRIM_BCR>; + reset-names = "core_reset"; + + qcom,core-clk-rate = <133333333>; + qcom,core-clk-rate-hs = <66666667>; + qcom,num-gsi-evt-buffs = <0x3>; + qcom,gsi-reg-offset = + <0x0fc /* GSI_GENERAL_CFG */ + 0x110 /* GSI_DBL_ADDR_L */ + 0x120 /* GSI_DBL_ADDR_H */ + 0x130 /* GSI_RING_BASE_ADDR_L */ + 0x144 /* GSI_RING_BASE_ADDR_H */ + 0x1a4>; /* GSI_IF_STS */ + qcom,dwc-usb3-msm-tx-fifo-size = <21288>; + qcom,pm-qos-latency = <62>; + + qcom,msm-bus,name = "usb0"; + qcom,msm-bus,num-cases = <4>; + qcom,msm-bus,num-paths = <3>; + qcom,msm-bus,vectors-KBps = + /* suspend vote */ + , + , + , + + /* nominal vote */ + , + , + , + + /* svs vote */ + , + , + , + + /* min vote */ + , + , + ; + + dwc3@a600000 { + compatible = "snps,dwc3"; + reg = <0x0a600000 0xcd00>; + interrupts = <0 133 0>; + linux,sysdev_is_parent; + snps,disable-clk-gating; + snps,dis_u2_susphy_quirk; + snps,dis_enblslpm_quirk; + snps,has-lpm-erratum; + snps,hird-threshold = /bits/ 8 <0x10>; + snps,usb3_lpm_capable; + usb-core-id = <0>; + tx-fifo-resize; + maximum-speed = "super-speed"; + dr_mode = "otg"; + }; + + qcom,usbbam@a704000 { + compatible = "qcom,usb-bam-msm"; + reg = <0xa704000 0x17000>; + interrupts = <0 132 0>; + + qcom,usb-bam-fifo-baseaddr = <0x146a6000>; + qcom,usb-bam-num-pipes = <4>; + qcom,disable-clk-gating; + qcom,usb-bam-override-threshold = <0x4001>; + qcom,usb-bam-max-mbps-highspeed = <400>; + qcom,usb-bam-max-mbps-superspeed = <3600>; + qcom,reset-bam-on-connect; + + qcom,pipe0 { + label = "ssusb-qdss-in-0"; + qcom,usb-bam-mem-type = <2>; + qcom,dir = <1>; + qcom,pipe-num = <0>; + qcom,peer-bam = <0>; + qcom,peer-bam-physical-address = <0x6064000>; + qcom,src-bam-pipe-index = <0>; + qcom,dst-bam-pipe-index = <0>; + qcom,data-fifo-offset = <0x0>; + qcom,data-fifo-size = <0x1800>; + qcom,descriptor-fifo-offset = <0x1800>; + qcom,descriptor-fifo-size = <0x800>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index b8d80771d662..022f35ce27fb 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -1674,3 +1674,4 @@ #include "atoll-pinctrl.dtsi" #include "atoll-pm.dtsi" #include "atoll-stub-regulator.dtsi" +#include "atoll-usb.dtsi" -- GitLab From efad955f38c830574b8ce43dff106d3ca9643342 Mon Sep 17 00:00:00 2001 From: Sharat Masetty Date: Wed, 5 Jun 2019 00:32:51 +0530 Subject: [PATCH 0486/1121] Revert "msm: kgsl: Call dma_buf_unmap_attachment() early" This reverts commit 0f09e6d06e1f71d7f15f353970890afbf19b677f. This patch is reported to be causing screen corruption issues with camera and some display use cases, so reverting this change until the root cause and fix is identified. Change-Id: I13677a05f358b445eaaa62a927f9bef5e14e0613 Signed-off-by: Sharat Masetty --- drivers/gpu/msm/kgsl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index edc07c7d0c01..a951a597087c 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -341,6 +341,8 @@ static void kgsl_destroy_ion(struct kgsl_dma_buf_meta *meta) { if (meta != NULL) { remove_dmabuf_list(meta); + dma_buf_unmap_attachment(meta->attach, meta->table, + DMA_FROM_DEVICE); dma_buf_detach(meta->dmabuf, meta->attach); dma_buf_put(meta->dmabuf); kfree(meta); @@ -2767,8 +2769,6 @@ static int kgsl_setup_dma_buf(struct kgsl_device *device, goto out; } - dma_buf_unmap_attachment(attach, sg_table, DMA_FROM_DEVICE); - meta->table = sg_table; entry->priv_data = meta; entry->memdesc.sgt = sg_table; -- GitLab From 6bc440d8d0150f8dfbdff97caf9dfc242ad15ed7 Mon Sep 17 00:00:00 2001 From: Tejas Prajapati Date: Thu, 30 May 2019 16:18:36 +0530 Subject: [PATCH 0487/1121] msm: camera: reqmgr: Reset previous skipped slot if valid request It makes sure that last applied index also get reset when it is modified with new index. Change-Id: I47f717886e8a5287c4488fe9cfd91542fe733386 Signed-off-by: Tejas Prajapati Signed-off-by: Alok Pandey --- .../msm/camera/cam_req_mgr/cam_req_mgr_core.c | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c index 4b9f51a16ef9..9d176678d9de 100644 --- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c +++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c @@ -348,7 +348,8 @@ static void __cam_req_mgr_reset_req_slot(struct cam_req_mgr_core_link *link, struct cam_req_mgr_req_queue *in_q = link->req.in_q; slot = &in_q->slot[idx]; - CAM_DBG(CAM_CRM, "RESET: idx: %d: slot->status %d", idx, slot->status); + CAM_DBG(CAM_CRM, "RESET: last applied idx %d: idx %d: slot->status %d", + in_q->last_applied_idx, idx, slot->status); /* Check if CSL has already pushed new request*/ if (slot->status == CRM_SLOT_STATUS_REQ_ADDED || @@ -1012,7 +1013,7 @@ static int __cam_req_mgr_check_sync_req_is_ready( static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link, uint32_t trigger) { - int rc = 0, idx; + int rc = 0, idx, last_app_idx; int reset_step = 0; struct cam_req_mgr_slot *slot = NULL; struct cam_req_mgr_req_queue *in_q; @@ -1146,8 +1147,7 @@ static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link, slot->req_id, link->link_hdl); idx = in_q->rd_idx; - if (slot->req_id > 0) - in_q->last_applied_idx = idx; + reset_step = link->max_delay; if (link->sync_link) { if ((link->in_msync_mode) && @@ -1155,6 +1155,25 @@ static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link, reset_step = link->sync_link->max_delay; } + + /* This is to handle a rare scenario of scheduling + * issue. If ISP sends multiple sofs due to scheduling + * issue, it is required to retain last applied index + * to help recover. + * In this case, ISP goes into Bubble, asking to reapply + * the bubbled request which has already been reset by + * CRM. Below code retains the last applied request. + */ + + if (slot->req_id > 0) { + last_app_idx = in_q->last_applied_idx; + in_q->last_applied_idx = idx; + if (abs(last_app_idx - idx) >= + reset_step + 1) + __cam_req_mgr_reset_req_slot(link, + last_app_idx); + } + __cam_req_mgr_dec_idx( &idx, reset_step + 1, in_q->num_slots); -- GitLab From 3091c72189edbcf21f60199ad3ea3e7cda0ae491 Mon Sep 17 00:00:00 2001 From: Mitul Golani Date: Wed, 6 Mar 2019 17:22:04 +0530 Subject: [PATCH 0488/1121] ARM: dts: msm: Add QUPV3 SE dt nodes for debug uart on atoll Add initial device tree node for QUPV3 uart instance to support serial console. Change-Id: I9be082d44cf1bd86d297a16e6e1361186ca97aa4 Signed-off-by: Mitul Golani Signed-off-by: Mukesh Kumar Savaliya --- arch/arm64/boot/dts/qcom/atoll-pinctrl.dtsi | 29 ++++++++++ arch/arm64/boot/dts/qcom/atoll-qupv3.dtsi | 62 +++++++++++++++++++++ arch/arm64/boot/dts/qcom/atoll.dtsi | 9 +++ 3 files changed, 100 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/atoll-qupv3.dtsi diff --git a/arch/arm64/boot/dts/qcom/atoll-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/atoll-pinctrl.dtsi index 12ce68f4d3ca..172cc1df55fd 100644 --- a/arch/arm64/boot/dts/qcom/atoll-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll-pinctrl.dtsi @@ -20,5 +20,34 @@ #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; + + qupv3_se8_2uart_pins: qupv3_se8_2uart_pins { + qupv3_se8_2uart_active: qupv3_se8_2uart_active { + mux { + pins = "gpio44", "gpio45"; + function = "qup12"; + }; + + config { + pins = "gpio44", "gpio45"; + drive-strength = <2>; + bias-disable; + }; + }; + + qupv3_se8_2uart_sleep: qupv3_se8_2uart_sleep { + mux { + pins = "gpio44", "gpio45"; + function = "gpio"; + }; + + config { + pins = "gpio44", "gpio45"; + drive-strength = <2>; + bias-disable; + }; + }; + }; + }; }; diff --git a/arch/arm64/boot/dts/qcom/atoll-qupv3.dtsi b/arch/arm64/boot/dts/qcom/atoll-qupv3.dtsi new file mode 100644 index 000000000000..a79cdac7c492 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/atoll-qupv3.dtsi @@ -0,0 +1,62 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +&soc { + + /* QUPv3 North instances */ + qupv3_0: qcom,qupv3_0_geni_se@0x8c0000 { + compatible = "qcom,qupv3-geni-se"; + reg = <0x8c0000 0x2000>; + qcom,bus-mas-id = ; + qcom,bus-slv-id = ; + qcom,iommu-s1-bypass; + + iommu_qupv3_0_geni_se_cb: qcom,iommu_qupv3_0_geni_se_cb { + compatible = "qcom,qupv3-geni-se-cb"; + iommus = <&apps_smmu 0x043 0x0>; + }; + }; + + /* QUPv3 South Instances */ + qupv3_1: qcom,qupv3_1_geni_se@0xac0000 { + compatible = "qcom,qupv3-geni-se"; + reg = <0xac0000 0x2000>; + qcom,bus-mas-id = ; + qcom,bus-slv-id = ; + qcom,iommu-s1-bypass; + + iommu_qupv3_1_geni_se_cb: qcom,iommu_qupv3_1_geni_se_cb { + compatible = "qcom,qupv3-geni-se-cb"; + iommus = <&apps_smmu 0x4c3 0x0>; + }; + }; + + /* Debug UART Instance for CDP/MTP/RUMI platform: QUPV3_1_SE2 */ + qupv3_se8_2uart: qcom,qup_uart@0xa88000 { + compatible = "qcom,msm-geni-console"; + reg = <0xa88000 0x4000>; + reg-names = "se_phys"; + clock-names = "se-clk", "m-ahb", "s-ahb"; + clocks = <&clock_gcc GCC_QUPV3_WRAP1_S2_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_1_M_AHB_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_1_S_AHB_CLK>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&qupv3_se8_2uart_active>; + pinctrl-1 = <&qupv3_se8_2uart_sleep>; + interrupts = ; + qcom,wrapper-core = <&qupv3_1>; + status = "disabled"; + }; +}; + diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index b8d80771d662..2878437b2226 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -30,6 +30,10 @@ qcom,msm-id = <407 0x0>; interrupt-parent = <&pdc>; + aliases { + serial0 = &qupv3_se8_2uart; + }; + cpus { #address-cells = <2>; #size-cells = <0>; @@ -1610,6 +1614,7 @@ #include "atoll-gdsc.dtsi" #include "atoll-ion.dtsi" #include "msm-arm-smmu-sdmatoll.dtsi" +#include "atoll-qupv3.dtsi" &ufs_phy_gdsc { status = "ok"; @@ -1671,6 +1676,10 @@ status = "ok"; }; +&qupv3_se8_2uart { + status = "ok"; +}; + #include "atoll-pinctrl.dtsi" #include "atoll-pm.dtsi" #include "atoll-stub-regulator.dtsi" -- GitLab From 3e9202c19a8a0db593c1bad809bb0a6d82327b91 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Mon, 29 Apr 2019 17:03:21 +0530 Subject: [PATCH 0489/1121] msm: vidc: refine clock calculation for both encoder and decoder Refined vsp & vpp cycle calculation for both encoder and decoder based on vperf recommendation. Change-Id: I41aa737dc010c2434afb85df3f97608f73470183 Signed-off-by: Govindaraj Rajagopal --- .../media/platform/msm/vidc/msm_vidc_clocks.c | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/msm/vidc/msm_vidc_clocks.c b/drivers/media/platform/msm/vidc/msm_vidc_clocks.c index 1f226a099dd9..7178fdfbe5e1 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_clocks.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_clocks.c @@ -633,6 +633,7 @@ static unsigned long msm_vidc_calc_freq(struct msm_vidc_inst *inst, u32 filled_len) { unsigned long freq = 0; + unsigned long sw_overhead = 0; unsigned long vpp_cycles = 0, vsp_cycles = 0; unsigned long fw_cycles = 0, fw_vpp_cycles = 0; u32 vpp_cycles_per_mb; @@ -668,9 +669,6 @@ static unsigned long msm_vidc_calc_freq(struct msm_vidc_inst *inst, vpp_cycles = mbs_per_second * vpp_cycles_per_mb / inst->clk_data.work_route; - /* 21 / 20 is minimum overhead factor */ - vpp_cycles += max(vpp_cycles / 20, fw_vpp_cycles); - vsp_cycles = mbs_per_second * inst->clk_data.entry->vsp_cycles; /* bitrate is based on fps, scale it using operating rate */ @@ -682,21 +680,36 @@ static unsigned long msm_vidc_calc_freq(struct msm_vidc_inst *inst, vsp_cycles += ((u64)inst->clk_data.bitrate * vsp_factor_num) / vsp_factor_den; - } else if (inst->session_type == MSM_VIDC_DECODER) { - vpp_cycles = mbs_per_second * inst->clk_data.entry->vpp_cycles / - inst->clk_data.work_route; + /* sw overhead factor */ + sw_overhead = ((u64)vsp_cycles * fw_vpp_cycles) / vpp_cycles; + vsp_cycles += max(vsp_cycles/20, sw_overhead); + /* 21 / 20 is minimum overhead factor */ vpp_cycles += max(vpp_cycles / 20, fw_vpp_cycles); - /* 1.059 pipeline overhead factor */ if (inst->clk_data.work_route > 1) - vpp_cycles += vpp_cycles/17; + vpp_cycles += (vpp_cycles * 14 / 1000); + + } else if (inst->session_type == MSM_VIDC_DECODER) { + vpp_cycles = mbs_per_second * inst->clk_data.entry->vpp_cycles / + inst->clk_data.work_route; vsp_cycles = mbs_per_second * inst->clk_data.entry->vsp_cycles; /* vsp perf is about 0.5 bits/cycle */ vsp_cycles += ((fps * filled_len * 8) * 10) / 5; + /* sw overhead factor */ + sw_overhead = ((u64)vsp_cycles * fw_vpp_cycles) / vpp_cycles; + vsp_cycles += max(vsp_cycles/20, sw_overhead); + + /* 21 / 20 is minimum overhead factor */ + vpp_cycles += max(vpp_cycles / 20, fw_vpp_cycles); + + /* 1.059 pipeline overhead factor */ + if (inst->clk_data.work_route > 1) + vpp_cycles += vpp_cycles/17; + } else { dprintk(VIDC_ERR, "Unknown session type = %s\n", __func__); return msm_vidc_max_freq(inst->core); -- GitLab From b5add91c1be93930c0656a1edcd41afde87cded9 Mon Sep 17 00:00:00 2001 From: Naveen Yadav Date: Fri, 7 Jun 2019 14:39:08 +0530 Subject: [PATCH 0490/1121] dt-bindings: qcom: clocks: Add SDXPRAIRIE V2 clock bindings Add the compatible string for the SDXPRAIRIE V2 global clock controller to the clock binding documentation. Change-Id: I137793f7b71680f682e2e740dfccf68c0df5623c Signed-off-by: Naveen Yadav --- Documentation/devicetree/bindings/clock/qcom,gcc.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc.txt b/Documentation/devicetree/bindings/clock/qcom,gcc.txt index 1d3fe751ae78..8136c5458220 100644 --- a/Documentation/devicetree/bindings/clock/qcom,gcc.txt +++ b/Documentation/devicetree/bindings/clock/qcom,gcc.txt @@ -28,6 +28,7 @@ Required properties : "qcom,gcc-sdxprairie" "qcom,gcc-trinket" "qcom,gcc-sa6155" + "qcom,gcc-sdxprairie-v2" - reg : shall contain base register location and length - #clock-cells : shall contain 1 -- GitLab From 6b4f257a735b7da4a48a549d4c1f35b8df514136 Mon Sep 17 00:00:00 2001 From: Rama Krishna Phani A Date: Thu, 6 Jun 2019 21:32:03 +0530 Subject: [PATCH 0491/1121] msm: ep_pcie: Enable edma only if the controller is up Initialize edma block only if the pcie enumeration is success. Change-Id: I45e229ea70bb5a2ed56cf313474be08a98a9628f Signed-off-by: Rama Krishna Phani A --- drivers/platform/msm/ep_pcie/ep_pcie_com.h | 10 +++++++++- drivers/platform/msm/ep_pcie/ep_pcie_core.c | 10 ++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/platform/msm/ep_pcie/ep_pcie_com.h b/drivers/platform/msm/ep_pcie/ep_pcie_com.h index 4e54d20b5ebe..fb7efc1a6d24 100644 --- a/drivers/platform/msm/ep_pcie/ep_pcie_com.h +++ b/drivers/platform/msm/ep_pcie/ep_pcie_com.h @@ -397,6 +397,15 @@ struct ep_pcie_dev_t { extern struct ep_pcie_dev_t ep_pcie_dev; extern struct ep_pcie_hw hw_drv; +#if IS_ENABLED(CONFIG_QCOM_PCI_EDMA) +int qcom_edma_init(struct device *dev); +#else +static inline int qcom_edma_init(struct device *dev) +{ + return 0; +} +#endif + static inline void ep_pcie_write_mask(void __iomem *addr, u32 clear_mask, u32 set_mask) { @@ -435,6 +444,5 @@ extern bool ep_pcie_phy_is_ready(struct ep_pcie_dev_t *dev); extern void ep_pcie_reg_dump(struct ep_pcie_dev_t *dev, u32 sel, bool linkdown); extern void ep_pcie_debugfs_init(struct ep_pcie_dev_t *ep_dev); extern void ep_pcie_debugfs_exit(void); -extern int qcom_edma_init(struct device *dev); #endif diff --git a/drivers/platform/msm/ep_pcie/ep_pcie_core.c b/drivers/platform/msm/ep_pcie/ep_pcie_core.c index fe566e8055d7..066c07d5405b 100644 --- a/drivers/platform/msm/ep_pcie/ep_pcie_core.c +++ b/drivers/platform/msm/ep_pcie/ep_pcie_core.c @@ -2834,12 +2834,14 @@ static int ep_pcie_probe(struct platform_device *pdev) } skip_mapping: ret = ep_pcie_enumeration(&ep_pcie_dev); - if (IS_ENABLED(CONFIG_QCOM_PCI_EDMA)) - qcom_edma_init(&pdev->dev); + if (ret && !ep_pcie_debug_keep_resource) + goto irq_deinit; - if (!ret || ep_pcie_debug_keep_resource) - return 0; + qcom_edma_init(&pdev->dev); + + return 0; +irq_deinit: ep_pcie_irq_deinit(&ep_pcie_dev); irq_failure: ep_pcie_gpio_deinit(&ep_pcie_dev); -- GitLab From 6e4bb1a37af305e7d4d1aa4eb124140133cf6fc0 Mon Sep 17 00:00:00 2001 From: Shankar Ravi Date: Fri, 7 Jun 2019 17:17:18 +0530 Subject: [PATCH 0492/1121] msm: camera: sensor: Increase the eeprom map buffer count Increase the eeprom mermory map count to 16 to support truly ov8858 eeprom. Change-Id: Ia6aaa9532b81a05294f26a500d8fe55f85a7896b Signed-off-by: Shankar Ravi --- .../msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_dev.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_dev.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_dev.h index 7ffafc377da6..9c36134a1b8f 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_dev.h +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_dev.h @@ -35,7 +35,7 @@ #define PROPERTY_MAXSIZE 32 #define MSM_EEPROM_MEMORY_MAP_MAX_SIZE 80 -#define MSM_EEPROM_MAX_MEM_MAP_CNT 8 +#define MSM_EEPROM_MAX_MEM_MAP_CNT 16 #define MSM_EEPROM_MEM_MAP_PROPERTIES_CNT 8 enum cam_eeprom_state { -- GitLab From bd8e9fb3bec43a56661c9997f6b8f28b1ad53da1 Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Fri, 26 Apr 2019 11:21:30 -0700 Subject: [PATCH 0493/1121] ARM: dts: msm: Add CNSS pin definitions for sdmshrike Provide device tree entries for CNSS pin definitions needed by sdmshrike. Change-Id: Id9b8ea8dc3a59acf64d586355fe2894040c725db Signed-off-by: Anant Goel --- .../boot/dts/qcom/sdmshrike-pinctrl.dtsi | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdmshrike-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sdmshrike-pinctrl.dtsi index cbf93be0dfaf..2af7383028f4 100644 --- a/arch/arm64/boot/dts/qcom/sdmshrike-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/sdmshrike-pinctrl.dtsi @@ -2714,6 +2714,35 @@ }; }; + cnss_pins { + cnss_wlan_en_active: cnss_wlan_en_active { + mux { + pins = "gpio169"; + function = "gpio"; + }; + + config { + pins = "gpio169"; + drive-strength = <16>; + output-high; + bias-pull-up; + }; + }; + cnss_wlan_en_sleep: cnss_wlan_en_sleep { + mux { + pins = "gpio169"; + function = "gpio"; + }; + + config { + pins = "gpio169"; + drive-strength = <2>; + output-low; + bias-pull-down; + }; + }; + }; + audio_ioexp_reset_active: audio_ioexp_reset_active { mux { pins = "gpio166"; -- GitLab From 87a732c86e910b15e2d4e0234d5e92cac910e9e7 Mon Sep 17 00:00:00 2001 From: Jilai Wang Date: Wed, 8 May 2019 11:52:36 -0400 Subject: [PATCH 0494/1121] msm: npu: Only allow to execute patched network Unpatched network can't be executed because the buffer address in the original network is not valid iommu mapped address. Change-Id: I8ec8c486e602abcd68b9259e9a282d110ba81738 Signed-off-by: Jilai Wang --- drivers/media/platform/msm/npu/npu_dev.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/msm/npu/npu_dev.c b/drivers/media/platform/msm/npu/npu_dev.c index 7e32f10e194a..72b9a321bc47 100644 --- a/drivers/media/platform/msm/npu/npu_dev.c +++ b/drivers/media/platform/msm/npu/npu_dev.c @@ -1483,6 +1483,11 @@ static int npu_exec_network(struct npu_client *client, return -EINVAL; } + if (!req.patching_required) { + pr_err("Only support patched network"); + return -EINVAL; + } + ret = npu_host_exec_network(client, &req); if (ret) { @@ -1513,7 +1518,8 @@ static int npu_exec_network_v2(struct npu_client *client, return -EFAULT; } - if (req.patch_buf_info_num > NPU_MAX_PATCH_NUM) { + if ((req.patch_buf_info_num > NPU_MAX_PATCH_NUM) || + (req.patch_buf_info_num == 0)) { pr_err("Invalid patch buf info num %d[max:%d]\n", req.patch_buf_info_num, NPU_MAX_PATCH_NUM); return -EINVAL; -- GitLab From eb380dffb17608393a6eae6a6b2a280c2c9d0bb7 Mon Sep 17 00:00:00 2001 From: Manu Gautam Date: Thu, 6 Jun 2019 14:29:39 +0530 Subject: [PATCH 0495/1121] usb: dwc3-msm: Use dummy buffer as doorbell until GSI is ready USB GSI wrapper can try to access IPA GSI Doorbell as soon as endpoint is enabled and transfers are started. However there is always going to be some delay when transfers are started and GSI doorbell address is updated. This may result in USB GSI wrapper accessing address-0. Prevent this by using some dummy buffer as doorbell until IPA GSI connections are setup. At that stage driver will override doorbell address with valid one. Change-Id: I477602d33737a994992c5394c6c08d63744e525f Signed-off-by: Manu Gautam --- drivers/usb/dwc3/dwc3-msm.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index 0f7f7ec2c1e6..487d3d231071 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -326,6 +326,8 @@ struct dwc3_msm { struct notifier_block dpdm_nb; struct regulator *dpdm_reg; + u64 dummy_gsi_db; + dma_addr_t dummy_gsi_db_dma; }; #define USB_HSPHY_3P3_VOL_MIN 3050000 /* uV */ @@ -1003,6 +1005,10 @@ static void gsi_store_ringbase_dbl_info(struct usb_ep *ep, ep->name, request->db_reg_phs_addr_lsb, (unsigned long long)request->mapped_db_reg_phs_addr_lsb); + /* + * Replace dummy doorbell address with real one as IPA connection + * is setup now and GSI must be ready to handle doorbell updates. + */ dwc3_msm_write_reg(mdwc->base, GSI_DBL_ADDR_L(mdwc->gsi_reg[DBL_ADDR_L], (n)), (u32)request->mapped_db_reg_phs_addr_lsb); @@ -1279,9 +1285,18 @@ static void gsi_configure_ep(struct usb_ep *ep, struct usb_gsi_request *request) struct dwc3_gadget_ep_cmd_params params; const struct usb_endpoint_descriptor *desc = ep->desc; const struct usb_ss_ep_comp_descriptor *comp_desc = ep->comp_desc; + int n = ep->ep_intr_num - 1; u32 reg; int ret; + /* setup dummy doorbell as IPA connection isn't setup yet */ + dwc3_msm_write_reg_field(mdwc->base, + GSI_DBL_ADDR_L(mdwc->gsi_reg[DBL_ADDR_L], (n)), + ~0x0, (u32)mdwc->dummy_gsi_db_dma); + dev_dbg(mdwc->dev, "Dummy DB Addr %pK: %llx %llx (LSB)\n", + &mdwc->dummy_gsi_db, mdwc->dummy_gsi_db_dma, + (u32)mdwc->dummy_gsi_db_dma); + memset(¶ms, 0x00, sizeof(params)); /* Configure GSI EP */ @@ -1972,6 +1987,19 @@ static void dwc3_msm_notify_event(struct dwc3 *dwc, unsigned int event, } mdwc->gsi_ev_buff[i] = evt; } + /* + * Set-up dummy buffer to use as doorbell while IPA GSI + * connection is in progress. + */ + mdwc->dummy_gsi_db_dma = dma_map_single(dwc->sysdev, + &mdwc->dummy_gsi_db, + sizeof(mdwc->dummy_gsi_db), + DMA_FROM_DEVICE); + + if (dma_mapping_error(dwc->sysdev, mdwc->dummy_gsi_db_dma)) { + dev_err(dwc->dev, "failed to map dummy doorbell buffer\n"); + mdwc->dummy_gsi_db_dma = (dma_addr_t)NULL; + } break; case DWC3_GSI_EVT_BUF_SETUP: dev_dbg(mdwc->dev, "DWC3_GSI_EVT_BUF_SETUP\n"); @@ -2045,6 +2073,12 @@ static void dwc3_msm_notify_event(struct dwc3 *dwc, unsigned int event, dma_free_coherent(dwc->sysdev, evt->length, evt->buf, evt->dma); } + if (mdwc->dummy_gsi_db_dma) { + dma_unmap_single(dwc->sysdev, mdwc->dummy_gsi_db_dma, + sizeof(mdwc->dummy_gsi_db), + DMA_FROM_DEVICE); + mdwc->dummy_gsi_db_dma = (dma_addr_t)NULL; + } break; case DWC3_CONTROLLER_NOTIFY_DISABLE_UPDXFER: dwc3_msm_dbm_disable_updxfer(dwc, value); -- GitLab From 52152018baf2e28f64b34c7684b0eb21219fca4e Mon Sep 17 00:00:00 2001 From: Shiju Mathew Date: Tue, 19 Mar 2019 18:29:57 -0400 Subject: [PATCH 0496/1121] msm: vidc: Add support for hibernation Add freeze to pm_op to unload firmware for hibernation, with a debugfs node trigger_ssr for testing and markers. Change-Id: I101369b447f83cac33667cde191e66fed4c549a8 Signed-off-by: Shiju Mathew --- .../media/platform/msm/vidc/msm_v4l2_vidc.c | 82 ++++++++++++++++++- .../platform/msm/vidc/msm_vidc_internal.h | 1 + 2 files changed, 82 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c index 6ccbccf70c9f..0791613ead21 100644 --- a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c +++ b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c @@ -781,12 +781,92 @@ static int msm_vidc_pm_suspend(struct device *dev) static int msm_vidc_pm_resume(struct device *dev) { + place_marker("vidc resumed"); dprintk(VIDC_INFO, "%s\n", __func__); return 0; } +int msm_vidc_freeze_core(struct msm_vidc_core *core) +{ + int rc = 0; + int max_retry = 300; + struct hfi_device *hdev; + + hdev = core->device; + + mutex_lock(&core->lock); + + dprintk(VIDC_WARN, "%s: fatal SSR intended to dismantle vidc\n", + __func__); + + core->ssr_type = SSR_ERR_FATAL; + + if (core->state == VIDC_CORE_INIT_DONE) { + dprintk(VIDC_INFO, "%s: ssr type %d\n", __func__, + core->ssr_type); + /* + * In current implementation user-initiated SSR triggers + * a fatal error from hardware. However, there is no way + * to know if fatal error is due to SSR or not. Handle + * user SSR as non-fatal. + */ + + core->trigger_ssr = true; + rc = call_hfi_op(hdev, core_trigger_ssr, + hdev->hfi_device_data, core->ssr_type); + + if (rc) { + dprintk(VIDC_ERR, "%s: trigger_ssr failed\n", __func__); + core->trigger_ssr = false; + } + + } else { + dprintk(VIDC_WARN, "%s: video core %pK not initialized\n", + __func__, core); + } + mutex_unlock(&core->lock); + + while ((core->state != VIDC_CORE_UNINIT) && (max_retry > 0)) { + msleep(20); + max_retry--; + } + + mutex_lock(&core->lock); + core->trigger_ssr = false; + mutex_unlock(&core->lock); + + return rc; +} + +static int msm_vidc_pm_freeze(struct device *dev) +{ + int rc = 0; + struct msm_vidc_core *core; + + if (!dev || !dev->driver) + return 0; + + core = dev_get_drvdata(dev); + if (!core) + return 0; + + if (of_device_is_compatible(dev->of_node, "qcom,msm-vidc")) { + place_marker("vidc hibernation start"); + + rc = msm_vidc_freeze_core(core); + + place_marker("vidc hibernation end"); + } + + dprintk(VIDC_INFO, "%s: done\n", __func__); + + return rc; +} + static const struct dev_pm_ops msm_vidc_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(msm_vidc_pm_suspend, msm_vidc_pm_resume) + .suspend = msm_vidc_pm_suspend, + .resume = msm_vidc_pm_resume, + .freeze = msm_vidc_pm_freeze, }; MODULE_DEVICE_TABLE(of, msm_vidc_dt_match); diff --git a/drivers/media/platform/msm/vidc/msm_vidc_internal.h b/drivers/media/platform/msm/vidc/msm_vidc_internal.h index b1be0124cf73..cc681d81656c 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_internal.h +++ b/drivers/media/platform/msm/vidc/msm_vidc_internal.h @@ -513,6 +513,7 @@ struct msm_vidc_ctrl { void handle_cmd_response(enum hal_command_response cmd, void *data); int msm_vidc_trigger_ssr(struct msm_vidc_core *core, enum hal_ssr_trigger_type type); +int msm_vidc_freeze_core(struct msm_vidc_core *core); int msm_vidc_noc_error_info(struct msm_vidc_core *core); bool heic_encode_session_supported(struct msm_vidc_inst *inst); int msm_vidc_check_session_supported(struct msm_vidc_inst *inst); -- GitLab From 1f48df32f43f7999d87c6bcaf93b08fb9d9af030 Mon Sep 17 00:00:00 2001 From: Ghanim Fodi Date: Tue, 4 Jun 2019 16:51:32 +0300 Subject: [PATCH 0497/1121] msm: ipa: Write to HOLB_EN twice for IPA 4.5 Due to H/W related issue, sometimes HOLB writing not taking effect due to specific timing. Change-Id: Iebbec9a45716a3516f2bc04c0aaddbfefc9711ea Signed-off-by: Ghanim Fodi --- drivers/platform/msm/ipa/ipa_v3/ipa.c | 6 ++++++ drivers/platform/msm/ipa/ipa_v3/ipa_client.c | 6 ++++++ drivers/platform/msm/ipa/ipa_v3/ipa_utils.c | 5 +++++ 3 files changed, 17 insertions(+) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index 65050073a9eb..f6a9c8b46300 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -2911,6 +2911,12 @@ static void ipa3_q6_avoid_holb(void) ipahal_write_reg_n_fields( IPA_ENDP_INIT_HOL_BLOCK_EN_n, ep_idx, &ep_holb); + + /* IPA4.5 issue requires HOLB_EN to be written twice */ + if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5) + ipahal_write_reg_n_fields( + IPA_ENDP_INIT_HOL_BLOCK_EN_n, + ep_idx, &ep_holb); } } } diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c index 5caf30a78bc4..35c2742eca54 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c @@ -1236,6 +1236,12 @@ int ipa3_set_reset_client_cons_pipe_sus_holb(bool set_reset, ipahal_write_reg_n_fields( IPA_ENDP_INIT_HOL_BLOCK_EN_n, pipe_idx, &ep_holb); + + /* IPA4.5 issue requires HOLB_EN to be written twice */ + if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5) + ipahal_write_reg_n_fields( + IPA_ENDP_INIT_HOL_BLOCK_EN_n, + pipe_idx, &ep_holb); } client_lock_unlock_cb(client, false); return 0; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c index dc5e7317a307..9788d13ce9e2 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c @@ -4885,6 +4885,11 @@ int ipa3_cfg_ep_holb(u32 clnt_hdl, const struct ipa_ep_cfg_holb *ep_holb) ipahal_write_reg_n_fields(IPA_ENDP_INIT_HOL_BLOCK_EN_n, clnt_hdl, ep_holb); + /* IPA4.5 issue requires HOLB_EN to be written twice */ + if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5) + ipahal_write_reg_n_fields(IPA_ENDP_INIT_HOL_BLOCK_EN_n, + clnt_hdl, ep_holb); + /* Configure timer */ if (ipa3_ctx->ipa_hw_type == IPA_HW_v4_2) { ipa3_cal_ep_holb_scale_base_val(ep_holb->tmr_val, -- GitLab From c978ad3a8b37537f0e225cbe1105a3f5a92fff92 Mon Sep 17 00:00:00 2001 From: Zhiqiang Tu Date: Wed, 20 Mar 2019 14:22:27 +0800 Subject: [PATCH 0498/1121] clk: qcom: Add virtio clock driver This is virtio clock frontend driver for guest virtual machine. It operates clocks by requesting clock backend which is in hypervisor. The frontend driver talks with backend device via the virtio interface. Change-Id: I0cd2def134e029b7762ddec2c799ab5057568caf Signed-off-by: Zhiqiang Tu --- drivers/clk/qcom/Kconfig | 6 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/virtio_clk.c | 726 ++++++++++++++++++++++++++ drivers/clk/qcom/virtio_clk_common.h | 38 ++ drivers/clk/qcom/virtio_clk_sa8195p.c | 73 +++ drivers/clk/qcom/virtio_clk_sm6150.c | 92 ++++ drivers/clk/qcom/virtio_clk_sm8150.c | 109 ++++ include/linux/virtio_clk.h | 50 ++ include/uapi/linux/virtio_ids.h | 1 + 9 files changed, 1096 insertions(+) create mode 100644 drivers/clk/qcom/virtio_clk.c create mode 100644 drivers/clk/qcom/virtio_clk_common.h create mode 100644 drivers/clk/qcom/virtio_clk_sa8195p.c create mode 100644 drivers/clk/qcom/virtio_clk_sm6150.c create mode 100644 drivers/clk/qcom/virtio_clk_sm8150.c create mode 100644 include/linux/virtio_clk.h diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 876c9aaca301..61ffeb6136c5 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -562,3 +562,9 @@ config QCOM_CLK_VIRT This is the virtual clock frontend driver which is based on HAB for the QTI virtual machine. Say Y if you want to support virtual clock. + +config VIRTIO_CLK + tristate "Virtio clock driver" + depends on VIRTIO + ---help--- + This is the virtual clock driver for virtio. diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 8f09f0c72765..157a9f7e2cbb 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -78,5 +78,6 @@ obj-$(CONFIG_SM_GCC_TRINKET) += gcc-trinket.o obj-$(CONFIG_SM_GPUCC_TRINKET) += gpucc-trinket.o obj-$(CONFIG_SM_VIDEOCC_TRINKET) += videocc-trinket.o obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o +obj-$(CONFIG_VIRTIO_CLK) += virtio_clk.o virtio_clk_sm8150.o virtio_clk_sm6150.o virtio_clk_sa8195p.o obj-y += mdss/ diff --git a/drivers/clk/qcom/virtio_clk.c b/drivers/clk/qcom/virtio_clk.c new file mode 100644 index 000000000000..ea1c6fc1835b --- /dev/null +++ b/drivers/clk/qcom/virtio_clk.c @@ -0,0 +1,726 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define pr_fmt(fmt) "%s: " fmt, __func__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "virtio_clk_common.h" + +#define VIRTIO_CLK_TIMEOUT (200) /* miliseconds */ + +struct virtio_clk { + struct virtio_device *vdev; + struct virtqueue *vq; + struct completion rsp_avail; + struct mutex lock; + struct reset_controller_dev rcdev; + const struct clk_virtio_desc *desc; + struct clk_virtio *clks; + size_t num_clks; + size_t num_resets; +}; + +#define to_clk_virtio(_hw) container_of(_hw, struct clk_virtio, hw) + +struct clk_virtio { + int clk_id; + struct clk_hw hw; + struct virtio_clk *vclk; +}; + +struct virtio_cc_map { + char cc_name[20]; + const struct clk_virtio_desc *desc; +}; + +static int virtio_clk_prepare(struct clk_hw *hw) +{ + struct clk_virtio *v = to_clk_virtio(hw); + struct virtio_clk *vclk = v->vclk; + struct virtio_clk_msg *req, *rsp; + struct scatterlist sg[1]; + unsigned int len; + int ret = 0; + + req = kzalloc(sizeof(struct virtio_clk_msg), GFP_KERNEL); + if (!req) + return -ENOMEM; + + strlcpy(req->name, clk_hw_get_name(hw), sizeof(req->name)); + req->id = cpu_to_virtio32(vclk->vdev, v->clk_id); + req->type = cpu_to_virtio32(vclk->vdev, VIRTIO_CLK_T_ENABLE); + sg_init_one(sg, req, sizeof(*req)); + + mutex_lock(&vclk->lock); + + ret = virtqueue_add_outbuf(vclk->vq, sg, 1, req, GFP_KERNEL); + if (ret) { + pr_err("%s: fail to add output buffer (%d)\n", + clk_hw_get_name(hw), ret); + goto out; + } + + virtqueue_kick(vclk->vq); + + ret = wait_for_completion_timeout(&vclk->rsp_avail, + msecs_to_jiffies(VIRTIO_CLK_TIMEOUT)); + if (!ret) { + pr_err("%s: wait for completion timeout\n", + clk_hw_get_name(hw)); + ret = -ETIMEDOUT; + goto out; + } + + rsp = virtqueue_get_buf(vclk->vq, &len); + if (!rsp) { + pr_err("%s: fail to get virtqueue buffer\n", + clk_hw_get_name(hw)); + ret = -EIO; + goto out; + } + + ret = virtio32_to_cpu(vclk->vdev, rsp->result); +out: + mutex_unlock(&vclk->lock); + kfree(req); + + return ret; +} + +static void virtio_clk_unprepare(struct clk_hw *hw) +{ + struct clk_virtio *v = to_clk_virtio(hw); + struct virtio_clk *vclk = v->vclk; + struct virtio_clk_msg *req, *rsp; + struct scatterlist sg[1]; + unsigned int len; + int ret = 0; + + req = kzalloc(sizeof(struct virtio_clk_msg), GFP_KERNEL); + if (!req) + return; + + strlcpy(req->name, clk_hw_get_name(hw), sizeof(req->name)); + req->id = cpu_to_virtio32(vclk->vdev, v->clk_id); + req->type = cpu_to_virtio32(vclk->vdev, VIRTIO_CLK_T_DISABLE); + sg_init_one(sg, req, sizeof(*req)); + + mutex_lock(&vclk->lock); + + ret = virtqueue_add_outbuf(vclk->vq, sg, 1, req, GFP_KERNEL); + if (ret) { + pr_err("%s: fail to add output buffer (%d)\n", + clk_hw_get_name(hw), ret); + goto out; + } + + virtqueue_kick(vclk->vq); + + ret = wait_for_completion_timeout(&vclk->rsp_avail, + msecs_to_jiffies(VIRTIO_CLK_TIMEOUT)); + if (!ret) { + pr_err("%s: wait for completion timeout\n", + clk_hw_get_name(hw)); + goto out; + } + + rsp = virtqueue_get_buf(vclk->vq, &len); + if (!rsp) { + pr_err("%s: fail to get virtqueue buffer\n", + clk_hw_get_name(hw)); + goto out; + } + + if (rsp->result) + pr_err("%s: error response (%d)\n", clk_hw_get_name(hw), + rsp->result); + +out: + mutex_unlock(&vclk->lock); + kfree(req); +} + +static int virtio_clk_set_rate(struct clk_hw *hw, + unsigned long rate, unsigned long parent_rate) +{ + struct clk_virtio *v = to_clk_virtio(hw); + struct virtio_clk *vclk = v->vclk; + struct virtio_clk_msg *req, *rsp; + struct scatterlist sg[1]; + unsigned int len; + int ret = 0; + + req = kzalloc(sizeof(struct virtio_clk_msg), GFP_KERNEL); + if (!req) + return -ENOMEM; + + strlcpy(req->name, clk_hw_get_name(hw), sizeof(req->name)); + req->id = cpu_to_virtio32(vclk->vdev, v->clk_id); + req->type = cpu_to_virtio32(vclk->vdev, VIRTIO_CLK_T_SET_RATE); + req->data[0] = cpu_to_virtio32(vclk->vdev, rate); + sg_init_one(sg, req, sizeof(*req)); + + mutex_lock(&vclk->lock); + + ret = virtqueue_add_outbuf(vclk->vq, sg, 1, req, GFP_KERNEL); + if (ret) { + pr_err("%s: fail to add output buffer (%d)\n", + clk_hw_get_name(hw), ret); + goto out; + } + + virtqueue_kick(vclk->vq); + + ret = wait_for_completion_timeout(&vclk->rsp_avail, + msecs_to_jiffies(VIRTIO_CLK_TIMEOUT)); + if (!ret) { + pr_err("%s: wait for completion timeout\n", + clk_hw_get_name(hw)); + ret = -ETIMEDOUT; + goto out; + } + + rsp = virtqueue_get_buf(vclk->vq, &len); + if (!rsp) { + pr_err("%s: fail to get virtqueue buffer\n", + clk_hw_get_name(hw)); + ret = -EIO; + goto out; + } + + ret = virtio32_to_cpu(vclk->vdev, rsp->result); +out: + mutex_unlock(&vclk->lock); + kfree(req); + + return ret; +} + +static long virtio_clk_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + struct clk_virtio *v = to_clk_virtio(hw); + struct virtio_clk *vclk = v->vclk; + struct virtio_clk_msg *req, *rsp; + struct scatterlist sg[1]; + unsigned int len; + int ret = 0; + + req = kzalloc(sizeof(struct virtio_clk_msg), GFP_KERNEL); + if (!req) + return 0; + + strlcpy(req->name, clk_hw_get_name(hw), sizeof(req->name)); + req->id = cpu_to_virtio32(vclk->vdev, v->clk_id); + req->type = cpu_to_virtio32(vclk->vdev, VIRTIO_CLK_T_ROUND_RATE); + req->data[0] = cpu_to_virtio32(vclk->vdev, rate); + sg_init_one(sg, req, sizeof(*req)); + + mutex_lock(&vclk->lock); + + ret = virtqueue_add_outbuf(vclk->vq, sg, 1, req, GFP_KERNEL); + if (ret) { + pr_err("%s: fail to add output buffer (%d)\n", + clk_hw_get_name(hw), ret); + goto out; + } + + virtqueue_kick(vclk->vq); + + ret = wait_for_completion_timeout(&vclk->rsp_avail, + msecs_to_jiffies(VIRTIO_CLK_TIMEOUT)); + if (!ret) { + pr_err("%s: wait for completion timeout\n", + clk_hw_get_name(hw)); + ret = 0; + goto out; + } + + rsp = virtqueue_get_buf(vclk->vq, &len); + if (!rsp) { + pr_err("%s: fail to get virtqueue buffer\n", + clk_hw_get_name(hw)); + ret = 0; + goto out; + } + + if (rsp->result) { + pr_err("%s: error response (%d)\n", clk_hw_get_name(hw), + rsp->result); + ret = 0; + } else + ret = virtio32_to_cpu(vclk->vdev, rsp->data[0]); + +out: + mutex_unlock(&vclk->lock); + kfree(req); + + return ret; +} + +static unsigned long virtio_clk_get_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_virtio *v = to_clk_virtio(hw); + struct virtio_clk *vclk = v->vclk; + struct virtio_clk_msg *req, *rsp; + struct scatterlist sg[1]; + unsigned int len; + int ret = 0; + + req = kzalloc(sizeof(struct virtio_clk_msg), GFP_KERNEL); + if (!req) + return 0; + + strlcpy(req->name, clk_hw_get_name(hw), sizeof(req->name)); + req->id = cpu_to_virtio32(vclk->vdev, v->clk_id); + req->type = cpu_to_virtio32(vclk->vdev, VIRTIO_CLK_T_GET_RATE); + sg_init_one(sg, req, sizeof(*req)); + + mutex_lock(&vclk->lock); + + ret = virtqueue_add_outbuf(vclk->vq, sg, 1, req, GFP_KERNEL); + if (ret) { + pr_err("%s: fail to add output buffer (%d)\n", + clk_hw_get_name(hw), ret); + goto out; + } + + virtqueue_kick(vclk->vq); + + ret = wait_for_completion_timeout(&vclk->rsp_avail, + msecs_to_jiffies(VIRTIO_CLK_TIMEOUT)); + if (!ret) { + pr_err("%s: wait for completion timeout\n", + clk_hw_get_name(hw)); + ret = 0; + goto out; + } + + rsp = virtqueue_get_buf(vclk->vq, &len); + if (!rsp) { + pr_err("%s: fail to get virtqueue buffer\n", + clk_hw_get_name(hw)); + ret = 0; + goto out; + } + + if (rsp->result) { + pr_err("%s: error response (%d)\n", clk_hw_get_name(hw), + rsp->result); + ret = 0; + } else + ret = virtio32_to_cpu(vclk->vdev, rsp->data[0]); + +out: + mutex_unlock(&vclk->lock); + kfree(req); + + return ret; +} + +static int virtio_clk_set_flags(struct clk_hw *hw, unsigned int flags) +{ + struct clk_virtio *v = to_clk_virtio(hw); + struct virtio_clk *vclk = v->vclk; + struct virtio_clk_msg *req, *rsp; + struct scatterlist sg[1]; + unsigned int len; + int ret = 0; + + req = kzalloc(sizeof(struct virtio_clk_msg), GFP_KERNEL); + if (!req) + return 0; + + strlcpy(req->name, clk_hw_get_name(hw), sizeof(req->name)); + req->id = cpu_to_virtio32(vclk->vdev, v->clk_id); + req->type = cpu_to_virtio32(vclk->vdev, VIRTIO_CLK_T_SET_FLAGS); + req->data[0] = cpu_to_virtio32(vclk->vdev, flags); + sg_init_one(sg, req, sizeof(*req)); + + mutex_lock(&vclk->lock); + + ret = virtqueue_add_outbuf(vclk->vq, sg, 1, req, GFP_KERNEL); + if (ret) { + pr_err("%s: fail to add output buffer (%d)\n", + clk_hw_get_name(hw), ret); + goto out; + } + + virtqueue_kick(vclk->vq); + + ret = wait_for_completion_timeout(&vclk->rsp_avail, + msecs_to_jiffies(VIRTIO_CLK_TIMEOUT)); + if (!ret) { + pr_err("%s: wait for completion timeout\n", + clk_hw_get_name(hw)); + ret = 0; + goto out; + } + + rsp = virtqueue_get_buf(vclk->vq, &len); + if (!rsp) { + pr_err("%s: fail to get virtqueue buffer\n", + clk_hw_get_name(hw)); + ret = -EIO; + goto out; + } + + ret = virtio32_to_cpu(vclk->vdev, rsp->result); +out: + mutex_unlock(&vclk->lock); + kfree(req); + + return ret; +} + +static const struct clk_ops clk_virtio_ops = { + .prepare = virtio_clk_prepare, + .unprepare = virtio_clk_unprepare, + .set_rate = virtio_clk_set_rate, + .round_rate = virtio_clk_round_rate, + .recalc_rate = virtio_clk_get_rate, + .set_flags = virtio_clk_set_flags, +}; + +static int +__virtio_reset(struct reset_controller_dev *rcdev, unsigned long id, + unsigned int action) +{ + struct virtio_clk *vclk = container_of(rcdev, struct virtio_clk, rcdev); + struct virtio_clk_msg *req, *rsp; + struct scatterlist sg[1]; + unsigned int len; + int ret = 0; + + req = kzalloc(sizeof(struct virtio_clk_msg), GFP_KERNEL); + if (!req) + return -ENOMEM; + + if (vclk->desc && vclk->desc->reset_names[id]) + strlcpy(req->name, vclk->desc->reset_names[id], + sizeof(req->name)); + req->id = cpu_to_virtio32(vclk->vdev, id); + req->type = cpu_to_virtio32(vclk->vdev, VIRTIO_CLK_T_RESET); + req->data[0] = cpu_to_virtio32(vclk->vdev, action); + sg_init_one(sg, req, sizeof(*req)); + + mutex_lock(&vclk->lock); + + ret = virtqueue_add_outbuf(vclk->vq, sg, 1, req, GFP_KERNEL); + if (ret) { + pr_err("fail to add output buffer (%d)\n", ret); + goto out; + } + + virtqueue_kick(vclk->vq); + + ret = wait_for_completion_timeout(&vclk->rsp_avail, + msecs_to_jiffies(VIRTIO_CLK_TIMEOUT)); + if (!ret) { + pr_err("wait for completion timeout\n"); + ret = -ETIMEDOUT; + goto out; + } + + rsp = virtqueue_get_buf(vclk->vq, &len); + if (!rsp) { + pr_err("fail to get virtqueue buffer\n"); + ret = -EIO; + goto out; + } + + ret = virtio32_to_cpu(vclk->vdev, rsp->result); + +out: + mutex_unlock(&vclk->lock); + kfree(req); + + return ret; +} + +static int +virtio_reset_assert(struct reset_controller_dev *rcdev, unsigned long id) +{ + return __virtio_reset(rcdev, id, 1); +} + +static int +virtio_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id) +{ + return __virtio_reset(rcdev, id, 0); +} + +static int +virtio_reset(struct reset_controller_dev *rcdev, unsigned long id) +{ + rcdev->ops->assert(rcdev, id); + udelay(1); + rcdev->ops->deassert(rcdev, id); + return 0; +} + +static const struct reset_control_ops virtio_reset_ops = { + .reset = virtio_reset, + .assert = virtio_reset_assert, + .deassert = virtio_reset_deassert, +}; + +static void virtclk_isr(struct virtqueue *vq) +{ + struct virtio_clk *vclk = vq->vdev->priv; + + complete(&vclk->rsp_avail); +} + +static int virtclk_init_vqs(struct virtio_clk *vclk) +{ + struct virtqueue *vqs[1]; + vq_callback_t *cbs[] = { virtclk_isr }; + static const char * const names[] = { "clock" }; + int ret; + + ret = virtio_find_vqs(vclk->vdev, 1, vqs, cbs, names, NULL); + if (ret) + return ret; + + vclk->vq = vqs[0]; + + return 0; +} + +static const struct virtio_cc_map clk_virtio_map_table[] = { + { .cc_name = "sm8150-gcc", .desc = &clk_virtio_sm8150_gcc, }, + { .cc_name = "sm8150-scc", .desc = &clk_virtio_sm8150_scc, }, + { .cc_name = "sm6150-gcc", .desc = &clk_virtio_sm6150_gcc, }, + { .cc_name = "sm6150-scc", .desc = &clk_virtio_sm6150_scc, }, + { .cc_name = "sa8195p-gcc", .desc = &clk_virtio_sa8195p_gcc, }, + { } +}; + +static const struct clk_virtio_desc *virtclk_find_desc( + const struct virtio_cc_map *maps, + const char *name) +{ + if (!maps) + return NULL; + + for (; maps->cc_name[0]; maps++) { + if (!strcmp(name, maps->cc_name)) + return maps->desc; + } + + return NULL; +} + +static struct clk_hw * +of_clk_hw_virtio_get(struct of_phandle_args *clkspec, void *data) +{ + struct virtio_clk *vclk = data; + unsigned int idx = clkspec->args[0]; + + if (idx >= vclk->num_clks) { + pr_err("%s: invalid index %u\n", __func__, idx); + return ERR_PTR(-EINVAL); + } + + return &vclk->clks[idx].hw; +} + +static int virtio_clk_probe(struct virtio_device *vdev) +{ + const struct clk_virtio_desc *desc = NULL; + struct virtio_clk *vclk; + struct virtio_clk_config config; + struct clk_virtio *virtio_clks; + char name[40]; + struct clk_init_data init; + static int instance; + unsigned int i; + int ret; + + if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) + return -ENODEV; + + vclk = devm_kzalloc(&vdev->dev, sizeof(*vclk), GFP_KERNEL); + if (!vclk) + return -ENOMEM; + + vdev->priv = vclk; + vclk->vdev = vdev; + mutex_init(&vclk->lock); + init_completion(&vclk->rsp_avail); + + ret = virtclk_init_vqs(vclk); + if (ret) { + dev_err(&vdev->dev, "failed to initialized virtqueue\n"); + return ret; + } + + virtio_device_ready(vdev); + + memset(&config, 0x0, sizeof(config)); + + virtio_cread(vdev, struct virtio_clk_config, num_clks, + &config.num_clks); + virtio_cread_feature(vdev, VIRTIO_CLK_F_RESET, struct virtio_clk_config, + num_resets, &config.num_resets); + + if (virtio_has_feature(vdev, VIRTIO_CLK_F_NAME)) { + virtio_cread_bytes(vdev, + offsetof(struct virtio_clk_config, name), + &config.name, sizeof(config.name)); + desc = virtclk_find_desc(clk_virtio_map_table, config.name); + if (!desc) { + ret = -ENXIO; + goto err_find_desc; + } + } + + dev_dbg(&vdev->dev, "num_clks=%d, num_resets=%d, name=%s\n", + config.num_clks, config.num_resets, config.name); + + if (desc) { + vclk->desc = desc; + vclk->num_clks = desc->num_clks; + if (desc->num_resets > 0) + vclk->num_resets = desc->num_resets; + } else { + vclk->num_clks = config.num_clks; + if (config.num_resets > 0) + vclk->num_resets = config.num_resets; + } + + virtio_clks = devm_kcalloc(&vdev->dev, vclk->num_clks, + sizeof(struct clk_virtio), GFP_KERNEL); + if (!virtio_clks) { + ret = -ENOMEM; + goto err_kcalloc; + } + + vclk->clks = virtio_clks; + + memset(&init, 0x0, sizeof(init)); + init.ops = &clk_virtio_ops; + + if (desc) { + for (i = 0; i < vclk->num_clks; i++) { + if (!desc->clk_names[i]) + continue; + + virtio_clks[i].clk_id = i; + virtio_clks[i].vclk = vclk; + init.name = desc->clk_names[i]; + virtio_clks[i].hw.init = &init; + ret = devm_clk_hw_register(&vdev->dev, + &virtio_clks[i].hw); + if (ret) { + dev_err(&vdev->dev, "fail to register clock\n"); + goto err_clk_register; + } + } + } else { + init.name = name; + + for (i = 0; i < config.num_clks; i++) { + virtio_clks[i].clk_id = i; + virtio_clks[i].vclk = vclk; + snprintf(name, sizeof(name), "virtio_%d_%d", + instance, i); + virtio_clks[i].hw.init = &init; + ret = devm_clk_hw_register(&vdev->dev, + &virtio_clks[i].hw); + if (ret) { + dev_err(&vdev->dev, "fail to register clock\n"); + goto err_clk_register; + } + } + } + + ret = of_clk_add_hw_provider(vdev->dev.parent->of_node, + of_clk_hw_virtio_get, vclk); + if (ret) { + dev_err(&vdev->dev, "failed to add clock provider\n"); + goto err_clk_register; + } + + if (vclk->num_resets > 0) { + vclk->rcdev.of_node = vdev->dev.parent->of_node; + vclk->rcdev.ops = &virtio_reset_ops; + vclk->rcdev.owner = vdev->dev.driver->owner; + vclk->rcdev.nr_resets = vclk->num_resets; + ret = devm_reset_controller_register(&vdev->dev, &vclk->rcdev); + if (ret) + goto err_rst_register; + } + + instance++; + + dev_info(&vdev->dev, "Registered virtio clocks (%s)\n", config.name); + + return 0; + +err_rst_register: + of_clk_del_provider(vdev->dev.parent->of_node); +err_clk_register: +err_kcalloc: +err_find_desc: + vdev->config->del_vqs(vdev); + return ret; +} + +static const struct virtio_device_id id_table[] = { + { VIRTIO_ID_CLOCK, VIRTIO_DEV_ANY_ID }, + { 0 }, +}; + +static unsigned int features[] = { + VIRTIO_CLK_F_RESET, + VIRTIO_CLK_F_NAME, +}; + +static struct virtio_driver virtio_clk_driver = { + .feature_table = features, + .feature_table_size = ARRAY_SIZE(features), + .driver.name = KBUILD_MODNAME, + .driver.owner = THIS_MODULE, + .id_table = id_table, + .probe = virtio_clk_probe, +}; + +static int __init virtio_clk_init(void) +{ + return register_virtio_driver(&virtio_clk_driver); +} + +static void __exit virtio_clk_fini(void) +{ + unregister_virtio_driver(&virtio_clk_driver); +} +subsys_initcall(virtio_clk_init); +module_exit(virtio_clk_fini); + +MODULE_DEVICE_TABLE(virtio, id_table); +MODULE_DESCRIPTION("Virtio clock driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/qcom/virtio_clk_common.h b/drivers/clk/qcom/virtio_clk_common.h new file mode 100644 index 000000000000..200fcd9e3784 --- /dev/null +++ b/drivers/clk/qcom/virtio_clk_common.h @@ -0,0 +1,38 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __VIRTIO_CLK_COMMON__ +#define __VIRTIO_CLK_COMMON__ + +#include + +/* + * struct clk_virtio_desc - virtio clock descriptor + * clk_names: the pointer of clock name pointer + * num_clks: number of clocks + * reset_names: the pointer of reset name pointer + * num_resets: number of resets + */ +struct clk_virtio_desc { + const char * const *clk_names; + size_t num_clks; + const char * const *reset_names; + size_t num_resets; +}; + +extern const struct clk_virtio_desc clk_virtio_sm8150_gcc; +extern const struct clk_virtio_desc clk_virtio_sm8150_scc; +extern const struct clk_virtio_desc clk_virtio_sm6150_gcc; +extern const struct clk_virtio_desc clk_virtio_sm6150_scc; +extern const struct clk_virtio_desc clk_virtio_sa8195p_gcc; + +#endif diff --git a/drivers/clk/qcom/virtio_clk_sa8195p.c b/drivers/clk/qcom/virtio_clk_sa8195p.c new file mode 100644 index 000000000000..2be46624a73d --- /dev/null +++ b/drivers/clk/qcom/virtio_clk_sa8195p.c @@ -0,0 +1,73 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include "virtio_clk_common.h" + +static const char * const sa8195p_gcc_virtio_clocks[] = { + [GCC_QUPV3_WRAP0_S0_CLK] = "gcc_qupv3_wrap0_s0_clk", + [GCC_QUPV3_WRAP0_S1_CLK] = "gcc_qupv3_wrap0_s1_clk", + [GCC_QUPV3_WRAP0_S2_CLK] = "gcc_qupv3_wrap0_s2_clk", + [GCC_QUPV3_WRAP0_S3_CLK] = "gcc_qupv3_wrap0_s3_clk", + [GCC_QUPV3_WRAP0_S4_CLK] = "gcc_qupv3_wrap0_s4_clk", + [GCC_QUPV3_WRAP0_S5_CLK] = "gcc_qupv3_wrap0_s5_clk", + [GCC_QUPV3_WRAP0_S6_CLK] = "gcc_qupv3_wrap0_s6_clk", + [GCC_QUPV3_WRAP0_S7_CLK] = "gcc_qupv3_wrap0_s7_clk", + [GCC_QUPV3_WRAP1_S0_CLK] = "gcc_qupv3_wrap1_s0_clk", + [GCC_QUPV3_WRAP1_S1_CLK] = "gcc_qupv3_wrap1_s1_clk", + [GCC_QUPV3_WRAP1_S2_CLK] = "gcc_qupv3_wrap1_s2_clk", + [GCC_QUPV3_WRAP1_S3_CLK] = "gcc_qupv3_wrap1_s3_clk", + [GCC_QUPV3_WRAP1_S4_CLK] = "gcc_qupv3_wrap1_s4_clk", + [GCC_QUPV3_WRAP1_S5_CLK] = "gcc_qupv3_wrap1_s5_clk", + [GCC_QUPV3_WRAP2_S0_CLK] = "gcc_qupv3_wrap2_s0_clk", + [GCC_QUPV3_WRAP2_S1_CLK] = "gcc_qupv3_wrap2_s1_clk", + [GCC_QUPV3_WRAP2_S2_CLK] = "gcc_qupv3_wrap2_s2_clk", + [GCC_QUPV3_WRAP2_S3_CLK] = "gcc_qupv3_wrap2_s3_clk", + [GCC_QUPV3_WRAP2_S4_CLK] = "gcc_qupv3_wrap2_s4_clk", + [GCC_QUPV3_WRAP2_S5_CLK] = "gcc_qupv3_wrap2_s5_clk", + [GCC_QUPV3_WRAP_0_M_AHB_CLK] = "gcc_qupv3_wrap_0_m_ahb_clk", + [GCC_QUPV3_WRAP_0_S_AHB_CLK] = "gcc_qupv3_wrap_0_s_ahb_clk", + [GCC_QUPV3_WRAP_1_M_AHB_CLK] = "gcc_qupv3_wrap_1_m_ahb_clk", + [GCC_QUPV3_WRAP_1_S_AHB_CLK] = "gcc_qupv3_wrap_1_s_ahb_clk", + [GCC_QUPV3_WRAP_2_M_AHB_CLK] = "gcc_qupv3_wrap_2_m_ahb_clk", + [GCC_QUPV3_WRAP_2_S_AHB_CLK] = "gcc_qupv3_wrap_2_s_ahb_clk", + [GCC_USB30_PRIM_MASTER_CLK] = "gcc_usb30_prim_master_clk", + [GCC_CFG_NOC_USB3_PRIM_AXI_CLK] = "gcc_cfg_noc_usb3_prim_axi_clk", + [GCC_AGGRE_USB3_PRIM_AXI_CLK] = "gcc_aggre_usb3_prim_axi_clk", + [GCC_USB30_PRIM_MOCK_UTMI_CLK] = "gcc_usb30_prim_mock_utmi_clk", + [GCC_PCIE_0_PIPE_CLK] = "gcc_pcie_0_pipe_clk", + [GCC_PCIE_0_AUX_CLK] = "gcc_pcie_0_aux_clk", + [GCC_PCIE_0_CFG_AHB_CLK] = "gcc_pcie_0_cfg_ahb_clk", + [GCC_PCIE_0_MSTR_AXI_CLK] = "gcc_pcie_0_mstr_axi_clk", + [GCC_PCIE_0_SLV_AXI_CLK] = "gcc_pcie_0_slv_axi_clk", + [GCC_PCIE_0_SLV_Q2A_AXI_CLK] = "gcc_pcie_0_slv_q2a_axi_clk", + [GCC_AGGRE_NOC_PCIE_TBU_CLK] = "gcc_aggre_noc_pcie_tbu_clk", + [GCC_PCIE0_PHY_REFGEN_CLK] = "gcc_pcie0_phy_refgen_clk", + [GCC_PCIE_PHY_AUX_CLK] = "gcc_pcie_phy_aux_clk", + [GCC_SDCC2_AHB_CLK] = "gcc_sdcc2_ahb_clk", + [GCC_SDCC2_APPS_CLK] = "gcc_sdcc2_apps_clk", +}; + +static const char * const sa8195p_gcc_virtio_resets[] = { + [GCC_QUSB2PHY_PRIM_BCR] = "gcc_qusb2phy_prim_bcr", + [GCC_USB30_PRIM_BCR] = "gcc_usb30_prim_master_clk", + [GCC_PCIE_0_BCR] = "gcc_pcie_0_mstr_axi_clk", + [GCC_PCIE_0_PHY_BCR] = "gcc_pcie_0_phy_bcr", +}; + +const struct clk_virtio_desc clk_virtio_sa8195p_gcc = { + .clk_names = sa8195p_gcc_virtio_clocks, + .num_clks = ARRAY_SIZE(sa8195p_gcc_virtio_clocks), + .reset_names = sa8195p_gcc_virtio_resets, + .num_resets = ARRAY_SIZE(sa8195p_gcc_virtio_resets), +}; diff --git a/drivers/clk/qcom/virtio_clk_sm6150.c b/drivers/clk/qcom/virtio_clk_sm6150.c new file mode 100644 index 000000000000..64a1c530644e --- /dev/null +++ b/drivers/clk/qcom/virtio_clk_sm6150.c @@ -0,0 +1,92 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include "virtio_clk_common.h" + +static const char * const sm6150_gcc_virtio_clocks[] = { + [GCC_QUPV3_WRAP0_S0_CLK] = "gcc_qupv3_wrap0_s0_clk", + [GCC_QUPV3_WRAP0_S1_CLK] = "gcc_qupv3_wrap0_s1_clk", + [GCC_QUPV3_WRAP0_S2_CLK] = "gcc_qupv3_wrap0_s2_clk", + [GCC_QUPV3_WRAP0_S3_CLK] = "gcc_qupv3_wrap0_s3_clk", + [GCC_QUPV3_WRAP0_S4_CLK] = "gcc_qupv3_wrap0_s4_clk", + [GCC_QUPV3_WRAP0_S5_CLK] = "gcc_qupv3_wrap0_s5_clk", + [GCC_QUPV3_WRAP1_S0_CLK] = "gcc_qupv3_wrap1_s0_clk", + [GCC_QUPV3_WRAP1_S1_CLK] = "gcc_qupv3_wrap1_s1_clk", + [GCC_QUPV3_WRAP1_S2_CLK] = "gcc_qupv3_wrap1_s2_clk", + [GCC_QUPV3_WRAP1_S3_CLK] = "gcc_qupv3_wrap1_s3_clk", + [GCC_QUPV3_WRAP1_S4_CLK] = "gcc_qupv3_wrap1_s4_clk", + [GCC_QUPV3_WRAP1_S5_CLK] = "gcc_qupv3_wrap1_s5_clk", + [GCC_QUPV3_WRAP_0_M_AHB_CLK] = "gcc_qupv3_wrap_0_m_ahb_clk", + [GCC_QUPV3_WRAP_0_S_AHB_CLK] = "gcc_qupv3_wrap_0_s_ahb_clk", + [GCC_QUPV3_WRAP_1_M_AHB_CLK] = "gcc_qupv3_wrap_1_m_ahb_clk", + [GCC_QUPV3_WRAP_1_S_AHB_CLK] = "gcc_qupv3_wrap_1_s_ahb_clk", + [GCC_USB30_PRIM_MASTER_CLK] = "gcc_usb30_prim_master_clk", + [GCC_CFG_NOC_USB3_PRIM_AXI_CLK] = "gcc_cfg_noc_usb3_prim_axi_clk", + [GCC_AGGRE_USB3_PRIM_AXI_CLK] = "gcc_aggre_usb3_prim_axi_clk", + [GCC_USB30_PRIM_MOCK_UTMI_CLK] = "gcc_usb30_prim_mock_utmi_clk", + [GCC_USB30_PRIM_SLEEP_CLK] = "gcc_usb30_prim_sleep_clk", + [GCC_USB3_SEC_CLKREF_CLK] = "gcc_usb3_sec_clkref_en", + [GCC_USB3_PRIM_PHY_AUX_CLK] = "gcc_usb3_prim_phy_aux_clk", + [GCC_USB3_PRIM_PHY_PIPE_CLK] = "gcc_usb3_prim_phy_pipe_clk", + [GCC_USB3_PRIM_CLKREF_CLK] = "gcc_usb3_prim_clkref_en", + [GCC_USB3_PRIM_PHY_COM_AUX_CLK] = "gcc_usb3_prim_phy_com_aux_clk", + [GCC_AHB2PHY_WEST_CLK] = "gcc_ahb2phy_west_clk", + [GCC_PCIE_0_PIPE_CLK] = "gcc_pcie_0_pipe_clk", + [GCC_PCIE_0_AUX_CLK] = "gcc_pcie_0_aux_clk", + [GCC_PCIE_0_CFG_AHB_CLK] = "gcc_pcie_0_cfg_ahb_clk", + [GCC_PCIE_0_MSTR_AXI_CLK] = "gcc_pcie_0_mstr_axi_clk", + [GCC_PCIE_0_SLV_AXI_CLK] = "gcc_pcie_0_slv_axi_clk", + [GCC_PCIE_0_CLKREF_CLK] = "gcc_pcie_0_clkref_clk", + [GCC_PCIE_0_SLV_Q2A_AXI_CLK] = "gcc_pcie_0_slv_q2a_axi_clk", + [GCC_PCIE0_PHY_REFGEN_CLK] = "gcc_pcie0_phy_refgen_clk", + [GCC_PCIE_PHY_AUX_CLK] = "gcc_pcie_phy_aux_clk", + [GCC_SDCC2_AHB_CLK] = "gcc_sdcc2_ahb_clk", + [GCC_SDCC2_APPS_CLK] = "gcc_sdcc2_apps_clk", +}; + +static const char * const sm6150_gcc_virtio_resets[] = { + [GCC_QUSB2PHY_PRIM_BCR] = "gcc_qusb2phy_prim_bcr", + [GCC_QUSB2PHY_SEC_BCR] = "gcc_qusb2phy_sec_bcr", + [GCC_USB30_PRIM_BCR] = "gcc_usb30_prim_master_clk", + [GCC_USB2_PHY_SEC_BCR] = "gcc_usb2_phy_sec_bcr", + [GCC_USB3_DP_PHY_SEC_BCR] = "gcc_usb3_dp_phy_sec_bcr", + [GCC_USB3PHY_PHY_SEC_BCR] = "gcc_usb3phy_phy_sec_bcr", + [GCC_USB20_SEC_BCR] = "gcc_usb20_sec_master_clk", + [GCC_USB3_PHY_PRIM_SP0_BCR] = "gcc_usb3_phy_prim_sp0_bcr", + [GCC_USB3PHY_PHY_PRIM_SP0_BCR] = "gcc_usb3phy_phy_prim_sp0_bcr", + [GCC_PCIE_0_BCR] = "gcc_pcie_0_mstr_axi_clk", + [GCC_PCIE_0_PHY_BCR] = "gcc_pcie_0_phy_bcr", +}; + +const struct clk_virtio_desc clk_virtio_sm6150_gcc = { + .clk_names = sm6150_gcc_virtio_clocks, + .num_clks = ARRAY_SIZE(sm6150_gcc_virtio_clocks), + .reset_names = sm6150_gcc_virtio_resets, + .num_resets = ARRAY_SIZE(sm6150_gcc_virtio_resets), +}; + +static const char * const sm6150_scc_virtio_clocks[] = { + [SCC_QUPV3_SE0_CLK] = "scc_qupv3_se0_clk", + [SCC_QUPV3_SE1_CLK] = "scc_qupv3_se1_clk", + [SCC_QUPV3_SE2_CLK] = "scc_qupv3_se2_clk", + [SCC_QUPV3_SE3_CLK] = "scc_qupv3_se3_clk", + [SCC_QUPV3_M_HCLK_CLK] = "scc_qupv3_m_hclk_clk", + [SCC_QUPV3_S_HCLK_CLK] = "scc_qupv3_s_hclk_clk", +}; + +const struct clk_virtio_desc clk_virtio_sm6150_scc = { + .clk_names = sm6150_scc_virtio_clocks, + .num_clks = ARRAY_SIZE(sm6150_scc_virtio_clocks), +}; diff --git a/drivers/clk/qcom/virtio_clk_sm8150.c b/drivers/clk/qcom/virtio_clk_sm8150.c new file mode 100644 index 000000000000..f71ec943b323 --- /dev/null +++ b/drivers/clk/qcom/virtio_clk_sm8150.c @@ -0,0 +1,109 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include "virtio_clk_common.h" + +static const char * const sm8150_gcc_virtio_clocks[] = { + [GCC_QUPV3_WRAP0_S0_CLK] = "gcc_qupv3_wrap0_s0_clk", + [GCC_QUPV3_WRAP0_S1_CLK] = "gcc_qupv3_wrap0_s1_clk", + [GCC_QUPV3_WRAP0_S2_CLK] = "gcc_qupv3_wrap0_s2_clk", + [GCC_QUPV3_WRAP0_S3_CLK] = "gcc_qupv3_wrap0_s3_clk", + [GCC_QUPV3_WRAP0_S4_CLK] = "gcc_qupv3_wrap0_s4_clk", + [GCC_QUPV3_WRAP0_S5_CLK] = "gcc_qupv3_wrap0_s5_clk", + [GCC_QUPV3_WRAP0_S6_CLK] = "gcc_qupv3_wrap0_s6_clk", + [GCC_QUPV3_WRAP0_S7_CLK] = "gcc_qupv3_wrap0_s7_clk", + [GCC_QUPV3_WRAP1_S0_CLK] = "gcc_qupv3_wrap1_s0_clk", + [GCC_QUPV3_WRAP1_S1_CLK] = "gcc_qupv3_wrap1_s1_clk", + [GCC_QUPV3_WRAP1_S2_CLK] = "gcc_qupv3_wrap1_s2_clk", + [GCC_QUPV3_WRAP1_S3_CLK] = "gcc_qupv3_wrap1_s3_clk", + [GCC_QUPV3_WRAP1_S4_CLK] = "gcc_qupv3_wrap1_s4_clk", + [GCC_QUPV3_WRAP1_S5_CLK] = "gcc_qupv3_wrap1_s5_clk", + [GCC_QUPV3_WRAP2_S0_CLK] = "gcc_qupv3_wrap2_s0_clk", + [GCC_QUPV3_WRAP2_S1_CLK] = "gcc_qupv3_wrap2_s1_clk", + [GCC_QUPV3_WRAP2_S2_CLK] = "gcc_qupv3_wrap2_s2_clk", + [GCC_QUPV3_WRAP2_S3_CLK] = "gcc_qupv3_wrap2_s3_clk", + [GCC_QUPV3_WRAP2_S4_CLK] = "gcc_qupv3_wrap2_s4_clk", + [GCC_QUPV3_WRAP2_S5_CLK] = "gcc_qupv3_wrap2_s5_clk", + [GCC_QUPV3_WRAP_0_M_AHB_CLK] = "gcc_qupv3_wrap_0_m_ahb_clk", + [GCC_QUPV3_WRAP_0_S_AHB_CLK] = "gcc_qupv3_wrap_0_s_ahb_clk", + [GCC_QUPV3_WRAP_1_M_AHB_CLK] = "gcc_qupv3_wrap_1_m_ahb_clk", + [GCC_QUPV3_WRAP_1_S_AHB_CLK] = "gcc_qupv3_wrap_1_s_ahb_clk", + [GCC_QUPV3_WRAP_2_M_AHB_CLK] = "gcc_qupv3_wrap_2_m_ahb_clk", + [GCC_QUPV3_WRAP_2_S_AHB_CLK] = "gcc_qupv3_wrap_2_s_ahb_clk", + [GCC_USB30_PRIM_MASTER_CLK] = "gcc_usb30_prim_master_clk", + [GCC_CFG_NOC_USB3_PRIM_AXI_CLK] = "gcc_cfg_noc_usb3_prim_axi_clk", + [GCC_AGGRE_USB3_PRIM_AXI_CLK] = "gcc_aggre_usb3_prim_axi_clk", + [GCC_USB30_PRIM_MOCK_UTMI_CLK] = "gcc_usb30_prim_mock_utmi_clk", + [GCC_USB30_PRIM_SLEEP_CLK] = "gcc_usb30_prim_sleep_clk", + [GCC_USB3_SEC_CLKREF_CLK] = "gcc_usb3_sec_clkref_en", + [GCC_USB3_PRIM_PHY_AUX_CLK] = "gcc_usb3_prim_phy_aux_clk", + [GCC_USB3_PRIM_PHY_PIPE_CLK] = "gcc_usb3_prim_phy_pipe_clk", + [GCC_USB3_PRIM_CLKREF_CLK] = "gcc_usb3_prim_clkref_en", + [GCC_USB3_PRIM_PHY_COM_AUX_CLK] = "gcc_usb3_prim_phy_com_aux_clk", + [GCC_USB30_SEC_MASTER_CLK] = "gcc_usb30_sec_master_clk", + [GCC_CFG_NOC_USB3_SEC_AXI_CLK] = "gcc_cfg_noc_usb3_sec_axi_clk", + [GCC_AGGRE_USB3_SEC_AXI_CLK] = "gcc_aggre_usb3_sec_axi_clk", + [GCC_USB30_SEC_MOCK_UTMI_CLK] = "gcc_usb30_sec_mock_utmi_clk", + [GCC_USB30_SEC_SLEEP_CLK] = "gcc_usb30_sec_sleep_clk", + [GCC_USB3_SEC_PHY_AUX_CLK] = "gcc_usb3_sec_phy_aux_clk", + [GCC_USB3_SEC_PHY_PIPE_CLK] = "gcc_usb3_sec_phy_pipe_clk", + [GCC_USB3_SEC_PHY_COM_AUX_CLK] = "gcc_usb3_sec_phy_com_aux_clk", + [GCC_PCIE_0_PIPE_CLK] = "gcc_pcie_0_pipe_clk", + [GCC_PCIE_0_AUX_CLK] = "gcc_pcie_0_aux_clk", + [GCC_PCIE_0_CFG_AHB_CLK] = "gcc_pcie_0_cfg_ahb_clk", + [GCC_PCIE_0_MSTR_AXI_CLK] = "gcc_pcie_0_mstr_axi_clk", + [GCC_PCIE_0_SLV_AXI_CLK] = "gcc_pcie_0_slv_axi_clk", + [GCC_PCIE_0_CLKREF_CLK] = "gcc_pcie_0_clkref_clk", + [GCC_PCIE_0_SLV_Q2A_AXI_CLK] = "gcc_pcie_0_slv_q2a_axi_clk", + [GCC_AGGRE_NOC_PCIE_TBU_CLK] = "gcc_aggre_noc_pcie_tbu_clk", + [GCC_PCIE0_PHY_REFGEN_CLK] = "gcc_pcie0_phy_refgen_clk", + [GCC_PCIE_PHY_AUX_CLK] = "gcc_pcie_phy_aux_clk", + [GCC_SDCC2_AHB_CLK] = "gcc_sdcc2_ahb_clk", + [GCC_SDCC2_APPS_CLK] = "gcc_sdcc2_apps_clk", +}; + +static const char * const sm8150_gcc_virtio_resets[] = { + [GCC_QUSB2PHY_PRIM_BCR] = "gcc_qusb2phy_prim_bcr", + [GCC_QUSB2PHY_SEC_BCR] = "gcc_qusb2phy_sec_bcr", + [GCC_USB3_PHY_PRIM_BCR] = "gcc_usb3_phy_prim_bcr", + [GCC_USB3_DP_PHY_PRIM_BCR] = "gcc_usb3_dp_phy_prim_bcr", + [GCC_USB3_PHY_SEC_BCR] = "gcc_usb3_phy_sec_bcr", + [GCC_USB3PHY_PHY_SEC_BCR] = "gcc_usb3phy_phy_sec_bcr", + [GCC_USB30_PRIM_BCR] = "gcc_usb30_prim_master_clk", + [GCC_USB30_SEC_BCR] = "gcc_usb30_sec_master_clk", + [GCC_PCIE_0_BCR] = "gcc_pcie_0_mstr_axi_clk", + [GCC_PCIE_0_PHY_BCR] = "gcc_pcie_0_phy_bcr", +}; + +const struct clk_virtio_desc clk_virtio_sm8150_gcc = { + .clk_names = sm8150_gcc_virtio_clocks, + .num_clks = ARRAY_SIZE(sm8150_gcc_virtio_clocks), + .reset_names = sm8150_gcc_virtio_resets, + .num_resets = ARRAY_SIZE(sm8150_gcc_virtio_resets), +}; + +static const char * const sm8150_scc_virtio_clocks[] = { + [SCC_QUPV3_SE0_CLK] = "scc_qupv3_se0_clk", + [SCC_QUPV3_SE1_CLK] = "scc_qupv3_se1_clk", + [SCC_QUPV3_SE2_CLK] = "scc_qupv3_se2_clk", + [SCC_QUPV3_SE3_CLK] = "scc_qupv3_se3_clk", + [SCC_QUPV3_M_HCLK_CLK] = "scc_qupv3_m_hclk_clk", + [SCC_QUPV3_S_HCLK_CLK] = "scc_qupv3_s_hclk_clk", +}; + +const struct clk_virtio_desc clk_virtio_sm8150_scc = { + .clk_names = sm8150_scc_virtio_clocks, + .num_clks = ARRAY_SIZE(sm8150_scc_virtio_clocks), +}; diff --git a/include/linux/virtio_clk.h b/include/linux/virtio_clk.h new file mode 100644 index 000000000000..552f5049a0e3 --- /dev/null +++ b/include/linux/virtio_clk.h @@ -0,0 +1,50 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _LINUX_VIRTIO_CLK_H +#define _LINUX_VIRTIO_CLK_H + +#include +#include +#include +#include + +/* Feature bits */ +#define VIRTIO_CLK_F_RESET 1 /* Support reset */ +#define VIRTIO_CLK_F_NAME 2 /* Support clock name */ + +/* Configuration layout */ +struct virtio_clk_config { + __u32 num_clks; + __u32 num_resets; + __u8 name[20]; +} __packed; + +/* Request/response message format */ +struct virtio_clk_msg { + u8 name[40]; + __virtio32 id; + __virtio32 type; + __virtio32 result; + __virtio32 data[4]; +}; + +/* Request type */ +#define VIRTIO_CLK_T_ENABLE 0 +#define VIRTIO_CLK_T_DISABLE 1 +#define VIRTIO_CLK_T_SET_RATE 2 +#define VIRTIO_CLK_T_GET_RATE 3 +#define VIRTIO_CLK_T_ROUND_RATE 4 +#define VIRTIO_CLK_T_RESET 5 +#define VIRTIO_CLK_T_SET_FLAGS 6 + +#endif /* _LINUX_VIRTIO_CLK_H */ diff --git a/include/uapi/linux/virtio_ids.h b/include/uapi/linux/virtio_ids.h index 6d5c3b2d4f4d..59e3a157e87d 100644 --- a/include/uapi/linux/virtio_ids.h +++ b/include/uapi/linux/virtio_ids.h @@ -43,5 +43,6 @@ #define VIRTIO_ID_INPUT 18 /* virtio input */ #define VIRTIO_ID_VSOCK 19 /* virtio vsock transport */ #define VIRTIO_ID_CRYPTO 20 /* virtio crypto */ +#define VIRTIO_ID_CLOCK 30 /* virtio clock */ #endif /* _LINUX_VIRTIO_IDS_H */ -- GitLab From 3165ec3338fa09ffb1243ccb650d3968e40913b5 Mon Sep 17 00:00:00 2001 From: Xianbin Zhu Date: Tue, 2 Apr 2019 10:41:34 +0800 Subject: [PATCH 0499/1121] i2c: add virtual i2c driver add virtual i2c driver for virtualization platform. Change-Id: I5aafa3b9db1e06d990b25a393f54f8763e73f9aa Signed-off-by: Xianbin Zhu --- drivers/i2c/busses/Kconfig | 6 + drivers/i2c/busses/Makefile | 1 + drivers/i2c/busses/virtio-i2c.c | 356 ++++++++++++++++++++++++++++++++ include/uapi/linux/virtio_ids.h | 2 + 4 files changed, 365 insertions(+) create mode 100644 drivers/i2c/busses/virtio-i2c.c diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 1ba1b89a0a52..5113fff4bd22 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -1347,4 +1347,10 @@ config I2C_ZX2967 This driver can also be built as a module. If so, the module will be called i2c-zx2967. +config VIRTIO_I2C + tristate "VIRTIO_I2C" + depends on VIRTIO + help + If you say yes to this option, the virtio i2c will be supported. + endmenu diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index 7fe0174c01f6..b2ddaf18d134 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -115,6 +115,7 @@ obj-$(CONFIG_I2C_XLP9XX) += i2c-xlp9xx.o obj-$(CONFIG_I2C_RCAR) += i2c-rcar.o obj-$(CONFIG_I2C_MSM_V2) += i2c-msm-v2.o obj-$(CONFIG_I2C_ZX2967) += i2c-zx2967.o +obj-$(CONFIG_VIRTIO_I2C) += virtio-i2c.o # External I2C/SMBus adapter drivers obj-$(CONFIG_I2C_DIOLAN_U2C) += i2c-diolan-u2c.o diff --git a/drivers/i2c/busses/virtio-i2c.c b/drivers/i2c/busses/virtio-i2c.c new file mode 100644 index 000000000000..f26551886f47 --- /dev/null +++ b/drivers/i2c/busses/virtio-i2c.c @@ -0,0 +1,356 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define I2C_ADAPTER_NR 0x00 + +#define I2C_VIRTIO_RD 0x01 +#define I2C_VIRTIO_WR 0x02 +#define I2C_VIRTIO_RDWR 0x03 + +/** + * struct virtio_i2c - virtio i2c device + * @adapter: i2c adapter + * @vdev: the virtio device + * @vq: i2c virtqueue + */ +struct virtio_i2c { + struct i2c_adapter adapter; + struct virtio_device *vdev; + struct virtqueue *vq; + wait_queue_head_t inq; +}; + +struct i2c_transfer_head { + u32 type; /* read or write from or to slave */ + u32 addr; /* slave addr */ + u32 length; /* buffer length */ + u32 total_length; /* merge write and read will use this segment */ +}; + +struct i2c_transfer_end { + u32 result; /* return value from backend */ +}; + +struct virtio_i2c_req { + struct i2c_transfer_head head; + char *buf; + struct i2c_transfer_end end; +}; + +static int virti2c_transfer(struct virtio_i2c *vi2c, + struct virtio_i2c_req *i2c_req) +{ + struct virtqueue *vq = vi2c->vq; + struct scatterlist outhdr, bufhdr, inhdr, *sgs[3]; + unsigned int num_out = 0, num_in = 0, err, len; + struct virtio_i2c_req *req_handled = NULL; + + /* send the head queue to the backend */ + sg_init_one(&outhdr, &i2c_req->head, sizeof(i2c_req->head)); + sgs[num_out++] = &outhdr; + + /* send the buffer queue to the backend */ + sg_init_one(&bufhdr, i2c_req->buf, + (i2c_req->head.type == I2C_VIRTIO_RDWR) ? + i2c_req->head.total_length : i2c_req->head.length); + if (i2c_req->head.type & I2C_VIRTIO_WR) + sgs[num_out++] = &bufhdr; + else + sgs[num_out + num_in++] = &bufhdr; + + /* send the result queue to the backend */ + sg_init_one(&inhdr, &i2c_req->end, sizeof(i2c_req->end)); + sgs[num_out + num_in++] = &inhdr; + + /* call the virtqueue function */ + err = virtqueue_add_sgs(vq, sgs, num_out, num_in, i2c_req, GFP_KERNEL); + if (err) + goto req_exit; + + /* Tell Host to go! */ + err = virtqueue_kick(vq); + + wait_event(vi2c->inq, + (req_handled = virtqueue_get_buf(vq, &len))); + + if (i2c_req->head.type == I2C_VIRTIO_RDWR) { + if (i2c_req->end.result == + i2c_req->head.total_length - i2c_req->head.length) + err = 0; + else + err = -EINVAL; + } else { + if (i2c_req->end.result == i2c_req->head.length) + err = 0; + else + err = -EINVAL; + } +req_exit: + return err; +} + +/* prepare the transfer req */ +static struct virtio_i2c_req *virti2c_transfer_prepare(struct i2c_msg *msg_1, + struct i2c_msg *msg_2) +{ + char *ptr = NULL; + int merge = 0; + struct virtio_i2c_req *i2c_req; + + if (msg_1 == NULL) + return NULL; + + if (msg_2) + merge = 1; + + i2c_req = kzalloc(sizeof(struct virtio_i2c_req), GFP_KERNEL); + if (i2c_req == NULL) + return NULL; + + if (merge) + ptr = kzalloc((msg_1->len + msg_2->len), GFP_KERNEL); + else + ptr = msg_1->buf; + if (ptr == NULL) + goto err_mem; + + /* prepare the head */ + i2c_req->head.type = merge ? + I2C_VIRTIO_RDWR : ((msg_1->flags & I2C_M_RD) ? + I2C_VIRTIO_RD : I2C_VIRTIO_WR); + i2c_req->head.addr = msg_1->addr; + i2c_req->head.length = msg_1->len; + if (merge) + i2c_req->head.total_length = msg_1->len + msg_2->len; + + /* prepare the buf */ + if (merge) + memcpy(ptr, msg_1->buf, msg_1->len); + i2c_req->buf = ptr; + + return i2c_req; +err_mem: + kfree(i2c_req); + i2c_req = NULL; + return NULL; +} + +static void virti2c_transfer_end(struct virtio_i2c_req *req, + struct i2c_msg *msg) +{ + if (req->head.type == I2C_VIRTIO_RDWR) { + memcpy(msg->buf, req->buf + req->head.length, msg->len); + kfree(req->buf); + req->buf = NULL; + } + + kfree(req); + req = NULL; +} + +static int virtio_i2c_master_xfer(struct i2c_adapter *adap, + struct i2c_msg *msgs, int num) +{ + int i, ret; + struct virtio_i2c_req *i2c_req; + struct virtio_i2c *vi2c = i2c_get_adapdata(adap); + + if (num < 1) { + dev_err(&vi2c->vdev->dev, + "error on number of msgs(%d) received\n", num); + return -EINVAL; + } + + if (IS_ERR_OR_NULL(msgs)) { + dev_err(&vi2c->vdev->dev, " error no msgs Accessing invalid pointer location\n"); + return PTR_ERR(msgs); + } + + for (i = 0; i < num; i++) { + + if (msgs[i].flags & I2C_M_RD) { + /* read the data from slave to master*/ + i2c_req = virti2c_transfer_prepare(&msgs[i], NULL); + + } else if ((i + 1 < num) && (msgs[i + 1].flags & I2C_M_RD) && + (msgs[i].addr == msgs[i + 1].addr)) { + /* write then read from same address*/ + i2c_req = virti2c_transfer_prepare(&msgs[i], + &msgs[i+1]); + i += 1; + + } else { + /* write the data to slave */ + i2c_req = virti2c_transfer_prepare(&msgs[i], NULL); + } + + if (i2c_req == NULL) { + ret = -ENOMEM; + goto err; + } + ret = virti2c_transfer(vi2c, i2c_req); + virti2c_transfer_end(i2c_req, &msgs[i]); + if (ret) + goto err; + } + return num; +err: + return ret; +} + +static u32 virtio_i2c_functionality(struct i2c_adapter *adapter) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +} + +static struct i2c_algorithm virtio_i2c_algorithm = { + .master_xfer = virtio_i2c_master_xfer, + .functionality = virtio_i2c_functionality, +}; + +/* virtqueue incoming data interrupt IRQ */ +static void virti2c_vq_isr(struct virtqueue *vq) +{ + struct virtio_i2c *vi2c = vq->vdev->priv; + + wake_up(&vi2c->inq); +} + +static int virti2c_init_vqs(struct virtio_i2c *vi2c) +{ + struct virtqueue *vqs[1]; + vq_callback_t *cbs[] = { virti2c_vq_isr }; + static const char * const names[] = { "virti2c_vq_isr" }; + int err; + + err = virtio_find_vqs(vi2c->vdev, 1, vqs, cbs, names, NULL); + if (err) + return err; + vi2c->vq = vqs[0]; + + return 0; +} + +static void virti2c_del_vqs(struct virtio_i2c *vi2c) +{ + vi2c->vdev->config->del_vqs(vi2c->vdev); +} + +static int virti2c_init_hw(struct virtio_device *vdev, + struct virtio_i2c *vi2c) +{ + int err; + + i2c_set_adapdata(&vi2c->adapter, vi2c); + vi2c->adapter.algo = &virtio_i2c_algorithm; + + vi2c->adapter.owner = THIS_MODULE; + vi2c->adapter.dev.parent = &vdev->dev; + vi2c->adapter.dev.of_node = vdev->dev.parent->of_node; + + /* read virtio i2c config info */ + vi2c->adapter.nr = virtio_cread32(vdev, I2C_ADAPTER_NR); + snprintf(vi2c->adapter.name, sizeof(vi2c->adapter.name), + "virtio_i2c_%d", vi2c->adapter.nr); + + err = i2c_add_numbered_adapter(&vi2c->adapter); + if (err) + return err; + return 0; +} + +static int virti2c_probe(struct virtio_device *vdev) +{ + struct virtio_i2c *vi2c; + int err = 0; + + if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) + return -ENODEV; + + vi2c = kzalloc(sizeof(*vi2c), GFP_KERNEL); + if (!vi2c) + return -ENOMEM; + + vi2c->vdev = vdev; + vdev->priv = vi2c; + init_waitqueue_head(&vi2c->inq); + + err = virti2c_init_vqs(vi2c); + if (err) + goto err_init_vq; + + err = virti2c_init_hw(vdev, vi2c); + if (err) + goto err_init_hw; + + virtio_device_ready(vdev); + + virtqueue_enable_cb(vi2c->vq); + return 0; + +err_init_hw: + virti2c_del_vqs(vi2c); +err_init_vq: + kfree(vi2c); + return err; +} +static void virti2c_remove(struct virtio_device *vdev) +{ + struct virtio_i2c *vi2c = vdev->priv; + + i2c_del_adapter(&vi2c->adapter); + vdev->config->reset(vdev); + virti2c_del_vqs(vi2c); + kfree(vi2c); +} + +static unsigned int features[] = { + /* none */ +}; +static struct virtio_device_id id_table[] = { + { VIRTIO_ID_I2C, VIRTIO_DEV_ANY_ID }, + { 0 }, +}; + +static struct virtio_driver virtio_i2c_driver = { + .driver.name = KBUILD_MODNAME, + .driver.owner = THIS_MODULE, + .feature_table = features, + .feature_table_size = ARRAY_SIZE(features), + .id_table = id_table, + .probe = virti2c_probe, + .remove = virti2c_remove, +}; + +module_virtio_driver(virtio_i2c_driver); +MODULE_DEVICE_TABLE(virtio, id_table); + +MODULE_DESCRIPTION("Virtio i2c frontend driver"); +MODULE_LICENSE("GPL v2"); diff --git a/include/uapi/linux/virtio_ids.h b/include/uapi/linux/virtio_ids.h index 6d5c3b2d4f4d..1be979110115 100644 --- a/include/uapi/linux/virtio_ids.h +++ b/include/uapi/linux/virtio_ids.h @@ -44,4 +44,6 @@ #define VIRTIO_ID_VSOCK 19 /* virtio vsock transport */ #define VIRTIO_ID_CRYPTO 20 /* virtio crypto */ +#define VIRTIO_ID_I2C 32 /* virtio i2c */ + #endif /* _LINUX_VIRTIO_IDS_H */ -- GitLab From 3b48381f59753f7f97183825293858b95cf50e9c Mon Sep 17 00:00:00 2001 From: Anirudh Ghayal Date: Tue, 28 May 2019 13:28:33 +0530 Subject: [PATCH 0500/1121] power: qpnp-qg: Add range checks to FIFO length In some erroneous cases there could be back-to-back calls to process the accumulator data which may lead to a array overflow. Fix this by adding range check while populating the FIFO data. Change-Id: I3f2495649153ae16040579b71dff5b78315b29a9 Signed-off-by: Anirudh Ghayal --- drivers/power/supply/qcom/qpnp-qg.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/power/supply/qcom/qpnp-qg.c b/drivers/power/supply/qcom/qpnp-qg.c index 78ed630a8ed6..98d43b33cf95 100644 --- a/drivers/power/supply/qcom/qpnp-qg.c +++ b/drivers/power/supply/qcom/qpnp-qg.c @@ -309,9 +309,10 @@ static int qg_process_fifo(struct qpnp_qg *chip, u32 fifo_length) /* * If there is pending data from suspend, append the new FIFO - * data to it. + * data to it. Only do this if we can accomadate 8 FIFOs */ - if (chip->suspend_data) { + if (chip->suspend_data && + (chip->kdata.fifo_length < (MAX_FIFO_LENGTH / 2))) { j = chip->kdata.fifo_length; /* append the data */ chip->suspend_data = false; qg_dbg(chip, QG_DEBUG_FIFO, @@ -380,7 +381,7 @@ static int qg_process_accumulator(struct qpnp_qg *chip) return rc; } - if (!count) { + if (!count || count < 10) { /* Ignore small accumulator data */ pr_debug("No ACCUMULATOR data!\n"); return 0; } @@ -412,6 +413,8 @@ static int qg_process_accumulator(struct qpnp_qg *chip) chip->kdata.fifo[index].interval = sample_interval; chip->kdata.fifo[index].count = count; chip->kdata.fifo_length++; + if (chip->kdata.fifo_length == MAX_FIFO_LENGTH) + chip->kdata.fifo_length = MAX_FIFO_LENGTH - 1; if (chip->kdata.fifo_length == 1) /* Only accumulator data */ chip->kdata.seq_no = chip->seq_no++ % U32_MAX; -- GitLab From 22b8ccbee926a96e0e679c1622c84cb386f59e5e Mon Sep 17 00:00:00 2001 From: vagdhan kumar kanukurthi Date: Mon, 15 Apr 2019 12:52:40 +0530 Subject: [PATCH 0501/1121] arm: dts: msm: Add QSEECom nodes for SA6155P virtual machine Add device-tree support for QSEECom driver and heaps, to SA6155P virtual machine. Change-Id: I4e2dbee5f94be4b8181b4f6fc535cacf7b5fdbbf Signed-off-by: Vagdhan Kanukurthi --- arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi | 41 ++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi b/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi index 84411ca184f5..c277d101ece8 100644 --- a/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi @@ -51,6 +51,22 @@ reg = <0x0 0xa0000000 0x0 0x20000000>; label = "pmem_shared_mem"; }; + + qseecom_mem: qseecom_region@0x9e400000 { + compatible = "shared-dma-pool"; + alloc-ranges = <0 0x00000000 0 0xffffffff>; + reusable; + alignment = <0 0x400000>; + size = <0 0x1400000>; + }; + + qseecom_ta_mem: qseecom_ta_region { + compatible = "shared-dma-pool"; + alloc-ranges = <0 0x00000000 0 0xffffffff>; + reusable; + alignment = <0 0x400000>; + size = <0 0x1000000>; + }; }; firmware: firmware { @@ -109,6 +125,18 @@ reg = <25>; qcom,ion-heap-type = "SYSTEM"; }; + + qcom,ion-heap@27 { /* QSEECOM HEAP */ + reg = <27>; + memory-region = <&qseecom_mem>; + qcom,ion-heap-type = "DMA"; + }; + + qcom,ion-heap@19 { /* QSEECOM TA HEAP */ + reg = <19>; + memory-region = <&qseecom_ta_mem>; + qcom,ion-heap-type = "DMA"; + }; }; qcom,hab { @@ -306,6 +334,19 @@ regulator-max-microvolt = <3230000>; status = "ok"; }; + + qcom_seecom: qseecom@86d00000 { + compatible = "qcom,qseecom"; + reg = <0x86d00000 0xe00000>; + reg-names = "secapp-region"; + memory-region = <&qseecom_mem>; + qcom,hlos-num-ce-hw-instances = <1>; + qcom,hlos-ce-hw-instance = <0>; + qcom,qsee-ce-hw-instance = <0>; + qcom,disk-encrypt-pipe-pair = <2>; + qcom,no-clock-support; + qcom,qsee-reentrancy-support = <2>; + }; }; #include "sa6155p-vm-pinctrl.dtsi" -- GitLab From 78cdf84b462298f0773b6a042b7bba65ba111b16 Mon Sep 17 00:00:00 2001 From: Tharun Kumar Merugu Date: Thu, 6 Jun 2019 15:01:42 +0530 Subject: [PATCH 0502/1121] msm: adsprpc: Fix integer overflow in refcount of map Integer overflow in refcount of map is leading to use after free. Error out if refcount reaches INT_MAX Change-Id: I21e88361a8e70ef8c5c9593f1fc0ddd2b351a55a Acked-by: Himateja Reddy Signed-off-by: Tharun Kumar Merugu --- drivers/char/adsprpc.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 946d33380be8..a404057e647f 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -608,8 +608,13 @@ static int fastrpc_mmap_find(struct fastrpc_file *fl, int fd, if (va >= map->va && va + len <= map->va + map->len && map->fd == fd) { - if (refs) + if (refs) { + if (map->refs + 1 == INT_MAX) { + spin_unlock(&me->hlock); + return -ETOOMANYREFS; + } map->refs++; + } match = map; break; } @@ -620,8 +625,11 @@ static int fastrpc_mmap_find(struct fastrpc_file *fl, int fd, if (va >= map->va && va + len <= map->va + map->len && map->fd == fd) { - if (refs) + if (refs) { + if (map->refs + 1 == INT_MAX) + return -ETOOMANYREFS; map->refs++; + } match = map; break; } -- GitLab From 866061a12d1622c216bd9414d69c0a24698ce3fc Mon Sep 17 00:00:00 2001 From: Tengfei Fan Date: Fri, 31 May 2019 15:55:11 +0800 Subject: [PATCH 0503/1121] ARM: dts: msm: Fix kernel warning for sm8150 When we compile kernel, we will get some similar warnings as follows: Warning (reg_format): "reg" property in /fragment@4/__overlay__/ qcom,pm8150l@5/qcom,amoled/oledb@e000 has invalid length (8 bytes) (#address-cells == 2, #size-cells == 1) Warning (reg_format): "reg" property in /fragment@35/__overlay__/ qcom,camera-flash@0 has invalid length (8 bytes) (#address-cells == 2, #size-cells == 1) To fix these compile warnings, "#address-cells" and "#size-cells" attributes are added in the necessary location. Change-Id: I39245c7da4f7075adb49b07b7e52d14a5ef121d4 Signed-off-by: Tengfei Fan --- arch/arm64/boot/dts/qcom/pm8150l.dtsi | 3 +++ arch/arm64/boot/dts/qcom/sa8155-adp-alcor-display.dtsi | 3 +++ arch/arm64/boot/dts/qcom/sa8155-adp-common.dtsi | 3 +++ arch/arm64/boot/dts/qcom/sa8155-adp-star-display.dtsi | 10 ++++++++-- arch/arm64/boot/dts/qcom/sa8155.dtsi | 2 ++ arch/arm64/boot/dts/qcom/sm8150-camera-sensor-cdp.dtsi | 2 ++ arch/arm64/boot/dts/qcom/sm8150-camera-sensor-hdk.dtsi | 8 +++++++- arch/arm64/boot/dts/qcom/sm8150-camera-sensor-mtp.dtsi | 3 +++ arch/arm64/boot/dts/qcom/sm8150-camera-sensor-qrd.dtsi | 3 +++ arch/arm64/boot/dts/qcom/sm8150-hdk-overlay.dts | 3 +++ .../boot/dts/qcom/sm8150-sdx50-camera-sensor-qrd.dtsi | 10 +++++++++- arch/arm64/boot/dts/qcom/sm8150-sdx50m-qrd.dtsi | 9 +++++++++ arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi | 2 ++ arch/arm64/boot/dts/qcom/trinket.dtsi | 2 ++ 14 files changed, 59 insertions(+), 4 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/pm8150l.dtsi b/arch/arm64/boot/dts/qcom/pm8150l.dtsi index 8a9fccafda97..96e20a8df850 100644 --- a/arch/arm64/boot/dts/qcom/pm8150l.dtsi +++ b/arch/arm64/boot/dts/qcom/pm8150l.dtsi @@ -400,6 +400,9 @@ }; pm8150a_amoled: qcom,amoled { + #address-cells = <1>; + #size-cells = <1>; + compatible = "qcom,qpnp-amoled-regulator"; status = "disabled"; diff --git a/arch/arm64/boot/dts/qcom/sa8155-adp-alcor-display.dtsi b/arch/arm64/boot/dts/qcom/sa8155-adp-alcor-display.dtsi index ab266f1e4108..7de3fa3b22ba 100644 --- a/arch/arm64/boot/dts/qcom/sa8155-adp-alcor-display.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8155-adp-alcor-display.dtsi @@ -61,6 +61,9 @@ }; &soc { + #address-cells = <1>; + #size-cells = <1>; + refgen: refgen-regulator@88e7000 { compatible = "qcom,refgen-regulator"; reg = <0x88e7000 0x60>; diff --git a/arch/arm64/boot/dts/qcom/sa8155-adp-common.dtsi b/arch/arm64/boot/dts/qcom/sa8155-adp-common.dtsi index fd8b6c6fec71..4e1b51afa74f 100644 --- a/arch/arm64/boot/dts/qcom/sa8155-adp-common.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8155-adp-common.dtsi @@ -51,6 +51,9 @@ }; &qupv3_se10_i2c { + #address-cells = <1>; + #size-cells = <0>; + status = "ok"; asm330@6a { compatible = "st,asm330lhh"; diff --git a/arch/arm64/boot/dts/qcom/sa8155-adp-star-display.dtsi b/arch/arm64/boot/dts/qcom/sa8155-adp-star-display.dtsi index 0db9ec2f68a1..e43df8e82220 100644 --- a/arch/arm64/boot/dts/qcom/sa8155-adp-star-display.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8155-adp-star-display.dtsi @@ -62,6 +62,9 @@ }; &qupv3_se15_i2c { + #address-cells = <1>; + #size-cells = <0>; + status = "ok"; pinctrl-0 = <&qupv3_se15_i2c_active @@ -119,9 +122,9 @@ #size-cells = <0>; i2c@0 { + reg = <0>; #address-cells = <1>; #size-cells = <0>; - reg = <0>; anx_7625_1: anx7625@2c { compatible = "analogix,anx7625"; @@ -135,9 +138,9 @@ }; i2c@1 { + reg = <1>; #address-cells = <1>; #size-cells = <0>; - reg = <1>; anx_7625_2: anx7625@2c { compatible = "analogix,anx7625"; @@ -192,6 +195,9 @@ }; &soc { + #address-cells = <1>; + #size-cells = <1>; + dsi_anx_7625_1: qcom,dsi-display@17 { label = "dsi_anx_7625_1"; qcom,dsi-display-active; diff --git a/arch/arm64/boot/dts/qcom/sa8155.dtsi b/arch/arm64/boot/dts/qcom/sa8155.dtsi index 0737dd717dd3..41041505fa88 100644 --- a/arch/arm64/boot/dts/qcom/sa8155.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8155.dtsi @@ -803,6 +803,8 @@ mhi,bhie-offset = <0x0324>; mhi_channels { + #address-cells = <1>; + #size-cells = <0>; mhi_chan@0 { reg = <0>; label = "LOOPBACK"; diff --git a/arch/arm64/boot/dts/qcom/sm8150-camera-sensor-cdp.dtsi b/arch/arm64/boot/dts/qcom/sm8150-camera-sensor-cdp.dtsi index 263b7bb5832f..645640f5d62d 100644 --- a/arch/arm64/boot/dts/qcom/sm8150-camera-sensor-cdp.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150-camera-sensor-cdp.dtsi @@ -124,6 +124,8 @@ }; &cam_cci0 { + #address-cells = <1>; + #size-cells = <0>; qcom,cam-res-mgr { compatible = "qcom,cam-res-mgr"; status = "ok"; diff --git a/arch/arm64/boot/dts/qcom/sm8150-camera-sensor-hdk.dtsi b/arch/arm64/boot/dts/qcom/sm8150-camera-sensor-hdk.dtsi index ec26a7703c57..04258207c3d9 100644 --- a/arch/arm64/boot/dts/qcom/sm8150-camera-sensor-hdk.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150-camera-sensor-hdk.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -12,6 +12,9 @@ */ &soc { + #address-cells = <1>; + #size-cells = <1>; + qcom,camera-flash@0 { cell-index = <0>; reg = <0x00 0x00>; @@ -55,6 +58,9 @@ }; &cam_cci0 { + #address-cells = <1>; + #size-cells = <0>; + qcom,cam-res-mgr { compatible = "qcom,cam-res-mgr"; status = "ok"; diff --git a/arch/arm64/boot/dts/qcom/sm8150-camera-sensor-mtp.dtsi b/arch/arm64/boot/dts/qcom/sm8150-camera-sensor-mtp.dtsi index c882e5d94843..2bd902951c54 100644 --- a/arch/arm64/boot/dts/qcom/sm8150-camera-sensor-mtp.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150-camera-sensor-mtp.dtsi @@ -124,6 +124,9 @@ }; &cam_cci0 { + #address-cells = <1>; + #size-cells = <0>; + qcom,cam-res-mgr { compatible = "qcom,cam-res-mgr"; status = "ok"; diff --git a/arch/arm64/boot/dts/qcom/sm8150-camera-sensor-qrd.dtsi b/arch/arm64/boot/dts/qcom/sm8150-camera-sensor-qrd.dtsi index 40563713b3e4..51751d45d947 100644 --- a/arch/arm64/boot/dts/qcom/sm8150-camera-sensor-qrd.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150-camera-sensor-qrd.dtsi @@ -49,6 +49,9 @@ }; &cam_cci0 { + #address-cells = <1>; + #size-cells = <0>; + qcom,cam-res-mgr { compatible = "qcom,cam-res-mgr"; status = "ok"; diff --git a/arch/arm64/boot/dts/qcom/sm8150-hdk-overlay.dts b/arch/arm64/boot/dts/qcom/sm8150-hdk-overlay.dts index 283081ad6651..23aefd9e6bab 100644 --- a/arch/arm64/boot/dts/qcom/sm8150-hdk-overlay.dts +++ b/arch/arm64/boot/dts/qcom/sm8150-hdk-overlay.dts @@ -55,6 +55,9 @@ }; &qupv3_se9_i2c { + #address-cells = <1>; + #size-cells = <0>; + status = "ok"; lt9611: lt,lt9611@3b { compatible = "lt,lt9611"; diff --git a/arch/arm64/boot/dts/qcom/sm8150-sdx50-camera-sensor-qrd.dtsi b/arch/arm64/boot/dts/qcom/sm8150-sdx50-camera-sensor-qrd.dtsi index f7b99c6ec739..174d572515b9 100644 --- a/arch/arm64/boot/dts/qcom/sm8150-sdx50-camera-sensor-qrd.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150-sdx50-camera-sensor-qrd.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -14,6 +14,9 @@ #include &soc { + #address-cells = <1>; + #size-cells = <1>; + led_flash_rear: qcom,camera-flash@0 { cell-index = <0>; reg = <0x00 0x00>; @@ -46,6 +49,9 @@ }; &cam_cci0 { + #address-cells = <1>; + #size-cells = <0>; + qcom,cam-res-mgr { compatible = "qcom,cam-res-mgr"; status = "ok"; @@ -312,6 +318,8 @@ }; &cam_cci1 { + #address-cells = <1>; + #size-cells = <0>; overlay_actuator_front: qcom,actuator@2 { cell-index = <2>; reg = <0x2>; diff --git a/arch/arm64/boot/dts/qcom/sm8150-sdx50m-qrd.dtsi b/arch/arm64/boot/dts/qcom/sm8150-sdx50m-qrd.dtsi index c68d6a07791f..e9a05cb2e764 100644 --- a/arch/arm64/boot/dts/qcom/sm8150-sdx50m-qrd.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150-sdx50m-qrd.dtsi @@ -89,6 +89,9 @@ }; &qupv3_se17_i2c { + #address-cells = <1>; + #size-cells = <0>; + status = "ok"; st_fts@49 { @@ -109,6 +112,9 @@ }; &qupv3_se9_i2c { + #address-cells = <1>; + #size-cells = <0>; + status = "ok"; nq@28 { compatible = "qcom,nq-nci"; @@ -192,6 +198,9 @@ }; &qupv3_se4_i2c { + #address-cells = <1>; + #size-cells = <0>; + status = "ok"; redriver@19 { compatible = "onnn,redriver"; diff --git a/arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi b/arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi index 78505248b54c..28a8b9da4cef 100644 --- a/arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi @@ -32,6 +32,8 @@ qcom,addr-win = <0x0 0x20000000 0x0 0x2fffffff>; mhi_channels { + #address-cells = <1>; + #size-cells = <0>; mhi_chan@25 { status = "disabled"; }; diff --git a/arch/arm64/boot/dts/qcom/trinket.dtsi b/arch/arm64/boot/dts/qcom/trinket.dtsi index ec6b86a8bd5d..f99e6907a58e 100644 --- a/arch/arm64/boot/dts/qcom/trinket.dtsi +++ b/arch/arm64/boot/dts/qcom/trinket.dtsi @@ -2807,6 +2807,8 @@ compatible = "qcom,adc-tm5-iio"; reg = <0x3400 0x100>; #thermal-sensor-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; io-channels = <&pm6125_vadc ADC_GPIO1_PU2>, <&pm6125_vadc ADC_GPIO3_PU2>; -- GitLab From 0c1add55e5983f60f8b0b7fe67ab8e4012c8cc90 Mon Sep 17 00:00:00 2001 From: Ravikishore Pampana Date: Fri, 26 Apr 2019 19:13:09 +0530 Subject: [PATCH 0504/1121] msm: camera: isp: Update the context hw events dump Update the context monitor with more filed to know the last applied request id, last reported id and frame id. Update the context monitor for every irq. Dump the context monitor values during the bubble and un handled irq scenarios. Change-Id: I8789e5662e81a3891d3f921ce6ac9f1e4b017a98 Signed-off-by: Ravikishore Pampana --- .../msm/camera/cam_isp/cam_isp_context.c | 324 +++++++++++------- .../msm/camera/cam_isp/cam_isp_context.h | 60 ++-- 2 files changed, 245 insertions(+), 139 deletions(-) diff --git a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c index 0078d61050b9..c0ab5e6f2e4e 100644 --- a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c +++ b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c @@ -38,18 +38,26 @@ static int cam_isp_context_dump_active_request(void *data, unsigned long iova, static void __cam_isp_ctx_update_state_monitor_array( struct cam_isp_context *ctx_isp, - enum cam_isp_state_change_trigger trigger_type, - uint32_t req_id) + enum cam_isp_hw_event_type hw_event, + enum cam_isp_ctx_activated_substate curr_state, + enum cam_isp_ctx_activated_substate next_state) { int iterator = 0; iterator = INC_STATE_MONITOR_HEAD(&ctx_isp->state_monitor_head); ctx_isp->cam_isp_ctx_state_monitor[iterator].curr_state = - ctx_isp->substate_activated; - ctx_isp->cam_isp_ctx_state_monitor[iterator].trigger = - trigger_type; - ctx_isp->cam_isp_ctx_state_monitor[iterator].req_id = - req_id; + curr_state; + ctx_isp->cam_isp_ctx_state_monitor[iterator].next_state = + next_state; + ctx_isp->cam_isp_ctx_state_monitor[iterator].hw_event = + hw_event; + ctx_isp->cam_isp_ctx_state_monitor[iterator].last_reported_id = + ctx_isp->req_info.reported_req_id; + ctx_isp->cam_isp_ctx_state_monitor[iterator].last_applied_req_id = + ctx_isp->req_info.last_applied_req_id; + ctx_isp->cam_isp_ctx_state_monitor[iterator].frame_id = + ctx_isp->frame_id; + ctx_isp->cam_isp_ctx_state_monitor[iterator].evt_time_stamp = jiffies_to_msecs(jiffies); } @@ -79,17 +87,17 @@ static const char *__cam_isp_hw_evt_val_to_type( uint32_t evt_id) { switch (evt_id) { - case CAM_ISP_STATE_CHANGE_TRIGGER_ERROR: + case CAM_ISP_HW_EVENT_ERROR: return "ERROR"; - case CAM_ISP_STATE_CHANGE_TRIGGER_SOF: + case CAM_ISP_HW_EVENT_SOF: return "SOF"; - case CAM_ISP_STATE_CHANGE_TRIGGER_REG_UPDATE: + case CAM_ISP_HW_EVENT_REG_UPDATE: return "REG_UPDATE"; - case CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH: + case CAM_ISP_HW_EVENT_EPOCH: return "EPOCH"; - case CAM_ISP_STATE_CHANGE_TRIGGER_EOF: + case CAM_ISP_HW_EVENT_EOF: return "EOF"; - case CAM_ISP_STATE_CHANGE_TRIGGER_DONE: + case CAM_ISP_HW_EVENT_DONE: return "DONE"; default: return "CAM_ISP_EVENT_INVALID"; @@ -97,29 +105,58 @@ static const char *__cam_isp_hw_evt_val_to_type( } static void __cam_isp_ctx_dump_state_monitor_array( - struct cam_isp_context *ctx_isp) + struct cam_isp_context *ctx_isp, bool log_rate_limit) { int i = 0; uint64_t state_head = 0; uint64_t index; + struct cam_isp_context_state_monitor *ctx_monitor; state_head = atomic64_read(&ctx_isp->state_monitor_head); - CAM_ERR_RATE_LIMIT(CAM_ISP, - "Dumping state information for preceding requests"); + + ctx_monitor = ctx_isp->cam_isp_ctx_state_monitor; + + if (log_rate_limit) + CAM_INFO_RATE_LIMIT_CUSTOM(CAM_ISP, 5, 20, + "Dumping state information for preceding requests"); + else + CAM_INFO(CAM_ISP, + "Dumping state information for preceding requests"); for (i = CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES - 1; i >= 0; i--) { index = (((state_head - i) + CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES) % CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES); - CAM_ERR_RATE_LIMIT(CAM_ISP, - "time[0x%llx] req_id[%u] state[%s] evt_type[%s]", - ctx_isp->cam_isp_ctx_state_monitor[index].evt_time_stamp, - ctx_isp->cam_isp_ctx_state_monitor[index].req_id, - __cam_isp_ctx_substate_val_to_type( - ctx_isp->cam_isp_ctx_state_monitor[index].curr_state), - __cam_isp_hw_evt_val_to_type( - ctx_isp->cam_isp_ctx_state_monitor[index].trigger)); + + if (log_rate_limit) { + CAM_INFO_RATE_LIMIT_CUSTOM(CAM_ISP, 5, 20, + "time[%lld] last reported req_id[%u] frame id[%lld] applied id[%lld] current state[%s] next state[%s] hw_event[%s]", + ctx_monitor[index].evt_time_stamp, + ctx_monitor[index].last_reported_id, + ctx_monitor[index].frame_id, + ctx_monitor[index].last_applied_req_id, + __cam_isp_ctx_substate_val_to_type( + ctx_monitor[index].curr_state), + __cam_isp_ctx_substate_val_to_type( + ctx_monitor[index].next_state), + __cam_isp_hw_evt_val_to_type( + ctx_monitor[index].hw_event)); + + } else { + CAM_INFO(CAM_ISP, + "time[%lld] last reported req_id[%u] frame id[%lld] applied id[%lld] current state[%s] next state[%s] hw_event[%s]", + ctx_monitor[index].evt_time_stamp, + ctx_monitor[index].last_reported_id, + ctx_monitor[index].frame_id, + ctx_monitor[index].last_applied_req_id, + __cam_isp_ctx_substate_val_to_type( + ctx_monitor[index].curr_state), + __cam_isp_ctx_substate_val_to_type( + ctx_monitor[index].next_state), + __cam_isp_hw_evt_val_to_type( + ctx_monitor[index].hw_event)); + } } } @@ -508,6 +545,10 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state( CAM_DBG(CAM_REQ, "Move active request %lld to pending list(cnt = %d) [bubble recovery], ctx %u", req->request_id, ctx_isp->active_req_cnt, ctx->ctx_id); + __cam_isp_ctx_update_state_monitor_array(ctx_isp, + CAM_ISP_HW_EVENT_DONE, + ctx_isp->substate_activated, + ctx_isp->substate_activated); } else { list_del_init(&req->list); list_add_tail(&req->list, &ctx->free_req_list); @@ -515,12 +556,16 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state( CAM_DBG(CAM_REQ, "Move active request %lld to free list(cnt = %d) [all fences done], ctx %u", req->request_id, ctx_isp->active_req_cnt, ctx->ctx_id); + ctx_isp->req_info.last_bufdone_req_id = req->request_id; + ctx_isp->req_info.last_bufdone_time_stamp = + jiffies_to_msecs(jiffies); + __cam_isp_ctx_update_state_monitor_array(ctx_isp, + CAM_ISP_HW_EVENT_DONE, + ctx_isp->substate_activated, + ctx_isp->substate_activated); } end: - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_DONE, - ctx_isp->base->req_list->request_id); return rc; } @@ -665,9 +710,12 @@ static int __cam_isp_ctx_notify_sof_in_activated_state( } list_for_each_entry(req, &ctx->active_req_list, list) { - if (req->request_id > ctx_isp->reported_req_id) { + if (req->request_id > + ctx_isp->req_info.reported_req_id) { request_id = req->request_id; - ctx_isp->reported_req_id = request_id; + ctx_isp->req_info.reported_req_id = request_id; + ctx_isp->req_info.last_reported_id_time_stamp = + jiffies_to_msecs(jiffies); break; } } @@ -675,6 +723,17 @@ static int __cam_isp_ctx_notify_sof_in_activated_state( if (ctx_isp->substate_activated == CAM_ISP_CTX_ACTIVATED_BUBBLE) request_id = 0; + if (request_id && ctx_isp->req_info.reported_req_id && + ((request_id - ctx_isp->req_info.reported_req_id) > + 1)){ + CAM_INFO(CAM_ISP, + "ctx:%d curr req id: %u last reported id:%u", + ctx->ctx_id, request_id, + ctx_isp->req_info.reported_req_id); + + __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true); + } + __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id, CAM_REQ_MGR_SOF_EVENT_SUCCESS); } else { @@ -742,8 +801,7 @@ static int __cam_isp_ctx_sof_in_activated_state( ctx_isp->frame_id++; ctx_isp->sof_timestamp_val = sof_event_data->timestamp; ctx_isp->boot_timestamp = sof_event_data->boot_time; - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_SOF, req->request_id); + CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx, ctx %u", ctx_isp->frame_id, ctx_isp->sof_timestamp_val, ctx->ctx_id); @@ -778,11 +836,7 @@ static int __cam_isp_ctx_reg_upd_in_sof(struct cam_isp_context *ctx_isp, CAM_ERR(CAM_ISP, "receive rup in unexpected state"); } - if (req != NULL) { - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_REG_UPDATE, - req->request_id); - } + end: return rc; } @@ -800,7 +854,8 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp, * If no wait req in epoch, this is an error case. * The recovery is to go back to sof state */ - CAM_ERR(CAM_ISP, "No wait request"); + CAM_ERR(CAM_ISP, "Ctx:%d No wait request", ctx->ctx_id); + __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true); ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF; /* Send SOF event as empty frame*/ @@ -815,7 +870,9 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp, req_isp = (struct cam_isp_ctx_req *)req->req_priv; req_isp->bubble_detected = true; - CAM_DBG(CAM_ISP, "Report Bubble flag %d", req_isp->bubble_report); + CAM_INFO(CAM_ISP, "ctx:%d Report Bubble flag %d req id:%lld", + ctx->ctx_id, req_isp->bubble_report, req->request_id); + __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true); if (req_isp->bubble_report && ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_err) { struct cam_req_mgr_error_notify notify; @@ -842,9 +899,11 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp, list_del_init(&req->list); list_add_tail(&req->list, &ctx->active_req_list); - if (req->request_id > ctx_isp->reported_req_id) { + if (req->request_id > ctx_isp->req_info.reported_req_id) { request_id = req->request_id; - ctx_isp->reported_req_id = request_id; + ctx_isp->req_info.reported_req_id = request_id; + ctx_isp->req_info.last_reported_id_time_stamp = + jiffies_to_msecs(jiffies); } __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id, CAM_REQ_MGR_SOF_EVENT_ERROR); @@ -853,15 +912,7 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp, CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated); end: - if (request_id == 0) { - req = list_last_entry(&ctx->active_req_list, - struct cam_ctx_request, list); - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, req->request_id); - } else { - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, request_id); - } + return 0; } @@ -884,7 +935,6 @@ static int __cam_isp_ctx_sof_in_epoch(struct cam_isp_context *ctx_isp, int rc = 0; struct cam_context *ctx = ctx_isp->base; struct cam_isp_hw_sof_event_data *sof_event_data = evt_data; - struct cam_ctx_request *req; if (!evt_data) { CAM_ERR(CAM_ISP, "in valid sof event data"); @@ -900,12 +950,6 @@ static int __cam_isp_ctx_sof_in_epoch(struct cam_isp_context *ctx_isp, else CAM_DBG(CAM_ISP, "Still need to wait for the buf done"); - req = list_last_entry(&ctx->active_req_list, - struct cam_ctx_request, list); - if (req) - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_SOF, - ctx->req_list->request_id); CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated); @@ -952,7 +996,8 @@ static int __cam_isp_ctx_epoch_in_bubble_applied( * If no pending req in epoch, this is an error case. * Just go back to the bubble state. */ - CAM_ERR(CAM_ISP, "No pending request."); + CAM_ERR(CAM_ISP, "ctx:%d No pending request.", ctx->ctx_id); + __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true); __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id, CAM_REQ_MGR_SOF_EVENT_SUCCESS); @@ -964,6 +1009,9 @@ static int __cam_isp_ctx_epoch_in_bubble_applied( list); req_isp = (struct cam_isp_ctx_req *)req->req_priv; req_isp->bubble_detected = true; + CAM_INFO(CAM_ISP, "Ctx:%d Report Bubble flag %d req id:%lld", + ctx->ctx_id, req_isp->bubble_report, req->request_id); + __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true); if (req_isp->bubble_report && ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_err) { @@ -992,9 +1040,11 @@ static int __cam_isp_ctx_epoch_in_bubble_applied( list_add_tail(&req->list, &ctx->active_req_list); if (!req_isp->bubble_report) { - if (req->request_id > ctx_isp->reported_req_id) { + if (req->request_id > ctx_isp->req_info.reported_req_id) { request_id = req->request_id; - ctx_isp->reported_req_id = request_id; + ctx_isp->req_info.reported_req_id = request_id; + ctx_isp->req_info.last_reported_id_time_stamp = + jiffies_to_msecs(jiffies); __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id, CAM_REQ_MGR_SOF_EVENT_ERROR); } else @@ -1007,11 +1057,7 @@ static int __cam_isp_ctx_epoch_in_bubble_applied( ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE; CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated); end: - req = list_last_entry(&ctx->active_req_list, struct cam_ctx_request, - list); - if (req) - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, req->request_id); + return 0; } @@ -1023,9 +1069,7 @@ static int __cam_isp_ctx_buf_done_in_bubble_applied( (struct cam_isp_hw_done_event_data *) evt_data; rc = __cam_isp_ctx_handle_buf_done_in_activated_state(ctx_isp, done, 1); - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_DONE, - ctx_isp->base->req_list->request_id); + return rc; } @@ -1083,9 +1127,6 @@ static int __cam_isp_ctx_handle_error(struct cam_isp_context *ctx_isp, if (error_event_data->enable_reg_dump) cam_isp_ctx_dump_req(req_isp); - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_ERROR, req_to_dump->request_id); - list_for_each_entry_safe(req, req_temp, &ctx->active_req_list, list) { req_isp = (struct cam_isp_ctx_req *) req->req_priv; @@ -1176,14 +1217,15 @@ static int __cam_isp_ctx_handle_error(struct cam_isp_context *ctx_isp, end: do { if (list_empty(&ctx->pending_req_list)) { - error_request_id = ctx_isp->last_applied_req_id + 1; + error_request_id = + ctx_isp->req_info.last_applied_req_id + 1; req_isp = NULL; break; } req = list_first_entry(&ctx->pending_req_list, struct cam_ctx_request, list); req_isp = (struct cam_isp_ctx_req *) req->req_priv; - error_request_id = ctx_isp->last_applied_req_id; + error_request_id = ctx_isp->req_info.last_applied_req_id; if (req_isp->bubble_report) { req_to_report = req; @@ -1201,7 +1243,8 @@ static int __cam_isp_ctx_handle_error(struct cam_isp_context *ctx_isp, list_del_init(&req->list); list_add_tail(&req->list, &ctx->free_req_list); - } while (req->request_id < ctx_isp->last_applied_req_id); + } while (req->request_id < + ctx_isp->req_info.last_applied_req_id); if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_err) { notify.link_hdl = ctx->link_hdl; @@ -1240,8 +1283,8 @@ static int __cam_isp_ctx_handle_error(struct cam_isp_context *ctx_isp, V4L_EVENT_CAM_REQ_MGR_EVENT)) CAM_ERR(CAM_ISP, "Error in notifying the error time for req id:%lld ctx %u", - ctx_isp->last_applied_req_id, - ctx->ctx_id); + ctx_isp->req_info.last_applied_req_id, + ctx->ctx_id); } ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_HW_ERROR; } else { @@ -1278,8 +1321,7 @@ static int __cam_isp_ctx_fs2_sof_in_sof_state( ctx_isp->frame_id++; ctx_isp->sof_timestamp_val = sof_event_data->timestamp; ctx_isp->boot_timestamp = sof_event_data->boot_time; - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_SOF, req->request_id); + CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx", ctx_isp->frame_id, ctx_isp->sof_timestamp_val); @@ -1300,9 +1342,12 @@ static int __cam_isp_ctx_fs2_sof_in_sof_state( } list_for_each_entry(req, &ctx->active_req_list, list) { - if (req->request_id > ctx_isp->reported_req_id) { + if (req->request_id > + ctx_isp->req_info.reported_req_id) { request_id = req->request_id; - ctx_isp->reported_req_id = request_id; + ctx_isp->req_info.reported_req_id = request_id; + ctx_isp->req_info.last_reported_id_time_stamp = + jiffies_to_msecs(jiffies); break; } } @@ -1343,8 +1388,10 @@ static int __cam_isp_ctx_fs2_buf_done(struct cam_isp_context *ctx_isp, CAM_DBG(CAM_ISP, "No request, move to SOF"); ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF; - if (ctx_isp->reported_req_id < curr_req_id) { - ctx_isp->reported_req_id = curr_req_id; + if (ctx_isp->req_info.reported_req_id < curr_req_id) { + ctx_isp->req_info.reported_req_id = curr_req_id; + ctx_isp->req_info.last_reported_id_time_stamp = + jiffies_to_msecs(jiffies); __cam_isp_ctx_send_sof_timestamp(ctx_isp, curr_req_id, CAM_REQ_MGR_SOF_EVENT_SUCCESS); @@ -1402,11 +1449,7 @@ static int __cam_isp_ctx_fs2_reg_upd_in_sof(struct cam_isp_context *ctx_isp, CAM_ERR(CAM_ISP, "receive rup in unexpected state"); } - if (req != NULL) { - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_REG_UPDATE, - req->request_id); - } + end: return rc; } @@ -1451,9 +1494,12 @@ static int __cam_isp_ctx_fs2_reg_upd_in_applied_state( if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger && ctx_isp->active_req_cnt <= 2) { list_for_each_entry(req, &ctx->active_req_list, list) { - if (req->request_id > ctx_isp->reported_req_id) { + if (req->request_id > + ctx_isp->req_info.reported_req_id) { request_id = req->request_id; - ctx_isp->reported_req_id = request_id; + ctx_isp->req_info.reported_req_id = request_id; + ctx_isp->req_info.last_reported_id_time_stamp = + jiffies_to_msecs(jiffies); break; } } @@ -1478,11 +1524,7 @@ static int __cam_isp_ctx_fs2_reg_upd_in_applied_state( CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated); end: - if (req != NULL && !rc) { - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, - req->request_id); - } + return rc; } @@ -1729,19 +1771,19 @@ static int __cam_isp_ctx_apply_req_in_activated_state( } else { spin_lock_bh(&ctx->lock); ctx_isp->substate_activated = next_state; - ctx_isp->last_applied_req_id = apply->request_id; + ctx_isp->req_info.last_applied_req_id = + apply->request_id; + ctx_isp->req_info.last_applied_time_stamp = + jiffies_to_msecs(jiffies); list_del_init(&req->list); list_add_tail(&req->list, &ctx->wait_req_list); CAM_DBG(CAM_ISP, "new substate state %d, applied req %lld", - next_state, ctx_isp->last_applied_req_id); + next_state, + ctx_isp->req_info.last_applied_req_id); spin_unlock_bh(&ctx->lock); } end: - if (ctx_isp != NULL) { - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_SOF, - ctx->req_list->request_id); - } + return rc; } @@ -1875,6 +1917,23 @@ static int __cam_isp_ctx_flush_req_in_top_state( CAM_DBG(CAM_ISP, "try to flush pending list"); spin_lock_bh(&ctx->lock); rc = __cam_isp_ctx_flush_req(ctx, &ctx->pending_req_list, flush_req); + + if (!list_empty(&ctx->active_req_list)) { + CAM_INFO_RATE_LIMIT_CUSTOM(CAM_ISP, 5, 20, + "ctx:%d last applied id:%lld, reported req id:%lld, buf done id:%lld", + ctx->ctx_id, + ctx_isp->req_info.last_applied_req_id, + ctx_isp->req_info.reported_req_id, + ctx_isp->req_info.last_bufdone_req_id); + CAM_INFO_RATE_LIMIT_CUSTOM(CAM_ISP, 5, 20, + "current time:%lld last apply time:%lld, reported req time:%lld, buf done time:%lld", + jiffies_to_msecs(jiffies), + ctx_isp->req_info.last_applied_time_stamp, + ctx_isp->req_info.last_reported_id_time_stamp, + ctx_isp->req_info.last_bufdone_time_stamp); + + __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true); + } spin_unlock_bh(&ctx->lock); atomic_set(&ctx_isp->process_bubble, 0); @@ -2133,8 +2192,10 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_applied( list); req_isp = (struct cam_isp_ctx_req *)req->req_priv; req_isp->bubble_detected = true; + CAM_INFO(CAM_ISP, "Ctx:%d Report Bubble flag %d req id:%lld", + ctx->ctx_id, req_isp->bubble_report, req->request_id); + __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true); - CAM_DBG(CAM_ISP, "Report Bubble flag %d", req_isp->bubble_report); if (req_isp->bubble_report && ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_err) { struct cam_req_mgr_error_notify notify; @@ -2161,9 +2222,11 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_applied( req->request_id, ctx_isp->active_req_cnt); if (!req_isp->bubble_report) { - if (req->request_id > ctx_isp->reported_req_id) { + if (req->request_id > ctx_isp->req_info.reported_req_id) { request_id = req->request_id; - ctx_isp->reported_req_id = request_id; + ctx_isp->req_info.reported_req_id = request_id; + ctx_isp->req_info.last_reported_id_time_stamp = + jiffies_to_msecs(jiffies); __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id, CAM_REQ_MGR_SOF_EVENT_ERROR); } else @@ -2305,8 +2368,11 @@ static int __cam_isp_ctx_rdi_only_reg_upd_in_bubble_applied_state( } else { CAM_ERR(CAM_ISP, "Can not notify SOF to CRM"); } - if (request_id) - ctx_isp->reported_req_id = request_id; + if (request_id) { + ctx_isp->req_info.reported_req_id = request_id; + ctx_isp->req_info.last_reported_id_time_stamp = + jiffies_to_msecs(jiffies); + } __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id, CAM_REQ_MGR_SOF_EVENT_SUCCESS); @@ -2481,9 +2547,14 @@ static int __cam_isp_ctx_release_hw_in_top_state(struct cam_context *ctx, ctx->last_flush_req = 0; ctx_isp->frame_id = 0; ctx_isp->active_req_cnt = 0; - ctx_isp->reported_req_id = 0; ctx_isp->hw_acquired = false; ctx_isp->init_received = false; + ctx_isp->req_info.reported_req_id = 0; + ctx_isp->req_info.last_applied_req_id = 0; + ctx_isp->req_info.last_bufdone_req_id = 0; + ctx_isp->req_info.last_applied_time_stamp = 0; + ctx_isp->req_info.last_bufdone_time_stamp = 0; + ctx_isp->req_info.last_reported_id_time_stamp = 0; /* * Ideally, we should never have any active request here. @@ -2538,11 +2609,16 @@ static int __cam_isp_ctx_release_dev_in_top_state(struct cam_context *ctx, ctx->last_flush_req = 0; ctx_isp->frame_id = 0; ctx_isp->active_req_cnt = 0; - ctx_isp->reported_req_id = 0; ctx_isp->hw_acquired = false; ctx_isp->init_received = false; ctx_isp->rdi_only_context = false; ctx_isp->split_acquire = false; + ctx_isp->req_info.reported_req_id = 0; + ctx_isp->req_info.last_applied_req_id = 0; + ctx_isp->req_info.last_bufdone_req_id = 0; + ctx_isp->req_info.last_applied_time_stamp = 0; + ctx_isp->req_info.last_bufdone_time_stamp = 0; + ctx_isp->req_info.last_reported_id_time_stamp = 0; /* * Ideally, we should never have any active request here. @@ -3169,7 +3245,7 @@ static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx, atomic_set(&ctx_isp->process_bubble, 0); ctx_isp->frame_id = 0; ctx_isp->active_req_cnt = 0; - ctx_isp->reported_req_id = 0; + ctx_isp->req_info.reported_req_id = 0; ctx_isp->substate_activated = ctx_isp->rdi_only_context ? CAM_ISP_CTX_ACTIVATED_APPLIED : (req_isp->num_fence_map_out) ? CAM_ISP_CTX_ACTIVATED_EPOCH : @@ -3301,7 +3377,13 @@ static int __cam_isp_ctx_stop_dev_in_activated_unlock( } ctx_isp->frame_id = 0; ctx_isp->active_req_cnt = 0; - ctx_isp->reported_req_id = 0; + ctx_isp->req_info.reported_req_id = 0; + ctx_isp->req_info.last_applied_req_id = 0; + ctx_isp->req_info.last_bufdone_req_id = 0; + ctx_isp->req_info.last_applied_time_stamp = 0; + ctx_isp->req_info.last_bufdone_time_stamp = 0; + ctx_isp->req_info.last_reported_id_time_stamp = 0; + atomic_set(&ctx_isp->process_bubble, 0); CAM_DBG(CAM_ISP, "Stop device success next state %d on ctx %u", @@ -3478,8 +3560,9 @@ static int __cam_isp_ctx_apply_req(struct cam_context *ctx, rc = ctx_ops->crm_ops.apply_req(ctx, apply); } else { CAM_ERR_RATE_LIMIT(CAM_ISP, - "No handle function in activated substate %d", - ctx_isp->substate_activated); + "Ctx:%d No handle function in activated substate %d", + ctx->ctx_id, ctx_isp->substate_activated); + __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true); rc = -EFAULT; } @@ -3500,22 +3583,27 @@ static int __cam_isp_ctx_handle_irq_in_activated(void *context, struct cam_context *ctx = (struct cam_context *)context; struct cam_isp_context *ctx_isp = (struct cam_isp_context *)ctx->ctx_priv; + enum cam_isp_ctx_activated_substate curr_state; spin_lock(&ctx->lock); trace_cam_isp_activated_irq(ctx, ctx_isp->substate_activated, evt_id, __cam_isp_ctx_get_event_ts(evt_id, evt_data)); + curr_state = ctx_isp->substate_activated; CAM_DBG(CAM_ISP, "Enter: State %d, Substate %d, evt id %d", ctx->state, ctx_isp->substate_activated, evt_id); irq_ops = &ctx_isp->substate_machine_irq[ctx_isp->substate_activated]; if (irq_ops->irq_ops[evt_id]) { rc = irq_ops->irq_ops[evt_id](ctx_isp, evt_data); } else { - CAM_DBG(CAM_ISP, "No handle function for substate %d", - ctx_isp->substate_activated); - __cam_isp_ctx_dump_state_monitor_array(ctx_isp); + CAM_INFO(CAM_ISP, "Ctx:%d No handle function for substate %d", + ctx->ctx_id, ctx_isp->substate_activated); + __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true); } + if (evt_id != CAM_ISP_HW_EVENT_DONE) + __cam_isp_ctx_update_state_monitor_array(ctx_isp, evt_id, + curr_state, ctx_isp->substate_activated); CAM_DBG(CAM_ISP, "Exit: State %d Substate %d", ctx->state, ctx_isp->substate_activated); @@ -3677,7 +3765,13 @@ int cam_isp_context_init(struct cam_isp_context *ctx, ctx->base = ctx_base; ctx->frame_id = 0; ctx->active_req_cnt = 0; - ctx->reported_req_id = 0; + ctx->req_info.reported_req_id = 0; + ctx->req_info.last_applied_req_id = 0; + ctx->req_info.last_bufdone_req_id = 0; + ctx->req_info.last_applied_time_stamp = 0; + ctx->req_info.last_bufdone_time_stamp = 0; + ctx->req_info.last_reported_id_time_stamp = 0; + ctx->hw_ctx = NULL; ctx->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF; ctx->substate_machine = cam_isp_ctx_activated_state_machine; diff --git a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h index 9bc6411011f9..bec84a85391c 100644 --- a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h +++ b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -61,20 +61,6 @@ enum cam_isp_ctx_activated_substate { CAM_ISP_CTX_ACTIVATED_MAX, }; -/** - * enum cam_isp_state_change_trigger - Different types of ISP events - * - */ -enum cam_isp_state_change_trigger { - CAM_ISP_STATE_CHANGE_TRIGGER_ERROR, - CAM_ISP_STATE_CHANGE_TRIGGER_SOF, - CAM_ISP_STATE_CHANGE_TRIGGER_REG_UPDATE, - CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, - CAM_ISP_STATE_CHANGE_TRIGGER_EOF, - CAM_ISP_STATE_CHANGE_TRIGGER_DONE, - CAM_ISP_STATE_CHANGE_TRIGGER_MAX -}; - /** * struct cam_isp_ctx_irq_ops - Function table for handling IRQ callbacks * @@ -125,19 +111,46 @@ struct cam_isp_ctx_req { * debug purposes * *@curr_state: Current sub state that received req - *@req_type: Event type of incoming req - *@req_id: Request id - *@evt_time_stamp Current time stamp + *@next_state: Next sub state that received req + *@hw_event: Hw Event type of incoming req + *@last_reported_id: Last_reported_id to userspace + *@last_applied_req_id Last applied request id to hardware + *@frame_id: Current Frame id + *@evt_time_stamp Current time stamp of this event logged * */ struct cam_isp_context_state_monitor { enum cam_isp_ctx_activated_substate curr_state; - enum cam_isp_state_change_trigger trigger; - uint32_t req_id; + enum cam_isp_ctx_activated_substate next_state; + enum cam_isp_hw_event_type hw_event; + int64_t last_reported_id; + int64_t last_applied_req_id; int64_t frame_id; uint64_t evt_time_stamp; }; +/** + * struct cam_isp_context_req_id_info - ISP context request id + * information for last applied, reported and bufdone. + * + *@last_applied_req_id: Last applied request id + *@last_bufdone_req_id: Last bufdone request id + *@reported_req_id: Last reported request id to userspace + *@last_applied_time_stamp: Last applied request time stamp information + *@last_bufdone_time_stamp Last bufdone request time stamp information + *@last_reported_id_time_stamp: Last reported request time stamp information + * + */ + +struct cam_isp_context_req_id_info { + int64_t last_applied_req_id; + int64_t last_bufdone_req_id; + int64_t reported_req_id; + int64_t last_applied_time_stamp; + int64_t last_bufdone_time_stamp; + int64_t last_reported_id_time_stamp; + +}; /** * struct cam_isp_context - ISP context object * @@ -154,11 +167,11 @@ struct cam_isp_context_state_monitor { * @sof_timestamp_val: Captured time stamp value at sof hw event * @boot_timestamp: Boot time stamp for a given req_id * @active_req_cnt: Counter for the active request - * @reported_req_id: Last reported request id * @subscribe_event: The irq event mask that CRM subscribes to, IFE * will invoke CRM cb at those event. - * @last_applied_req_id: Last applied request id * @state_monitor_head: Write index to the state monitoring array + * @req_info Request id information about last applied, + * reported and buf done * @cam_isp_ctx_state_monitor: State monitoring array * @rdi_only_context: Get context type information. * true, if context is rdi only context @@ -183,12 +196,11 @@ struct cam_isp_context { uint64_t sof_timestamp_val; uint64_t boot_timestamp; int32_t active_req_cnt; - int64_t reported_req_id; uint32_t subscribe_event; - int64_t last_applied_req_id; atomic64_t state_monitor_head; struct cam_isp_context_state_monitor cam_isp_ctx_state_monitor[ CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES]; + struct cam_isp_context_req_id_info req_info; bool rdi_only_context; bool hw_acquired; bool init_received; -- GitLab From 90224a39434e261a55a7c028d38857817a0be526 Mon Sep 17 00:00:00 2001 From: Ashok Vuyyuru Date: Mon, 10 Jun 2019 12:46:05 +0530 Subject: [PATCH 0505/1121] msm: ipa4: fix to increment IPA clock vote count after enabling clock In SM6125 target clock will be enabled through RPM driver, before enabling clocks some times IPA clock vote was increased causing NOC error. Add changes to increment IPA clock vote count after enabling clock. Change-Id: I6f19da9e0d03eab744292588c5bc526b8a90482a Signed-off-by: Ashok Vuyyuru --- drivers/platform/msm/ipa/ipa_v3/ipa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index 2d3b7add8b0e..681ab2de1be6 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -4482,8 +4482,8 @@ void ipa3_enable_clks(void) if (msm_bus_scale_client_update_request(ipa3_ctx->ipa_bus_hdl, ipa3_get_bus_vote())) WARN(1, "bus scaling failed"); - atomic_set(&ipa3_ctx->ipa_clk_vote, 1); ipa3_ctx->ctrl->ipa3_enable_clks(); + atomic_set(&ipa3_ctx->ipa_clk_vote, 1); } -- GitLab From 3e67fd937435679e6bb37bd2756be2ea00ad9d6e Mon Sep 17 00:00:00 2001 From: Yingjie Zhu Date: Thu, 6 Jun 2019 16:02:12 +0800 Subject: [PATCH 0506/1121] ARM: dts: msm: add support for controlling LGA power for bt module This change is to add support for controlling pin PWR_CTR1_VDD_PA and pin PWR_CTR2_VDD_1P8 which are required by LGA combo chip Change-Id: I01c4260d31ebd62698c1fffa5a5679b85e2ccea2 Signed-off-by: Yingjie Zhu --- arch/arm64/boot/dts/qcom/sa8155-vm.dtsi | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi b/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi index 4f294ac7d3ad..097fc5e5afe5 100644 --- a/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi @@ -476,7 +476,12 @@ compatible = "qca,qca6174"; pinctrl-names = "default"; pinctrl-0 = <&bt_en_active>; - qca,bt-reset-gpio = <&tlmm 172 0>; /* BT_EN */ + /* BT_EN */ + qca,bt-reset-gpio = <&tlmm 172 0>; + /* PWR_CTR1_VDD_PA */ + qca,bt-vdd-pa-supply = <&vreg_conn_pa>; + /* PWR_CTR2_VDD_1P8 */ + qca,bt-chip-pwd-supply = <&vreg_conn_1p8>; status = "ok"; }; -- GitLab From e99b1eb704ddeb0383d276ae3e9267977e01daeb Mon Sep 17 00:00:00 2001 From: Pratham Pratap Date: Fri, 7 Jun 2019 19:20:49 +0530 Subject: [PATCH 0507/1121] usb: dwc3: Flush bh work before disabling dwc3_irq Consider a case of quick pull-up disable after pull-up is enabled. If a SETUP packet comes after bus reset event followed by connection done event, there is a possibility of race between composite_dev_cleanup() freeing cdev->req called from configfs_composite_unbind() and composite_setup() storing req pointer to stack. This causes use after free of cdev->req. To fix this flush the bottom half work if there was any work pending before disabling dwc3_irq. Change-Id:I309f2117325c500f31e93925ac0a7b0d61ccc078 Signed-off-by: Pratham Pratap --- drivers/usb/dwc3/gadget.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 62d06d002de0..aff6059aa854 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2195,6 +2195,10 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) } disable_irq(dwc->irq); + + /* prevent pending bh to run later */ + flush_work(&dwc->bh_work); + spin_lock_irqsave(&dwc->lock, flags); if (dwc->ep0state != EP0_SETUP_PHASE) dbg_event(0xFF, "EP0 is not in SETUP phase\n", 0); -- GitLab From d30a2e82c247c4bd0e1b05100f26d26520908cdb Mon Sep 17 00:00:00 2001 From: Perry Randise Date: Tue, 4 Jun 2019 11:00:51 -0400 Subject: [PATCH 0508/1121] msm: ipa3: embellish access control policy algorithm Altered access control policy rule search such that rules further down the policy table will be used. This mitigates register offset to rule ambiguity. Also now using kernel defined reads and writes instead of local ones. Change-Id: Icbd94d41b565ad1af07c420d2ff25d9742db1f15 Signed-off-by: Perry Randise Signed-off-by: Ghanim Fodi --- .../platform/msm/ipa/ipa_v3/dump/ipa_reg_dump.c | 2 +- .../platform/msm/ipa/ipa_v3/dump/ipa_reg_dump.h | 14 ++------------ 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/dump/ipa_reg_dump.c b/drivers/platform/msm/ipa/ipa_v3/dump/ipa_reg_dump.c index 2a0d1eb551ef..879c31adccaa 100644 --- a/drivers/platform/msm/ipa/ipa_v3/dump/ipa_reg_dump.c +++ b/drivers/platform/msm/ipa/ipa_v3/dump/ipa_reg_dump.c @@ -667,7 +667,7 @@ static struct reg_access_funcs_s *get_access_funcs(u32 addr) for (i = 0; i < ARRAY_SIZE(mem_access_map); i++) { if (addr >= mem_access_map[i].addr_range_begin && - addr <= mem_access_map[i].addr_range_end) { + addr < mem_access_map[i].addr_range_end) { return mem_access_map[i].access[asub]; } } diff --git a/drivers/platform/msm/ipa/ipa_v3/dump/ipa_reg_dump.h b/drivers/platform/msm/ipa/ipa_v3/dump/ipa_reg_dump.h index 3eddb514f0c8..29b7a7256b85 100644 --- a/drivers/platform/msm/ipa/ipa_v3/dump/ipa_reg_dump.h +++ b/drivers/platform/msm/ipa/ipa_v3/dump/ipa_reg_dump.h @@ -20,16 +20,6 @@ #include "ipa_pkt_cntxt.h" #include "ipa_hw_common_ex.h" -/* - * The following macros are used to peek and poke register values and - * are required by some of the macros and include files that follow... - */ -#define my_in_dword(addr) \ - (readl(addr)) - -#define my_out_dword(addr, val) \ - ({ __iowmb(); writel_relaxed((val), (addr)); }) - #define IPA_0_IPA_WRAPPER_BASE 0 /* required by following includes */ #include "ipa_hwio.h" @@ -1253,7 +1243,7 @@ struct regs_save_hierarchy_s { static inline u32 act_read(void __iomem *addr) { - u32 val = my_in_dword(addr); + u32 val = ioread32(addr); return val; } @@ -1264,7 +1254,7 @@ act_read(void __iomem *addr) static inline void act_write(void __iomem *addr, u32 val) { - my_out_dword(addr, val); + iowrite32(val, addr); } /* -- GitLab From 007678f2e7e32639c929f8ad227b5135cb4dd164 Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Thu, 30 May 2019 23:21:59 -0700 Subject: [PATCH 0509/1121] soc: qcom: pil: Increase max number of PIL descriptors Increase the maximum number of PIL descriptors possible to accommodate for the rising number of PIL clients. Change-Id: Ib6f6ed7b642d9cb032333621831d0ecee94349ee Signed-off-by: Isaac J. Manjarres --- drivers/soc/qcom/peripheral-loader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/soc/qcom/peripheral-loader.c b/drivers/soc/qcom/peripheral-loader.c index 7611b2540b0e..1d12fdf47a04 100644 --- a/drivers/soc/qcom/peripheral-loader.c +++ b/drivers/soc/qcom/peripheral-loader.c @@ -56,7 +56,7 @@ #define pil_memset_io(d, c, count) memset_io(d, c, count) #endif -#define PIL_NUM_DESC 10 +#define PIL_NUM_DESC 16 #define MAX_LEN 96 #define NUM_OF_ENCRYPTED_KEY 3 -- GitLab From 928a94d48fa187a8c901a424b934333ef1ae070d Mon Sep 17 00:00:00 2001 From: "Thomas (Wonyoung) Yun" Date: Mon, 10 Jun 2019 11:49:55 -0400 Subject: [PATCH 0510/1121] ARM: dts: msm: Update GPU power levels for SA6155 Update max GPU frequencies for Nominal and SVS_L1 power levels. Change-Id: I38a724e82b9081df6e00f4cd6d825ea9c5de6d10 Signed-off-by: Vijayakumar Badiger Signed-off-by: Thomas (Wonyoung) Yun --- arch/arm64/boot/dts/qcom/sa6155.dtsi | 364 ++++++++++++++++++++++++++ arch/arm64/boot/dts/qcom/sa6155p.dtsi | 364 ++++++++++++++++++++++++++ 2 files changed, 728 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sa6155.dtsi b/arch/arm64/boot/dts/qcom/sa6155.dtsi index 6cfbba1807e2..d97cf7e4bcb0 100644 --- a/arch/arm64/boot/dts/qcom/sa6155.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155.dtsi @@ -125,3 +125,367 @@ }; }; }; + +/* GPU power level overrides */ +&msm_gpu { + /* + * Speed-bin zero is default speed bin. + * For rest of the speed bins, speed-bin value + * is calulated as FMAX/4.8 MHz round up to zero + * decimal places. + */ + qcom,gpu-pwrlevel-bins { + #address-cells = <1>; + #size-cells = <0>; + + compatible="qcom,gpu-pwrlevel-bins"; + + qcom,gpu-pwrlevels-0 { + #address-cells = <1>; + #size-cells = <0>; + + qcom,speed-bin = <0>; + + qcom,initial-pwrlevel = <5>; + qcom,ca-target-pwrlevel = <3>; + + /* TURBO */ + qcom,gpu-pwrlevel@0 { + reg = <0>; + qcom,gpu-freq = <845000000>; + qcom,bus-freq = <11>; + qcom,bus-min = <10>; + qcom,bus-max = <11>; + }; + + /* NOM L1 */ + qcom,gpu-pwrlevel@1 { + reg = <1>; + qcom,gpu-freq = <745000000>; + qcom,bus-freq = <10>; + qcom,bus-min = <9>; + qcom,bus-max = <11>; + }; + + /* NOM */ + qcom,gpu-pwrlevel@2 { + reg = <2>; + qcom,gpu-freq = <650000000>; + qcom,bus-freq = <9>; + qcom,bus-min = <8>; + qcom,bus-max = <10>; + }; + + /* SVS L1 */ + qcom,gpu-pwrlevel@3 { + reg = <3>; + qcom,gpu-freq = <500000000>; + qcom,bus-freq = <8>; + qcom,bus-min = <7>; + qcom,bus-max = <9>; + }; + + /* SVS */ + qcom,gpu-pwrlevel@4 { + reg = <4>; + qcom,gpu-freq = <435000000>; + qcom,bus-freq = <7>; + qcom,bus-min = <5>; + qcom,bus-max = <8>; + }; + + /* Low SVS */ + qcom,gpu-pwrlevel@5 { + reg = <5>; + qcom,gpu-freq = <290000000>; + qcom,bus-freq = <4>; + qcom,bus-min = <4>; + qcom,bus-max = <5>; + }; + + /* XO */ + qcom,gpu-pwrlevel@6 { + reg = <6>; + qcom,gpu-freq = <0>; + qcom,bus-freq = <0>; + qcom,bus-min = <0>; + qcom,bus-max = <0>; + }; + }; + + qcom,gpu-pwrlevels-1 { + #address-cells = <1>; + #size-cells = <0>; + + qcom,speed-bin = <177>; + + qcom,initial-pwrlevel = <5>; + qcom,ca-target-pwrlevel = <3>; + + /* TURBO */ + qcom,gpu-pwrlevel@0 { + reg = <0>; + qcom,gpu-freq = <845000000>; + qcom,bus-freq = <11>; + qcom,bus-min = <10>; + qcom,bus-max = <11>; + }; + + /* NOM L1 */ + qcom,gpu-pwrlevel@1 { + reg = <1>; + qcom,gpu-freq = <745000000>; + qcom,bus-freq = <10>; + qcom,bus-min = <9>; + qcom,bus-max = <11>; + }; + + /* NOM */ + qcom,gpu-pwrlevel@2 { + reg = <2>; + qcom,gpu-freq = <650000000>; + qcom,bus-freq = <9>; + qcom,bus-min = <8>; + qcom,bus-max = <10>; + }; + + /* SVS L1 */ + qcom,gpu-pwrlevel@3 { + reg = <3>; + qcom,gpu-freq = <500000000>; + qcom,bus-freq = <8>; + qcom,bus-min = <7>; + qcom,bus-max = <9>; + }; + + /* SVS */ + qcom,gpu-pwrlevel@4 { + reg = <4>; + qcom,gpu-freq = <435000000>; + qcom,bus-freq = <7>; + qcom,bus-min = <5>; + qcom,bus-max = <8>; + }; + + /* Low SVS */ + qcom,gpu-pwrlevel@5 { + reg = <5>; + qcom,gpu-freq = <290000000>; + qcom,bus-freq = <4>; + qcom,bus-min = <4>; + qcom,bus-max = <5>; + }; + + /* XO */ + qcom,gpu-pwrlevel@6 { + reg = <6>; + qcom,gpu-freq = <0>; + qcom,bus-freq = <0>; + qcom,bus-min = <0>; + qcom,bus-max = <0>; + }; + }; + + qcom,gpu-pwrlevels-2 { + #address-cells = <1>; + #size-cells = <0>; + + qcom,speed-bin = <156>; + + qcom,initial-pwrlevel = <4>; + qcom,ca-target-pwrlevel = <2>; + + /* NOM L1 */ + qcom,gpu-pwrlevel@0 { + reg = <0>; + qcom,gpu-freq = <745000000>; + qcom,bus-freq = <11>; + qcom,bus-min = <10>; + qcom,bus-max = <11>; + }; + + /* NOM */ + qcom,gpu-pwrlevel@1 { + reg = <1>; + qcom,gpu-freq = <650000000>; + qcom,bus-freq = <9>; + qcom,bus-min = <8>; + qcom,bus-max = <10>; + }; + + /* SVS L1 */ + qcom,gpu-pwrlevel@2 { + reg = <2>; + qcom,gpu-freq = <500000000>; + qcom,bus-freq = <8>; + qcom,bus-min = <7>; + qcom,bus-max = <9>; + }; + + /* SVS */ + qcom,gpu-pwrlevel@3 { + reg = <3>; + qcom,gpu-freq = <435000000>; + qcom,bus-freq = <7>; + qcom,bus-min = <5>; + qcom,bus-max = <8>; + }; + + /* Low SVS */ + qcom,gpu-pwrlevel@4 { + reg = <4>; + qcom,gpu-freq = <290000000>; + qcom,bus-freq = <4>; + qcom,bus-min = <4>; + qcom,bus-max = <5>; + }; + + /* XO */ + qcom,gpu-pwrlevel@5 { + reg = <5>; + qcom,gpu-freq = <0>; + qcom,bus-freq = <0>; + qcom,bus-min = <0>; + qcom,bus-max = <0>; + }; + }; + + qcom,gpu-pwrlevels-3 { + #address-cells = <1>; + #size-cells = <0>; + + qcom,speed-bin = <136>; + + qcom,initial-pwrlevel = <3>; + qcom,ca-target-pwrlevel = <1>; + + /* NOM */ + qcom,gpu-pwrlevel@0 { + reg = <0>; + qcom,gpu-freq = <650000000>; + qcom,bus-freq = <9>; + qcom,bus-min = <8>; + qcom,bus-max = <10>; + }; + + /* SVS L1 */ + qcom,gpu-pwrlevel@1 { + reg = <1>; + qcom,gpu-freq = <500000000>; + qcom,bus-freq = <8>; + qcom,bus-min = <7>; + qcom,bus-max = <9>; + }; + + /* SVS */ + qcom,gpu-pwrlevel@2 { + reg = <2>; + qcom,gpu-freq = <435000000>; + qcom,bus-freq = <7>; + qcom,bus-min = <5>; + qcom,bus-max = <8>; + }; + + /* Low SVS */ + qcom,gpu-pwrlevel@3 { + reg = <3>; + qcom,gpu-freq = <290000000>; + qcom,bus-freq = <4>; + qcom,bus-min = <4>; + qcom,bus-max = <5>; + }; + + /* XO */ + qcom,gpu-pwrlevel@4 { + reg = <4>; + qcom,gpu-freq = <0>; + qcom,bus-freq = <0>; + qcom,bus-min = <0>; + qcom,bus-max = <0>; + }; + }; + + qcom,gpu-pwrlevels-4 { + #address-cells = <1>; + #size-cells = <0>; + + qcom,speed-bin = <105>; + + qcom,initial-pwrlevel = <1>; + qcom,ca-target-pwrlevel = <2>; + + /* SVS L1 */ + qcom,gpu-pwrlevel@0 { + reg = <0>; + qcom,gpu-freq = <500000000>; + qcom,bus-freq = <8>; + qcom,bus-min = <7>; + qcom,bus-max = <9>; + }; + + /* SVS */ + qcom,gpu-pwrlevel@1 { + reg = <1>; + qcom,gpu-freq = <435000000>; + qcom,bus-freq = <7>; + qcom,bus-min = <5>; + qcom,bus-max = <8>; + }; + + /* Low SVS */ + qcom,gpu-pwrlevel@2 { + reg = <2>; + qcom,gpu-freq = <290000000>; + qcom,bus-freq = <4>; + qcom,bus-min = <4>; + qcom,bus-max = <5>; + }; + + /* XO */ + qcom,gpu-pwrlevel@3 { + reg = <3>; + qcom,gpu-freq = <0>; + qcom,bus-freq = <0>; + qcom,bus-min = <0>; + qcom,bus-max = <0>; + }; + }; + + qcom,gpu-pwrlevels-5 { + #address-cells = <1>; + #size-cells = <0>; + + qcom,speed-bin = <73>; + + qcom,initial-pwrlevel = <1>; + qcom,ca-target-pwrlevel = <0>; + + /* SVS */ + qcom,gpu-pwrlevel@0 { + reg = <0>; + qcom,gpu-freq = <350000000>; + qcom,bus-freq = <7>; + qcom,bus-min = <5>; + qcom,bus-max = <8>; + }; + + /* Low SVS */ + qcom,gpu-pwrlevel@1 { + reg = <1>; + qcom,gpu-freq = <290000000>; + qcom,bus-freq = <4>; + qcom,bus-min = <4>; + qcom,bus-max = <5>; + }; + + /* XO */ + qcom,gpu-pwrlevel@2 { + reg = <2>; + qcom,gpu-freq = <0>; + qcom,bus-freq = <0>; + qcom,bus-min = <0>; + qcom,bus-max = <0>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/sa6155p.dtsi b/arch/arm64/boot/dts/qcom/sa6155p.dtsi index 05036d70d25f..f44bc020a4c4 100644 --- a/arch/arm64/boot/dts/qcom/sa6155p.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155p.dtsi @@ -161,6 +161,370 @@ }; }; +/* GPU power level overrides */ +&msm_gpu { + /* + * Speed-bin zero is default speed bin. + * For rest of the speed bins, speed-bin value + * is calulated as FMAX/4.8 MHz round up to zero + * decimal places. + */ + qcom,gpu-pwrlevel-bins { + #address-cells = <1>; + #size-cells = <0>; + + compatible="qcom,gpu-pwrlevel-bins"; + + qcom,gpu-pwrlevels-0 { + #address-cells = <1>; + #size-cells = <0>; + + qcom,speed-bin = <0>; + + qcom,initial-pwrlevel = <5>; + qcom,ca-target-pwrlevel = <3>; + + /* TURBO */ + qcom,gpu-pwrlevel@0 { + reg = <0>; + qcom,gpu-freq = <845000000>; + qcom,bus-freq = <11>; + qcom,bus-min = <10>; + qcom,bus-max = <11>; + }; + + /* NOM L1 */ + qcom,gpu-pwrlevel@1 { + reg = <1>; + qcom,gpu-freq = <745000000>; + qcom,bus-freq = <10>; + qcom,bus-min = <9>; + qcom,bus-max = <11>; + }; + + /* NOM */ + qcom,gpu-pwrlevel@2 { + reg = <2>; + qcom,gpu-freq = <650000000>; + qcom,bus-freq = <9>; + qcom,bus-min = <8>; + qcom,bus-max = <10>; + }; + + /* SVS L1 */ + qcom,gpu-pwrlevel@3 { + reg = <3>; + qcom,gpu-freq = <500000000>; + qcom,bus-freq = <8>; + qcom,bus-min = <7>; + qcom,bus-max = <9>; + }; + + /* SVS */ + qcom,gpu-pwrlevel@4 { + reg = <4>; + qcom,gpu-freq = <435000000>; + qcom,bus-freq = <7>; + qcom,bus-min = <5>; + qcom,bus-max = <8>; + }; + + /* Low SVS */ + qcom,gpu-pwrlevel@5 { + reg = <5>; + qcom,gpu-freq = <290000000>; + qcom,bus-freq = <4>; + qcom,bus-min = <4>; + qcom,bus-max = <5>; + }; + + /* XO */ + qcom,gpu-pwrlevel@6 { + reg = <6>; + qcom,gpu-freq = <0>; + qcom,bus-freq = <0>; + qcom,bus-min = <0>; + qcom,bus-max = <0>; + }; + }; + + qcom,gpu-pwrlevels-1 { + #address-cells = <1>; + #size-cells = <0>; + + qcom,speed-bin = <177>; + + qcom,initial-pwrlevel = <5>; + qcom,ca-target-pwrlevel = <3>; + + /* TURBO */ + qcom,gpu-pwrlevel@0 { + reg = <0>; + qcom,gpu-freq = <845000000>; + qcom,bus-freq = <11>; + qcom,bus-min = <10>; + qcom,bus-max = <11>; + }; + + /* NOM L1 */ + qcom,gpu-pwrlevel@1 { + reg = <1>; + qcom,gpu-freq = <745000000>; + qcom,bus-freq = <10>; + qcom,bus-min = <9>; + qcom,bus-max = <11>; + }; + + /* NOM */ + qcom,gpu-pwrlevel@2 { + reg = <2>; + qcom,gpu-freq = <650000000>; + qcom,bus-freq = <9>; + qcom,bus-min = <8>; + qcom,bus-max = <10>; + }; + + /* SVS L1 */ + qcom,gpu-pwrlevel@3 { + reg = <3>; + qcom,gpu-freq = <500000000>; + qcom,bus-freq = <8>; + qcom,bus-min = <7>; + qcom,bus-max = <9>; + }; + + /* SVS */ + qcom,gpu-pwrlevel@4 { + reg = <4>; + qcom,gpu-freq = <435000000>; + qcom,bus-freq = <7>; + qcom,bus-min = <5>; + qcom,bus-max = <8>; + }; + + /* Low SVS */ + qcom,gpu-pwrlevel@5 { + reg = <5>; + qcom,gpu-freq = <290000000>; + qcom,bus-freq = <4>; + qcom,bus-min = <4>; + qcom,bus-max = <5>; + }; + + /* XO */ + qcom,gpu-pwrlevel@6 { + reg = <6>; + qcom,gpu-freq = <0>; + qcom,bus-freq = <0>; + qcom,bus-min = <0>; + qcom,bus-max = <0>; + }; + }; + + qcom,gpu-pwrlevels-2 { + #address-cells = <1>; + #size-cells = <0>; + + qcom,speed-bin = <156>; + + qcom,initial-pwrlevel = <4>; + qcom,ca-target-pwrlevel = <2>; + + /* NOM L1 */ + qcom,gpu-pwrlevel@0 { + reg = <0>; + qcom,gpu-freq = <745000000>; + qcom,bus-freq = <11>; + qcom,bus-min = <10>; + qcom,bus-max = <11>; + }; + + /* NOM */ + qcom,gpu-pwrlevel@1 { + reg = <1>; + qcom,gpu-freq = <650000000>; + qcom,bus-freq = <9>; + qcom,bus-min = <8>; + qcom,bus-max = <10>; + }; + + /* SVS L1 */ + qcom,gpu-pwrlevel@2 { + reg = <2>; + qcom,gpu-freq = <500000000>; + qcom,bus-freq = <8>; + qcom,bus-min = <7>; + qcom,bus-max = <9>; + }; + + /* SVS */ + qcom,gpu-pwrlevel@3 { + reg = <3>; + qcom,gpu-freq = <435000000>; + qcom,bus-freq = <7>; + qcom,bus-min = <5>; + qcom,bus-max = <8>; + }; + + /* Low SVS */ + qcom,gpu-pwrlevel@4 { + reg = <4>; + qcom,gpu-freq = <290000000>; + qcom,bus-freq = <4>; + qcom,bus-min = <4>; + qcom,bus-max = <5>; + }; + + /* XO */ + qcom,gpu-pwrlevel@5 { + reg = <5>; + qcom,gpu-freq = <0>; + qcom,bus-freq = <0>; + qcom,bus-min = <0>; + qcom,bus-max = <0>; + }; + }; + + qcom,gpu-pwrlevels-3 { + #address-cells = <1>; + #size-cells = <0>; + + qcom,speed-bin = <136>; + + qcom,initial-pwrlevel = <3>; + qcom,ca-target-pwrlevel = <1>; + + /* NOM */ + qcom,gpu-pwrlevel@0 { + reg = <0>; + qcom,gpu-freq = <650000000>; + qcom,bus-freq = <9>; + qcom,bus-min = <8>; + qcom,bus-max = <10>; + }; + + /* SVS L1 */ + qcom,gpu-pwrlevel@1 { + reg = <1>; + qcom,gpu-freq = <500000000>; + qcom,bus-freq = <8>; + qcom,bus-min = <7>; + qcom,bus-max = <9>; + }; + + /* SVS */ + qcom,gpu-pwrlevel@2 { + reg = <2>; + qcom,gpu-freq = <435000000>; + qcom,bus-freq = <7>; + qcom,bus-min = <5>; + qcom,bus-max = <8>; + }; + + /* Low SVS */ + qcom,gpu-pwrlevel@3 { + reg = <3>; + qcom,gpu-freq = <290000000>; + qcom,bus-freq = <4>; + qcom,bus-min = <4>; + qcom,bus-max = <5>; + }; + + /* XO */ + qcom,gpu-pwrlevel@4 { + reg = <4>; + qcom,gpu-freq = <0>; + qcom,bus-freq = <0>; + qcom,bus-min = <0>; + qcom,bus-max = <0>; + }; + }; + + qcom,gpu-pwrlevels-4 { + #address-cells = <1>; + #size-cells = <0>; + + qcom,speed-bin = <105>; + + qcom,initial-pwrlevel = <1>; + qcom,ca-target-pwrlevel = <2>; + + /* SVS L1 */ + qcom,gpu-pwrlevel@0 { + reg = <0>; + qcom,gpu-freq = <500000000>; + qcom,bus-freq = <8>; + qcom,bus-min = <7>; + qcom,bus-max = <9>; + }; + + /* SVS */ + qcom,gpu-pwrlevel@1 { + reg = <1>; + qcom,gpu-freq = <435000000>; + qcom,bus-freq = <7>; + qcom,bus-min = <5>; + qcom,bus-max = <8>; + }; + + /* Low SVS */ + qcom,gpu-pwrlevel@2 { + reg = <2>; + qcom,gpu-freq = <290000000>; + qcom,bus-freq = <4>; + qcom,bus-min = <4>; + qcom,bus-max = <5>; + }; + + /* XO */ + qcom,gpu-pwrlevel@3 { + reg = <3>; + qcom,gpu-freq = <0>; + qcom,bus-freq = <0>; + qcom,bus-min = <0>; + qcom,bus-max = <0>; + }; + }; + + qcom,gpu-pwrlevels-5 { + #address-cells = <1>; + #size-cells = <0>; + + qcom,speed-bin = <73>; + + qcom,initial-pwrlevel = <1>; + qcom,ca-target-pwrlevel = <0>; + + /* SVS */ + qcom,gpu-pwrlevel@0 { + reg = <0>; + qcom,gpu-freq = <350000000>; + qcom,bus-freq = <7>; + qcom,bus-min = <5>; + qcom,bus-max = <8>; + }; + + /* Low SVS */ + qcom,gpu-pwrlevel@1 { + reg = <1>; + qcom,gpu-freq = <290000000>; + qcom,bus-freq = <4>; + qcom,bus-min = <4>; + qcom,bus-max = <5>; + }; + + /* XO */ + qcom,gpu-pwrlevel@2 { + reg = <2>; + qcom,gpu-freq = <0>; + qcom,bus-freq = <0>; + qcom,bus-min = <0>; + qcom,bus-max = <0>; + }; + }; + }; +}; + /* Audio device tree */ #include "sa6155-audio.dtsi" #include "sa6155-pcie.dtsi" -- GitLab From a24b0402d911492d49e81b245ba02b468b3b9e0b Mon Sep 17 00:00:00 2001 From: Michael Adisumarta Date: Mon, 10 Jun 2019 13:35:35 -0700 Subject: [PATCH 0511/1121] msm: ipa: set the property for caching the entries in IOMMU This change sets the property for caching the entries to ensure coherency is enabled. Change-Id: Ib50823ad195fe4086d2371e3846c8c64c02f5b8b Acked-by: Jyothij Signed-off-by: Michael Adisumarta --- drivers/platform/msm/ipa/ipa_v3/ipa.c | 23 ++++++++++++++++++++++- drivers/platform/msm/ipa/ipa_v3/ipa_i.h | 1 + 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index f6a9c8b46300..ae45f92dbb87 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -7282,12 +7282,16 @@ static int ipa_smmu_wlan_cb_probe(struct device *dev) /* assume this failure is because iommu driver is not ready */ return -EPROBE_DEFER; } + + cb->is_cache_coherent = of_property_read_bool(dev->of_node, + "dma-coherent"); cb->valid = true; if (of_property_read_bool(dev->of_node, "qcom,smmu-s1-bypass") || ipa3_ctx->ipa_config_is_mhi) { smmu_info.s1_bypass_arr[IPA_SMMU_CB_WLAN] = true; ipa3_ctx->s1_bypass_arr[IPA_SMMU_CB_WLAN] = true; + cb->is_cache_coherent = false; if (iommu_domain_set_attr(cb->iommu, DOMAIN_ATTR_S1_BYPASS, @@ -7419,6 +7423,8 @@ static int ipa_smmu_uc_cb_probe(struct device *dev) /* assume this failure is because iommu driver is not ready */ return -EPROBE_DEFER; } + cb->is_cache_coherent = of_property_read_bool(dev->of_node, + "dma-coherent"); IPADBG("SMMU mapping created\n"); cb->valid = true; @@ -7428,6 +7434,7 @@ static int ipa_smmu_uc_cb_probe(struct device *dev) ipa3_ctx->ipa_config_is_mhi) { smmu_info.s1_bypass_arr[IPA_SMMU_CB_UC] = true; ipa3_ctx->s1_bypass_arr[IPA_SMMU_CB_UC] = true; + cb->is_cache_coherent = false; if (iommu_domain_set_attr(cb->mapping->domain, DOMAIN_ATTR_S1_BYPASS, @@ -7548,6 +7555,8 @@ static int ipa_smmu_ap_cb_probe(struct device *dev) } } + cb->is_cache_coherent = of_property_read_bool(dev->of_node, + "dma-coherent"); cb->dev = dev; cb->mapping = arm_iommu_create_mapping(dev->bus, cb->va_start, cb->va_size); @@ -7563,6 +7572,8 @@ static int ipa_smmu_ap_cb_probe(struct device *dev) "qcom,smmu-s1-bypass") || ipa3_ctx->ipa_config_is_mhi) { smmu_info.s1_bypass_arr[IPA_SMMU_CB_AP] = true; ipa3_ctx->s1_bypass_arr[IPA_SMMU_CB_AP] = true; + cb->is_cache_coherent = false; + if (iommu_domain_set_attr(cb->mapping->domain, DOMAIN_ATTR_S1_BYPASS, &bypass)) { @@ -8035,6 +8046,7 @@ int ipa3_iommu_map(struct iommu_domain *domain, { struct ipa_smmu_cb_ctx *ap_cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_AP); struct ipa_smmu_cb_ctx *uc_cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_UC); + struct ipa_smmu_cb_ctx *wlan_cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_WLAN); IPADBG_LOW("domain =0x%pK iova 0x%lx\n", domain, iova); IPADBG_LOW("paddr =0x%pa size 0x%x\n", &paddr, (u32)size); @@ -8046,20 +8058,29 @@ int ipa3_iommu_map(struct iommu_domain *domain, ipa_assert(); return -EFAULT; } + if (ap_cb->is_cache_coherent) + prot |= IOMMU_CACHE; } else if (domain == ipa3_get_wlan_smmu_domain()) { /* wlan is one time map */ + if (wlan_cb->is_cache_coherent) + prot |= IOMMU_CACHE; } else if (domain == ipa3_get_uc_smmu_domain()) { if (iova >= uc_cb->va_start && iova < uc_cb->va_end) { IPAERR("iommu uC overlap addr 0x%lx\n", iova); ipa_assert(); return -EFAULT; } + if (uc_cb->is_cache_coherent) + prot |= IOMMU_CACHE; } else { IPAERR("Unexpected domain 0x%pK\n", domain); ipa_assert(); return -EFAULT; } - + /* + * IOMMU_CACHE is needed in prot to make the entries cachable + * if cache coherency is enabled in dtsi. + */ return iommu_map(domain, iova, paddr, size, prot); } diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index dd46cce45d08..e745e3a8a140 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -474,6 +474,7 @@ struct ipa_smmu_cb_ctx { u32 va_start; u32 va_size; u32 va_end; + bool is_cache_coherent; }; /** -- GitLab From 43aecbfea7311d3c9a16971ff9f714f667021ade Mon Sep 17 00:00:00 2001 From: Sean Tranchetti Date: Wed, 5 Jun 2019 15:13:52 -0600 Subject: [PATCH 0512/1121] net: qualcomm: rmnet: Fix skb->csum_start value Now that we can reuse the original SKB from the lower level drivers during RSB/RSC processing, we can no longer assume that the transport header offset is set when stamping the GSO information. Change-Id: I017c089bfc99eae6a07b2f60632c9e4ffac89de1 Signed-off-by: Sean Tranchetti --- drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c index 3e1ed8c2549b..ff9aa988f900 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c @@ -667,7 +667,7 @@ static void rmnet_map_gso_stamp(struct sk_buff *skb, } skb->ip_summed = CHECKSUM_PARTIAL; - skb->csum_start = skb_transport_header(skb) - skb->head; + skb->csum_start = skb->data + coal_meta->ip_len - skb->head; shinfo->gso_size = coal_meta->data_len; shinfo->gso_segs = coal_meta->pkt_count; } -- GitLab From 659b65868bbec3af8c6a6f7254f2bbb7661e0fe3 Mon Sep 17 00:00:00 2001 From: Kiran Gunda Date: Fri, 7 Jun 2019 14:53:16 +0530 Subject: [PATCH 0513/1121] ARM: dts: msm: Add PM6150 and PM6150L peripherals for atoll Add PM6150 and PM6150L PMIC peripherals like Charger, GPIOs, PON, flash and RGB for atoll. Change-Id: I3fa2f880f7ca165c12638f4f07d49be7dd26da51 Signed-off-by: Kiran Gunda --- arch/arm64/boot/dts/qcom/atoll.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index 2878437b2226..37d980de0df8 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -1609,6 +1609,8 @@ compatible = "qcom,cmd-db"; reg = <0xc3f000c 8>; }; + + thermal_zones: thermal-zones {}; }; #include "atoll-gdsc.dtsi" @@ -1680,6 +1682,8 @@ status = "ok"; }; +#include "pm6150.dtsi" +#include "pm6150l.dtsi" #include "atoll-pinctrl.dtsi" #include "atoll-pm.dtsi" #include "atoll-stub-regulator.dtsi" -- GitLab From dc5ad43a2ef1cdc8b08a69043eb9c55dbac8513f Mon Sep 17 00:00:00 2001 From: Zhiqiang Tu Date: Tue, 9 Apr 2019 15:36:52 +0800 Subject: [PATCH 0514/1121] defconfig: msm: Enable virtio clock for QTI Quin GVM Enable virtio clock for Quin virtual machine. Change-Id: Idf1eda53776d1a695214969c3de20db898271c2c Signed-off-by: Zhiqiang Tu --- arch/arm64/configs/vendor/qti-quin-gvm-perf_defconfig | 1 + arch/arm64/configs/vendor/qti-quin-gvm_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm64/configs/vendor/qti-quin-gvm-perf_defconfig b/arch/arm64/configs/vendor/qti-quin-gvm-perf_defconfig index 9d0eb2b5db78..d9989c6dd3f5 100644 --- a/arch/arm64/configs/vendor/qti-quin-gvm-perf_defconfig +++ b/arch/arm64/configs/vendor/qti-quin-gvm-perf_defconfig @@ -404,6 +404,7 @@ CONFIG_SPS_SUPPORT_NDP_BAM=y CONFIG_USB_BAM=y CONFIG_COMMON_CLK_QCOM=y CONFIG_QCOM_CLK_VIRT=y +CONFIG_VIRTIO_CLK=y CONFIG_HWSPINLOCK=y CONFIG_MAILBOX=y CONFIG_IOMMU_IO_PGTABLE_FAST=y diff --git a/arch/arm64/configs/vendor/qti-quin-gvm_defconfig b/arch/arm64/configs/vendor/qti-quin-gvm_defconfig index ef71e9d141f4..7eed8e1c416a 100644 --- a/arch/arm64/configs/vendor/qti-quin-gvm_defconfig +++ b/arch/arm64/configs/vendor/qti-quin-gvm_defconfig @@ -417,6 +417,7 @@ CONFIG_SPS_SUPPORT_NDP_BAM=y CONFIG_USB_BAM=y CONFIG_COMMON_CLK_QCOM=y CONFIG_QCOM_CLK_VIRT=y +CONFIG_VIRTIO_CLK=y CONFIG_HWSPINLOCK=y CONFIG_MAILBOX=y CONFIG_IOMMU_IO_PGTABLE_FAST=y -- GitLab From ad5d6ae46b6bdb3599befef98dd25f9724234501 Mon Sep 17 00:00:00 2001 From: Zhiqiang Tu Date: Tue, 9 Apr 2019 15:39:25 +0800 Subject: [PATCH 0515/1121] ARM: dts: msm: Enable virtio clock for sa8155 vm Replace hab based virtual clock with virtio clock for SA8155 virtual machine. Change-Id: I9d2125fdf116c0a2b424062cf0482e7ae7600c15 Signed-off-by: Zhiqiang Tu --- arch/arm64/boot/dts/qcom/sa8155-vm.dtsi | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi b/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi index 4f294ac7d3ad..198546270913 100644 --- a/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi @@ -95,14 +95,18 @@ ranges = <0 0 0 0xffffffff>; compatible = "simple-bus"; - clock_virt: qcom,virt-gcc { - compatible = "qcom,virt-clk-sm8150-gcc"; + clock_virt: qcom,virtio-gcc { + compatible = "virtio,mmio"; + reg = <0x1c200000 0x1000>; + interrupts = <0 100 0>; #clock-cells = <1>; #reset-cells = <1>; }; - clock_virt_scc: qcom,virt-scc { - compatible = "qcom,virt-clk-sm8150-scc"; + clock_virt_scc: qcom,virtio-scc { + compatible = "virtio,mmio"; + reg = <0x1c300000 0x1000>; + interrupts = <0 101 0>; #clock-cells = <1>; #reset-cells = <1>; }; -- GitLab From 32c33983e3330ac6577c17d5f967a2e1e5de02e9 Mon Sep 17 00:00:00 2001 From: Omkar Savagaonkar Date: Wed, 8 May 2019 15:13:38 +0530 Subject: [PATCH 0516/1121] defconfig: Enable hibernation feature for sa8155 Enable hibernation feature for sa8155 also set hibernation partition. Change-Id: I790c26860a03d6b8c102fc3b224a45db49c7803f Signed-off-by: Omkar Savagaonkar --- arch/arm64/configs/vendor/sa8155_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/configs/vendor/sa8155_defconfig b/arch/arm64/configs/vendor/sa8155_defconfig index 5596252e06a8..804b904b712a 100644 --- a/arch/arm64/configs/vendor/sa8155_defconfig +++ b/arch/arm64/configs/vendor/sa8155_defconfig @@ -86,6 +86,8 @@ CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y CONFIG_BUILD_ARM64_UNCOMPRESSED_KERNEL=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_COMPAT=y +CONFIG_HIBERNATION=y +CONFIG_PM_STD_PARTITION="/dev/sda7" CONFIG_PM_AUTOSLEEP=y CONFIG_PM_WAKELOCKS=y CONFIG_PM_WAKELOCKS_LIMIT=0 -- GitLab From 13ea642ee12a06a116837f061ef7e0e647623936 Mon Sep 17 00:00:00 2001 From: Omkar Savagaonkar Date: Wed, 8 May 2019 12:38:11 +0530 Subject: [PATCH 0517/1121] iommu: arm-smmu: Remove check for hibernation and secure use case Hibernation with secure use case can be supported with hyp_assign tracker. It is being committed as part of separate patch. Hence, remove this particular check. Change-Id: Id76e0d4544d82acb889dc8b803e795cca6762350 Signed-off-by: Omkar Savagaonkar --- drivers/iommu/arm-smmu.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index cb3ac4f793a8..f921a63d49e7 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -524,11 +524,6 @@ static void arm_smmu_secure_domain_unlock(struct arm_smmu_domain *smmu_domain) mutex_unlock(&smmu_domain->assign_lock); } -static bool arm_smmu_opt_hibernation(struct arm_smmu_device *smmu) -{ - return IS_ENABLED(CONFIG_HIBERNATION); -} - #ifdef CONFIG_ARM_SMMU_SELFTEST static int selftest; @@ -1915,14 +1910,6 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, goto out_unlock; } - if (arm_smmu_has_secure_vmid(smmu_domain) && - arm_smmu_opt_hibernation(smmu)) { - dev_err(smmu->dev, - "Secure usecases not supported with hibernation\n"); - ret = -EPERM; - goto out_unlock; - } - /* * Mapping the requested stage onto what we support is surprisingly * complicated, mainly because the spec allows S1+S2 SMMUs without -- GitLab From 899e1b2f0ef6133353c5e0cbb0375e53742d6262 Mon Sep 17 00:00:00 2001 From: Linyu Yuan Date: Tue, 11 Jun 2019 11:32:14 +0800 Subject: [PATCH 0518/1121] usb: misc: nb7vpq904m: fix possible array overflow Array 'eq' of size 2 may use index value(s) 2. Change-Id: I69f8a0992a26cc7dabed35d734cf046e9bd42408 Signed-off-by: Linyu Yuan --- drivers/usb/misc/ssusb-redriver-nb7vpq904m.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/usb/misc/ssusb-redriver-nb7vpq904m.c b/drivers/usb/misc/ssusb-redriver-nb7vpq904m.c index e3a6e7bfca45..ec3783568653 100644 --- a/drivers/usb/misc/ssusb-redriver-nb7vpq904m.c +++ b/drivers/usb/misc/ssusb-redriver-nb7vpq904m.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #include @@ -85,9 +85,11 @@ enum operation_mode { enum channel_mode { CHAN_MODE_USB, CHAN_MODE_DP, - CHAN_MODE_NUM, + /* update CHAN_MODE_NUM if new mode is added */ }; +#define CHAN_MODE_NUM 2 + /** * struct ssusb_redriver - representation of USB re-driver * @dev: struct device pointer -- GitLab From 0ae8ff7712077f715d8bf924917761d304bc06cc Mon Sep 17 00:00:00 2001 From: Yuan Zhao Date: Tue, 14 May 2019 21:55:29 +0800 Subject: [PATCH 0519/1121] drm/msm/dsi-staging: Add a new bridge DTS property support Parse the "qcom,qcom,mdss-dsi-ext-bridge" DTS property instead of the old mdss-dsi-ext-bridge-mode. This node defines the port reg value, can match the port setting in dsi display. Now use this property to define bridge setting, if it was not set, it should be a DSI panel. Change-Id: Ibb514b541f8c1c413b365c48fdf95247867c4f45 Signed-off-by: Yuan Zhao --- drivers/gpu/drm/msm/dsi-staging/dsi_defs.h | 10 ++- drivers/gpu/drm/msm/dsi-staging/dsi_display.c | 65 +++++++-------- drivers/gpu/drm/msm/dsi-staging/dsi_display.h | 5 +- drivers/gpu/drm/msm/dsi-staging/dsi_panel.c | 79 +++++++++++++++---- 4 files changed, 103 insertions(+), 56 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h b/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h index 64565f3da807..431173effcbd 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h @@ -18,6 +18,9 @@ #include #include "msm_drv.h" +#define MAX_EXT_BRIDGE_PORT_CONFIG 16 +#define MAX_DSI_CTRLS_PER_DISPLAY 2 + #define DSI_H_TOTAL(t) (((t)->h_active) + ((t)->h_back_porch) + \ ((t)->h_sync_width) + ((t)->h_front_porch)) @@ -450,7 +453,9 @@ struct dsi_split_link_config { * @ignore_rx_eot: Ignore Rx EOT packets if set to true. * @append_tx_eot: Append EOT packets for forward transmissions if set to * true. - * @ext_bridge_mode: External bridge is connected. + * @ext_bridge_num: Connected external bridge count. + * @ext_bridge_map: External bridge config reg needs to match with the port + * reg config. * @force_hs_clk_lane: Send continuous clock to the panel. * @dsi_split_link_config: Split Link Configuration. */ @@ -471,7 +476,8 @@ struct dsi_host_common_cfg { u32 t_clk_pre; bool ignore_rx_eot; bool append_tx_eot; - bool ext_bridge_mode; + u32 ext_bridge_num; + u32 ext_bridge_map[MAX_DSI_CTRLS_PER_DISPLAY]; bool force_hs_clk_lane; struct dsi_split_link_config split_link; }; diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c index bc346173b19d..4d3b99883d33 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c @@ -3603,13 +3603,11 @@ static int dsi_display_parse_dt(struct dsi_display *display) /* Parse TE data */ dsi_display_parse_te_data(display); - /* Parse all external bridges from port 0 */ - display_for_each_ctrl(i, display) { + /* Parse all external bridges config, endpoint0 */ + for (i = 0; i < MAX_EXT_BRIDGE_PORT_CONFIG; i++) { display->ext_bridge[i].node_of = of_graph_get_remote_node(of_node, 0, i); - if (display->ext_bridge[i].node_of) - display->ext_bridge_cnt++; - else + if (!display->ext_bridge[i].node_of) break; } @@ -4893,7 +4891,7 @@ static int dsi_display_bind(struct device *dev, char *client1 = "dsi_clk_client"; char *client2 = "mdp_event_client"; char dsi_client_name[DSI_CLIENT_NAME_SIZE]; - int i, rc = 0; + int i, j, rc = 0; if (!dev || !pdev || !master) { pr_err("invalid param(s), dev %pK, pdev %pK, master %pK\n", @@ -4914,14 +4912,17 @@ static int dsi_display_bind(struct device *dev, return 0; /* defer bind if ext bridge driver is not loaded */ - if (display->panel && display->panel->host_config.ext_bridge_mode) { - for (i = 0; i < display->ext_bridge_cnt; i++) { - if (!of_drm_find_bridge( - display->ext_bridge[i].node_of)) { - pr_debug("defer for bridge[%d] %s\n", i, - display->ext_bridge[i].node_of->full_name); - return -EPROBE_DEFER; - } + for (i = 0; i < display->panel->host_config.ext_bridge_num; i++) { + j = display->panel->host_config.ext_bridge_map[i]; + if (!display->ext_bridge[j].node_of) { + pr_err("invalid ext bridge node\n"); + return -EINVAL; + } + + if (!of_drm_find_bridge(display->ext_bridge[j].node_of)) { + pr_debug("defer for bridge[%d] %s\n", j, + display->ext_bridge[j].node_of->full_name); + return -EPROBE_DEFER; } } @@ -5580,11 +5581,9 @@ static struct dsi_display_ext_bridge *dsi_display_ext_get_bridge( { struct msm_drm_private *priv; struct sde_kms *sde_kms; - struct list_head *connector_list; - struct drm_connector *conn_iter; - struct sde_connector *sde_conn; struct dsi_display *display; - int i; + int i, j, k; + u32 bridge_num; if (!bridge || !bridge->encoder) { SDE_ERROR("invalid argument\n"); @@ -5593,16 +5592,14 @@ static struct dsi_display_ext_bridge *dsi_display_ext_get_bridge( priv = bridge->dev->dev_private; sde_kms = to_sde_kms(priv->kms); - connector_list = &sde_kms->dev->mode_config.connector_list; - - list_for_each_entry(conn_iter, connector_list, head) { - sde_conn = to_sde_connector(conn_iter); - if (sde_conn->encoder == bridge->encoder) { - display = sde_conn->display; - display_for_each_ctrl(i, display) { - if (display->ext_bridge[i].bridge == bridge) - return &display->ext_bridge[i]; - } + + for (i = 0; i < sde_kms->dsi_display_count; i++) { + display = sde_kms->dsi_displays[i]; + bridge_num = display->panel->host_config.ext_bridge_num; + for (j = 0; j < bridge_num; j++) { + k = display->panel->host_config.ext_bridge_map[j]; + if (display->ext_bridge[k].bridge == bridge) + return &display->ext_bridge[k]; } } @@ -5766,12 +5763,10 @@ int dsi_display_drm_ext_bridge_init(struct dsi_display *display, struct drm_bridge *prev_bridge = bridge; int rc = 0, i; - if (display->panel && !display->panel->host_config.ext_bridge_mode) - return 0; - - for (i = 0; i < display->ext_bridge_cnt; i++) { + for (i = 0; i < display->panel->host_config.ext_bridge_num; i++) { + int j = display->panel->host_config.ext_bridge_map[i]; struct dsi_display_ext_bridge *ext_bridge_info = - &display->ext_bridge[i]; + &display->ext_bridge[j]; /* return if ext bridge is already initialized */ if (ext_bridge_info->bridge) @@ -5785,7 +5780,7 @@ int dsi_display_drm_ext_bridge_init(struct dsi_display *display, } /* override functions for mode adjustment */ - if (display->ext_bridge_cnt > 1) { + if (display->panel->host_config.ext_bridge_num > 1) { ext_bridge_info->bridge_funcs = *ext_bridge->funcs; if (ext_bridge->funcs->mode_fixup) ext_bridge_info->bridge_funcs.mode_fixup = @@ -5830,7 +5825,7 @@ int dsi_display_drm_ext_bridge_init(struct dsi_display *display, if (!display->ext_conn || !display->ext_conn->funcs || !display->ext_conn->helper_private || - display->ext_bridge_cnt > 1) { + display->panel->host_config.ext_bridge_num > 1) { display->ext_conn = NULL; continue; } diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h index 1eef2fa5aa03..4cf3cebb7d02 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h @@ -29,7 +29,6 @@ #include "dsi_phy.h" #include "dsi_panel.h" -#define MAX_DSI_CTRLS_PER_DISPLAY 2 #define DSI_CLIENT_NAME_SIZE 20 #define MAX_CMDLINE_PARAM_LEN 512 #define MAX_CMD_PAYLOAD_SIZE 256 @@ -160,7 +159,6 @@ struct dsi_display_ext_bridge { * @panel: Handle to DSI panel. * @panel_of: pHandle to DSI panel. * @ext_bridge: External bridge information for DSI display. - * @ext_bridge_cnt: Number of external bridges * @modes: Array of probed DSI modes * @type: DSI display type. * @clk_master_idx: The master controller for controlling clocks. This is an @@ -216,8 +214,7 @@ struct dsi_display { struct device_node *parser_node; /* external bridge */ - struct dsi_display_ext_bridge ext_bridge[MAX_DSI_CTRLS_PER_DISPLAY]; - u32 ext_bridge_cnt; + struct dsi_display_ext_bridge ext_bridge[MAX_EXT_BRIDGE_PORT_CONFIG]; struct dsi_display_mode *modes; diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c index 3b3d5de25cac..3ac97ca92d07 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c @@ -414,7 +414,7 @@ static int dsi_panel_set_pinctrl_state(struct dsi_panel *panel, bool enable) int rc = 0; struct pinctrl_state *state; - if (panel->host_config.ext_bridge_mode) + if (panel->host_config.ext_bridge_num) return 0; if (enable) @@ -548,7 +548,7 @@ static int dsi_panel_pinctrl_deinit(struct dsi_panel *panel) { int rc = 0; - if (panel->host_config.ext_bridge_mode) + if (panel->host_config.ext_bridge_num) return 0; devm_pinctrl_put(panel->pinctrl.pinctrl); @@ -560,7 +560,7 @@ static int dsi_panel_pinctrl_init(struct dsi_panel *panel) { int rc = 0; - if (panel->host_config.ext_bridge_mode) + if (panel->host_config.ext_bridge_num) return 0; /* TODO: pinctrl is defined in dsi dt node */ @@ -683,7 +683,7 @@ int dsi_panel_set_backlight(struct dsi_panel *panel, u32 bl_lvl) int rc = 0; struct dsi_backlight_config *bl = &panel->bl_config; - if (panel->host_config.ext_bridge_mode) + if (panel->host_config.ext_bridge_num) return 0; pr_debug("backlight type:%d lvl:%d\n", bl->type, bl_lvl); @@ -764,7 +764,7 @@ static int dsi_panel_bl_register(struct dsi_panel *panel) int rc = 0; struct dsi_backlight_config *bl = &panel->bl_config; - if (panel->host_config.ext_bridge_mode) + if (panel->host_config.ext_bridge_num) return 0; switch (bl->type) { @@ -800,7 +800,7 @@ static int dsi_panel_bl_unregister(struct dsi_panel *panel) int rc = 0; struct dsi_backlight_config *bl = &panel->bl_config; - if (panel->host_config.ext_bridge_mode) + if (panel->host_config.ext_bridge_num) return 0; switch (bl->type) { @@ -1129,6 +1129,51 @@ static int dsi_panel_parse_triggers(struct dsi_host_common_cfg *host, return rc; } +static int dsi_panel_parse_ext_bridge_config(struct dsi_host_common_cfg *host, + struct dsi_parser_utils *utils, + const char *name) +{ + u32 len = 0, i = 0; + int rc = 0; + + host->ext_bridge_num = 0; + + len = utils->count_u32_elems(utils->data, "qcom,mdss-dsi-ext-bridge"); + + if (len > MAX_DSI_CTRLS_PER_DISPLAY) { + pr_debug("[%s] Invalid ext bridge count set\n", name); + return -EINVAL; + } + + if (len == 0) { + pr_debug("[%s] It's a DSI panel, not bridge\n", name); + return rc; + } + + rc = utils->read_u32_array(utils->data, "qcom,mdss-dsi-ext-bridge", + host->ext_bridge_map, + len); + + if (rc) { + pr_debug("[%s] Did not get ext bridge set\n", name); + return rc; + } + + for (i = 0; i < len; i++) { + if (host->ext_bridge_map[i] >= MAX_EXT_BRIDGE_PORT_CONFIG) { + pr_debug("[%s] Invalid bridge port value %d\n", + name, host->ext_bridge_map[i]); + return -EINVAL; + } + } + + host->ext_bridge_num = len; + + pr_debug("[%s] ext bridge count is %d\n", name, host->ext_bridge_num); + + return rc; +} + static int dsi_panel_parse_misc_host_config(struct dsi_host_common_cfg *host, struct dsi_parser_utils *utils, const char *name) @@ -1155,9 +1200,6 @@ static int dsi_panel_parse_misc_host_config(struct dsi_host_common_cfg *host, host->append_tx_eot = utils->read_bool(utils->data, "qcom,mdss-dsi-tx-eot-append"); - host->ext_bridge_mode = utils->read_bool(utils->data, - "qcom,mdss-dsi-ext-bridge-mode"); - host->force_hs_clk_lane = utils->read_bool(utils->data, "qcom,mdss-dsi-force-clock-lane-hs"); return 0; @@ -1246,6 +1288,13 @@ static int dsi_panel_parse_host_config(struct dsi_panel *panel) goto error; } + dsi_panel_parse_ext_bridge_config(&panel->host_config, utils, + panel->name); + if (rc) { + pr_err("[%s] failed to parse ext bridge config, rc=%d\n", + panel->name, rc); + } + dsi_panel_parse_split_link_config(&panel->host_config, utils, panel->name); @@ -1888,7 +1937,7 @@ static int dsi_panel_parse_reset_sequence(struct dsi_panel *panel) struct dsi_parser_utils *utils = &panel->utils; struct dsi_reset_seq *seq; - if (panel->host_config.ext_bridge_mode) + if (panel->host_config.ext_bridge_num) return 0; arr = utils->get_property(utils->data, @@ -2024,7 +2073,7 @@ static int dsi_panel_parse_power_cfg(struct dsi_panel *panel) int rc = 0; char *supply_name; - if (panel->host_config.ext_bridge_mode) + if (panel->host_config.ext_bridge_num) return 0; if (!strcmp(panel->type, "primary")) @@ -2061,7 +2110,7 @@ static int dsi_panel_parse_gpios(struct dsi_panel *panel) panel->reset_config.reset_gpio = utils->get_named_gpio(utils->data, reset_gpio_name, 0); if (!gpio_is_valid(panel->reset_config.reset_gpio) && - !panel->host_config.ext_bridge_mode) { + !panel->host_config.ext_bridge_num) { rc = panel->reset_config.reset_gpio; pr_err("[%s] failed get reset gpio, rc=%d\n", panel->name, rc); goto error; @@ -3386,14 +3435,14 @@ int dsi_panel_get_mode_count(struct dsi_panel *panel) timings_np = utils->get_child_by_name(utils->data, "qcom,mdss-dsi-display-timings"); - if (!timings_np && !panel->host_config.ext_bridge_mode) { + if (!timings_np && !panel->host_config.ext_bridge_num) { pr_err("no display timing nodes defined\n"); rc = -EINVAL; goto error; } count = utils->get_child_count(timings_np); - if ((!count && !panel->host_config.ext_bridge_mode) || + if ((!count && !panel->host_config.ext_bridge_num) || count > DSI_MODE_MAX) { pr_err("invalid count of timing nodes: %d\n", count); rc = -EINVAL; @@ -3402,7 +3451,7 @@ int dsi_panel_get_mode_count(struct dsi_panel *panel) /* No multiresolution support is available for video mode panels */ if (panel->panel_mode != DSI_OP_CMD_MODE && - !panel->host_config.ext_bridge_mode) + !panel->host_config.ext_bridge_num) count = SINGLE_MODE_SUPPORT; panel->num_timing_nodes = count; -- GitLab From b94ce946954bec4588a17f3920f0a3f8413c594a Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Fri, 26 Apr 2019 14:05:56 -0700 Subject: [PATCH 0520/1121] ARM: dts: msm: Add USB PHY AC pin definitions for sdmshrike Provide device tree entries for USB to PHY AC pin definitions needed by sdmshrike. Change-Id: Iaea0fe710f69996b191896f75df7f6cf5b0e3a3f Signed-off-by: Anant Goel --- .../boot/dts/qcom/sdmshrike-pinctrl.dtsi | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdmshrike-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sdmshrike-pinctrl.dtsi index 2af7383028f4..28d312ae4122 100644 --- a/arch/arm64/boot/dts/qcom/sdmshrike-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/sdmshrike-pinctrl.dtsi @@ -2743,6 +2743,32 @@ }; }; + usb2phy_ac_en1_default: usb2phy_ac_en1_default { + mux { + pins = "gpio113"; + function = "usb2phy_ac"; + }; + + config { + pins = "gpio113"; + drive-strength = <2>; + bias-disable; + }; + }; + + usb2phy_ac_en2_default: usb2phy_ac_en2_default { + mux { + pins = "gpio123"; + function = "usb2phy_ac"; + }; + + config { + pins = "gpio123"; + drive-strength = <2>; + bias-disable; + }; + }; + audio_ioexp_reset_active: audio_ioexp_reset_active { mux { pins = "gpio166"; -- GitLab From 19ea40dfc90e2a817624432e523fa5e16d9a25df Mon Sep 17 00:00:00 2001 From: Yuan Zhao Date: Tue, 14 May 2019 22:14:44 +0800 Subject: [PATCH 0521/1121] ARM: dts: msm: Set mdss-dsi-ext-bridge for all bridge used devices Because we used a new property for extern bridge, need to enable it for all the used devices. Change-Id: I6a1671de68e30e48b85ce37bbc11855758b96874 Signed-off-by: Yuan Zhao --- arch/arm64/boot/dts/qcom/dsi-panel-ext-bridge-1080p.dtsi | 3 +-- arch/arm64/boot/dts/qcom/dsi-panel-ext-bridge-hdmi-1080p.dtsi | 3 +-- arch/arm64/boot/dts/qcom/qcs610-iot.dtsi | 3 +++ arch/arm64/boot/dts/qcom/sa6155-display.dtsi | 4 ++++ arch/arm64/boot/dts/qcom/sa8155-adp-star-display.dtsi | 2 ++ arch/arm64/boot/dts/qcom/sa8195p-adp-star-display.dtsi | 2 ++ arch/arm64/boot/dts/qcom/sm8150-hdk-overlay.dts | 4 ++++ 7 files changed, 17 insertions(+), 4 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/dsi-panel-ext-bridge-1080p.dtsi b/arch/arm64/boot/dts/qcom/dsi-panel-ext-bridge-1080p.dtsi index 0d518a6901eb..9347de7ecc7a 100644 --- a/arch/arm64/boot/dts/qcom/dsi-panel-ext-bridge-1080p.dtsi +++ b/arch/arm64/boot/dts/qcom/dsi-panel-ext-bridge-1080p.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -30,7 +30,6 @@ qcom,mdss-dsi-t-clk-post = <0x03>; qcom,mdss-dsi-t-clk-pre = <0x24>; qcom,mdss-dsi-force-clock-lane-hs; - qcom,mdss-dsi-ext-bridge-mode; qcom,mdss-dsi-display-timings { timing@0{ diff --git a/arch/arm64/boot/dts/qcom/dsi-panel-ext-bridge-hdmi-1080p.dtsi b/arch/arm64/boot/dts/qcom/dsi-panel-ext-bridge-hdmi-1080p.dtsi index 3d3362a4fcd9..ed9398f1cae6 100644 --- a/arch/arm64/boot/dts/qcom/dsi-panel-ext-bridge-hdmi-1080p.dtsi +++ b/arch/arm64/boot/dts/qcom/dsi-panel-ext-bridge-hdmi-1080p.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -30,7 +30,6 @@ qcom,mdss-dsi-t-clk-post = <0x18>; qcom,mdss-dsi-t-clk-pre = <0x1b>; qcom,mdss-dsi-force-clock-lane-hs; - qcom,mdss-dsi-ext-bridge-mode; qcom,mdss-dsi-display-timings { timing@0{ diff --git a/arch/arm64/boot/dts/qcom/qcs610-iot.dtsi b/arch/arm64/boot/dts/qcom/qcs610-iot.dtsi index 3d0c30f8c254..b23676e2e1c4 100644 --- a/arch/arm64/boot/dts/qcom/qcs610-iot.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs610-iot.dtsi @@ -406,6 +406,9 @@ }; }; +&dsi_ext_bridge_hdmi_1080p { + qcom,mdss-dsi-ext-bridge = <0>; +}; &soc { ext_dsi_bridge_display: qcom,dsi-display@50 { diff --git a/arch/arm64/boot/dts/qcom/sa6155-display.dtsi b/arch/arm64/boot/dts/qcom/sa6155-display.dtsi index 6de3f59a480c..8e203077e4c9 100644 --- a/arch/arm64/boot/dts/qcom/sa6155-display.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155-display.dtsi @@ -154,6 +154,10 @@ }; }; +&dsi_ext_bridge_1080p { + qcom,mdss-dsi-ext-bridge = <0>; +}; + &soc { dsi_anx_7625_1: qcom,dsi-display@17 { label = "dsi_anx_7625_1"; diff --git a/arch/arm64/boot/dts/qcom/sa8155-adp-star-display.dtsi b/arch/arm64/boot/dts/qcom/sa8155-adp-star-display.dtsi index e43df8e82220..1ab460283332 100644 --- a/arch/arm64/boot/dts/qcom/sa8155-adp-star-display.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8155-adp-star-display.dtsi @@ -186,6 +186,8 @@ #include "dsi-panel-ext-bridge-1080p.dtsi" &dsi_ext_bridge_1080p { + qcom,mdss-dsi-ext-bridge = <0>; + qcom,mdss-dsi-display-timings { timing@0{ qcom,mdss-dsi-panel-phy-timings = [00 1E 08 07 24 22 diff --git a/arch/arm64/boot/dts/qcom/sa8195p-adp-star-display.dtsi b/arch/arm64/boot/dts/qcom/sa8195p-adp-star-display.dtsi index 6b4a017ac2fc..24262a3a9614 100644 --- a/arch/arm64/boot/dts/qcom/sa8195p-adp-star-display.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8195p-adp-star-display.dtsi @@ -183,6 +183,8 @@ #include "dsi-panel-ext-bridge-1080p.dtsi" &dsi_ext_bridge_1080p { + qcom,mdss-dsi-ext-bridge = <0>; + qcom,mdss-dsi-display-timings { timing@0{ qcom,mdss-dsi-panel-phy-timings = [00 1E 08 07 24 22 diff --git a/arch/arm64/boot/dts/qcom/sm8150-hdk-overlay.dts b/arch/arm64/boot/dts/qcom/sm8150-hdk-overlay.dts index 23aefd9e6bab..e1580d227fd9 100644 --- a/arch/arm64/boot/dts/qcom/sm8150-hdk-overlay.dts +++ b/arch/arm64/boot/dts/qcom/sm8150-hdk-overlay.dts @@ -105,6 +105,10 @@ #include "dsi-panel-ext-bridge-hdmi-1080p.dtsi" +&dsi_ext_bridge_hdmi_1080p { + qcom,mdss-dsi-ext-bridge = <0>; +}; + &soc { ext_dsi_bridge_display: qcom,dsi-display@50 { label = "ext_dsi_bridge_display hdmi 1080p"; -- GitLab From c197c98c6e2b4f9ac1bf8f6b2372d851ad785201 Mon Sep 17 00:00:00 2001 From: Ziqi Chen Date: Wed, 5 Jun 2019 21:08:36 +0800 Subject: [PATCH 0522/1121] scsi: ufs: update VCCQ and VCCQ2 min value UFS 3.0 JEDEC already updated VCCQ2 min voltage from 1.65V to 1.7V and VCCQ min voltage from 1.1V to 1.14V. Correct them from hard code to follow UFS JEDEC. Change-Id: Icb44a23050c240cdc0ff22db04eb97e351f0ca94 Signed-off-by: Ziqi Chen --- drivers/scsi/ufs/ufs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h index 00df8861aeac..5ff6531c0b7d 100644 --- a/drivers/scsi/ufs/ufs.h +++ b/drivers/scsi/ufs/ufs.h @@ -462,9 +462,9 @@ struct ufs_query_res { #define UFS_VREG_VCC_MAX_UV 3600000 /* uV */ #define UFS_VREG_VCC_1P8_MIN_UV 1700000 /* uV */ #define UFS_VREG_VCC_1P8_MAX_UV 1950000 /* uV */ -#define UFS_VREG_VCCQ_MIN_UV 1100000 /* uV */ +#define UFS_VREG_VCCQ_MIN_UV 1140000 /* uV */ #define UFS_VREG_VCCQ_MAX_UV 1300000 /* uV */ -#define UFS_VREG_VCCQ2_MIN_UV 1650000 /* uV */ +#define UFS_VREG_VCCQ2_MIN_UV 1700000 /* uV */ #define UFS_VREG_VCCQ2_MAX_UV 1950000 /* uV */ /* -- GitLab From 64734b52c803d2e16f383bb9632ce42d35066431 Mon Sep 17 00:00:00 2001 From: Prateek Sood Date: Thu, 9 May 2019 13:52:17 +0530 Subject: [PATCH 0523/1121] ARM: dts: msm: Add modem pil node for atoll Add modem pil node to facilitate modem subsystem loading for atoll. Change-Id: I0abcf307be8b143aa1abc6cd99d87e18675b6a0f Signed-off-by: Prateek Sood Signed-off-by: Mayank Grover --- arch/arm64/boot/dts/qcom/atoll.dtsi | 37 +++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index 55fb60204fe7..67ee9366b35c 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -784,6 +784,43 @@ qcom,guard-memory; }; + pil_modem: qcom,mss@4080000 { + compatible = "qcom,pil-tz-generic"; + reg = <0x4080000 0x100>; + + qcom,firmware-name = "modem"; + memory-region = <&pil_modem_mem>; + qcom,proxy-timeout-ms = <10000>; + qcom,sysmon-id = <0>; + qcom,ssctl-instance-id = <0x12>; + qcom,pas-id = <4>; + qcom,smem-id = <421>; + qcom,signal-aop; + qcom,minidump-id = <3>; + qcom,complete-ramdump; + + /* Inputs from mss */ + interrupts-extended = <&pdc GIC_SPI 266 IRQ_TYPE_EDGE_RISING>, + <&modem_smp2p_in 0 IRQ_TYPE_NONE>, + <&modem_smp2p_in 1 IRQ_TYPE_NONE>, + <&modem_smp2p_in 2 IRQ_TYPE_NONE>, + <&modem_smp2p_in 3 IRQ_TYPE_NONE>, + <&modem_smp2p_in 7 IRQ_TYPE_NONE>; + + interrupt-names = "qcom,wdog", + "qcom,err-fatal", + "qcom,err-ready", + "qcom,proxy-unvote", + "qcom,stop-ack", + "qcom,shutdown-ack"; + /* Outputs to mss */ + qcom,smem-states = <&modem_smp2p_out 0>; + qcom,smem-state-names = "qcom,force-stop"; + + mboxes = <&qmp_aop 0>; + mbox-names = "mss-pil"; + }; + qcom,llcc@9200000 { compatible = "qcom,llcc-core", "syscon", "simple-mfd"; reg = <0x9200000 0x450000>; -- GitLab From 87c3311e386275cedcc85c9603de8ab036e920c6 Mon Sep 17 00:00:00 2001 From: Prateek Sood Date: Thu, 9 May 2019 16:26:38 +0530 Subject: [PATCH 0524/1121] ARM: dts: msm: Add cdsp pil node for atoll Add cdsp pil node to facilitate cdsp subsystem loading for atoll. Change-Id: Iaaa067209177ddf35d754084f7aeebddeca01010 Signed-off-by: Prateek Sood Signed-off-by: Mayank Grover --- arch/arm64/boot/dts/qcom/atoll.dtsi | 35 +++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index 67ee9366b35c..91cafd8f8fbc 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -821,6 +821,41 @@ mbox-names = "mss-pil"; }; + qcom,turing@8300000 { + compatible = "qcom,pil-tz-generic"; + reg = <0x8300000 0x100000>; + + qcom,pas-id = <18>; + qcom,proxy-timeout-ms = <10000>; + qcom,smem-id = <601>; + qcom,sysmon-id = <7>; + qcom,ssctl-instance-id = <0x17>; + qcom,firmware-name = "cdsp"; + memory-region = <&pil_cdsp_mem>; + qcom,signal-aop; + qcom,complete-ramdump; + + /* Inputs from turing */ + interrupts-extended = <&pdc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>, + <&cdsp_smp2p_in 0 0>, + <&cdsp_smp2p_in 1 0>, + <&cdsp_smp2p_in 2 0>, + <&cdsp_smp2p_in 3 0>; + + interrupt-names = "qcom,wdog", + "qcom,err-fatal", + "qcom,err-ready", + "qcom,proxy-unvote", + "qcom,stop-ack"; + + /* Outputs to turing */ + qcom,smem-states = <&cdsp_smp2p_out 0>; + qcom,smem-state-names = "qcom,force-stop"; + + mboxes = <&qmp_aop 0>; + mbox-names = "cdsp-pil"; + }; + qcom,llcc@9200000 { compatible = "qcom,llcc-core", "syscon", "simple-mfd"; reg = <0x9200000 0x450000>; -- GitLab From cc8090ec9fb1a312f1d56b8745233c3adff7a43d Mon Sep 17 00:00:00 2001 From: Mayank Grover Date: Fri, 24 May 2019 14:48:17 +0530 Subject: [PATCH 0525/1121] ARM: dts: msm: Add adsp pil node for atoll Add adsp pil node to facilitate adsp subsystem loading for atoll. Change-Id: Id0b54b3ab84fe29993869e44aa33ce8bb8d7b5ae Signed-off-by: Mayank Grover --- arch/arm64/boot/dts/qcom/atoll.dtsi | 35 +++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index 91cafd8f8fbc..66d5d3d65d7f 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -856,6 +856,41 @@ mbox-names = "cdsp-pil"; }; + qcom,lpass@62400000 { + compatible = "qcom,pil-tz-generic"; + reg = <0x62400000 0x00100>; + + qcom,pas-id = <1>; + qcom,proxy-timeout-ms = <10000>; + qcom,smem-id = <423>; + qcom,sysmon-id = <1>; + qcom,ssctl-instance-id = <0x14>; + qcom,firmware-name = "adsp"; + memory-region = <&pil_adsp_mem>; + qcom,signal-aop; + qcom,complete-ramdump; + + /* Inputs from lpass */ + interrupts-extended = <&pdc GIC_SPI 162 IRQ_TYPE_EDGE_RISING>, + <&adsp_smp2p_in 0 0>, + <&adsp_smp2p_in 1 0>, + <&adsp_smp2p_in 2 0>, + <&adsp_smp2p_in 3 0>; + + interrupt-names = "qcom,wdog", + "qcom,err-fatal", + "qcom,err-ready", + "qcom,proxy-unvote", + "qcom,stop-ack"; + + /* Outputs to lpass */ + qcom,smem-states = <&adsp_smp2p_out 0>; + qcom,smem-state-names = "qcom,force-stop"; + + mboxes = <&qmp_aop 0>; + mbox-names = "adsp-pil"; + }; + qcom,llcc@9200000 { compatible = "qcom,llcc-core", "syscon", "simple-mfd"; reg = <0x9200000 0x450000>; -- GitLab From 210bff9579c5348470b191ad3e14135179a31706 Mon Sep 17 00:00:00 2001 From: Ziqi Chen Date: Tue, 11 Jun 2019 14:44:03 +0800 Subject: [PATCH 0526/1121] ARM: dts: msm: keep UFS phy regulator always on for SM6150 We may see some glitch on UFS host TX when turning on/off the UFS PHY regulator, this change keeps this regulator always ON but still tries to keep the regulator in LPM mode. Change-Id: Ifcf6a7277db40bbdccba46819bcb553df8e54bcd Signed-off-by: Subhash Jadavani Signed-off-by: Ziqi Chen --- arch/arm64/boot/dts/qcom/sm6150-idp.dtsi | 1 + arch/arm64/boot/dts/qcom/sm6150-qrd.dtsi | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sm6150-idp.dtsi b/arch/arm64/boot/dts/qcom/sm6150-idp.dtsi index 2edb9047c145..82ef40d8a8d0 100644 --- a/arch/arm64/boot/dts/qcom/sm6150-idp.dtsi +++ b/arch/arm64/boot/dts/qcom/sm6150-idp.dtsi @@ -165,6 +165,7 @@ compatible = "qcom,ufs-phy-qmp-v3-660"; vdda-phy-supply = <&pm6150_l4>; /* 0.9v */ + vdda-phy-always-on; vdda-pll-supply = <&pm6150_l11>; vdda-phy-max-microamp = <30000>; vdda-pll-max-microamp = <12000>; diff --git a/arch/arm64/boot/dts/qcom/sm6150-qrd.dtsi b/arch/arm64/boot/dts/qcom/sm6150-qrd.dtsi index 96ac936751b9..8035667588db 100644 --- a/arch/arm64/boot/dts/qcom/sm6150-qrd.dtsi +++ b/arch/arm64/boot/dts/qcom/sm6150-qrd.dtsi @@ -86,6 +86,7 @@ compatible = "qcom,ufs-phy-qmp-v3-660"; vdda-phy-supply = <&pm6150_l4>; /* 0.9v */ + vdda-phy-always-on; vdda-pll-supply = <&pm6150_l11>; vdda-phy-max-microamp = <30000>; vdda-pll-max-microamp = <12000>; -- GitLab From 6d9712c59a49450a4b5099c7a82cadbde508a125 Mon Sep 17 00:00:00 2001 From: Yuanfang Zhang Date: Wed, 8 May 2019 18:17:21 +0800 Subject: [PATCH 0527/1121] Coresight-cti: add support to enable/disable multiple clks and regulators Some CTIs can go into power collapse when accessing CTI's register space, hence require a bunch of clks and regulators to be configured. This change add support in CIT driver to enable them when CTI is used for first time and disable them when CTI isn't used. Change-Id: Ia8a54cbc0f8363d19811c3a0712f5b8c23530b32 Signed-off-by: Yuanfang Zhang Signed-off-by: Mao Jinlong --- drivers/hwtracing/coresight/coresight-cti.c | 36 ++++++++++++++++----- drivers/hwtracing/coresight/coresight.c | 8 +++-- include/linux/coresight.h | 7 ++-- 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-cti.c b/drivers/hwtracing/coresight/coresight-cti.c index 6c036bc666dc..0d1d334f8de6 100644 --- a/drivers/hwtracing/coresight/coresight-cti.c +++ b/drivers/hwtracing/coresight/coresight-cti.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2017, 2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -382,20 +382,27 @@ int coresight_cti_map_trigin(struct coresight_cti *cti, int trig, int ch) ret = pm_runtime_get_sync(drvdata->dev); if (ret) goto err1; + ret = coresight_enable_reg_clk(drvdata->csdev); + if (ret) + goto err2; } spin_lock_irqsave(&drvdata->spinlock, flag); ret = cti_cpu_verify_access(drvdata); if (ret) - goto err2; + goto err3; __cti_map_trigin(drvdata, trig, ch); spin_unlock_irqrestore(&drvdata->spinlock, flag); mutex_unlock(&drvdata->mutex); return 0; -err2: +err3: spin_unlock_irqrestore(&drvdata->spinlock, flag); + + if (drvdata->refcnt == 0) + coresight_disable_reg_clk(drvdata->csdev); +err2: /* * We come here before refcnt is potentially modified in * __cti_map_trigin so it is safe to check it against 0 without @@ -466,20 +473,27 @@ int coresight_cti_map_trigout(struct coresight_cti *cti, int trig, int ch) ret = pm_runtime_get_sync(drvdata->dev); if (ret) goto err1; + ret = coresight_enable_reg_clk(drvdata->csdev); + if (ret) + goto err2; } spin_lock_irqsave(&drvdata->spinlock, flag); ret = cti_cpu_verify_access(drvdata); if (ret) - goto err2; + goto err3; __cti_map_trigout(drvdata, trig, ch); spin_unlock_irqrestore(&drvdata->spinlock, flag); mutex_unlock(&drvdata->mutex); return 0; -err2: +err3: spin_unlock_irqrestore(&drvdata->spinlock, flag); + + if (drvdata->refcnt == 0) + coresight_disable_reg_clk(drvdata->csdev); +err2: /* * We come here before refcnt is potentially incremented in * __cti_map_trigout so it is safe to check it against 0. @@ -562,8 +576,10 @@ void coresight_cti_unmap_trigin(struct coresight_cti *cti, int trig, int ch) * refcnt can be used here since in all cases its value is modified only * within the mutex lock region in addition to within the spinlock. */ - if (drvdata->refcnt == 0) + if (drvdata->refcnt == 0) { pm_runtime_put(drvdata->dev); + coresight_disable_reg_clk(drvdata->csdev); + } if (drvdata->gpio_trigin->trig == trig) cti_trigin_gpio_disable(drvdata); @@ -631,8 +647,10 @@ void coresight_cti_unmap_trigout(struct coresight_cti *cti, int trig, int ch) * refcnt can be used here since in all cases its value is modified only * within the mutex lock region in addition to within the spinlock. */ - if (drvdata->refcnt == 0) + if (drvdata->refcnt == 0) { pm_runtime_put(drvdata->dev); + coresight_disable_reg_clk(drvdata->csdev); + } if (drvdata->gpio_trigout->trig == trig) cti_trigout_gpio_disable(drvdata); @@ -694,8 +712,10 @@ void coresight_cti_reset(struct coresight_cti *cti) cti_trigout_gpio_disable(drvdata); } - if (refcnt) + if (refcnt) { pm_runtime_put(drvdata->dev); + coresight_disable_reg_clk(drvdata->csdev); + } mutex_unlock(&drvdata->mutex); return; err: diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c index 1c3015db9208..d90d74ff36a0 100644 --- a/drivers/hwtracing/coresight/coresight.c +++ b/drivers/hwtracing/coresight/coresight.c @@ -120,14 +120,14 @@ static void coresight_reset_all_sink(void) bus_for_each_dev(&coresight_bustype, NULL, NULL, coresight_reset_sink); } -void coresight_enable_reg_clk(struct coresight_device *csdev) +int coresight_enable_reg_clk(struct coresight_device *csdev) { struct coresight_reg_clk *reg_clk = csdev->reg_clk; int ret; int i, j; if (IS_ERR_OR_NULL(reg_clk)) - return; + return -EINVAL; for (i = 0; i < reg_clk->nr_reg; i++) { ret = regulator_enable(reg_clk->reg[i]); @@ -141,7 +141,7 @@ void coresight_enable_reg_clk(struct coresight_device *csdev) goto err_clks; } - return; + return 0; err_clks: for (j--; j >= 0; j--) @@ -149,6 +149,8 @@ void coresight_enable_reg_clk(struct coresight_device *csdev) err_regs: for (i--; i >= 0; i--) regulator_disable(reg_clk->reg[i]); + + return ret; } EXPORT_SYMBOL(coresight_enable_reg_clk); diff --git a/include/linux/coresight.h b/include/linux/coresight.h index 3266e07e1d7e..f4954a6389ae 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -278,7 +278,7 @@ extern int coresight_timeout(void __iomem *addr, u32 offset, int position, int value); extern void coresight_abort(void); extern void coresight_disable_reg_clk(struct coresight_device *csdev); -extern void coresight_enable_reg_clk(struct coresight_device *csdev); +extern int coresight_enable_reg_clk(struct coresight_device *csdev); #else static inline struct coresight_device * coresight_register(struct coresight_desc *desc) { return NULL; } @@ -290,7 +290,10 @@ static inline int coresight_timeout(void __iomem *addr, u32 offset, int position, int value) { return 1; } static inline void coresight_abort(void) {} static inline void coresight_disable_reg_clk(struct coresight_device *csdev) {} -static inline void coresight_enable_reg_clk(struct coresight_device *csdev) {} +static inline int coresight_enable_reg_clk(struct coresight_device *csdev) +{ + return -EINVAL; +} #endif #if defined(CONFIG_OF) && defined(CONFIG_CORESIGHT) -- GitLab From 91e04bf005c889c25a364d057376ae7783aa968b Mon Sep 17 00:00:00 2001 From: Mao Jinlong Date: Wed, 5 Jun 2019 16:04:29 +0800 Subject: [PATCH 0528/1121] ARM: dts: msm: Add clocks and regulators to gpu cti for trinket Need to vote the gpu clocks and regulators for gpu cti when enable and disable it. Change-Id: I01c023a607cd623086d1c21dc4ac52ef0fa13494 Signed-off-by: Mao Jinlong --- arch/arm64/boot/dts/qcom/trinket-coresight.dtsi | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/trinket-coresight.dtsi b/arch/arm64/boot/dts/qcom/trinket-coresight.dtsi index c23f23efc587..e991d4159b1a 100644 --- a/arch/arm64/boot/dts/qcom/trinket-coresight.dtsi +++ b/arch/arm64/boot/dts/qcom/trinket-coresight.dtsi @@ -2219,8 +2219,15 @@ coresight-name = "coresight-cti-gpu_isdb_cti"; - clocks = <&clock_rpmcc RPM_SMD_QDSS_CLK>; - clock-names = "apb_pclk"; + clocks = <&clock_rpmcc RPM_SMD_QDSS_CLK>, + <&clock_gpucc GPU_CC_CX_APB_CLK>; + clock-names = "apb_pclk", "gpu_apb_clk"; + qcom,proxy-clks = "gpu_apb_clk"; + + vddcx-supply = <&gpu_cx_gdsc>; + vdd-supply = <&gpu_gx_gdsc>; + regulator-names = "vddcx", "vdd"; + qcom,proxy-regs = "vddcx", "vdd"; }; cti_lpass_q6_cti: cti@8987000 { -- GitLab From 2a4070877a240d0a4471e579b066b2684f28251d Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Tue, 11 Jun 2019 12:18:38 +0530 Subject: [PATCH 0529/1121] msm: vidc: avoid bug on during noc error Video firmware may trigger system error with type NOC error. During such error handling, to get more debug information, system was intentionally made to reset. It is no more needed now and hence removing the same. Change-Id: I8a33911ee02f374c9279644998034b1f8eeeb0f8 Signed-off-by: Vikash Garodia --- drivers/media/platform/msm/vidc/msm_vidc_common.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c index 405d62fedc8f..747ce2286511 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_common.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c @@ -2247,10 +2247,6 @@ static void handle_sys_error(enum hal_command_response cmd, void *data) /* handle the hw error before core released to get full debug info */ msm_vidc_handle_hw_error(core); - if (response->status == VIDC_ERR_NOC_ERROR) { - dprintk(VIDC_WARN, "Got NOC error"); - MSM_VIDC_ERROR(true); - } dprintk(VIDC_DBG, "Calling core_release\n"); rc = call_hfi_op(hdev, core_release, hdev->hfi_device_data); -- GitLab From 3b4e4233f7c7bcb4fa8a712cffca484fdc28c317 Mon Sep 17 00:00:00 2001 From: Yu Wang Date: Wed, 5 Jun 2019 16:24:06 +0800 Subject: [PATCH 0530/1121] ARM: dts: msm: move cnss related nodes to board specific tree for sa8155 The configurations for external BT/WLAN devices are NOT SoC specific, but board specific. Therefore, move them from SoC device tree to board device tree. Change-Id: I000ca7addd7ebd20dfc36fb0bbdc051f9940ac58 Signed-off-by: Yu Wang --- .../boot/dts/qcom/sa8155-adp-common.dtsi | 5 +- arch/arm64/boot/dts/qcom/sa8155-cnss.dtsi | 350 ++++++++++++++++++ .../arm64/boot/dts/qcom/sa8155-regulator.dtsi | 31 +- arch/arm64/boot/dts/qcom/sa8155.dtsi | 310 ---------------- 4 files changed, 352 insertions(+), 344 deletions(-) create mode 100644 arch/arm64/boot/dts/qcom/sa8155-cnss.dtsi diff --git a/arch/arm64/boot/dts/qcom/sa8155-adp-common.dtsi b/arch/arm64/boot/dts/qcom/sa8155-adp-common.dtsi index 4e1b51afa74f..16e671cfb580 100644 --- a/arch/arm64/boot/dts/qcom/sa8155-adp-common.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8155-adp-common.dtsi @@ -14,6 +14,7 @@ #include #include "sa8155-pmic-overlay.dtsi" +#include "sa8155-cnss.dtsi" &qupv3_se0_spi { status = "ok"; @@ -163,10 +164,6 @@ linux,can-disable; }; }; - - bluetooth: bt_qca6174 { - status = "ok"; - }; }; &ufsphy_mem { diff --git a/arch/arm64/boot/dts/qcom/sa8155-cnss.dtsi b/arch/arm64/boot/dts/qcom/sa8155-cnss.dtsi new file mode 100644 index 000000000000..2fa828eba6fc --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sa8155-cnss.dtsi @@ -0,0 +1,350 @@ +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + /* Rome 3.3V supply */ + vreg_wlan: vreg_wlan { + compatible = "qcom,stub-regulator"; + regulator-name = "vreg_wlan"; + }; + + /* PWR_CTR2_VDD_1P8 supply */ + vreg_conn_1p8: vreg_conn_1p8 { + compatible = "regulator-fixed"; + regulator-name = "vreg_conn_1p8"; + pinctrl-names = "default"; + pinctrl-0 = <&conn_power_1p8_active>; + startup-delay-us = <4000>; + enable-active-high; + gpio = <&tlmm 173 0>; + }; + + /* PWR_CTR1_VDD_PA supply */ + vreg_conn_pa: vreg_conn_pa { + compatible = "regulator-fixed"; + regulator-name = "vreg_conn_pa"; + pinctrl-names = "default"; + pinctrl-0 = <&conn_power_pa_active>; + startup-delay-us = <4000>; + enable-active-high; + gpio = <&tlmm 174 0>; + }; + + bluetooth: bt_qca6174 { + compatible = "qca,qca6174"; + pinctrl-names = "default"; + pinctrl-0 = <&bt_en_active>; + /* BT_EN */ + qca,bt-reset-gpio = <&tlmm 172 0>; + /* PWR_CTR1_VDD_PA */ + qca,bt-vdd-pa-supply = <&vreg_conn_pa>; + /* PWR_CTR2_VDD_1P8 */ + qca,bt-chip-pwd-supply = <&vreg_conn_1p8>; + qca,bt-vdd-vl-supply = <&pm8150_1_s6>; + qca,bt-vdd-vm-supply = <&pm8150_2_s4>; + qca,bt-vdd-5c-supply = <&pm8150_2_s5>; + qca,bt-vdd-vh-supply = <&pm8150_2_l15>; + + qca,bt-vdd-vl-voltage-level = <1055000 1055000>; + qca,bt-vdd-vm-voltage-level = <1370000 1370000>; + qca,bt-vdd-5c-voltage-level = <2040000 2040000>; + qca,bt-vdd-vh-voltage-level = <1900000 1900000>; + + qca,bt-vdd-vl-current-level = <0>; + qca,bt-vdd-vm-current-level = <0>; + qca,bt-vdd-5c-current-level = <0>; + qca,bt-vdd-vh-current-level = <450000>; + }; + + qcom,cnss-qca6390@a0000000 { + status = "disabled"; + }; + + cnss_pcie: qcom,cnss-qca-converged { + compatible = "qcom,cnss-qca-converged"; + + qcom,converged-dt; + qcom,wlan-rc-num = <0>; + qcom,bus-type=<0>; + qcom,notify-modem-status; + qcom,msm-bus,name = "msm-cnss"; + qcom,msm-bus,num-cases = <4>; + qcom,msm-bus,num-paths = <2>; + qcom,msm-bus,vectors-KBps = + <45 512 0 0>, <1 512 0 0>, + /* Upto 200 Mbps */ + <45 512 41421 655360>, <1 512 41421 655360>, + /* Upto 400 Mbps */ + <45 512 98572 655360>, <1 512 98572 1600000>, + /* Upto 800 Mbps */ + <45 512 207108 1146880>, <1 512 207108 3124992>; + + #address-cells=<1>; + #size-cells=<1>; + ranges = <0x10000000 0x10000000 0x10000000>, + <0x20000000 0x20000000 0x10000>, + <0xa0000000 0xa0000000 0x10000000>, + <0xb0000000 0xb0000000 0x10000>; + + vdd-wlan-ctrl1-supply = <&vreg_conn_pa>; + vdd-wlan-ctrl2-supply = <&vreg_conn_1p8>; + vdd-wlan-supply = <&vreg_wlan>; + vdd-wlan-aon-supply = <&pm8150_1_s6>; + vdd-wlan-rfa1-supply = <&pm8150_2_s4>; + vdd-wlan-rfa2-supply = <&pm8150_2_s5>; + vdd-wlan-rfa3-supply = <&pm8150_2_l15>; + + wlan_vregs = "vdd-wlan-ctrl1", "vdd-wlan-ctrl2"; + qcom,vdd-wlan-ctrl1-info = <0 0 0 0>; + qcom,vdd-wlan-ctrl2-info = <0 0 0 0>; + wlan-en-gpio = <&tlmm 169 0>; + pinctrl-names = "wlan_en_active", "wlan_en_sleep"; + pinctrl-0 = <&cnss_wlan_en_active>; + pinctrl-1 = <&cnss_wlan_en_sleep>; + + chip_cfg@0 { + reg = <0x10000000 0x10000000>, + <0x20000000 0x10000>; + reg-names = "smmu_iova_base", "smmu_iova_ipa"; + + supported-ids = <0x003e>; + wlan_vregs = "vdd-wlan"; + qcom,vdd-wlan-info = <0 0 0 10>; + + qcom,smmu-s1-enable; + qcom,wlan-ramdump-dynamic = <0x200000>; + }; + + chip_cfg@1 { + reg = <0xa0000000 0x10000000>, + <0xb0000000 0x10000>; + reg-names = "smmu_iova_base", "smmu_iova_ipa"; + + supported-ids = <0x1101>; + wlan_vregs = "vdd-wlan-aon", "vdd-wlan-rfa1", + "vdd-wlan-rfa2", "vdd-wlan-rfa3"; + qcom,vdd-wlan-aon-info = <1055000 1055000 0 0>; + qcom,vdd-wlan-rfa1-info = <1370000 1370000 0 0>; + qcom,vdd-wlan-rfa2-info = <2040000 2040000 0 0>; + qcom,vdd-wlan-rfa3-info = <1900000 1900000 450000 0>; + + qcom,wlan-ramdump-dynamic = <0x400000>; + mhi,max-channels = <30>; + mhi,timeout = <10000>; + + mhi_channels { + #address-cells = <1>; + #size-cells = <0>; + mhi_chan@0 { + reg = <0>; + label = "LOOPBACK"; + mhi,num-elements = <32>; + mhi,event-ring = <1>; + mhi,chan-dir = <1>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x14>; + }; + + mhi_chan@1 { + reg = <1>; + label = "LOOPBACK"; + mhi,num-elements = <32>; + mhi,event-ring = <1>; + mhi,chan-dir = <2>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x14>; + }; + + mhi_chan@4 { + reg = <4>; + label = "DIAG"; + mhi,num-elements = <32>; + mhi,event-ring = <1>; + mhi,chan-dir = <1>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x14>; + }; + + mhi_chan@5 { + reg = <5>; + label = "DIAG"; + mhi,num-elements = <32>; + mhi,event-ring = <1>; + mhi,chan-dir = <2>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x14>; + }; + + mhi_chan@20 { + reg = <20>; + label = "IPCR"; + mhi,num-elements = <32>; + mhi,event-ring = <1>; + mhi,chan-dir = <1>; + mhi,data-type = <1>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x14>; + mhi,auto-start; + }; + + mhi_chan@21 { + reg = <21>; + label = "IPCR"; + mhi,num-elements = <32>; + mhi,event-ring = <1>; + mhi,chan-dir = <2>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x14>; + mhi,auto-queue; + mhi,auto-start; + }; + }; + + mhi_events { + mhi_event@0 { + mhi,num-elements = <32>; + mhi,intmod = <1>; + mhi,msi = <1>; + mhi,priority = <1>; + mhi,brstmode = <2>; + mhi,data-type = <1>; + }; + + mhi_event@1 { + mhi,num-elements = <256>; + mhi,intmod = <1>; + mhi,msi = <2>; + mhi,priority = <1>; + mhi,brstmode = <2>; + }; + }; + }; + + chip_cfg@2 { + reg = <0xa0000000 0x10000000>, + <0xb0000000 0x10000>; + reg-names = "smmu_iova_base", "smmu_iova_ipa"; + + supported-ids = <0x1102>; + wlan_vregs = "vdd-wlan-aon", "vdd-wlan-rfa1", + "vdd-wlan-rfa2", "vdd-wlan-rfa3"; + qcom,vdd-wlan-aon-info = <1055000 1055000 0 0>; + qcom,vdd-wlan-rfa1-info = <1370000 1370000 0 0>; + qcom,vdd-wlan-rfa2-info = <2040000 2040000 0 0>; + qcom,vdd-wlan-rfa3-info = <1900000 1900000 0 0>; + + qcom,wlan-ramdump-dynamic = <0x300000>; + mhi,max-channels = <30>; + mhi,timeout = <10000>; + mhi,ee = <0x3>, <0x4>; + mhi,ee-names = "SBL", "RDDM"; + mhi,bhie-offset = <0x0324>; + + mhi_channels { + #address-cells = <1>; + #size-cells = <0>; + mhi_chan@0 { + reg = <0>; + label = "LOOPBACK"; + mhi,num-elements = <32>; + mhi,event-ring = <1>; + mhi,chan-dir = <1>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x14>; + }; + + mhi_chan@1 { + reg = <1>; + label = "LOOPBACK"; + mhi,num-elements = <32>; + mhi,event-ring = <1>; + mhi,chan-dir = <2>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x14>; + }; + + mhi_chan@4 { + reg = <4>; + label = "DIAG"; + mhi,num-elements = <32>; + mhi,event-ring = <1>; + mhi,chan-dir = <1>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x14>; + }; + + mhi_chan@5 { + reg = <5>; + label = "DIAG"; + mhi,num-elements = <32>; + mhi,event-ring = <1>; + mhi,chan-dir = <2>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x14>; + }; + + mhi_chan@16 { + reg = <16>; + label = "IPCR"; + mhi,num-elements = <32>; + mhi,event-ring = <1>; + mhi,chan-dir = <1>; + mhi,data-type = <1>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x14>; + mhi,auto-start; + }; + + mhi_chan@17 { + reg = <17>; + label = "IPCR"; + mhi,num-elements = <32>; + mhi,event-ring = <1>; + mhi,chan-dir = <2>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x14>; + mhi,auto-queue; + mhi,auto-start; + }; + }; + + mhi_events { + mhi_event@0 { + mhi,num-elements = <32>; + mhi,intmod = <1>; + mhi,msi = <1>; + mhi,priority = <1>; + mhi,brstmode = <2>; + mhi,data-type = <1>; + }; + + mhi_event@1 { + mhi,num-elements = <256>; + mhi,intmod = <1>; + mhi,msi = <2>; + mhi,priority = <1>; + mhi,brstmode = <2>; + }; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/sa8155-regulator.dtsi b/arch/arm64/boot/dts/qcom/sa8155-regulator.dtsi index 02c9fe63a217..33e45516d62d 100644 --- a/arch/arm64/boot/dts/qcom/sa8155-regulator.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8155-regulator.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -723,33 +723,4 @@ qcom,init-mode = ; }; }; - - /* Rome 3.3V supply */ - vreg_wlan: vreg_wlan { - compatible = "qcom,stub-regulator"; - regulator-name = "vreg_wlan"; - }; - - /* PWR_CTR2_VDD_1P8 supply */ - vreg_conn_1p8: vreg_conn_1p8 { - compatible = "regulator-fixed"; - regulator-name = "vreg_conn_1p8"; - pinctrl-names = "default"; - pinctrl-0 = <&conn_power_1p8_active>; - startup-delay-us = <4000>; - enable-active-high; - gpio = <&tlmm 173 0>; - }; - - /* PWR_CTR1_VDD_PA supply */ - vreg_conn_pa: vreg_conn_pa { - compatible = "regulator-fixed"; - regulator-name = "vreg_conn_pa"; - pinctrl-names = "default"; - pinctrl-0 = <&conn_power_pa_active>; - startup-delay-us = <4000>; - enable-active-high; - gpio = <&tlmm 174 0>; - }; - }; diff --git a/arch/arm64/boot/dts/qcom/sa8155.dtsi b/arch/arm64/boot/dts/qcom/sa8155.dtsi index 41041505fa88..0efa2b9e1346 100644 --- a/arch/arm64/boot/dts/qcom/sa8155.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8155.dtsi @@ -63,34 +63,6 @@ /delete-node/ rpmh-regulator-ldof2; /delete-node/ rpmh-regulator-ldof5; /delete-node/ rpmh-regulator-ldof6; - - bluetooth: bt_qca6174 { - compatible = "qca,qca6174"; - pinctrl-names = "default"; - pinctrl-0 = <&bt_en_active>; - /* BT_EN */ - qca,bt-reset-gpio = <&tlmm 172 0>; - /* PWR_CTR1_VDD_PA */ - qca,bt-vdd-pa-supply = <&vreg_conn_pa>; - /* PWR_CTR2_VDD_1P8 */ - qca,bt-chip-pwd-supply = <&vreg_conn_1p8>; - qca,bt-vdd-vl-supply = <&pm8150_1_s6>; - qca,bt-vdd-vm-supply = <&pm8150_2_s4>; - qca,bt-vdd-5c-supply = <&pm8150_2_s5>; - qca,bt-vdd-vh-supply = <&pm8150_2_l15>; - - qca,bt-vdd-vl-voltage-level = <1055000 1055000>; - qca,bt-vdd-vm-voltage-level = <1370000 1370000>; - qca,bt-vdd-5c-voltage-level = <2040000 2040000>; - qca,bt-vdd-vh-voltage-level = <1900000 1900000>; - - qca,bt-vdd-vl-current-level = <0>; - qca,bt-vdd-vm-current-level = <0>; - qca,bt-vdd-5c-current-level = <0>; - qca,bt-vdd-vh-current-level = <450000>; - - status = "disabled"; - }; }; /* Add regulator nodes specific to SA8155 */ @@ -614,288 +586,6 @@ }; }; - qcom,cnss-qca6390@a0000000 { - status = "disabled"; - }; - - qcom,cnss-qca-converged { - compatible = "qcom,cnss-qca-converged"; - - qcom,converged-dt; - qcom,wlan-rc-num = <0>; - qcom,bus-type=<0>; - qcom,notify-modem-status; - qcom,msm-bus,name = "msm-cnss"; - qcom,msm-bus,num-cases = <4>; - qcom,msm-bus,num-paths = <2>; - qcom,msm-bus,vectors-KBps = - <45 512 0 0>, <1 512 0 0>, - /* Upto 200 Mbps */ - <45 512 41421 655360>, <1 512 41421 655360>, - /* Upto 400 Mbps */ - <45 512 98572 655360>, <1 512 98572 1600000>, - /* Upto 800 Mbps */ - <45 512 207108 1146880>, <1 512 207108 3124992>; - - #address-cells=<1>; - #size-cells=<1>; - ranges = <0x10000000 0x10000000 0x10000000>, - <0x20000000 0x20000000 0x10000>, - <0xa0000000 0xa0000000 0x10000000>, - <0xb0000000 0xb0000000 0x10000>; - - vdd-wlan-ctrl1-supply = <&vreg_conn_pa>; - vdd-wlan-ctrl2-supply = <&vreg_conn_1p8>; - vdd-wlan-supply = <&vreg_wlan>; - vdd-wlan-aon-supply = <&pm8150_1_s6>; - vdd-wlan-rfa1-supply = <&pm8150_2_s4>; - vdd-wlan-rfa2-supply = <&pm8150_2_s5>; - vdd-wlan-rfa3-supply = <&pm8150_2_l15>; - - wlan_vregs = "vdd-wlan-ctrl1", "vdd-wlan-ctrl2"; - qcom,vdd-wlan-ctrl1-info = <0 0 0 0>; - qcom,vdd-wlan-ctrl2-info = <0 0 0 0>; - wlan-en-gpio = <&tlmm 169 0>; - pinctrl-names = "wlan_en_active", "wlan_en_sleep"; - pinctrl-0 = <&cnss_wlan_en_active>; - pinctrl-1 = <&cnss_wlan_en_sleep>; - - chip_cfg@0 { - reg = <0x10000000 0x10000000>, - <0x20000000 0x10000>; - reg-names = "smmu_iova_base", "smmu_iova_ipa"; - - supported-ids = <0x003e>; - wlan_vregs = "vdd-wlan"; - qcom,vdd-wlan-info = <0 0 0 10>; - - qcom,smmu-s1-enable; - qcom,wlan-ramdump-dynamic = <0x200000>; - }; - - chip_cfg@1 { - reg = <0xa0000000 0x10000000>, - <0xb0000000 0x10000>; - reg-names = "smmu_iova_base", "smmu_iova_ipa"; - - supported-ids = <0x1101>; - wlan_vregs = "vdd-wlan-aon", "vdd-wlan-rfa1", - "vdd-wlan-rfa2", "vdd-wlan-rfa3"; - qcom,vdd-wlan-aon-info = <1055000 1055000 0 0>; - qcom,vdd-wlan-rfa1-info = <1370000 1370000 0 0>; - qcom,vdd-wlan-rfa2-info = <2040000 2040000 0 0>; - qcom,vdd-wlan-rfa3-info = <1900000 1900000 450000 0>; - - qcom,wlan-ramdump-dynamic = <0x400000>; - mhi,max-channels = <30>; - mhi,timeout = <10000>; - - mhi_channels { - #address-cells = <1>; - #size-cells = <0>; - mhi_chan@0 { - reg = <0>; - label = "LOOPBACK"; - mhi,num-elements = <32>; - mhi,event-ring = <1>; - mhi,chan-dir = <1>; - mhi,data-type = <0>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x14>; - }; - - mhi_chan@1 { - reg = <1>; - label = "LOOPBACK"; - mhi,num-elements = <32>; - mhi,event-ring = <1>; - mhi,chan-dir = <2>; - mhi,data-type = <0>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x14>; - }; - - mhi_chan@4 { - reg = <4>; - label = "DIAG"; - mhi,num-elements = <32>; - mhi,event-ring = <1>; - mhi,chan-dir = <1>; - mhi,data-type = <0>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x14>; - }; - - mhi_chan@5 { - reg = <5>; - label = "DIAG"; - mhi,num-elements = <32>; - mhi,event-ring = <1>; - mhi,chan-dir = <2>; - mhi,data-type = <0>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x14>; - }; - - mhi_chan@20 { - reg = <20>; - label = "IPCR"; - mhi,num-elements = <32>; - mhi,event-ring = <1>; - mhi,chan-dir = <1>; - mhi,data-type = <1>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x14>; - mhi,auto-start; - }; - - mhi_chan@21 { - reg = <21>; - label = "IPCR"; - mhi,num-elements = <32>; - mhi,event-ring = <1>; - mhi,chan-dir = <2>; - mhi,data-type = <0>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x14>; - mhi,auto-queue; - mhi,auto-start; - }; - }; - - mhi_events { - mhi_event@0 { - mhi,num-elements = <32>; - mhi,intmod = <1>; - mhi,msi = <1>; - mhi,priority = <1>; - mhi,brstmode = <2>; - mhi,data-type = <1>; - }; - - mhi_event@1 { - mhi,num-elements = <256>; - mhi,intmod = <1>; - mhi,msi = <2>; - mhi,priority = <1>; - mhi,brstmode = <2>; - }; - }; - }; - chip_cfg@2 { - reg = <0xa0000000 0x10000000>, - <0xb0000000 0x10000>; - reg-names = "smmu_iova_base", "smmu_iova_ipa"; - - supported-ids = <0x1102>; - wlan_vregs = "vdd-wlan-aon", "vdd-wlan-rfa1", - "vdd-wlan-rfa2", "vdd-wlan-rfa3"; - qcom,vdd-wlan-aon-info = <1055000 1055000 0 0>; - qcom,vdd-wlan-rfa1-info = <1370000 1370000 0 0>; - qcom,vdd-wlan-rfa2-info = <2040000 2040000 0 0>; - qcom,vdd-wlan-rfa3-info = <1900000 1900000 0 0>; - - qcom,wlan-ramdump-dynamic = <0x300000>; - mhi,max-channels = <30>; - mhi,timeout = <10000>; - mhi,ee = <0x3>, <0x4>; - mhi,ee-names = "SBL", "RDDM"; - mhi,bhie-offset = <0x0324>; - - mhi_channels { - #address-cells = <1>; - #size-cells = <0>; - mhi_chan@0 { - reg = <0>; - label = "LOOPBACK"; - mhi,num-elements = <32>; - mhi,event-ring = <1>; - mhi,chan-dir = <1>; - mhi,data-type = <0>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x14>; - }; - - mhi_chan@1 { - reg = <1>; - label = "LOOPBACK"; - mhi,num-elements = <32>; - mhi,event-ring = <1>; - mhi,chan-dir = <2>; - mhi,data-type = <0>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x14>; - }; - - mhi_chan@4 { - reg = <4>; - label = "DIAG"; - mhi,num-elements = <32>; - mhi,event-ring = <1>; - mhi,chan-dir = <1>; - mhi,data-type = <0>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x14>; - }; - - mhi_chan@5 { - reg = <5>; - label = "DIAG"; - mhi,num-elements = <32>; - mhi,event-ring = <1>; - mhi,chan-dir = <2>; - mhi,data-type = <0>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x14>; - }; - - mhi_chan@16 { - reg = <16>; - label = "IPCR"; - mhi,num-elements = <32>; - mhi,event-ring = <1>; - mhi,chan-dir = <1>; - mhi,data-type = <1>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x14>; - mhi,auto-start; - }; - - mhi_chan@17 { - reg = <17>; - label = "IPCR"; - mhi,num-elements = <32>; - mhi,event-ring = <1>; - mhi,chan-dir = <2>; - mhi,data-type = <0>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x14>; - mhi,auto-queue; - mhi,auto-start; - }; - }; - - mhi_events { - mhi_event@0 { - mhi,num-elements = <32>; - mhi,intmod = <1>; - mhi,msi = <1>; - mhi,priority = <1>; - mhi,brstmode = <2>; - mhi,data-type = <1>; - }; - - mhi_event@1 { - mhi,num-elements = <256>; - mhi,intmod = <1>; - mhi,msi = <2>; - mhi,priority = <1>; - mhi,brstmode = <2>; - }; - }; - }; - }; - qcom,rmnet-ipa { status="disabled"; }; -- GitLab From 3df8bc043f3cd8310248688ae9efd5d984a3a9cd Mon Sep 17 00:00:00 2001 From: Manoj Prabhu B Date: Sun, 9 Jun 2019 13:16:51 +0530 Subject: [PATCH 0531/1121] diag: Prevent switching mode for non mdlog process Switching the mode between USB and PCIE is incorrectly happening while closing non mdlog process. Patch prevents this issue case for non mdlog process by checking against the pid of the process which caused the switch between USB and PCIE. Change-Id: I609076633fe9dd20287cfc35f0098004bdd11618 Signed-off-by: Manoj Prabhu B --- drivers/char/diag/diagchar.h | 5 +++++ drivers/char/diag/diagchar_core.c | 35 ++++++++++++++++++++++++------- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h index a2e072360830..e46b9de8efa6 100644 --- a/drivers/char/diag/diagchar.h +++ b/drivers/char/diag/diagchar.h @@ -289,6 +289,10 @@ do { \ #define DIAG_NUM_PROC (1 + NUM_REMOTE_DEV) #endif +#define DIAG_MSM_MASK (0x0001) /* Bit mask for MSM */ +#define DIAG_MDM_MASK (0x0002) /* Bit mask for first mdm device */ +#define DIAG_MDM2_MASK (0x0004) /* Bit mask for second mdm device */ + #define DIAG_WS_DCI 0 #define DIAG_WS_MUX 1 @@ -685,6 +689,7 @@ struct diagchar_dev { int usb_connected; #endif int pcie_connected; + int pcie_switch_pid; struct workqueue_struct *diag_wq; struct work_struct diag_drain_work; struct work_struct update_user_clients; diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c index 37f39bf9a514..e4ee6b53107e 100644 --- a/drivers/char/diag/diagchar_core.c +++ b/drivers/char/diag/diagchar_core.c @@ -463,15 +463,20 @@ static void diag_close_logging_process(const int pid) session_info = diag_md_session_get_pid(pid); if (!session_info) { mutex_unlock(&driver->md_session_lock); - if (driver->pcie_transport_def == DIAG_ROUTE_TO_PCIE) - params.req_mode = PCIE_MODE; - else - params.req_mode = USB_MODE; - params.mode_param = 0; - params.pd_mask = 0; - params.peripheral_mask = DIAG_CON_ALL; mutex_lock(&driver->diagchar_mutex); - diag_switch_logging(¶ms); + if (driver->pcie_switch_pid == pid) { + if (driver->pcie_transport_def == + DIAG_ROUTE_TO_PCIE) + params.req_mode = PCIE_MODE; + else + params.req_mode = USB_MODE; + params.mode_param = 0; + params.pd_mask = 0; + params.device_mask = DIAG_MSM_MASK; + params.peripheral_mask = DIAG_CON_ALL; + diag_switch_logging(¶ms); + driver->pcie_switch_pid = 0; + } mutex_unlock(&driver->diagchar_mutex); return; } @@ -1935,6 +1940,19 @@ static int diag_switch_logging(struct diag_logging_mode_param_t *param) } driver->logging_mode[proc] = new_mode; driver->logging_mask[proc] = peripheral_mask; + if (((curr_mode == DIAG_PCIE_MODE && + new_mode == DIAG_USB_MODE) || + (curr_mode == DIAG_USB_MODE && + new_mode == DIAG_PCIE_MODE)) && + !driver->pcie_switch_pid) { + /* + * Store the pid of process affecting switch + * from USB to PCIE or vice versa to help + * close only this process while closing + * logging process. + */ + driver->pcie_switch_pid = current->tgid; + } if (new_mode == DIAG_PCIE_MODE) { driver->transport_set = DIAG_ROUTE_TO_PCIE; diagmem_setsize(POOL_TYPE_MUX_APPS, @@ -4332,6 +4350,7 @@ static int __init diagchar_init(void) driver->mask_check = 0; driver->in_busy_pktdata = 0; driver->in_busy_dcipktdata = 0; + driver->pcie_switch_pid = 0; driver->rsp_buf_ctxt = SET_BUF_CTXT(APPS_DATA, TYPE_CMD, TYPE_CMD); hdlc_data.ctxt = SET_BUF_CTXT(APPS_DATA, TYPE_DATA, 1); hdlc_data.len = 0; -- GitLab From 8f2bcb7ba2b195626ef2bc43a011733cdde496a9 Mon Sep 17 00:00:00 2001 From: Yu Wang Date: Tue, 19 Mar 2019 10:30:59 +0800 Subject: [PATCH 0532/1121] ARM: dts: msm: move cnss related nodes to board device tree for sa6155 The configurations for external BT/WLAN devices are NOT SoC specific, but board specific. Therefore, move them from SoC device tree to board device tree. Change-Id: Ifd7be297d6477e5d94564106218c41e0b2fae726 Signed-off-by: Yu Wang --- arch/arm64/boot/dts/qcom/sa6155-adp-air.dtsi | 7 +- arch/arm64/boot/dts/qcom/sa6155-adp-star.dtsi | 7 +- arch/arm64/boot/dts/qcom/sa6155-cnss.dtsi | 223 ++++++++++++++++++ .../arm64/boot/dts/qcom/sa6155-regulator.dtsi | 23 -- arch/arm64/boot/dts/qcom/sa6155.dts | 3 +- arch/arm64/boot/dts/qcom/sa6155.dtsi | 30 --- arch/arm64/boot/dts/qcom/sa6155p.dts | 3 +- arch/arm64/boot/dts/qcom/sa6155p.dtsi | 57 +---- 8 files changed, 236 insertions(+), 117 deletions(-) create mode 100644 arch/arm64/boot/dts/qcom/sa6155-cnss.dtsi diff --git a/arch/arm64/boot/dts/qcom/sa6155-adp-air.dtsi b/arch/arm64/boot/dts/qcom/sa6155-adp-air.dtsi index d0ebb604d858..ba6c68a60bb5 100644 --- a/arch/arm64/boot/dts/qcom/sa6155-adp-air.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155-adp-air.dtsi @@ -11,7 +11,11 @@ */ #include #include +#include "sa6155-cnss.dtsi" +&bluetooth_ext { + status = "ok"; +}; &qupv3_se6_spi { status = "ok"; @@ -120,9 +124,6 @@ }; }; - bluetooth_ext: bt_qca6174 { - status = "ok"; - }; }; &ufsphy_mem { diff --git a/arch/arm64/boot/dts/qcom/sa6155-adp-star.dtsi b/arch/arm64/boot/dts/qcom/sa6155-adp-star.dtsi index a1342376bdff..9c9908c51f6c 100644 --- a/arch/arm64/boot/dts/qcom/sa6155-adp-star.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155-adp-star.dtsi @@ -11,7 +11,11 @@ */ #include #include +#include "sa6155-cnss.dtsi" +&bluetooth_ext { + status = "ok"; +}; &qupv3_se6_spi { status = "ok"; @@ -120,9 +124,6 @@ }; }; - bluetooth_ext: bt_qca6174 { - status = "ok"; - }; }; &ufsphy_mem { diff --git a/arch/arm64/boot/dts/qcom/sa6155-cnss.dtsi b/arch/arm64/boot/dts/qcom/sa6155-cnss.dtsi new file mode 100644 index 000000000000..948571cab28c --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sa6155-cnss.dtsi @@ -0,0 +1,223 @@ +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + /* PWR_CTR1_VDD_1P8 supply */ + vreg_conn_1p8: vreg_conn_1p8 { + compatible = "regulator-fixed"; + regulator-name = "vreg_conn_1p8"; + startup-delay-us = <4000>; + enable-active-high; + gpio = <&pm6155_1_gpios 1 0>; + }; + + /* PWR_CTR2_VDD_PA supply */ + vreg_conn_pa: vreg_conn_pa { + compatible = "regulator-fixed"; + regulator-name = "vreg_conn_pa"; + startup-delay-us = <4000>; + enable-active-high; + gpio = <&pm6155_1_gpios 6 0>; + }; + + vreg_wlan: vreg_wlan { + compatible = "qcom,stub-regulator"; + regulator-name = "vreg_wlan"; + }; + + bluetooth_ext: bt_qca6174 { + compatible = "qca,qca6174"; + /* BT_EN */ + pinctrl-names = "default"; + pinctrl-0 = <&bt_en_active>; + qca,bt-reset-gpio = <&tlmm 85 0>; + /* PWR_CTR1_VDD_PA */ + qca,bt-vdd-pa-supply = <&vreg_conn_pa>; + qca,bt-chip-pwd-supply = <&vreg_conn_1p8>; + qca,bt-vdd-vm-supply = <&pm6155_1_s6>; + qca,bt-vdd-5a-supply = <&pm6155_1_s5>; + qca,bt-vdd-vh-supply = <&pm6155_1_l15>; + + qca,bt-vdd-vm-voltage-level = <1370000 1370000>; + qca,bt-vdd-5a-voltage-level = <2040000 2040000>; + qca,bt-vdd-vh-voltage-level = <1904000 1904000>; + + qca,bt-vdd-vm-current-level = <0>; + qca,bt-vdd-5a-current-level = <0>; + qca,bt-vdd-vh-current-level = <450000>; + + status = "disabled"; + }; + + cnss_pcie: qcom,cnss-qca-converged { + compatible = "qcom,cnss-qca-converged"; + + qcom,converged-dt; + qcom,wlan-rc-num = <0>; + qcom,bus-type=<0>; + qcom,notify-modem-status; + qcom,msm-bus,name = "msm-cnss"; + qcom,msm-bus,num-cases = <4>; + qcom,msm-bus,num-paths = <2>; + qcom,msm-bus,vectors-KBps = + <45 512 0 0>, <1 512 0 0>, + /* Upto 200 Mbps */ + <45 512 41421 655360>, <1 512 41421 655360>, + /* Upto 400 Mbps */ + <45 512 98572 655360>, <1 512 98572 1600000>, + /* Upto 800 Mbps */ + <45 512 207108 1146880>, <1 512 207108 3124992>; + + #address-cells=<1>; + #size-cells=<1>; + ranges = <0x10000000 0x10000000 0x10000000>, + <0x20000000 0x20000000 0x10000>, + <0xa0000000 0xa0000000 0x10000000>, + <0xb0000000 0xb0000000 0x10000>; + + vdd-wlan-ctrl1-supply = <&vreg_conn_pa>; + vdd-wlan-ctrl2-supply = <&vreg_conn_1p8>; + vdd-wlan-supply = <&vreg_wlan>; + vdd-wlan-rfa1-supply = <&pm6155_1_s6>; + vdd-wlan-rfa2-supply = <&pm6155_1_s5>; + vdd-wlan-rfa3-supply = <&pm6155_1_l15>; + + wlan_vregs = "vdd-wlan-ctrl1", "vdd-wlan-ctrl2"; + qcom,vdd-wlan-ctrl1-info = <0 0 0 0>; + qcom,vdd-wlan-ctrl2-info = <0 0 0 0>; + + wlan-en-gpio = <&tlmm 98 0>; + pinctrl-names = "wlan_en_active", "wlan_en_sleep"; + pinctrl-0 = <&cnss_wlan_en_active>; + pinctrl-1 = <&cnss_wlan_en_sleep>; + + chip_cfg@0 { + reg = <0x10000000 0x10000000>, + <0x20000000 0x10000>; + reg-names = "smmu_iova_base", "smmu_iova_ipa"; + + supported-ids = <0x003e>; + wlan_vregs = "vdd-wlan"; + qcom,vdd-wlan-info = <0 0 0 10>; + + qcom,smmu-s1-enable; + qcom,wlan-ramdump-dynamic = <0x200000>; + }; + + chip_cfg@1 { + reg = <0xa0000000 0x10000000>, + <0xb0000000 0x10000>; + reg-names = "smmu_iova_base", "smmu_iova_ipa"; + + supported-ids = <0x1101>; + wlan_vregs = "vdd-wlan-rfa1", "vdd-wlan-rfa2", + "vdd-wlan-rfa3"; + qcom,vdd-wlan-rfa1-info = <1350000 1350000 0 0>; + qcom,vdd-wlan-rfa2-info = <2040000 2040000 0 0>; + qcom,vdd-wlan-rfa3-info = <1904000 1904000 0 0>; + + qcom,wlan-ramdump-dynamic = <0x400000>; + mhi,max-channels = <30>; + mhi,timeout = <10000>; + + mhi_channels { + mhi_chan@0 { + reg = <0>; + label = "LOOPBACK"; + mhi,num-elements = <32>; + mhi,event-ring = <1>; + mhi,chan-dir = <1>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x14>; + }; + + mhi_chan@1 { + reg = <1>; + label = "LOOPBACK"; + mhi,num-elements = <32>; + mhi,event-ring = <1>; + mhi,chan-dir = <2>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x14>; + }; + + mhi_chan@4 { + reg = <4>; + label = "DIAG"; + mhi,num-elements = <32>; + mhi,event-ring = <1>; + mhi,chan-dir = <1>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x14>; + }; + + mhi_chan@5 { + reg = <5>; + label = "DIAG"; + mhi,num-elements = <32>; + mhi,event-ring = <1>; + mhi,chan-dir = <2>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x14>; + }; + + mhi_chan@20 { + reg = <20>; + label = "IPCR"; + mhi,num-elements = <32>; + mhi,event-ring = <1>; + mhi,chan-dir = <1>; + mhi,data-type = <1>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x14>; + mhi,auto-start; + }; + + mhi_chan@21 { + reg = <21>; + label = "IPCR"; + mhi,num-elements = <32>; + mhi,event-ring = <1>; + mhi,chan-dir = <2>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x14>; + mhi,auto-queue; + mhi,auto-start; + }; + }; + + mhi_events { + mhi_event@0 { + mhi,num-elements = <32>; + mhi,intmod = <1>; + mhi,msi = <1>; + mhi,priority = <1>; + mhi,brstmode = <2>; + mhi,data-type = <1>; + }; + + mhi_event@1 { + mhi,num-elements = <256>; + mhi,intmod = <1>; + mhi,msi = <2>; + mhi,priority = <1>; + mhi,brstmode = <2>; + }; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/sa6155-regulator.dtsi b/arch/arm64/boot/dts/qcom/sa6155-regulator.dtsi index f03a12391c4a..b7745ffd32da 100644 --- a/arch/arm64/boot/dts/qcom/sa6155-regulator.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155-regulator.dtsi @@ -533,28 +533,5 @@ qcom,init-mode = ; }; }; - - /* PWR_CTR1_VDD_1P8 supply */ - vreg_conn_1p8: vreg_conn_1p8 { - compatible = "regulator-fixed"; - regulator-name = "vreg_conn_1p8"; - startup-delay-us = <4000>; - enable-active-high; - gpio = <&pm6155_1_gpios 1 0>; - }; - - /* PWR_CTR2_VDD_PA supply */ - vreg_conn_pa: vreg_conn_pa { - compatible = "regulator-fixed"; - regulator-name = "vreg_conn_pa"; - startup-delay-us = <4000>; - enable-active-high; - gpio = <&pm6155_1_gpios 6 0>; - }; - - vreg_wlan: vreg_wlan { - compatible = "qcom,stub-regulator"; - regulator-name = "vreg_wlan"; - }; }; diff --git a/arch/arm64/boot/dts/qcom/sa6155.dts b/arch/arm64/boot/dts/qcom/sa6155.dts index 0494f3f96a36..7ee1fede6906 100644 --- a/arch/arm64/boot/dts/qcom/sa6155.dts +++ b/arch/arm64/boot/dts/qcom/sa6155.dts @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -13,6 +13,7 @@ /dts-v1/; #include "sa6155.dtsi" +#include "sa6155-cnss.dtsi" / { model = "Qualcomm Technologies, Inc. SA6155 SoC"; diff --git a/arch/arm64/boot/dts/qcom/sa6155.dtsi b/arch/arm64/boot/dts/qcom/sa6155.dtsi index ff6c4b6f79f5..dfb7d0c3b268 100644 --- a/arch/arm64/boot/dts/qcom/sa6155.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155.dtsi @@ -89,36 +89,6 @@ #include "sa6155-pcie.dtsi" &soc { - cnss_pcie: qcom,cnss { - compatible = "qcom,cnss"; - wlan-en-gpio = <&tlmm 98 0>; - vdd-wlan-supply = <&vreg_wlan>; - vdd-wlan-io-supply = <&pm6155_1_s4>; - vdd-wlan-ctrl1-supply = <&vreg_conn_pa>; - vdd-wlan-ctrl2-supply = <&vreg_conn_1p8>; - reg = <0x10000000 0x10000000>, - <0x20000000 0x10000>; - reg-names = "smmu_iova_base", "smmu_iova_ipa"; - qcom,notify-modem-status; - pinctrl-names = "wlan_en_active", "wlan_en_sleep"; - pinctrl-0 = <&cnss_wlan_en_active>; - pinctrl-1 = <&cnss_wlan_en_sleep>; - qcom,wlan-rc-num = <0>; - qcom,wlan-ramdump-dynamic = <0x200000>; - - qcom,msm-bus,name = "msm-cnss"; - qcom,msm-bus,num-cases = <4>; - qcom,msm-bus,num-paths = <2>; - qcom,msm-bus,vectors-KBps = - <45 512 0 0>, <1 512 0 0>, - /* Upto 200 Mbps */ - <45 512 41421 655360>, <1 512 41421 655360>, - /* Upto 400 Mbps */ - <45 512 98572 655360>, <1 512 98572 1600000>, - /* Upto 800 Mbps */ - <45 512 207108 1146880>, <1 512 207108 3124992>; - qcom,smmu-s1-enable; - }; qfprom: qfprom@780130 { compatible = "qcom,qfprom"; reg = <0x00780130 0x4>; diff --git a/arch/arm64/boot/dts/qcom/sa6155p.dts b/arch/arm64/boot/dts/qcom/sa6155p.dts index 371125467fd6..980ec1b96776 100644 --- a/arch/arm64/boot/dts/qcom/sa6155p.dts +++ b/arch/arm64/boot/dts/qcom/sa6155p.dts @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -13,6 +13,7 @@ /dts-v1/; #include "sa6155p.dtsi" +#include "sa6155-cnss.dtsi" / { model = "Qualcomm Technologies, Inc. SA6155P SoC"; diff --git a/arch/arm64/boot/dts/qcom/sa6155p.dtsi b/arch/arm64/boot/dts/qcom/sa6155p.dtsi index 1180a756c733..ca669db10029 100644 --- a/arch/arm64/boot/dts/qcom/sa6155p.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155p.dtsi @@ -13,8 +13,8 @@ #include "sm6150.dtsi" #include "sa6155-pmic.dtsi" #include "sa6155-display.dtsi" - #include "sm6150-camera-sensor-adp.dtsi" + / { model = "Qualcomm Technologies, Inc. SA6155P"; qcom,msm-name = "SA6155P"; @@ -43,61 +43,6 @@ /delete-node/ rpmh-regulator-ldoc18; /delete-node/ bt_wcn3990; - bluetooth_ext: bt_qca6174 { - compatible = "qca,qca6174"; - /* BT_EN */ - pinctrl-names = "default"; - pinctrl-0 = <&bt_en_active>; - qca,bt-reset-gpio = <&tlmm 85 0>; - /* PWR_CTR1_VDD_PA */ - qca,bt-vdd-pa-supply = <&vreg_conn_pa>; - qca,bt-chip-pwd-supply = <&vreg_conn_1p8>; - qca,bt-vdd-vm-supply = <&pm6155_1_s6>; - qca,bt-vdd-5a-supply = <&pm6155_1_s5>; - qca,bt-vdd-vh-supply = <&pm6155_1_l15>; - - qca,bt-vdd-vm-voltage-level = <1370000 1370000>; - qca,bt-vdd-5a-voltage-level = <2040000 2040000>; - qca,bt-vdd-vh-voltage-level = <1904000 1904000>; - - qca,bt-vdd-vm-current-level = <0>; - qca,bt-vdd-5a-current-level = <0>; - qca,bt-vdd-vh-current-level = <450000>; - - status = "disabled"; - }; - - cnss_pcie: qcom,cnss { - compatible = "qcom,cnss"; - wlan-en-gpio = <&tlmm 98 0>; - vdd-wlan-supply = <&vreg_wlan>; - vdd-wlan-io-supply = <&pm6155_1_s4>; - vdd-wlan-ctrl1-supply = <&vreg_conn_pa>; - vdd-wlan-ctrl2-supply = <&vreg_conn_1p8>; - reg = <0x10000000 0x10000000>, - <0x20000000 0x10000>; - reg-names = "smmu_iova_base", "smmu_iova_ipa"; - qcom,smmu-s1-enable; - qcom,notify-modem-status; - pinctrl-names = "wlan_en_active", "wlan_en_sleep"; - pinctrl-0 = <&cnss_wlan_en_active>; - pinctrl-1 = <&cnss_wlan_en_sleep>; - qcom,wlan-rc-num = <0>; - qcom,wlan-ramdump-dynamic = <0x200000>; - - qcom,msm-bus,name = "msm-cnss"; - qcom,msm-bus,num-cases = <4>; - qcom,msm-bus,num-paths = <2>; - qcom,msm-bus,vectors-KBps = - <45 512 0 0>, <1 512 0 0>, - /* Upto 200 Mbps */ - <45 512 41421 655360>, <1 512 41421 655360>, - /* Upto 400 Mbps */ - <45 512 98572 655360>, <1 512 98572 1600000>, - /* Upto 800 Mbps */ - <45 512 207108 1146880>, <1 512 207108 3124992>; - }; - qcom,rmnet-ipa { status="disabled"; }; -- GitLab From ff9515b806512f8eb92b44826402da6295ed4fa7 Mon Sep 17 00:00:00 2001 From: raghavendra ambadas Date: Wed, 22 May 2019 17:14:21 +0530 Subject: [PATCH 0533/1121] fbdev: msm: check the length of the external input buffer properly dchdr->dlen is a short variable controlled by the user-provided data. If the value is negative, loop continues, also increasing the value of "len". As a result buffer overflow occurs. So define the len as unsigned and check with length of string input from user space. Change-Id: I8bb9ab33d543c826eb330e16ae116385d823ca98 Signed-off-by: raghavendra ambadas Signed-off-by: Ritesh Kumar --- drivers/video/fbdev/msm/mdss_dsi.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c index bdd616aaa6ec..ba3ed70eb042 100644 --- a/drivers/video/fbdev/msm/mdss_dsi.c +++ b/drivers/video/fbdev/msm/mdss_dsi.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -905,7 +905,8 @@ static ssize_t mdss_dsi_cmd_write(struct file *file, const char __user *p, static int mdss_dsi_cmd_flush(struct file *file, fl_owner_t id) { struct buf_data *pcmds = file->private_data; - int blen, len, i; + unsigned int len; + int blen, i; char *buf, *bufp, *bp; struct dsi_ctrl_hdr *dchdr; @@ -949,7 +950,7 @@ static int mdss_dsi_cmd_flush(struct file *file, fl_owner_t id) while (len >= sizeof(*dchdr)) { dchdr = (struct dsi_ctrl_hdr *)bp; dchdr->dlen = ntohs(dchdr->dlen); - if (dchdr->dlen > len || dchdr->dlen < 0) { + if (dchdr->dlen > (len - sizeof(*dchdr)) || dchdr->dlen < 0) { pr_err("%s: dtsi cmd=%x error, len=%d\n", __func__, dchdr->dtype, dchdr->dlen); kfree(buf); -- GitLab From 08641a16018f4c9e75bdc5ad7ec19569f6d9ad55 Mon Sep 17 00:00:00 2001 From: Shankar Ravi Date: Mon, 10 Jun 2019 14:31:20 +0530 Subject: [PATCH 0534/1121] ARM: dts: msm: Add new nodes for triple camera for sm6150 1. Add sensor nodes for tele and ultrawide camera. 2. Add eeprom, actuators and flash fro triple camera. Change-Id: I277a3aa37be717b33dae50cb84ab2982903a6e31 Signed-off-by: Shankar Ravi --- .../dts/qcom/sm6150-camera-sensor-idp.dtsi | 191 +++++++++++++++++- 1 file changed, 190 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sm6150-camera-sensor-idp.dtsi b/arch/arm64/boot/dts/qcom/sm6150-camera-sensor-idp.dtsi index 1301850794aa..c29345c7cbcb 100644 --- a/arch/arm64/boot/dts/qcom/sm6150-camera-sensor-idp.dtsi +++ b/arch/arm64/boot/dts/qcom/sm6150-camera-sensor-idp.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -47,6 +47,16 @@ pinctrl-0 = <&flash_led3_front_en>; }; + led_flash_rear_aux2: qcom,camera-flash@3 { + cell-index = <3>; + reg = <0x03 0x00>; + compatible = "qcom,camera-flash"; + flash-source = <&pm6150l_flash0 &pm6150l_flash1>; + torch-source = <&pm6150l_torch0 &pm6150l_torch1>; + switch-source = <&pm6150l_switch2 &pm6150l_switch2>; + status = "ok"; + }; + camera_ldo: gpio-regulator@0 { compatible = "regulator-fixed"; reg = <0x00 0x00>; @@ -135,6 +145,19 @@ rgltr-load-current = <100000>; }; + actuator_triple_tele: qcom,actuator@3 { + cell-index = <3>; + reg = <0x3>; + compatible = "qcom,actuator"; + cci-master = <0>; + cam_vaf-supply = <&pm6150_l19>; + regulator-names = "cam_vaf"; + rgltr-cntrl-support; + rgltr-min-voltage = <2800000>; + rgltr-max-voltage = <2800000>; + rgltr-load-current = <100000>; + }; + ois_rear: qcom,ois@0 { cell-index = <0>; reg = <0x0>; @@ -260,6 +283,43 @@ clock-rates = <24000000>; }; + eeprom_triple_rear_aux: qcom,eeprom@3 { + cell-index = <3>; + reg = <3>; + compatible = "qcom,eeprom"; + cam_vio-supply = <&pm6150_l13>; + cam_vana-supply = <&camera_vana0_ldo>; + cam_vdig-supply = <&camera_ldo>; + cam_clk-supply = <&titan_top_gdsc>; + cam_vaf-supply = <&pm6150_l19>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", + "cam_clk", "cam_vaf"; + rgltr-cntrl-support; + rgltr-min-voltage = <1800000 2850000 1200000 0 2800000>; + rgltr-max-voltage = <1800000 2850000 1200000 0 2800000>; + rgltr-load-current = <0 80000 105000 0 100000>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_active + &cam_sensor_rear_active>; + pinctrl-1 = <&cam_sensor_mclk0_suspend + &cam_sensor_rear_suspend>; + gpios = <&tlmm 28 0>, + <&tlmm 47 0>; + gpio-reset = <1>; + gpio-req-tbl-num = <0 1>; + gpio-req-tbl-flags = <1 0>; + gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET0"; + sensor-mode = <0>; + cci-master = <0>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK0_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <24000000>; + }; + qcom,cam-sensor@0 { cell-index = <0>; compatible = "qcom,cam-sensor"; @@ -432,4 +492,133 @@ clock-cntl-level = "turbo"; clock-rates = <24000000>; }; + + qcom,cam-sensor@4 { + cell-index = <4>; + compatible = "qcom,cam-sensor"; + reg = <0x4>; + csiphy-sd-index = <0>; + sensor-position-roll = <90>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + led-flash-src = <&led_flash_rear>; + actuator-src = <&actuator_rear>; + eeprom-src = <&eeprom_rear>; + cam_vio-supply = <&pm6150_l13>; + cam_vana-supply = <&camera_vana0_ldo>; + cam_vdig-supply = <&camera_ldo>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", + "cam_clk"; + rgltr-cntrl-support; + rgltr-min-voltage = <1800000 2850000 1200000 0>; + rgltr-max-voltage = <1800000 2850000 1200000 0>; + rgltr-load-current = <0 80000 105000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_active + &cam_sensor_rear_active>; + pinctrl-1 = <&cam_sensor_mclk0_suspend + &cam_sensor_rear_suspend>; + gpios = <&tlmm 28 0>, + <&tlmm 47 0>; + gpio-reset = <1>; + gpio-req-tbl-num = <0 1>; + gpio-req-tbl-flags = <1 0>; + gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET0"; + sensor-mode = <0>; + cci-master = <0>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK0_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <24000000>; + }; + + qcom,cam-sensor@5 { + cell-index = <5>; + compatible = "qcom,cam-sensor"; + reg = <0x5>; + csiphy-sd-index = <1>; + sensor-position-roll = <90>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + led-flash-src = <&led_flash_rear_aux>; + actuator-src = <&actuator_triple_tele>; + eeprom-src = <&eeprom_triple_rear_aux>; + cam_vio-supply = <&pm6150_l13>; + cam_vana-supply = <&camera_vana1_2_ldo>; + cam_vdig-supply = <&camera_ldo>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", + "cam_clk"; + rgltr-cntrl-support; + rgltr-min-voltage = <1800000 2850000 1200000 0>; + rgltr-max-voltage = <1800000 2850000 1200000 0>; + rgltr-load-current = <105000 0 80000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_rear2_active>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_rear2_suspend>; + gpios = <&tlmm 29 0>, + <&tlmm 45 0>; + gpio-reset = <1>; + gpio-req-tbl-num = <0 1>; + gpio-req-tbl-flags = <1 0>; + gpio-req-tbl-label = "CAMIF_MCLK1", + "CAM_RESET1"; + sensor-mode = <0>; + cci-master = <0>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <24000000>; + }; + + qcom,cam-sensor@6 { + cell-index = <6>; + compatible = "qcom,cam-sensor"; + reg = <0x6>; + csiphy-sd-index = <2>; + sensor-position-roll = <90>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + eeprom-src = <&eeprom_front>; + actuator-src = <&actuator_front>; + led-flash-src = <&led_flash_rear_aux2>; + cam_vio-supply = <&pm6150_l13>; + cam_vana-supply = <&camera_vana1_2_ldo>; + cam_vdig-supply = <&camera_ldo>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", + "cam_clk"; + rgltr-cntrl-support; + rgltr-min-voltage = <1800000 2850000 1200000 0>; + rgltr-max-voltage = <1800000 2850000 1200000 0>; + rgltr-load-current = <0 80000 105000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk2_active + &cam_sensor_front_active>; + pinctrl-1 = <&cam_sensor_mclk2_suspend + &cam_sensor_front_suspend>; + gpios = <&tlmm 30 0>, + <&tlmm 37 0>; + gpio-reset = <1>; + gpio-req-tbl-num = <0 1>; + gpio-req-tbl-flags = <1 0>; + gpio-req-tbl-label = "CAMIF_MCLK2", + "CAM_RESET2"; + sensor-mode = <0>; + cci-master = <1>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK2_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <24000000>; + }; }; -- GitLab From 7283e70f30c45ba0078dbe4b40e2b63c923bd4f2 Mon Sep 17 00:00:00 2001 From: Ayush Kumar Date: Mon, 6 May 2019 12:37:18 +0530 Subject: [PATCH 0535/1121] msm: camera: isp: Buffer size validation at IFE This change is to validate io config buffer size, which will help to prevent SMMU page fault in case UMD passes corrupt values. Change-Id: I225646f89dd1ab4211a71d95a1f4d94022bd98f7 Signed-off-by: Ayush Kumar --- .../hw_utils/cam_isp_packet_parser.c | 19 +++ .../msm/camera/cam_utils/cam_packet_util.c | 118 ++++++++++++++++++ .../msm/camera/cam_utils/cam_packet_util.h | 16 +++ 3 files changed, 153 insertions(+) diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c index 1b64913f0919..593c9bf0aacc 100644 --- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c +++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c @@ -473,6 +473,7 @@ int cam_isp_add_io_buffers( int32_t hdl; int mmu_hdl; bool mode, is_buf_secure; + uint64_t req_id; io_cfg = (struct cam_buf_io_cfg *) ((uint8_t *) &prepare->packet->payload + @@ -481,6 +482,7 @@ int cam_isp_add_io_buffers( num_in_buf = 0; io_cfg_used_bytes = 0; prepare->pf_data->packet = prepare->packet; + req_id = prepare->packet->header.request_id; /* Max one hw entries required for each base */ if (prepare->num_hw_update_entries + 1 >= @@ -628,6 +630,23 @@ int cam_isp_add_io_buffers( return rc; } + if (j == 0) { + rc = cam_packet_validate_plane_size( + &io_cfg[i], + plane_id, + size); + if (rc) { + CAM_ERR(CAM_ISP, + "Invalid buffer size, port 0x%x plane %d req_id %llu format %d memh 0x%x", + io_cfg[i].resource_type, + plane_id, + req_id, + io_cfg[i].format, + io_cfg[i].mem_handle[plane_id]); + return -EINVAL; + } + } + /* need to update with offset */ io_addr[plane_id] += io_cfg[i].offsets[plane_id]; diff --git a/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.c b/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.c index eae0dc00c03f..ecb4fe4c401a 100644 --- a/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.c +++ b/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.c @@ -353,3 +353,121 @@ int cam_packet_util_process_generic_cmd_buffer( return rc; } + +int32_t cam_packet_validate_plane_size( + struct cam_buf_io_cfg *io_cfg, + int plane_index, + size_t size) +{ + int rc = 0; + uint32_t kmd_plane_size = 0; + uint32_t bpp = io_cfg->bpp; + uint32_t plane_stride = 0; + uint32_t slice_height = 0; + uint32_t metadata_size = 0; + uint32_t format = io_cfg->format; + uint32_t plane_pixel_size = 0; + + if (plane_index < CAM_PACKET_MAX_PLANES) { + plane_stride = io_cfg->planes[plane_index].plane_stride; + slice_height = io_cfg->planes[plane_index].slice_height; + } + + if (!(plane_stride && slice_height)) { + CAM_ERR(CAM_ISP, + "Invalid values from UMD stride %d, slice height %d", + plane_stride, + slice_height); + return -EINVAL; + } + + switch (format) { + case CAM_FORMAT_MIPI_RAW_6: + case CAM_FORMAT_MIPI_RAW_8: + kmd_plane_size = ((plane_stride * slice_height) + 16 - 1) + / 16 * 16; + break; + case CAM_FORMAT_MIPI_RAW_10: + if (plane_stride % 4 == 0) + kmd_plane_size = ((plane_stride * slice_height) + + 16 - 1) / 16 * 16; + break; + case CAM_FORMAT_MIPI_RAW_12: + if (plane_stride % 2 == 0) + kmd_plane_size = ((plane_stride * slice_height) + + 16 - 1) / 16 * 16; + break; + case CAM_FORMAT_MIPI_RAW_14: + if (plane_stride % 4 == 0) + kmd_plane_size = plane_stride * slice_height * 7 / 4; + break; + case CAM_FORMAT_PLAIN16_8: + case CAM_FORMAT_PLAIN16_10: + case CAM_FORMAT_PLAIN16_12: + case CAM_FORMAT_PLAIN16_14: + case CAM_FORMAT_PLAIN16_16: + if (bpp == 8 || bpp == 10 || bpp == 12 + || bpp == 14 || bpp == 16) + kmd_plane_size = plane_stride * slice_height; + break; + case CAM_FORMAT_PLAIN64: + if (bpp == 64) + kmd_plane_size = plane_stride * slice_height; + break; + case CAM_FORMAT_NV21: + case CAM_FORMAT_NV12: + if (plane_index < CAM_PACKET_MAX_PLANES) + kmd_plane_size = plane_stride * slice_height; + break; + case CAM_FORMAT_PD10: + if (plane_index < CAM_PACKET_MAX_PLANES) + kmd_plane_size = plane_stride * slice_height; + break; + case CAM_FORMAT_UBWC_NV12: + case CAM_FORMAT_UBWC_NV12_4R: + case CAM_FORMAT_UBWC_TP10: + metadata_size = io_cfg->planes[plane_index].meta_size; + plane_pixel_size = ((plane_stride * slice_height) + + (4096 - 1)) & ~((uint32_t) 4096 - 1); + kmd_plane_size = metadata_size + plane_pixel_size; + break; + case CAM_FORMAT_UBWC_P010: + case CAM_FORMAT_PLAIN32_20: + case CAM_FORMAT_TP10: + case CAM_FORMAT_YUV422: + case CAM_FORMAT_PD8: + case CAM_FORMAT_PLAIN128: + case CAM_FORMAT_ARGB: + case CAM_FORMAT_ARGB_10: + case CAM_FORMAT_ARGB_12: + case CAM_FORMAT_ARGB_14: + case CAM_FORMAT_MIPI_RAW_16: + case CAM_FORMAT_MIPI_RAW_20: + case CAM_FORMAT_QTI_RAW_8: + case CAM_FORMAT_QTI_RAW_10: + case CAM_FORMAT_QTI_RAW_12: + case CAM_FORMAT_QTI_RAW_14: + case CAM_FORMAT_PLAIN8: + case CAM_FORMAT_PLAIN8_SWAP: + case CAM_FORMAT_PLAIN8_10: + case CAM_FORMAT_PLAIN8_10_SWAP: + kmd_plane_size = plane_stride * slice_height; + break; + default: + kmd_plane_size = plane_stride * slice_height; + break; + } + if (!kmd_plane_size || + kmd_plane_size > (size - io_cfg->offsets[plane_index])) { + CAM_ERR(CAM_ISP, + "kmd size: %d umd size: %d width: %d height: %d stride: %d sliceheight: %d ", + kmd_plane_size, + size, + io_cfg->planes[plane_index].width, + io_cfg->planes[plane_index].height, + plane_stride, + slice_height); + return -EINVAL; + } + return rc; +} diff --git a/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.h b/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.h index 33c07ad89f4e..e49968e6a291 100644 --- a/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.h +++ b/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.h @@ -135,4 +135,20 @@ int cam_packet_util_process_generic_cmd_buffer( struct cam_cmd_buf_desc *cmd_buf, cam_packet_generic_blob_handler blob_handler_cb, void *user_data); +/** + * cam_packet_validate_plane_size() + * + * @brief: Utility function to calculate and validate size of buffer + * required for a format. + * @io_cfg: Contains IO config info + * @plane_index Plane index for which size is to be calculated + * + * @return: Size of buffer + * + */ +int32_t cam_packet_validate_plane_size( + struct cam_buf_io_cfg *io_cfg, + int plane_index, + size_t size); + #endif /* _CAM_PACKET_UTIL_H_ */ -- GitLab From 5c615071d9721708c28c048273264b28ef260873 Mon Sep 17 00:00:00 2001 From: Veerabhadrarao Badiganti Date: Mon, 10 Jun 2019 14:39:39 +0530 Subject: [PATCH 0536/1121] ARM: dts: msm: Add emmc and sdcard device node for atoll Add emmc and sdcard device node for atoll. Change-Id: I109bc3398451e6b57b82f6656e0eba41f32e1264 Signed-off-by: Veerabhadrarao Badiganti --- arch/arm64/boot/dts/qcom/atoll-pinctrl.dtsi | 138 ++++++++++++++++++++ arch/arm64/boot/dts/qcom/atoll-rumi.dtsi | 48 +++++++ arch/arm64/boot/dts/qcom/atoll.dtsi | 65 +++++++++ 3 files changed, 251 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/atoll-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/atoll-pinctrl.dtsi index 172cc1df55fd..c26a2155edb0 100644 --- a/arch/arm64/boot/dts/qcom/atoll-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll-pinctrl.dtsi @@ -21,6 +21,144 @@ interrupt-controller; #interrupt-cells = <2>; + /* SDC pin type */ + sdc1_clk_on: sdc1_clk_on { + config { + pins = "sdc1_clk"; + bias-disable; /* NO pull */ + drive-strength = <16>; /* 16 MA */ + }; + }; + + sdc1_clk_off: sdc1_clk_off { + config { + pins = "sdc1_clk"; + bias-disable; /* NO pull */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + sdc1_cmd_on: sdc1_cmd_on { + config { + pins = "sdc1_cmd"; + bias-pull-up; /* pull up */ + drive-strength = <10>; /* 10 MA */ + }; + }; + + sdc1_cmd_off: sdc1_cmd_off { + config { + pins = "sdc1_cmd"; + num-grp-pins = <1>; + bias-pull-up; /* pull up */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + sdc1_data_on: sdc1_data_on { + config { + pins = "sdc1_data"; + bias-pull-up; /* pull up */ + drive-strength = <10>; /* 10 MA */ + }; + }; + + sdc1_data_off: sdc1_data_off { + config { + pins = "sdc1_data"; + bias-pull-up; /* pull up */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + sdc1_rclk_on: sdc1_rclk_on { + config { + pins = "sdc1_rclk"; + bias-pull-down; /* pull down */ + }; + }; + + sdc1_rclk_off: sdc1_rclk_off { + config { + pins = "sdc1_rclk"; + bias-pull-down; /* pull down */ + }; + }; + + sdc2_clk_on: sdc2_clk_on { + config { + pins = "sdc2_clk"; + bias-disable; /* NO pull */ + drive-strength = <16>; /* 16 MA */ + }; + }; + + sdc2_clk_off: sdc2_clk_off { + config { + pins = "sdc2_clk"; + bias-disable; /* NO pull */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + sdc2_cmd_on: sdc2_cmd_on { + config { + pins = "sdc2_cmd"; + bias-pull-up; /* pull up */ + drive-strength = <10>; /* 10 MA */ + }; + }; + + sdc2_cmd_off: sdc2_cmd_off { + config { + pins = "sdc2_cmd"; + bias-pull-up; /* pull up */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + sdc2_data_on: sdc2_data_on { + config { + pins = "sdc2_data"; + bias-pull-up; /* pull up */ + drive-strength = <10>; /* 10 MA */ + }; + }; + + sdc2_data_off: sdc2_data_off { + config { + pins = "sdc2_data"; + bias-pull-up; /* pull up */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + sdc2_cd_on: cd_on { + mux { + pins = "gpio69"; + function = "gpio"; + }; + + config { + pins = "gpio69"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + sdc2_cd_off: cd_off { + mux { + pins = "gpio69"; + function = "gpio"; + }; + + config { + pins = "gpio69"; + drive-strength = <2>; + bias-disable; + }; + }; + qupv3_se8_2uart_pins: qupv3_se8_2uart_pins { qupv3_se8_2uart_active: qupv3_se8_2uart_active { mux { diff --git a/arch/arm64/boot/dts/qcom/atoll-rumi.dtsi b/arch/arm64/boot/dts/qcom/atoll-rumi.dtsi index da467fa80faf..a177943e1586 100644 --- a/arch/arm64/boot/dts/qcom/atoll-rumi.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll-rumi.dtsi @@ -53,6 +53,54 @@ }; }; +#include "atoll-stub-regulator.dtsi" + +&sdhc_1 { + vdd-supply = <&pm6150_l19>; + qcom,vdd-voltage-level = <2950000 2950000>; + qcom,vdd-current-level = <0 570000>; + + vdd-io-supply = <&pm6150_l12>; + qcom,vdd-io-always-on; + qcom,vdd-io-lpm-sup; + qcom,vdd-io-voltage-level = <1800000 1800000>; + qcom,vdd-io-current-level = <0 325000>; + + pinctrl-names = "active", "sleep"; + pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on + &sdc1_rclk_on>; + pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off + &sdc1_rclk_off>; + + qcom,clk-rates = <400000 20000000 25000000 50000000>; + qcom,bus-speed-mode = "DDR_1p8v"; + + /delete-property/qcom,devfreq,freq-table; + + status = "ok"; +}; + +&sdhc_2 { + vdd-supply = <&pm6150l_l9>; + qcom,vdd-voltage-level = <2960000 2960000>; + qcom,vdd-current-level = <0 800000>; + + vdd-io-supply = <&pm6150l_l6>; + qcom,vdd-io-voltage-level = <1800000 2950000>; + qcom,vdd-io-current-level = <0 22000>; + + pinctrl-names = "active", "sleep"; + pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on>; + pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off>; + + qcom,clk-rates = <400000 20000000 25000000 50000000>; + qcom,bus-speed-mode = "SDR12", "SDR25", "SDR50"; + + /delete-property/qcom,devfreq,freq-table; + + status = "ok"; +}; + &usb0 { dwc3@a600000 { usb-phy = <&usb_emu_phy>, <&usb_nop_phy>; diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index 967bbb528181..05e738faf684 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -32,6 +32,8 @@ aliases { serial0 = &qupv3_se8_2uart; + sdhc1 = &sdhc_1; /* eMMC */ + sdhc2 = &sdhc_2; /* SD Card */ }; cpus { @@ -1587,6 +1589,69 @@ ; }; + sdhc_1: sdhci@7c4000 { + compatible = "qcom,sdhci-msm-v5"; + reg = <0x7c4000 0x1000>, <0x7c5000 0x1000>; + reg-names = "hc_mem", "cmdq_mem"; + + interrupts = , + ; + interrupt-names = "hc_irq", "pwr_irq"; + + qcom,bus-width = <8>; + qcom,large-address-bus; + + qcom,clk-rates = <400000 20000000 25000000 50000000 100000000 + 192000000 384000000>; + qcom,bus-speed-mode = "HS400_1p8v", "HS200_1p8v", "DDR_1p8v"; + + qcom,devfreq,freq-table = <50000000 200000000>; + + clocks = <&clock_gcc GCC_SDCC1_AHB_CLK>, + <&clock_gcc GCC_SDCC1_APPS_CLK>, + <&clock_gcc GCC_SDCC1_ICE_CORE_CLK>; + clock-names = "iface_clk", "core_clk", "ice_core_clk"; + + qcom,ice-clk-rates = <300000000 100000000>; + + qcom,scaling-lower-bus-speed-mode = "DDR52"; + + /* DLL HSR settings. Refer go/hsr - DLL settings */ + qcom,dll-hsr-list = <0x000F642C 0x0 0x0 0x00010800 0x80040868>; + + qcom,nonremovable; + status = "disabled"; + }; + + sdhc_2: sdhci@8804000 { + compatible = "qcom,sdhci-msm-v5"; + reg = <0x8804000 0x1000>; + reg-names = "hc_mem"; + + interrupts = , + ; + interrupt-names = "hc_irq", "pwr_irq"; + + qcom,bus-width = <4>; + qcom,large-address-bus; + + qcom,clk-rates = <400000 20000000 25000000 + 50000000 100000000 202000000>; + qcom,bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50", + "SDR104"; + + qcom,devfreq,freq-table = <50000000 202000000>; + + clocks = <&clock_gcc GCC_SDCC2_AHB_CLK>, + <&clock_gcc GCC_SDCC2_APPS_CLK>; + clock-names = "iface_clk", "core_clk"; + + /* DLL HSR settings. Refer go/hsr - DLL settings */ + qcom,dll-hsr-list = <0x0007642C 0x0 0x0 0x00010800 0x80040868>; + + status = "disabled"; + }; + disp_rsc: mailbox@af20000 { compatible = "qcom,tcs-drv"; label = "display_rsc"; -- GitLab From f9602119cfc579eb6fb914d4b5813929d7d4b818 Mon Sep 17 00:00:00 2001 From: Puranam V G Tejaswi Date: Mon, 27 May 2019 13:00:49 +0530 Subject: [PATCH 0537/1121] msm: kgsl: check if state change to suspend succeeds Check the return value of kgsl_pwrctrl_change_state() when requested state is suspend. This call can fail and we encounter adverse effects, if we proceed without checking if the call succeeded. For instance, in case of _preemption_store(), it is fatal to change ringbuffer, when state change to suspend fails. Also add a helper function that changes a given flag safely, only after successful state change to suspend. Change-Id: I8a929cc201d127baeaabed194655ac73a8032b2f Signed-off-by: Puranam V G Tejaswi --- drivers/gpu/msm/adreno_a6xx_gmu.c | 11 +++++++---- drivers/gpu/msm/adreno_a6xx_rgmu.c | 11 +++++++---- drivers/gpu/msm/adreno_debugfs.c | 22 ++++++++-------------- drivers/gpu/msm/adreno_sysfs.c | 30 ++++++++++-------------------- drivers/gpu/msm/kgsl_device.h | 20 ++++++++++++++++++++ drivers/gpu/msm/kgsl_gmu.c | 14 ++------------ 6 files changed, 54 insertions(+), 54 deletions(-) diff --git a/drivers/gpu/msm/adreno_a6xx_gmu.c b/drivers/gpu/msm/adreno_a6xx_gmu.c index 28cf1812d2ac..315eea3a3a85 100644 --- a/drivers/gpu/msm/adreno_a6xx_gmu.c +++ b/drivers/gpu/msm/adreno_a6xx_gmu.c @@ -1399,6 +1399,7 @@ static int a6xx_gmu_ifpc_store(struct adreno_device *adreno_dev, struct kgsl_device *device = KGSL_DEVICE(adreno_dev); struct gmu_device *gmu = KGSL_GMU_DEVICE(device); unsigned int requested_idle_level; + int ret; if (!gmu_core_gpmu_isenabled(device) || !ADRENO_FEATURE(adreno_dev, ADRENO_IFPC)) @@ -1420,13 +1421,15 @@ static int a6xx_gmu_ifpc_store(struct adreno_device *adreno_dev, mutex_lock(&device->mutex); /* Power down the GPU before changing the idle level */ - kgsl_pwrctrl_change_state(device, KGSL_STATE_SUSPEND); - gmu->idle_level = requested_idle_level; - kgsl_pwrctrl_change_state(device, KGSL_STATE_SLUMBER); + ret = kgsl_pwrctrl_change_state(device, KGSL_STATE_SUSPEND); + if (!ret) { + gmu->idle_level = requested_idle_level; + kgsl_pwrctrl_change_state(device, KGSL_STATE_SLUMBER); + } mutex_unlock(&device->mutex); - return 0; + return ret; } static unsigned int a6xx_gmu_ifpc_show(struct adreno_device *adreno_dev) diff --git a/drivers/gpu/msm/adreno_a6xx_rgmu.c b/drivers/gpu/msm/adreno_a6xx_rgmu.c index 7035223d68d4..29eec8cf9fc9 100644 --- a/drivers/gpu/msm/adreno_a6xx_rgmu.c +++ b/drivers/gpu/msm/adreno_a6xx_rgmu.c @@ -217,6 +217,7 @@ static int a6xx_rgmu_ifpc_store(struct adreno_device *adreno_dev, struct kgsl_device *device = KGSL_DEVICE(adreno_dev); struct rgmu_device *rgmu = KGSL_RGMU_DEVICE(device); unsigned int requested_idle_level; + int ret; if (!gmu_core_gpmu_isenabled(device) || !ADRENO_FEATURE(adreno_dev, ADRENO_IFPC)) @@ -233,13 +234,15 @@ static int a6xx_rgmu_ifpc_store(struct adreno_device *adreno_dev, mutex_lock(&device->mutex); /* Power down the GPU before changing the idle level */ - kgsl_pwrctrl_change_state(device, KGSL_STATE_SUSPEND); - rgmu->idle_level = requested_idle_level; - kgsl_pwrctrl_change_state(device, KGSL_STATE_SLUMBER); + ret = kgsl_pwrctrl_change_state(device, KGSL_STATE_SUSPEND); + if (!ret) { + rgmu->idle_level = requested_idle_level; + kgsl_pwrctrl_change_state(device, KGSL_STATE_SLUMBER); + } mutex_unlock(&device->mutex); - return 0; + return ret; } static unsigned int a6xx_rgmu_ifpc_show(struct adreno_device *adreno_dev) diff --git a/drivers/gpu/msm/adreno_debugfs.c b/drivers/gpu/msm/adreno_debugfs.c index 1b05411913bc..2dd651a446b1 100644 --- a/drivers/gpu/msm/adreno_debugfs.c +++ b/drivers/gpu/msm/adreno_debugfs.c @@ -30,19 +30,8 @@ static int _isdb_set(void *data, u64 val) if (test_bit(ADRENO_DEVICE_ISDB_ENABLED, &adreno_dev->priv)) return 0; - mutex_lock(&device->mutex); - - /* - * Bring down the GPU so we can bring it back up with the correct power - * and clock settings - */ - kgsl_pwrctrl_change_state(device, KGSL_STATE_SUSPEND); - set_bit(ADRENO_DEVICE_ISDB_ENABLED, &adreno_dev->priv); - kgsl_pwrctrl_change_state(device, KGSL_STATE_SLUMBER); - - mutex_unlock(&device->mutex); - - return 0; + return kgsl_change_flag(device, ADRENO_DEVICE_ISDB_ENABLED, + &adreno_dev->priv); } static int _isdb_get(void *data, u64 *val) @@ -60,6 +49,7 @@ static int _lm_limit_set(void *data, u64 val) { struct kgsl_device *device = data; struct adreno_device *adreno_dev = ADRENO_DEVICE(device); + int ret; if (!ADRENO_FEATURE(adreno_dev, ADRENO_LM)) return 0; @@ -74,7 +64,11 @@ static int _lm_limit_set(void *data, u64 val) if (test_bit(ADRENO_LM_CTRL, &adreno_dev->pwrctrl_flag)) { mutex_lock(&device->mutex); - kgsl_pwrctrl_change_state(device, KGSL_STATE_SUSPEND); + ret = kgsl_pwrctrl_change_state(device, KGSL_STATE_SUSPEND); + if (ret) { + mutex_unlock(&device->mutex); + return ret; + } kgsl_pwrctrl_change_state(device, KGSL_STATE_SLUMBER); mutex_unlock(&device->mutex); } diff --git a/drivers/gpu/msm/adreno_sysfs.c b/drivers/gpu/msm/adreno_sysfs.c index c0f92e511e38..407c05b79bd3 100644 --- a/drivers/gpu/msm/adreno_sysfs.c +++ b/drivers/gpu/msm/adreno_sysfs.c @@ -208,16 +208,7 @@ static int _pwrctrl_store(struct adreno_device *adreno_dev, if (val == test_bit(flag, &adreno_dev->pwrctrl_flag)) return 0; - mutex_lock(&device->mutex); - - /* Power down the GPU before changing the state */ - kgsl_pwrctrl_change_state(device, KGSL_STATE_SUSPEND); - change_bit(flag, &adreno_dev->pwrctrl_flag); - kgsl_pwrctrl_change_state(device, KGSL_STATE_SLUMBER); - - mutex_unlock(&device->mutex); - - return 0; + return kgsl_change_flag(device, flag, &adreno_dev->pwrctrl_flag); } static int _preemption_store(struct adreno_device *adreno_dev, @@ -226,7 +217,7 @@ static int _preemption_store(struct adreno_device *adreno_dev, struct kgsl_device *device = KGSL_DEVICE(adreno_dev); struct kgsl_context *context; struct adreno_context *drawctxt; - int id; + int id, ret; mutex_lock(&device->mutex); @@ -237,7 +228,11 @@ static int _preemption_store(struct adreno_device *adreno_dev, return 0; } - kgsl_pwrctrl_change_state(device, KGSL_STATE_SUSPEND); + ret = kgsl_pwrctrl_change_state(device, KGSL_STATE_SUSPEND); + if (ret) { + mutex_unlock(&device->mutex); + return ret; + } change_bit(ADRENO_DEVICE_PREEMPTION, &adreno_dev->priv); adreno_dev->cur_rb = &(adreno_dev->ringbuffers[0]); @@ -717,14 +712,9 @@ static ssize_t ppd_enable_store(struct kgsl_device *device, if (ppd_on == test_bit(ADRENO_PPD_CTRL, &adreno_dev->pwrctrl_flag)) return count; - mutex_lock(&device->mutex); - - kgsl_pwrctrl_change_state(device, KGSL_STATE_SUSPEND); - change_bit(ADRENO_PPD_CTRL, &adreno_dev->pwrctrl_flag); - kgsl_pwrctrl_change_state(device, KGSL_STATE_SLUMBER); - - mutex_unlock(&device->mutex); - return count; + ret = kgsl_change_flag(device, ADRENO_PPD_CTRL, + &adreno_dev->pwrctrl_flag); + return ret ? ret : count; } static ssize_t ppd_enable_show(struct kgsl_device *device, diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h index 9a9d1e1ca507..b7c73b70a3de 100644 --- a/drivers/gpu/msm/kgsl_device.h +++ b/drivers/gpu/msm/kgsl_device.h @@ -694,6 +694,26 @@ static inline int kgsl_state_is_awake(struct kgsl_device *device) return false; } +static inline int kgsl_change_flag(struct kgsl_device *device, + unsigned long flag, unsigned long *val) +{ + int ret; + + mutex_lock(&device->mutex); + /* + * Bring down the GPU, so that we can bring it back up with the correct + * power and clock settings + */ + ret = kgsl_pwrctrl_change_state(device, KGSL_STATE_SUSPEND); + if (!ret) { + change_bit(flag, val); + kgsl_pwrctrl_change_state(device, KGSL_STATE_SLUMBER); + } + + mutex_unlock(&device->mutex); + return ret; +} + int kgsl_readtimestamp(struct kgsl_device *device, void *priv, enum kgsl_timestamp_type type, unsigned int *timestamp); diff --git a/drivers/gpu/msm/kgsl_gmu.c b/drivers/gpu/msm/kgsl_gmu.c index 41cb7d75242f..b3caff205c66 100644 --- a/drivers/gpu/msm/kgsl_gmu.c +++ b/drivers/gpu/msm/kgsl_gmu.c @@ -1316,18 +1316,8 @@ static int gmu_acd_set(struct kgsl_device *device, unsigned int val) if (val == test_bit(ADRENO_ACD_CTRL, &adreno_dev->pwrctrl_flag)) return 0; - mutex_lock(&device->mutex); - - /* Power down the GPU before enabling or disabling ACD */ - kgsl_pwrctrl_change_state(device, KGSL_STATE_SUSPEND); - if (val) - set_bit(ADRENO_ACD_CTRL, &adreno_dev->pwrctrl_flag); - else - clear_bit(ADRENO_ACD_CTRL, &adreno_dev->pwrctrl_flag); - kgsl_pwrctrl_change_state(device, KGSL_STATE_SLUMBER); - - mutex_unlock(&device->mutex); - return 0; + return kgsl_change_flag(device, ADRENO_ACD_CTRL, + &adreno_dev->pwrctrl_flag); } /* Do not access any GMU registers in GMU probe function */ -- GitLab From 4c9b36af9cf24abf891cc3c0a880311bcffd9c5b Mon Sep 17 00:00:00 2001 From: Bojun Pan Date: Fri, 17 May 2019 10:29:59 -0700 Subject: [PATCH 0538/1121] msm: ipa3: Handle missing cleanup in IMP_READY state on shutdown In current implementation, the cleanup QMI / smmu unmapping are missing if IMP is in IMP_READY state. This fix is to handle those missing cleanup properly. Change-Id: Ie554a264443d300bb92312932eae10d5655f7ad6 Signed-off-by: Bojun Pan --- drivers/platform/msm/ipa/ipa_v3/ipa_mhi_proxy.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_mhi_proxy.c b/drivers/platform/msm/ipa/ipa_v3/ipa_mhi_proxy.c index 0b46190e35f3..269aab75a8b0 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_mhi_proxy.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_mhi_proxy.c @@ -706,7 +706,8 @@ static void imp_mhi_shutdown(void) IMP_FUNC_ENTRY(); - if (imp_ctx->state == IMP_STARTED) { + if (imp_ctx->state == IMP_STARTED || + imp_ctx->state == IMP_READY) { req.cleanup_valid = true; req.cleanup = true; ipa3_qmi_send_mhi_cleanup_request(&req); -- GitLab From 4766872a374c4833b306b1dcc7409e922c67fa18 Mon Sep 17 00:00:00 2001 From: Yu Wang Date: Fri, 19 Apr 2019 09:55:38 +0800 Subject: [PATCH 0539/1121] defconfig: msm: Enable required configurations for sa6155 Enable required configurations to bring up qca6390 for sa6155. Change-Id: Ia5f9de0d0d7a1f3c059b91b0e9a34d6036575a59 Signed-off-by: Yu Wang --- arch/arm64/configs/vendor/sdmsteppe-auto-perf_defconfig | 3 +++ arch/arm64/configs/vendor/sdmsteppe-auto_defconfig | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/arch/arm64/configs/vendor/sdmsteppe-auto-perf_defconfig b/arch/arm64/configs/vendor/sdmsteppe-auto-perf_defconfig index 2ee606b3211f..58941f6747bd 100644 --- a/arch/arm64/configs/vendor/sdmsteppe-auto-perf_defconfig +++ b/arch/arm64/configs/vendor/sdmsteppe-auto-perf_defconfig @@ -236,6 +236,7 @@ CONFIG_NET_ACT_MIRRED=y CONFIG_NET_ACT_SKBEDIT=y CONFIG_QRTR=y CONFIG_QRTR_SMD=y +CONFIG_QRTR_MHI=y CONFIG_QRTR_USB=y CONFIG_RMNET_USB=y CONFIG_SOCKEV_NLMCAST=y @@ -306,6 +307,8 @@ CONFIG_WIL6210=m CONFIG_WCNSS_MEM_PRE_ALLOC=y CONFIG_CLD_LL_CORE=y CONFIG_CNSS2=y +CONFIG_CNSS2_QMI=y +CONFIG_CNSS_ASYNC=y CONFIG_CNSS_UTILS=y CONFIG_CNSS_GENL=y CONFIG_INPUT_EVDEV=y diff --git a/arch/arm64/configs/vendor/sdmsteppe-auto_defconfig b/arch/arm64/configs/vendor/sdmsteppe-auto_defconfig index f6e53d4cf14f..a43a5aa45d41 100644 --- a/arch/arm64/configs/vendor/sdmsteppe-auto_defconfig +++ b/arch/arm64/configs/vendor/sdmsteppe-auto_defconfig @@ -244,6 +244,7 @@ CONFIG_NET_ACT_SKBEDIT=y CONFIG_DNS_RESOLVER=y CONFIG_QRTR=y CONFIG_QRTR_SMD=y +CONFIG_QRTR_MHI=y CONFIG_QRTR_USB=y CONFIG_RMNET_USB=y CONFIG_SOCKEV_NLMCAST=y @@ -263,6 +264,7 @@ CONFIG_REGMAP_WCD_IRQ=y CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y CONFIG_DMA_CMA=y CONFIG_MHI_BUS=y +CONFIG_MHI_DEBUG=y CONFIG_ZRAM=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y @@ -316,6 +318,8 @@ CONFIG_WCNSS_MEM_PRE_ALLOC=y CONFIG_CLD_LL_CORE=y CONFIG_CNSS2=y CONFIG_CNSS2_DEBUG=y +CONFIG_CNSS2_QMI=y +CONFIG_CNSS_ASYNC=y CONFIG_CNSS_UTILS=y CONFIG_CNSS_GENL=y CONFIG_INPUT_EVDEV=y -- GitLab From 41d4fbffacd91e02b4adb1e14d991fcfb1001e13 Mon Sep 17 00:00:00 2001 From: Ramesh V Date: Mon, 10 Jun 2019 19:05:36 +0530 Subject: [PATCH 0540/1121] msm: camera_v2: isp: Reserve rdi ub based on image size Allocate rdi ub based on stream size, this will prevent overflow for rdi stream. Change-Id: If45ec22c45e0f8e5b2899384c384b58cb517ffd2 Signed-off-by: Ramesh V --- .../platform/msm/camera_v2/isp/msm_isp47.c | 82 +++++-------------- 1 file changed, 20 insertions(+), 62 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c index 61351734368f..5d77e7565dcc 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c @@ -1900,25 +1900,15 @@ void msm_vfe47_cfg_axi_ub_equal_default( uint32_t wm_ub_size; uint64_t delta; - if (frame_src == VFE_PIX_0) { - for (i = 0; i < axi_data->hw_info->num_wm; i++) { - if (axi_data->free_wm[i] && - SRC_TO_INTF( - HANDLE_TO_IDX(axi_data->free_wm[i])) == - VFE_PIX_0) { - num_used_wms++; - total_image_size += - axi_data->wm_image_size[i]; - } + for (i = 0; i < axi_data->hw_info->num_wm; i++) { + if (axi_data->free_wm[i]) { + num_used_wms++; + total_image_size += + axi_data->wm_image_size[i]; } - ub_offset = (axi_data->hw_info->num_rdi * 2) * - axi_data->hw_info->min_wm_ub; - prop_size = vfe_dev->hw_info->vfe_ops.axi_ops.get_ub_size( - vfe_dev) - - axi_data->hw_info->min_wm_ub * (num_used_wms + - axi_data->hw_info->num_rdi * 2); } - + prop_size = vfe_dev->hw_info->vfe_ops.axi_ops.get_ub_size( + vfe_dev) - axi_data->hw_info->min_wm_ub * num_used_wms; for (i = 0; i < axi_data->hw_info->num_wm; i++) { if (!axi_data->free_wm[i]) { msm_camera_io_w(0, @@ -1932,52 +1922,20 @@ void msm_vfe47_cfg_axi_ub_equal_default( HANDLE_TO_IDX(axi_data->free_wm[i]))) continue; - if (frame_src == VFE_PIX_0) { - if (total_image_size) { - delta = (uint64_t)axi_data->wm_image_size[i] * - (uint64_t)prop_size; - do_div(delta, total_image_size); - wm_ub_size = axi_data->hw_info->min_wm_ub + - (uint32_t)delta; - msm_camera_io_w(ub_offset << 16 | - (wm_ub_size - 1), - vfe_dev->vfe_base + - vfe_dev->hw_info->vfe_ops.axi_ops - .ub_reg_offset(vfe_dev, i)); - ub_offset += wm_ub_size; - } else { - pr_err("%s: image size is zero\n", __func__); - } - } else { - uint32_t rdi_ub_offset; - int plane; - int vfe_idx; - struct msm_vfe_axi_stream *stream_info; - - stream_info = msm_isp_get_stream_common_data(vfe_dev, - HANDLE_TO_IDX(axi_data->free_wm[i])); - if (!stream_info) { - pr_err("%s: stream_info is NULL!", __func__); - return; - } - vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, - stream_info); - for (plane = 0; plane < stream_info->num_planes; - plane++) - if (stream_info->wm[vfe_idx][plane] == - axi_data->free_wm[i]) - break; - - rdi_ub_offset = (SRC_TO_INTF( - HANDLE_TO_IDX(axi_data->free_wm[i])) - - VFE_RAW_0) * - axi_data->hw_info->min_wm_ub * 2; - wm_ub_size = axi_data->hw_info->min_wm_ub * 2; - msm_camera_io_w(rdi_ub_offset << 16 | (wm_ub_size - 1), - vfe_dev->vfe_base + - vfe_dev->hw_info->vfe_ops.axi_ops.ub_reg_offset( - vfe_dev, i)); + delta = (uint64_t)axi_data->wm_image_size[i] * + (uint64_t)prop_size; + do_div(delta, total_image_size); + if (frame_src != VFE_PIX_0) { + if (delta <= axi_data->hw_info->min_wm_ub) + delta = axi_data->hw_info->min_wm_ub; } + wm_ub_size = axi_data->hw_info->min_wm_ub + + (uint32_t)delta; + msm_camera_io_w(ub_offset << 16 | (wm_ub_size - 1), + vfe_dev->vfe_base + + vfe_dev->hw_info->vfe_ops.axi_ops.ub_reg_offset( + vfe_dev, i)); + ub_offset += wm_ub_size; } } -- GitLab From 3d6b54dc41d2e235638477885b8f15a62012e578 Mon Sep 17 00:00:00 2001 From: Veerabhadrarao Badiganti Date: Thu, 30 May 2019 14:32:41 +0530 Subject: [PATCH 0541/1121] ARM: dts: Add UFS device node for atoll Add ufs device node for atoll and enable it. Change-Id: I830c328531b360e99cc35e00e1b6380fca9f12a1 Signed-off-by: Veerabhadrarao Badiganti --- arch/arm64/boot/dts/qcom/atoll-pinctrl.dtsi | 46 +++++++++ arch/arm64/boot/dts/qcom/atoll-rumi.dtsi | 35 +++++++ arch/arm64/boot/dts/qcom/atoll.dtsi | 106 ++++++++++++++++++++ 3 files changed, 187 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/atoll-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/atoll-pinctrl.dtsi index c26a2155edb0..506a18623dba 100644 --- a/arch/arm64/boot/dts/qcom/atoll-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll-pinctrl.dtsi @@ -21,6 +21,52 @@ interrupt-controller; #interrupt-cells = <2>; + ufs_dev_reset_assert: ufs_dev_reset_assert { + config { + pins = "ufs_reset"; + bias-pull-down; /* default: pull down */ + /* + * UFS_RESET driver strengths are having + * different values/steps compared to typical + * GPIO drive strengths. + * + * Following table clarifies: + * + * HDRV value | UFS_RESET | Typical GPIO + * (dec) | (mA) | (mA) + * 0 | 0.8 | 2 + * 1 | 1.55 | 4 + * 2 | 2.35 | 6 + * 3 | 3.1 | 8 + * 4 | 3.9 | 10 + * 5 | 4.65 | 12 + * 6 | 5.4 | 14 + * 7 | 6.15 | 16 + * + * POR value for UFS_RESET HDRV is 3 which means + * 3.1mA and we want to use that. Hence just + * specify 8mA to "drive-strength" binding and + * that should result into writing 3 to HDRV + * field. + */ + drive-strength = <8>; /* default: 3.1 mA */ + output-low; /* active low reset */ + }; + }; + + ufs_dev_reset_deassert: ufs_dev_reset_deassert { + config { + pins = "ufs_reset"; + bias-pull-down; /* default: pull down */ + /* + * default: 3.1 mA + * check comments under ufs_dev_reset_assert + */ + drive-strength = <8>; + output-high; /* active low reset */ + }; + }; + /* SDC pin type */ sdc1_clk_on: sdc1_clk_on { config { diff --git a/arch/arm64/boot/dts/qcom/atoll-rumi.dtsi b/arch/arm64/boot/dts/qcom/atoll-rumi.dtsi index a177943e1586..1d0c58235836 100644 --- a/arch/arm64/boot/dts/qcom/atoll-rumi.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll-rumi.dtsi @@ -101,6 +101,41 @@ status = "ok"; }; +&ufsphy_mem { + compatible = "qcom,ufs-phy-qrbtc-sdm845"; + + vdda-phy-supply = <&pm6150_l4>; /* 0.88v */ + vdda-pll-supply = <&pm6150l_l3>; /* 1.2v */ + vdda-phy-max-microamp = <62900>; + vdda-pll-max-microamp = <18300>; + + status = "ok"; +}; + +&ufshc_mem { + limit-tx-hs-gear = <1>; + limit-rx-hs-gear = <1>; + scsi-cmd-timeout = <300000>; + + vdd-hba-supply = <&ufs_phy_gdsc>; + vdd-hba-fixed-regulator; + vcc-supply = <&pm6150_l19>; + vccq2-supply = <&pm6150_l12>; + vcc-max-microamp = <600000>; + vccq2-max-microamp = <600000>; + + qcom,vddp-ref-clk-supply = <&pm6150l_l3>; + qcom,vddp-ref-clk-max-microamp = <100>; + qcom,vddp-ref-clk-min-uV = <1200000>; + qcom,vddp-ref-clk-max-uV = <1200000>; + + + qcom,disable-lpm; + rpm-level = <0>; + spm-level = <0>; + status = "ok"; +}; + &usb0 { dwc3@a600000 { usb-phy = <&usb_emu_phy>, <&usb_nop_phy>; diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index 05e738faf684..bab362fce8d3 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -34,6 +34,7 @@ serial0 = &qupv3_se8_2uart; sdhc1 = &sdhc_1; /* eMMC */ sdhc2 = &sdhc_2; /* SD Card */ + ufshc1 = &ufshc_mem; /* Embedded UFS slot */ }; cpus { @@ -1652,6 +1653,111 @@ status = "disabled"; }; + ufsphy_mem: ufsphy_mem@1d87000 { + reg = <0x1d87000 0xddc>; /* PHY regs */ + reg-names = "phy_mem"; + #phy-cells = <0>; + + lanes-per-direction = <1>; + + clock-names = "ref_clk_src", + "ref_clk", + "ref_aux_clk"; + clocks = <&clock_rpmh RPMH_CXO_CLK>, + <&clock_gcc GCC_UFS_MEM_CLKREF_CLK>, + <&clock_gcc GCC_UFS_PHY_PHY_AUX_CLK>; + + status = "disabled"; + }; + + ufshc_mem: ufshc@1d84000 { + compatible = "qcom,ufshc"; + reg = <0x1d84000 0x3000>; + interrupts = <0 265 0>; + phys = <&ufsphy_mem>; + phy-names = "ufsphy"; + + lanes-per-direction = <1>; + dev-ref-clk-freq = <0>; /* 19.2 MHz */ + spm-level = <5>; + + clock-names = + "core_clk", + "bus_aggr_clk", + "iface_clk", + "core_clk_unipro", + "core_clk_ice", + "ref_clk", + "tx_lane0_sync_clk", + "rx_lane0_sync_clk"; + clocks = + <&clock_gcc GCC_UFS_PHY_AXI_CLK>, + <&clock_gcc GCC_AGGRE_UFS_PHY_AXI_CLK>, + <&clock_gcc GCC_UFS_PHY_AHB_CLK>, + <&clock_gcc GCC_UFS_PHY_UNIPRO_CORE_CLK>, + <&clock_gcc GCC_UFS_PHY_ICE_CORE_CLK>, + <&clock_rpmh RPMH_CXO_CLK>, + <&clock_gcc GCC_UFS_PHY_TX_SYMBOL_0_CLK>, + <&clock_gcc GCC_UFS_PHY_RX_SYMBOL_0_CLK>; + freq-table-hz = + <50000000 200000000>, + <0 0>, + <0 0>, + <37500000 150000000>, + <75000000 300000000>, + <0 0>, + <0 0>, + <0 0>; + + qcom,msm-bus,name = "ufshc_mem"; + qcom,msm-bus,num-cases = <12>; + qcom,msm-bus,num-paths = <2>; + qcom,msm-bus,vectors-KBps = + /* + * During HS G3 UFS runs at nominal voltage corner, vote + * higher bandwidth to push other buses in the data path + * to run at nominal to achieve max throughput. + * 4GBps pushes BIMC to run at nominal. + * 200MBps pushes CNOC to run at nominal. + * Vote for half of this bandwidth for HS G3 1-lane. + * For max bandwidth, vote high enough to push the buses + * to run in turbo voltage corner. + */ + <123 512 0 0>, <1 757 0 0>, /* No vote */ + <123 512 922 0>, <1 757 1000 0>, /* PWM G1 */ + <123 512 1844 0>, <1 757 1000 0>, /* PWM G2 */ + <123 512 3688 0>, <1 757 1000 0>, /* PWM G3 */ + <123 512 7376 0>, <1 757 1000 0>, /* PWM G4 */ + <123 512 127796 0>, <1 757 1000 0>, /* HS G1 RA */ + <123 512 255591 0>, <1 757 1000 0>, /* HS G2 RA */ + <123 512 2097152 0>, <1 757 102400 0>, /* HS G3 RA */ + <123 512 149422 0>, <1 757 1000 0>, /* HS G1 RB */ + <123 512 298189 0>, <1 757 1000 0>, /* HS G2 RB */ + <123 512 2097152 0>, <1 757 102400 0>, /* HS G3 RB */ + <123 512 7643136 0>, <1 757 307200 0>; /* Max. bandwidth */ + + qcom,bus-vector-names = "MIN", + "PWM_G1_L1", "PWM_G2_L1", "PWM_G3_L1", "PWM_G4_L1", + "HS_RA_G1_L1", "HS_RA_G2_L1", "HS_RA_G3_L1", + "HS_RB_G1_L1", "HS_RB_G2_L1", "HS_RB_G3_L1", + "MAX"; + + /* PM QoS */ + qcom,pm-qos-cpu-groups = <0x3f 0xC0>; + qcom,pm-qos-cpu-group-latency-us = <67 67>; + qcom,pm-qos-default-cpu = <0>; + + pinctrl-names = "dev-reset-assert", "dev-reset-deassert"; + pinctrl-0 = <&ufs_dev_reset_assert>; + pinctrl-1 = <&ufs_dev_reset_deassert>; + + resets = <&clock_gcc GCC_UFS_PHY_BCR>; + reset-names = "core_reset"; + non-removable; + + status = "disabled"; + }; + disp_rsc: mailbox@af20000 { compatible = "qcom,tcs-drv"; label = "display_rsc"; -- GitLab From 6629e7f20b1c8c1c1b2673605206dfaae590ecf9 Mon Sep 17 00:00:00 2001 From: Mao Jinlong Date: Thu, 16 May 2019 17:27:47 +0530 Subject: [PATCH 0542/1121] ARM: dts: msm: Add coresight nodes for atoll Add coresight nodes for atoll to enable coresight components. Change-Id: I05ec1d085d6e8d8a40da941d953d48844300c042 Signed-off-by: Mao Jinlong --- arch/arm64/boot/dts/qcom/atoll-coresight.dtsi | 2976 +++++++++++++++++ arch/arm64/boot/dts/qcom/atoll.dtsi | 1 + 2 files changed, 2977 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/atoll-coresight.dtsi diff --git a/arch/arm64/boot/dts/qcom/atoll-coresight.dtsi b/arch/arm64/boot/dts/qcom/atoll-coresight.dtsi new file mode 100644 index 000000000000..feac82b9d69e --- /dev/null +++ b/arch/arm64/boot/dts/qcom/atoll-coresight.dtsi @@ -0,0 +1,2976 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + csr: csr@6001000 { + compatible = "qcom,coresight-csr"; + reg = <0x6001000 0x1000>; + reg-names = "csr-base"; + + coresight-name = "coresight-csr"; + + qcom,usb-bam-support; + qcom,hwctrl-set-support; + qcom,set-byte-cntr-support; + qcom,blk-size = <1>; + }; + + audio_etm0: audio_etm0 { + compatible = "qcom,coresight-remote-etm"; + coresight-name = "coresight-audio-etm0"; + + qcom,inst-id = <5>; + + port { + audio_etm0_out_funnel_swao: endpoint { + remote-endpoint = + <&funnel_swao_in_audio_etm0>; + }; + }; + }; + + tpdm_lpass_lpi: tpdm@6b26000 { + compatible = "qcom,coresight-dummy"; + + coresight-name = "coresight-tpdm-lpass-lpi"; + qcom,dummy-source; + + port { + tpdm_lpss_lpi_out_funnel_swao: endpoint { + remote-endpoint = <&funnel_swao_in_tpdm_lpass_lpi>; + }; + }; + }; + + tpdm_swao_0: tpdm@6b09000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b968>; + reg = <0x6b09000 0x1000>; + reg-names = "tpdm-base"; + + coresight-name = "coresight-tpdm-swao-0"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + port { + tpdm_swao_0_out_tpda_swao0: endpoint { + remote-endpoint = + <&tpda_swao0_in_tpdm_swao_0>; + }; + }; + }; + + tpdm_swao_1: tpdm@6b0a000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b968>; + reg = <0x6b0a000 0x1000>; + reg-names = "tpdm-base"; + + coresight-name = "coresight-tpdm-swao-1"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + port { + tpdm_swao_1_out_tpda_swao1: endpoint { + remote-endpoint = + <&tpda_swao1_in_tpdm_swao_1>; + }; + }; + }; + + tpdm_vsense: tpdm@6834000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b968>; + reg = <0x6834000 0x1000>; + reg-names = "tpdm-base"; + + coresight-name = "coresight-tpdm-vsense"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + port { + tpdm_vsense_out_tpda21: endpoint { + remote-endpoint = + <&tpda21_in_tpdm_vsense>; + }; + }; + }; + + tpdm_dcc: tpdm@6870000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b968>; + reg = <0x6870000 0x1000>; + reg-names = "tpdm-base"; + + qcom,hw-enable-check; + coresight-name = "coresight-tpdm-dcc"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + port { + tpdm_dcc_out_tpda22: endpoint { + remote-endpoint = + <&tpda22_in_tpdm_dcc>; + }; + }; + }; + + tpdm_prng: tpdm@684c000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b968>; + reg = <0x684c000 0x1000>; + reg-names = "tpdm-base"; + + coresight-name = "coresight-tpdm-prng"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + port { + tpdm_prng_out_tpda23: endpoint { + remote-endpoint = + <&tpda23_in_tpdm_prng>; + }; + }; + }; + + tpdm_qm: tpdm@69d0000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b968>; + reg = <0x69d0000 0x1000>; + reg-names = "tpdm-base"; + + coresight-name = "coresight-tpdm-qm"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + port { + tpdm_qm_out_tpda24: endpoint { + remote-endpoint = + <&tpda24_in_tpdm_qm>; + }; + }; + }; + + tpdm_lpass: tpdm@6844000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b968>; + reg = <0x6844000 0x1000>; + reg-names = "tpdm-base"; + + qcom,msr-fix-req; + coresight-name = "coresight-tpdm-lpass"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + port { + tpdm_lpass_out_funnel_lpass: endpoint { + remote-endpoint = + <&funnel_lpass_in_tpdm_lpass>; + }; + }; + }; + + tpdm_npu: tpdm@6c47000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b968>; + reg = <0x6c47000 0x1000>; + reg-names = "tpdm-base"; + status = "disabled"; + + coresight-name = "coresight-tpdm-npu"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + port { + tpdm_npu_out_funnel_npu: endpoint { + remote-endpoint = + <&funnel_npu_in_tpdm_npu>; + }; + }; + }; + + tpdm_npu_llm: tpdm@6c40000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b968>; + reg = <0x6c40000 0x1000>; + reg-names = "tpdm-base"; + + status = "disabled"; + coresight-name = "coresight-tpdm-npu-llm"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + port { + tpdm_npu_llm_out_funnel_npu: endpoint { + remote-endpoint = + <&funnel_npu_in_tpdm_npu_llm>; + }; + }; + }; + + tpdm_npu_dpm: tpdm@6c41000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b968>; + reg = <0x6c41000 0x1000>; + reg-names = "tpdm-base"; + + coresight-name = "coresight-tpdm-npu-dpm"; + + status = "disabled"; + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + port { + tpdm_npu_dpm_out_funnel_npu: endpoint { + remote-endpoint = + <&funnel_npu_in_tpdm_npu_dpm>; + }; + }; + }; + + npu_etm0: npu_etm0 { + compatible = "qcom,coresight-remote-etm"; + coresight-name = "coresight-npu-etm0"; + + qcom,inst-id = <2>; + + port { + npu_etm0_out_funnel_npu: endpoint { + remote-endpoint = + <&funnel_npu_in_npu_etm0>; + }; + }; + }; + + tpdm_mdss: tpdm@6c60000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b968>; + reg = <0x6c60000 0x1000>; + reg-names = "tpdm-base"; + + coresight-name = "coresight-tpdm-mdss"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + port { + tpdm_mdss_out_funnel_dlnt: endpoint { + remote-endpoint = + <&funnel_dlnt_in_tpdm_mdss>; + }; + }; + }; + + tpdm_dl_north: tpdm@6ac0000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b968>; + reg = <0x6ac0000 0x1000>; + reg-names = "tpdm-base"; + + coresight-name = "coresight-tpdm-dl-north"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + port { + tpdm_dl_north_out_funnel_dlnt: endpoint { + remote-endpoint = + <&funnel_dlnt_in_tpdm_dl_north>; + }; + }; + }; + + tpdm_nav: tpdm@6842000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b968>; + reg = <0x6842000 0x1000>; + reg-names = "tpdm-base"; + + coresight-name = "coresight-tpdm-nav"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + port { + tpdm_nav_out_tpda_nav0: endpoint { + remote-endpoint = + <&tpda_nav0_in_tpdm_nav>; + }; + }; + }; + + modem_etm0: modem_etm0 { + compatible = "qcom,coresight-remote-etm"; + coresight-name = "coresight-modem-etm0"; + + qcom,inst-id = <11>; + + port { + modem_etm0_out_funnel_dlnt: endpoint { + remote-endpoint = + <&funnel_dlnt_in_modem_etm0>; + }; + }; + }; + + tpdm_modem_0: tpdm@6800000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b968>; + reg = <0x6800000 0x1000>; + reg-names = "tpdm-base"; + + coresight-name = "coresight-tpdm-modem-0"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + port { + tpdm_modem_0_out_tpda_modem0: endpoint { + remote-endpoint = + <&tpda_modem0_in_tpdm_modem_0>; + }; + }; + }; + + tpdm_modem_1: tpdm@6804000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b968>; + reg = <0x6804000 0x1000>; + reg-names = "tpdm-base"; + + coresight-name = "coresight-tpdm-modem-1"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + port { + tpdm_modem_1_out_tpda_modem1: endpoint { + remote-endpoint = + <&tpda_modem1_in_tpdm_modem_1>; + }; + }; + }; + + tpdm_dlct: tpdm@6c28000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b968>; + reg = <0x6c28000 0x1000>; + reg-names = "tpdm-base"; + + coresight-name = "coresight-tpdm-dlct"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + port { + tpdm_dlct_out_funnel_dlct0: endpoint { + remote-endpoint = + <&funnel_dlct0_in_tpdm_dlct>; + }; + }; + }; + + tpdm_pimem: tpdm@6850000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b968>; + reg = <0x6850000 0x1000>; + reg-names = "tpdm-base"; + + coresight-name = "coresight-tpdm-pimem"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + port { + tpdm_pimem_out_tpda_dl_center16: endpoint { + remote-endpoint = + <&tpda_dl_center16_in_tpdm_pimem>; + }; + }; + }; + + tpdm_gpu: tpdm@6940000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b968>; + reg = <0x6940000 0x1000>; + reg-names = "tpdm-base"; + + coresight-name = "coresight-tpdm-gpu"; + status = "disabled"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + port { + tpdm_gpu_out_funnel_gpu: endpoint { + remote-endpoint = + <&funnel_gpu_in_tpdm_gpu>; + }; + }; + }; + + tpdm_ddr: tpdm@6f80000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b968>; + reg = <0x6f80000 0x1000>; + reg-names = "tpdm-base"; + + coresight-name = "coresight-tpdm-ddr"; + qcom,msr-fix-req; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + port { + tpdm_ddr_out_funnel_ddr0: endpoint { + remote-endpoint = + <&funnel_ddr0_in_tpdm_ddr>; + }; + }; + }; + + tpdm_turing: tpdm@6980000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b968>; + reg = <0x6980000 0x1000>; + reg-names = "tpdm-base"; + + coresight-name = "coresight-tpdm-turing"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + port { + tpdm_turing_out_funnel_turing: endpoint { + remote-endpoint = + <&funnel_turing_in_tpdm_turing>; + }; + }; + }; + + tpdm_turing_llm: tpdm@6981000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b968>; + reg = <0x6981000 0x1000>; + reg-names = "tpdm-base"; + + coresight-name = "coresight-tpdm-turing-llm"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + port { + tpdm_turing_llm_out_funnel_turing: endpoint { + remote-endpoint = + <&funnel_turing_in_tpdm_turing_llm>; + }; + }; + }; + + turing_etm0: turing_etm0 { + compatible = "qcom,coresight-remote-etm"; + coresight-name = "coresight-turing-etm0"; + + qcom,inst-id = <13>; + + port { + turing_etm0_out_funnel_turing: endpoint { + remote-endpoint = + <&funnel_turing_in_turing_etm0>; + }; + }; + }; + + tpdm_wcss: tpdm@69a4000 { + compatible = "qcom,coresight-dummy"; + + coresight-name = "coresight-tpdm-wcss"; + qcom,dummy-source; + + port { + tpdm_wcss_out_funnel_in1: endpoint { + remote-endpoint = + <&funnel_in1_in_tpdm_wcss>; + }; + }; + }; + + etm0: tpdm@7040000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x000bb95d>; + reg = <0x7040000 0x1000>; + cpu = <&CPU0>; + + coresight-name = "coresight-etm0"; + + qcom,tupwr-disable; + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + port { + etm0_out_funnel_apss: endpoint { + remote-endpoint = + <&funnel_apss_in_etm0>; + }; + }; + }; + + etm1: tpdm@7140000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x000bb95d>; + reg = <0x7140000 0x1000>; + cpu = <&CPU1>; + + coresight-name = "coresight-etm1"; + + qcom,tupwr-disable; + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + port { + etm1_out_funnel_apss: endpoint { + remote-endpoint = + <&funnel_apss_in_etm1>; + }; + }; + }; + + etm2: tpdm@7240000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x000bb95d>; + reg = <0x7240000 0x1000>; + cpu = <&CPU2>; + + qcom,tupwr-disable; + coresight-name = "coresight-etm2"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + port { + etm2_out_funnel_apss: endpoint { + remote-endpoint = + <&funnel_apss_in_etm2>; + }; + }; + }; + + etm3: tpdm@7340000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x000bb95d>; + reg = <0x7340000 0x1000>; + cpu = <&CPU3>; + + qcom,tupwr-disable; + coresight-name = "coresight-etm3"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + port { + etm3_out_funnel_apss: endpoint { + remote-endpoint = + <&funnel_apss_in_etm3>; + }; + }; + }; + + etm4: tpdm@7440000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x000bb95d>; + reg = <0x7440000 0x1000>; + cpu = <&CPU4>; + + coresight-name = "coresight-etm4"; + + qcom,tupwr-disable; + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + port { + etm4_out_funnel_apss: endpoint { + remote-endpoint = + <&funnel_apss_in_etm4>; + }; + }; + }; + + etm5: tpdm@7540000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x000bb95d>; + reg = <0x7540000 0x1000>; + cpu = <&CPU5>; + + coresight-name = "coresight-etm5"; + + qcom,tupwr-disable; + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + port { + etm5_out_funnel_apss: endpoint { + remote-endpoint = + <&funnel_apss_in_etm5>; + }; + }; + }; + + etm6: tpdm@7640000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x000bb95d>; + reg = <0x7640000 0x1000>; + cpu = <&CPU6>; + + coresight-name = "coresight-etm6"; + + qcom,tupwr-disable; + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + port { + etm6_out_funnel_apss: endpoint { + remote-endpoint = + <&funnel_apss_in_etm6>; + }; + }; + }; + + etm7: tpdm@7740000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x000bb95d>; + reg = <0x7740000 0x1000>; + cpu = <&CPU7>; + + coresight-name = "coresight-etm7"; + + qcom,tupwr-disable; + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + port { + etm7_out_funnel_apss: endpoint { + remote-endpoint = + <&funnel_apss_in_etm7>; + }; + }; + }; + + tpdm_olc: tpdm@7830000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b968>; + reg = <0x7830000 0x1000>; + reg-names = "tpdm-base"; + + coresight-name = "coresight-tpdm-olc"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + port { + tpdm_olc_out_tpda_olc0: endpoint { + remote-endpoint = + <&tpda_olc0_in_tpdm_olc>; + }; + }; + }; + + tpdm_llm_silver: tpdm@78a0000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b968>; + reg = <0x78a0000 0x1000>; + reg-names = "tpdm-base"; + + coresight-name = "coresight-tpdm-llm-silver"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + port { + tpdm_llm_silver_out_tpda_llm_silver0: endpoint { + remote-endpoint = + <&tpda_llm_silver0_in_tpdm_llm_silver>; + }; + }; + }; + + tpdm_llm_gold: tpdm@78b0000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b968>; + reg = <0x78b0000 0x1000>; + reg-names = "tpdm-base"; + + coresight-name = "coresight-tpdm-llm-gold"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + port { + tpdm_llm_gold_out_tpda_llm_gold0: endpoint { + remote-endpoint = + <&tpda_llm_gold0_in_tpdm_llm_gold>; + }; + }; + }; + + tpdm_apss: tpdm@7860000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b968>; + reg = <0x7860000 0x1000>; + reg-names = "tpdm-base"; + + coresight-name = "coresight-tpdm-apss"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + port { + tpdm_apss_out_tpda_apss0: endpoint { + remote-endpoint = + <&tpda_apss0_in_tpdm_apss>; + }; + }; + }; + + funnel_lpass: funnel@6846000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b908>; + reg = <0x6846000 0x1000>; + reg-names = "funnel-base"; + + coresight-name = "coresight-funnel-lpass"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + funnel_lpass_out_funnel_dlct0: endpoint { + remote-endpoint = + <&funnel_dlct0_in_funnel_lpass>; + }; + }; + + port@1 { + reg = <0>; + funnel_lpass_in_tpdm_lpass: endpoint { + slave-mode; + remote-endpoint = + <&tpdm_lpass_out_funnel_lpass>; + }; + }; + + }; + }; + + funnel_npu: funnel@6c44000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b908>; + reg = <0x6c44000 0x1000>; + reg-names = "funnel-base"; + + coresight-name = "coresight-funnel-npu"; + + status = "disabled"; + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + funnel_npu_out_funnel_dlct0: endpoint { + remote-endpoint = + <&funnel_dlct0_in_funnel_npu>; + }; + }; + + port@1 { + reg = <0>; + funnel_npu_in_tpdm_npu: endpoint { + slave-mode; + remote-endpoint = + <&tpdm_npu_out_funnel_npu>; + }; + }; + + port@2 { + reg = <1>; + funnel_npu_in_tpdm_npu_llm: endpoint { + slave-mode; + remote-endpoint = + <&tpdm_npu_llm_out_funnel_npu>; + }; + }; + + port@3 { + reg = <2>; + funnel_npu_in_tpdm_npu_dpm: endpoint { + slave-mode; + remote-endpoint = + <&tpdm_npu_dpm_out_funnel_npu>; + }; + }; + + port@4 { + reg = <3>; + funnel_npu_in_npu_etm0: endpoint { + slave-mode; + remote-endpoint = + <&npu_etm0_out_funnel_npu>; + }; + }; + + }; + }; + + tpda_nav: tpda@6843000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b969>; + reg = <0x6843000 0x1000>; + reg-names = "tpda-base"; + + coresight-name = "coresight-tpda-nav"; + qcom,tpda-atid = <68>; + qcom,cmb-elem-size = <0 32>; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + tpda_nav_out_funnel_dlnt: endpoint { + remote-endpoint = + <&funnel_dlnt_in_tpda_nav>; + }; + }; + + port@1 { + reg = <0>; + tpda_nav0_in_tpdm_nav: endpoint { + slave-mode; + remote-endpoint = + <&tpdm_nav_out_tpda_nav0>; + }; + }; + + }; + }; + + tpda_modem0: tpda@6801000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b969>; + reg = <0x6801000 0x1000>; + reg-names = "tpda-base"; + + coresight-name = "coresight-tpda-modem0"; + qcom,tpda-atid = <67>; + qcom,dsb-elem-size = <0 32>; + qcom,cmb-elem-size = <0 64>; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + tpda_modem0_out_funnel_modem: endpoint { + remote-endpoint = + <&funnel_modem_in_tpda_modem0>; + }; + }; + + port@1 { + reg = <0>; + tpda_modem0_in_tpdm_modem_0: endpoint { + slave-mode; + remote-endpoint = + <&tpdm_modem_0_out_tpda_modem0>; + }; + }; + + }; + }; + + tpda_modem1: tpda@6803000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b969>; + reg = <0x6803000 0x1000>; + reg-names = "tpda-base"; + + coresight-name = "coresight-tpda-modem1"; + qcom,tpda-atid = <98>; + qcom,dsb-elem-size = <0 32>; + qcom,cmb-elem-size = <0 64>; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + tpda_modem1_out_funnel_modem: endpoint { + remote-endpoint = + <&funnel_modem_in_tpda_modem1>; + }; + }; + + port@1 { + reg = <0>; + tpda_modem1_in_tpdm_modem_1: endpoint { + slave-mode; + remote-endpoint = + <&tpdm_modem_1_out_tpda_modem1>; + }; + }; + + }; + }; + + funnel_modem: funnel@6802000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b908>; + reg = <0x6802000 0x1000>; + reg-names = "funnel-base"; + + coresight-name = "coresight-funnel-modem"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + funnel_modem_out_funnel_dlnt: endpoint { + remote-endpoint = + <&funnel_dlnt_in_funnel_modem>; + }; + }; + + port@1 { + reg = <0>; + funnel_modem_in_tpda_modem0: endpoint { + slave-mode; + remote-endpoint = + <&tpda_modem0_out_funnel_modem>; + }; + }; + + port@2 { + reg = <1>; + funnel_modem_in_tpda_modem1: endpoint { + slave-mode; + remote-endpoint = + <&tpda_modem1_out_funnel_modem>; + }; + }; + + }; + }; + + funnel_dlnt: funnel@6ac5000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b908>; + reg = <0x6ac5000 0x1000>; + reg-names = "funnel-base"; + + coresight-name = "coresight-funnel-dlnt"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + funnel_dlnt_out_funnel_dlct0: endpoint { + remote-endpoint = + <&funnel_dlct0_in_funnel_dlnt>; + }; + }; + + port@1 { + reg = <0>; + funnel_dlnt_in_tpdm_mdss: endpoint { + slave-mode; + remote-endpoint = + <&tpdm_mdss_out_funnel_dlnt>; + }; + }; + + port@2 { + reg = <1>; + funnel_dlnt_in_tpdm_dl_north: endpoint { + slave-mode; + remote-endpoint = + <&tpdm_dl_north_out_funnel_dlnt>; + }; + }; + + port@3 { + reg = <2>; + funnel_dlnt_in_tpda_nav: endpoint { + slave-mode; + remote-endpoint = + <&tpda_nav_out_funnel_dlnt>; + }; + }; + + port@4 { + reg = <5>; + funnel_dlnt_in_modem_etm0: endpoint { + slave-mode; + remote-endpoint = + <&modem_etm0_out_funnel_dlnt>; + }; + }; + + port@5 { + reg = <6>; + funnel_dlnt_in_funnel_modem: endpoint { + slave-mode; + remote-endpoint = + <&funnel_modem_out_funnel_dlnt>; + }; + }; + + }; + }; + + funnel_dlct0: funnel@6c2d000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b908>; + reg = <0x6c2d000 0x1000>; + reg-names = "funnel-base"; + + coresight-name = "coresight-funnel-dlct0"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + funnel_dlct0_out_tpda2: endpoint { + remote-endpoint = + <&tpda2_in_funnel_dlct0>; + source = <&tpdm_lpass>; + }; + }; + + port@1 { + reg = <0>; + funnel_dlct0_out_tpda11: endpoint { + remote-endpoint = + <&tpda11_in_funnel_dlct0>; + source = <&tpdm_npu>; + }; + }; + + port@2 { + reg = <0>; + funnel_dlct0_out_tpda12: endpoint { + remote-endpoint = + <&tpda12_in_funnel_dlct0>; + source = <&tpdm_npu_llm>; + }; + }; + + port@3 { + reg = <0>; + funnel_dlct0_out_tpda13: endpoint { + remote-endpoint = + <&tpda13_in_funnel_dlct0>; + source = <&tpdm_npu_dpm>; + }; + }; + + port@4 { + reg = <0>; + funnel_dlct0_out_tpda14: endpoint { + remote-endpoint = + <&tpda14_in_funnel_dlct0>; + source = <&tpdm_mdss>; + }; + }; + + port@5 { + reg = <0>; + funnel_dlct0_out_tpda15: endpoint { + remote-endpoint = + <&tpda15_in_funnel_dlct0>; + source = <&tpdm_dl_north>; + }; + }; + + port@6 { + reg = <0>; + funnel_dlct0_out_tpda19: endpoint { + remote-endpoint = + <&tpda19_in_funnel_dlct0>; + source = <&tpdm_dlct>; + }; + }; + + port@7 { + reg = <0>; + funnel_dlct0_out_funnel_qatb: endpoint { + remote-endpoint = + <&funnel_qatb_in_funnel_dlct0>; + }; + }; + + port@8 { + reg = <0>; + funnel_dlct0_in_funnel_lpass: endpoint { + slave-mode; + remote-endpoint = + <&funnel_lpass_out_funnel_dlct0>; + }; + }; + + port@9 { + reg = <4>; + funnel_dlct0_in_funnel_npu: endpoint { + slave-mode; + remote-endpoint = + <&funnel_npu_out_funnel_dlct0>; + }; + }; + + port@10 { + reg = <5>; + funnel_dlct0_in_funnel_dlnt: endpoint { + slave-mode; + remote-endpoint = + <&funnel_dlnt_out_funnel_dlct0>; + }; + }; + + port@11 { + reg = <6>; + funnel_dlct0_in_tpdm_dlct: endpoint { + slave-mode; + remote-endpoint = + <&tpdm_dlct_out_funnel_dlct0>; + }; + }; + + }; + }; + + funnel_gpu: funnel@6944000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b908>; + reg = <0x6944000 0x1000>; + reg-names = "funnel-base"; + + coresight-name = "coresight-funnel-gpu"; + status = "disabled"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + funnel_gpu_out_tpda_dl_center: endpoint { + remote-endpoint = + <&tpda_dl_center_in_funnel_gpu>; + }; + }; + + port@1 { + reg = <0>; + funnel_gpu_in_tpdm_gpu: endpoint { + slave-mode; + remote-endpoint = + <&tpdm_gpu_out_funnel_gpu>; + }; + }; + + }; + }; + + funnel_ddr0: funnel@6f85000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b908>; + reg = <0x6f85000 0x1000>; + reg-names = "funnel-base"; + + coresight-name = "coresight-funnel-ddr0"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + funnel_ddr0_out_tpda_dl_center: endpoint { + remote-endpoint = + <&tpda_dl_center_in_funnel_ddr0>; + }; + }; + + port@1 { + reg = <0>; + funnel_ddr0_in_tpdm_ddr: endpoint { + slave-mode; + remote-endpoint = + <&tpdm_ddr_out_funnel_ddr0>; + }; + }; + + }; + }; + + funnel_turing: funnel@6983000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b908>; + reg = <0x6983000 0x1000>; + reg-names = "funnel-base"; + + coresight-name = "coresight-funnel-turing"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + funnel_turing_out_tpda_dl_center5: endpoint { + remote-endpoint = + <&tpda_dl_center5_in_funnel_turing>; + source = <&tpdm_turing>; + }; + }; + + port@1 { + reg = <0>; + funnel_turing_out_tpda_dl_center6: endpoint { + remote-endpoint = + <&tpda_dl_center6_in_funnel_turing>; + source = <&tpdm_turing_llm>; + }; + }; + + port@2 { + reg = <0>; + funnel_turing_out_funnel_dlct1: endpoint { + remote-endpoint = + <&funnel_dlct1_in_funnel_turing>; + }; + }; + + port@3 { + reg = <0>; + funnel_turing_in_tpdm_turing: endpoint { + slave-mode; + remote-endpoint = + <&tpdm_turing_out_funnel_turing>; + }; + }; + + port@4 { + reg = <1>; + funnel_turing_in_tpdm_turing_llm: endpoint { + slave-mode; + remote-endpoint = + <&tpdm_turing_llm_out_funnel_turing>; + }; + }; + + port@5 { + reg = <2>; + funnel_turing_in_turing_etm0: endpoint { + slave-mode; + remote-endpoint = + <&turing_etm0_out_funnel_turing>; + }; + }; + + }; + }; + + tpda_dl_center: tpda@6c38000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b969>; + reg = <0x6c38000 0x1000>; + reg-names = "tpda-base"; + + coresight-name = "coresight-tpda-dl-center"; + qcom,tpda-atid = <78>; + qcom,dsb-elem-size = <0 32>, + <3 32>, + <5 32>, + <16 32>; + qcom,cmb-elem-size = <3 32>, + <6 32>, + <16 64>; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + tpda_dl_center_out_funnel_dlct1: endpoint { + remote-endpoint = + <&funnel_dlct1_in_tpda_dl_center>; + }; + }; + + port@1 { + reg = <16>; + tpda_dl_center16_in_tpdm_pimem: endpoint { + slave-mode; + remote-endpoint = + <&tpdm_pimem_out_tpda_dl_center16>; + }; + }; + + port@2 { + reg = <0>; + tpda_dl_center_in_funnel_gpu: endpoint { + slave-mode; + remote-endpoint = + <&funnel_gpu_out_tpda_dl_center>; + }; + }; + + port@3 { + reg = <3>; + tpda_dl_center_in_funnel_ddr0: endpoint { + slave-mode; + remote-endpoint = + <&funnel_ddr0_out_tpda_dl_center>; + }; + }; + + port@4 { + reg = <5>; + tpda_dl_center5_in_funnel_turing: endpoint { + slave-mode; + remote-endpoint = + <&funnel_turing_out_tpda_dl_center5>; + }; + }; + + port@5 { + reg = <6>; + tpda_dl_center6_in_funnel_turing: endpoint { + slave-mode; + remote-endpoint = + <&funnel_turing_out_tpda_dl_center6>; + }; + }; + + }; + }; + + funnel_dlct1: funnel@6c39000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b908>; + reg = <0x6c39000 0x1000>; + reg-names = "funnel-base"; + + coresight-name = "coresight-funnel-dlct1"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + funnel_dlct1_out_funnel_in1: endpoint { + remote-endpoint = + <&funnel_in1_in_funnel_dlct1>; + }; + }; + + port@1 { + reg = <0>; + funnel_dlct1_in_tpda_dl_center: endpoint { + slave-mode; + remote-endpoint = + <&tpda_dl_center_out_funnel_dlct1>; + }; + }; + + port@2 { + reg = <4>; + funnel_dlct1_in_funnel_turing: endpoint { + slave-mode; + remote-endpoint = + <&funnel_turing_out_funnel_dlct1>; + }; + }; + + }; + }; + + funnel_apss: funnel@7800000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b908>; + reg = <0x7800000 0x1000>; + reg-names = "funnel-base"; + + coresight-name = "coresight-funnel-apss"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + funnel_apss_out_funnel_apss_merge: endpoint { + remote-endpoint = + <&funnel_apss_merge_in_funnel_apss>; + }; + }; + + port@1 { + reg = <0>; + funnel_apss_in_etm0: endpoint { + slave-mode; + remote-endpoint = + <&etm0_out_funnel_apss>; + }; + }; + + port@2 { + reg = <1>; + funnel_apss_in_etm1: endpoint { + slave-mode; + remote-endpoint = + <&etm1_out_funnel_apss>; + }; + }; + + port@3 { + reg = <2>; + funnel_apss_in_etm2: endpoint { + slave-mode; + remote-endpoint = + <&etm2_out_funnel_apss>; + }; + }; + + port@4 { + reg = <3>; + funnel_apss_in_etm3: endpoint { + slave-mode; + remote-endpoint = + <&etm3_out_funnel_apss>; + }; + }; + + port@5 { + reg = <4>; + funnel_apss_in_etm4: endpoint { + slave-mode; + remote-endpoint = + <&etm4_out_funnel_apss>; + }; + }; + + port@6 { + reg = <5>; + funnel_apss_in_etm5: endpoint { + slave-mode; + remote-endpoint = + <&etm5_out_funnel_apss>; + }; + }; + + port@7 { + reg = <6>; + funnel_apss_in_etm6: endpoint { + slave-mode; + remote-endpoint = + <&etm6_out_funnel_apss>; + }; + }; + + port@8 { + reg = <7>; + funnel_apss_in_etm7: endpoint { + slave-mode; + remote-endpoint = + <&etm7_out_funnel_apss>; + }; + }; + + }; + }; + + tpda_olc: tpda@7832000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b969>; + reg = <0x7832000 0x1000>; + reg-names = "tpda-base"; + + coresight-name = "coresight-tpda-olc"; + qcom,tpda-atid = <69>; + qcom,cmb-elem-size = <0 64>; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + tpda_olc_out_funnel_apss_merge: endpoint { + remote-endpoint = + <&funnel_apss_merge_in_tpda_olc>; + }; + }; + + port@1 { + reg = <0>; + tpda_olc0_in_tpdm_olc: endpoint { + slave-mode; + remote-endpoint = + <&tpdm_olc_out_tpda_olc0>; + }; + }; + + }; + }; + + tpda_llm_silver: tpda@78c0000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b969>; + reg = <0x78c0000 0x1000>; + reg-names = "tpda-base"; + + coresight-name = "coresight-tpda-llm-silver"; + qcom,tpda-atid = <72>; + qcom,cmb-elem-size = <0 32>; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + tpda_silver_out_funnel_apss_merge: endpoint { + remote-endpoint = + <&funnel_apss_merge_in_tpda_llm_silver>; + }; + }; + + port@1 { + reg = <0>; + tpda_llm_silver0_in_tpdm_llm_silver: endpoint { + slave-mode; + remote-endpoint = + <&tpdm_llm_silver_out_tpda_llm_silver0>; + }; + }; + + }; + }; + + tpda_llm_gold: tpda@78d0000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b969>; + reg = <0x78d0000 0x1000>; + reg-names = "tpda-base"; + + coresight-name = "coresight-tpda-llm-gold"; + qcom,tpda-atid = <73>; + qcom,cmb-elem-size = <0 32>; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + tpda_llm_gold_out_funnel_apss_merge: endpoint { + remote-endpoint = + <&funnel_apss_merge_in_tpda_llm_gold>; + }; + }; + + port@1 { + reg = <0>; + tpda_llm_gold0_in_tpdm_llm_gold: endpoint { + slave-mode; + remote-endpoint = + <&tpdm_llm_gold_out_tpda_llm_gold0>; + }; + }; + + }; + }; + + tpda_apss: tpda@7862000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b969>; + reg = <0x7862000 0x1000>; + reg-names = "tpda-base"; + + coresight-name = "coresight-tpda-apss"; + qcom,tpda-atid = <66>; + qcom,dsb-elem-size = <0 32>; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + tpda_apss_out_funnel_apss_merge: endpoint { + remote-endpoint = + <&funnel_apss_merge_in_tpda_apss>; + }; + }; + + port@1 { + reg = <0>; + tpda_apss0_in_tpdm_apss: endpoint { + slave-mode; + remote-endpoint = + <&tpdm_apss_out_tpda_apss0>; + }; + }; + + }; + }; + + funnel_apss_merge: funnel@7810000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b908>; + reg = <0x7810000 0x1000>; + reg-names = "funnel-base"; + + coresight-name = "coresight-funnel-apss-merge"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + funnel_apss_merge_out_funnel_in1: endpoint { + remote-endpoint = + <&funnel_in1_in_funnel_apss_merge>; + }; + }; + + port@1 { + reg = <0>; + funnel_apss_merge_in_funnel_apss: endpoint { + slave-mode; + remote-endpoint = + <&funnel_apss_out_funnel_apss_merge>; + }; + }; + + port@2 { + reg = <2>; + funnel_apss_merge_in_tpda_olc: endpoint { + slave-mode; + remote-endpoint = + <&tpda_olc_out_funnel_apss_merge>; + }; + }; + + port@3 { + reg = <3>; + funnel_apss_merge_in_tpda_llm_silver: endpoint { + slave-mode; + remote-endpoint = + <&tpda_silver_out_funnel_apss_merge>; + }; + }; + + port@4 { + reg = <4>; + funnel_apss_merge_in_tpda_llm_gold: endpoint { + slave-mode; + remote-endpoint = + <&tpda_llm_gold_out_funnel_apss_merge>; + }; + }; + + port@5 { + reg = <5>; + funnel_apss_merge_in_tpda_apss: endpoint { + slave-mode; + remote-endpoint = + <&tpda_apss_out_funnel_apss_merge>; + }; + }; + + }; + }; + + tpda: tpda@6004000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b969>; + reg = <0x6004000 0x1000>; + reg-names = "tpda-base"; + + coresight-name = "coresight-tpda"; + qcom,tpda-atid = <65>; + qcom,bc-elem-size = <16 32>, + <24 32>, + <25 32>; + qcom,tc-elem-size = <16 32>, + <25 32>; + qcom,dsb-elem-size = <2 32>, + <11 32>, + <14 32>, + <15 32>, + <19 32>, + <24 32>; + qcom,cmb-elem-size = <11 32>, + <12 32>, + <13 64>, + <14 32>, + <21 32>, + <22 32>, + <23 32>; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + tpda_out_funnel_qatb: endpoint { + remote-endpoint = + <&funnel_qatb_in_tpda>; + }; + }; + + port@1 { + reg = <21>; + tpda21_in_tpdm_vsense: endpoint { + slave-mode; + remote-endpoint = + <&tpdm_vsense_out_tpda21>; + }; + }; + + port@2 { + reg = <22>; + tpda22_in_tpdm_dcc: endpoint { + slave-mode; + remote-endpoint = + <&tpdm_dcc_out_tpda22>; + }; + }; + + port@3 { + reg = <23>; + tpda23_in_tpdm_prng: endpoint { + slave-mode; + remote-endpoint = + <&tpdm_prng_out_tpda23>; + }; + }; + + port@4 { + reg = <24>; + tpda24_in_tpdm_qm: endpoint { + slave-mode; + remote-endpoint = + <&tpdm_qm_out_tpda24>; + }; + }; + + port@5 { + reg = <2>; + tpda2_in_funnel_dlct0: endpoint { + slave-mode; + remote-endpoint = + <&funnel_dlct0_out_tpda2>; + }; + }; + + port@6 { + reg = <11>; + tpda11_in_funnel_dlct0: endpoint { + slave-mode; + remote-endpoint = + <&funnel_dlct0_out_tpda11>; + }; + }; + + port@7 { + reg = <12>; + tpda12_in_funnel_dlct0: endpoint { + slave-mode; + remote-endpoint = + <&funnel_dlct0_out_tpda12>; + }; + }; + + port@8 { + reg = <13>; + tpda13_in_funnel_dlct0: endpoint { + slave-mode; + remote-endpoint = + <&funnel_dlct0_out_tpda13>; + }; + }; + + port@9 { + reg = <14>; + tpda14_in_funnel_dlct0: endpoint { + slave-mode; + remote-endpoint = + <&funnel_dlct0_out_tpda14>; + }; + }; + + port@10 { + reg = <15>; + tpda15_in_funnel_dlct0: endpoint { + slave-mode; + remote-endpoint = + <&funnel_dlct0_out_tpda15>; + }; + }; + + port@11 { + reg = <19>; + tpda19_in_funnel_dlct0: endpoint { + slave-mode; + remote-endpoint = + <&funnel_dlct0_out_tpda19>; + }; + }; + + }; + }; + + funnel_qatb: funnel@6005000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b908>; + reg = <0x6005000 0x1000>; + reg-names = "funnel-base"; + + coresight-name = "coresight-funnel-qatb"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + funnel_qatb_out_funnel_in0: endpoint { + remote-endpoint = + <&funnel_in0_in_funnel_qatb>; + }; + }; + + port@1 { + reg = <0>; + funnel_qatb_in_tpda: endpoint { + slave-mode; + remote-endpoint = + <&tpda_out_funnel_qatb>; + }; + }; + + port@2 { + reg = <3>; + funnel_qatb_in_funnel_dlct0: endpoint { + slave-mode; + remote-endpoint = + <&funnel_dlct0_out_funnel_qatb>; + }; + }; + + }; + }; + + funnel_in0: funnel@6041000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b908>; + reg = <0x6041000 0x1000>; + reg-names = "funnel-base"; + + coresight-name = "coresight-funnel-in0"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + funnel_in0_out_funnel_merge: endpoint { + remote-endpoint = + <&funnel_merge_in_funnel_in0>; + }; + }; + + port@1 { + reg = <6>; + funnel_in0_in_funnel_qatb: endpoint { + slave-mode; + remote-endpoint = + <&funnel_qatb_out_funnel_in0>; + }; + }; + + port@2 { + reg = <7>; + funnel_in0_in_stm: endpoint { + slave-mode; + remote-endpoint = + <&stm_out_funnel_in0>; + }; + }; + + }; + }; + + funnel_in1: funnel@6042000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b908>; + reg = <0x6042000 0x1000>; + reg-names = "funnel-base"; + + coresight-name = "coresight-funnel-in1"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + funnel_in1_out_funnel_merge: endpoint { + remote-endpoint = + <&funnel_merge_in_funnel_in1>; + }; + }; + + port@1 { + reg = <1>; + funnel_in1_in_funnel_dlct1: endpoint { + slave-mode; + remote-endpoint = + <&funnel_dlct1_out_funnel_in1>; + }; + }; + + port@2 { + reg = <2>; + funnel_in1_in_tpdm_wcss: endpoint { + slave-mode; + remote-endpoint = + <&tpdm_wcss_out_funnel_in1>; + }; + }; + + port@3 { + reg = <4>; + funnel_in1_in_funnel_apss_merge: endpoint { + slave-mode; + remote-endpoint = + <&funnel_apss_merge_out_funnel_in1>; + }; + }; + + }; + }; + + funnel_merge: funnel@6045000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b908>; + reg = <0x6045000 0x1000>; + reg-names = "funnel-base"; + + coresight-name = "coresight-funnel-merge"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + funnel_merge_out_funnel_swao: endpoint { + remote-endpoint = + <&funnel_swao_in_funnel_merge>; + }; + }; + + port@1 { + reg = <0>; + funnel_merge_in_funnel_in0: endpoint { + slave-mode; + remote-endpoint = + <&funnel_in0_out_funnel_merge>; + }; + }; + + port@2 { + reg = <1>; + funnel_merge_in_funnel_in1: endpoint { + slave-mode; + remote-endpoint = + <&funnel_in1_out_funnel_merge>; + }; + }; + + }; + }; + + tpda_swao: tpda@6b08000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b969>; + reg = <0x6b08000 0x1000>; + reg-names = "tpda-base"; + + coresight-name = "coresight-tpda-swao"; + qcom,tpda-atid = <71>; + qcom,dsb-elem-size = <1 32>; + qcom,cmb-elem-size = <0 64>; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + tpda_swao_out_funnel_swao: endpoint { + remote-endpoint = + <&funnel_swao_in_tpda_swao>; + }; + }; + + port@1 { + reg = <0>; + tpda_swao0_in_tpdm_swao_0: endpoint { + slave-mode; + remote-endpoint = + <&tpdm_swao_0_out_tpda_swao0>; + }; + }; + + port@2 { + reg = <1>; + tpda_swao1_in_tpdm_swao_1: endpoint { + slave-mode; + remote-endpoint = + <&tpdm_swao_1_out_tpda_swao1>; + }; + }; + + }; + }; + + funnel_swao: funnel@6b04000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b908>; + reg = <0x6b04000 0x1000>; + reg-names = "funnel-base"; + + coresight-name = "coresight-funnel-swao"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + funnel_swao_out_tmc_etf: endpoint { + remote-endpoint = + <&tmc_etf_in_funnel_swao>; + }; + }; + + port@1 { + reg = <5>; + funnel_swao_in_audio_etm0: endpoint { + slave-mode; + remote-endpoint = + <&audio_etm0_out_funnel_swao>; + }; + }; + + port@2 { + reg = <5>; + funnel_swao_in_tpdm_lpass_lpi: endpoint { + slave-mode; + remote-endpoint = + <&tpdm_lpss_lpi_out_funnel_swao>; + }; + }; + + port@3 { + reg = <6>; + funnel_swao_in_tpda_swao: endpoint { + slave-mode; + remote-endpoint = + <&tpda_swao_out_funnel_swao>; + }; + }; + + port@4 { + reg = <7>; + funnel_swao_in_funnel_merge: endpoint { + slave-mode; + remote-endpoint = + <&funnel_merge_out_funnel_swao>; + }; + }; + + }; + }; + + tmc_etf: tmc@6b05000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b961>; + reg = <0x6b05000 0x1000>; + reg-names = "tmc-base"; + + coresight-csr = <&csr>; + coresight-name = "coresight-tmc-etf"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + tmc_etf_out_replicator_swao: endpoint { + remote-endpoint = + <&replicator_swao_in_tmc_etf>; + }; + }; + + port@1 { + reg = <0>; + tmc_etf_in_funnel_swao: endpoint { + slave-mode; + remote-endpoint = + <&funnel_swao_out_tmc_etf>; + }; + }; + + }; + }; + + replicator_swao: replicator@6b06000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b909>; + reg = <0x6b06000 0x1000>; + reg-names = "replicator-base"; + + coresight-name = "coresight-replicator-swao"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + replicator_swao_out_replicator_qdss: endpoint { + remote-endpoint = + <&replicator_qdss_in_replicator_swao>; + }; + }; + + port@1 { + reg = <1>; + replicator_swao_out_eud: endpoint { + remote-endpoint = + <&eud_in_replicator_swao>; + }; + }; + + port@2 { + reg = <0>; + replicator_swao_in_tmc_etf: endpoint { + slave-mode; + remote-endpoint = + <&tmc_etf_out_replicator_swao>; + }; + }; + + }; + }; + + replicator_qdss: replicator@6046000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b909>; + reg = <0x6046000 0x1000>; + reg-names = "replicator-base"; + + coresight-name = "coresight-replicator-qdss"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + replicator_qdss_out_tmc_etr: endpoint { + remote-endpoint = + <&tmc_etr_in_replicator_qdss>; + }; + }; + + port@1 { + reg = <0>; + replicator_qdss_in_replicator_swao: endpoint { + slave-mode; + remote-endpoint = + <&replicator_swao_out_replicator_qdss>; + }; + }; + + }; + }; + + tmc_etr: tmc@6048000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b961>; + reg = <0x6048000 0x1000>, + <0x6064000 0x15000>; + reg-names = "tmc-base", "bam-base"; + + qcom,smmu-s1-bypass; + iommus = <&apps_smmu 0x04a0 0>, + <&apps_smmu 0x0480 0>; + + coresight-ctis = <&cti0 &cti0>; + coresight-csr = <&csr>; + coresight-name = "coresight-tmc-etr"; + arm,buffer-size = <0x400000>; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + + interrupts = ; + interrupt-names = "byte-cntr-irq"; + + port { + tmc_etr_in_replicator_qdss: endpoint { + slave-mode; + remote-endpoint = + <&replicator_qdss_out_tmc_etr>; + }; + }; + }; + + cti_apss_cti0: cti@78e0000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x78e0000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti-apss_cti0"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_apss_cti1: cti@78f0000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x78f0000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti-apss_cti1"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_apss_cti2: cti@7900000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x7900000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti-apss_cti2"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti0: cti@6010000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6010000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti0"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti1: cti@6011000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6011000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti1"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti10: cti@601a000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x601a000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti10"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti11: cti@601b000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x601b000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti11"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti12: cti@601c000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x601c000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti12"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti13: cti@601d000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x601d000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti13"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti14: cti@601e000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x601e000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti14"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti15: cti@601f000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x601f000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti15"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti2: cti@6012000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6012000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti2"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti3: cti@6013000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6013000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti3"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti4: cti@6014000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6014000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti4"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti5: cti@6015000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6015000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti5"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti6: cti@6016000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6016000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti6"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti7: cti@6017000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6017000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti7"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti8: cti@6018000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6018000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti8"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti9: cti@6019000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6019000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti9"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_mss: cti@680b000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x680b000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti-mss_q6"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_venus: cti@6830000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6830000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti-arm9"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_lpass_dl_cti: cti@6845000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6845000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti-lpass_dl_cti"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_gpu_isdb_cti: cti@6941000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6941000 0x1000>; + reg-names = "cti-base"; + + status = "disabled"; + coresight-name = "coresight-cti-gpu_isdb_cti"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_gpu_cortex_m3: cti@6942000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6942000 0x1000>; + reg-names = "cti-base"; + + status = "disabled"; + coresight-name = "coresight-cti-gpu_cortex_m3"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_turing_dl_cti: cti@6982000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6982000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti-turing_dl_cti"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_turing_q6_cti: cti@698b000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x698b000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti-turing_q6_cti"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_dl_north_cti0: cti@6ac1000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6ac1000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti-dlnt_cti0"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_dl_north_cti1: cti@6ac2000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6ac2000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti-dlnt_cti1"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_dl_north_cti2: cti@6ac3000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6ac3000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti-dlnt_cti2"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_dl_north_cti3: cti@6ac4000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6ac4000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti-dlnt_cti3"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_swao_cti0: cti@6b00000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6b00000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti-swao_cti0"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_swao_cti1: cti@6b01000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6b01000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti-swao_cti1"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_swao_cti2: cti@6b02000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6b02000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti-swao_cti2"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_swao_cti3: cti@6b03000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6b03000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti-swao_cti3"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_aop_m3: cti@6b0e000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6b0e000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti-cortex_m3"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_lpass_lpi_cti: cti@6b21000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6b21000 0x1000>; + reg-names = "cti-base"; + + status = "disabled"; + + coresight-name = "coresight-cti-lpass_lpi_cti"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_lpass_q6_cti: cti@6b2B000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6b2B000 0x1000>; + reg-names = "cti-base"; + + status = "disabled"; + coresight-name = "coresight-cti-lpass_q6_cti"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_dlct_cti0: cti@6c2a000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6c2a000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti-dlct0_cti0"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_dlct_cti1: cti@6C2b000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6C2b000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti-dlct0_cti1"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_dlct_cti2: cti@6c2c000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6c2c000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti-dlct0_cti2"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_npu_dl_cti_0: cti@6c42000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6c42000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti-npu_dl_cti_0"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_npu_dl_cti_1: cti@6C43000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6C43000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti-npu_dl_cti_1"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_npu_q6_cti: cti@6C4b000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6C4b000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti-npu_q6_cti"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_sierra_a6_cti: cti@6c13000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6c13000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti-sierra_a6_cti"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_mdss_dl_cti: cti@6c61000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6c61000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti-mdss_dl_cti"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_ddr_dl_0_cti_0: cti@6f82000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6f82000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti-ddr_dl_0_cti_0"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_ddr_dl_0_cti_1: cti@6f83000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6f83000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti-ddr_dl_0_cti_1"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_ddr_dl_0_cti_2: cti@6f84000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6f84000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti-ddr_dl_0_cti_2"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_ddr_dl_1_cti_0: cti@6f90000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6f90000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti-ddr_dl_1_cti_0"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_ddr_dl_1_cti_1: cti@6f91000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6f91000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti-ddr_dl_1_cti_1"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_ddr_dl_1_cti_2: cti@6f92000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x6f92000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti-ddr_dl_1_cti_2"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_olc: cti@7831000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x7831000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti-olc"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + cti_dl_apss: cti@7861000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b966>; + reg = <0x7861000 0x1000>; + reg-names = "cti-base"; + + coresight-name = "coresight-cti-dl-apss"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + stm: stm@6002000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b962>; + + reg = <0x6002000 0x1000>, + <0x16280000 0x180000>; + reg-names = "stm-base", "stm-stimulus-base"; + + coresight-name = "coresight-stm"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + + port { + stm_out_funnel_in0: endpoint { + remote-endpoint = <&funnel_in0_in_stm>; + }; + }; + + }; + + swao_csr: csr@6b0c000 { + compatible = "qcom,coresight-csr"; + reg = <0x6b0c000 0x1000>; + reg-names = "csr-base"; + + coresight-name = "coresight-swao-csr"; + qcom,timestamp-support; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + + qcom,blk-size = <1>; + }; + + hwevent { + compatible = "qcom,coresight-hwevent"; + + coresight-name = "coresight-hwevent"; + coresight-csr = <&csr>; + clocks = <&clock_aop QDSS_CLK>; + clock-names = "apb_pclk"; + }; + + dummy_eud: dummy_sink { + compatible = "qcom,coresight-dummy"; + + coresight-name = "coresight-eud"; + + qcom,dummy-sink; + port { + eud_in_replicator_swao: endpoint { + slave-mode; + remote-endpoint = + <&replicator_swao_out_eud>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index 05e738faf684..08599320e9d0 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -1751,5 +1751,6 @@ #include "pm6150l.dtsi" #include "atoll-pinctrl.dtsi" #include "atoll-pm.dtsi" +#include "atoll-coresight.dtsi" #include "atoll-stub-regulator.dtsi" #include "atoll-usb.dtsi" -- GitLab From e5971af7ba53fbc8a0b8c6ba3ce128b8f8601cc8 Mon Sep 17 00:00:00 2001 From: Sujeev Dias Date: Tue, 5 Mar 2019 19:06:59 -0800 Subject: [PATCH 0543/1121] mhi: core: add support for dynamic bandwidth scaling Some MHI based devices support dynamic bandwidth scaling, based on required throughput device will request required bandwidth. CRs-Fixed: 2418347 Change-Id: I7903570eb225b2fe38a1fd425a23c63339f5f691 Signed-off-by: Sujeev Dias --- drivers/bus/mhi/core/mhi_internal.h | 3 +++ drivers/bus/mhi/core/mhi_main.c | 19 +++++++++++++++++++ drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c | 5 +---- include/linux/mhi.h | 16 ++++++++++++++++ 4 files changed, 39 insertions(+), 4 deletions(-) diff --git a/drivers/bus/mhi/core/mhi_internal.h b/drivers/bus/mhi/core/mhi_internal.h index 5da0feab0eab..dac18684e27a 100644 --- a/drivers/bus/mhi/core/mhi_internal.h +++ b/drivers/bus/mhi/core/mhi_internal.h @@ -336,6 +336,8 @@ enum mhi_cmd_type { #define MHI_TRE_GET_EV_TIME(tre) ((tre)->ptr) #define MHI_TRE_GET_EV_COOKIE(tre) lower_32_bits((tre)->ptr) #define MHI_TRE_GET_EV_VEID(tre) (((tre)->dword[0] >> 16) & 0xFF) +#define MHI_TRE_GET_EV_LINKSPEED(tre) (((tre)->dword[1] >> 24) & 0xFF) +#define MHI_TRE_GET_EV_LINKWIDTH(tre) ((tre)->dword[0] & 0xFF) /* transfer descriptor macros */ #define MHI_TRE_DATA_PTR(ptr) (ptr) @@ -368,6 +370,7 @@ enum MHI_PKT_TYPE { MHI_PKT_TYPE_RSC_TX_EVENT = 0x28, MHI_PKT_TYPE_EE_EVENT = 0x40, MHI_PKT_TYPE_TSYNC_EVENT = 0x48, + MHI_PKT_TYPE_BW_REQ_EVENT = 0x50, MHI_PKT_TYPE_STALE_EVENT, /* internal event */ }; diff --git a/drivers/bus/mhi/core/mhi_main.c b/drivers/bus/mhi/core/mhi_main.c index d4d943c6a64e..c0871a3320c5 100644 --- a/drivers/bus/mhi/core/mhi_main.c +++ b/drivers/bus/mhi/core/mhi_main.c @@ -1124,6 +1124,25 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl, local_rp->ptr, local_rp->dword[0], local_rp->dword[1]); switch (type) { + case MHI_PKT_TYPE_BW_REQ_EVENT: + { + struct mhi_link_info *link_info; + + link_info = &mhi_cntrl->mhi_link_info; + write_lock_irq(&mhi_cntrl->pm_lock); + link_info->target_link_speed = + MHI_TRE_GET_EV_LINKSPEED(local_rp); + link_info->target_link_width = + MHI_TRE_GET_EV_LINKWIDTH(local_rp); + write_unlock_irq(&mhi_cntrl->pm_lock); + MHI_VERB( + "Received BW_REQ with link speed:0x%x width:0x%x\n", + link_info->target_link_speed, + link_info->target_link_width); + mhi_cntrl->status_cb(mhi_cntrl, mhi_cntrl->priv_data, + MHI_CB_BW_REQ); + break; + } case MHI_PKT_TYPE_STATE_CHANGE_EVENT: { enum mhi_dev_state new_state; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c b/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c index 940012679921..0ffa9babe78f 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c @@ -2262,10 +2262,7 @@ static void ipa_mpm_mhi_status_cb(struct mhi_device *mhi_dev, IPA_MPM_DBG("Already out of lpm\n"); } break; - case MHI_CB_EE_RDDM: - case MHI_CB_PENDING_DATA: - case MHI_CB_SYS_ERROR: - case MHI_CB_FATAL_ERROR: + default: IPA_MPM_ERR("unexpected event %d\n", mhi_cb); break; } diff --git a/include/linux/mhi.h b/include/linux/mhi.h index ca05705ad7b1..1afd8e45f498 100644 --- a/include/linux/mhi.h +++ b/include/linux/mhi.h @@ -30,6 +30,7 @@ struct mhi_buf_info; * @MHI_CB_EE_RDDM: MHI device entered RDDM execution enviornment * @MHI_CB_SYS_ERROR: MHI device enter error state (may recover) * @MHI_CB_FATAL_ERROR: MHI device entered fatal error + * @MHI_CB_BW_REQ: Received a bandwidth switch request from device */ enum MHI_CB { MHI_CB_IDLE, @@ -39,6 +40,7 @@ enum MHI_CB { MHI_CB_EE_RDDM, MHI_CB_SYS_ERROR, MHI_CB_FATAL_ERROR, + MHI_CB_BW_REQ, }; /** @@ -115,6 +117,16 @@ enum mhi_dev_state { MHI_STATE_MAX, }; +/** + * struct mhi_link_info - bw requirement + * target_link_speed - as defined by TLS bits in LinkControl reg + * target_link_width - as defined by NLW bits in LinkStatus reg + */ +struct mhi_link_info { + unsigned int target_link_speed; + unsigned int target_link_width; +}; + /** * struct image_info - firmware and rddm table table * @mhi_buf - Contain device firmware and rddm table @@ -164,6 +176,7 @@ struct image_info { * @pm_state: Power management state * @ee: MHI device execution environment * @dev_state: MHI STATE + * @mhi_link_info: requested link bandwidth by device * @status_cb: CB function to notify various power states to but master * @link_status: Query link status in case of abnormal value read from device * @runtime_get: Async runtime resume function @@ -255,6 +268,9 @@ struct mhi_controller { spinlock_t transition_lock; spinlock_t wlock; + /* target bandwidth info */ + struct mhi_link_info mhi_link_info; + /* debug counters */ u32 M0, M2, M3; -- GitLab From 5d28d8917800027b96823ad5a2cfca1cd05f5890 Mon Sep 17 00:00:00 2001 From: Sujeev Dias Date: Fri, 22 Mar 2019 13:42:42 -0700 Subject: [PATCH 0544/1121] mhi: cntrl: add support to dynamically change bandwidth scale For power saving benefits dynamically scale PCIe bandwidth based on throughput requirements. CRs-Fixed: 2418347 Change-Id: I12e5e333caf18f740dc417ba29ae1a2a7cb47771 Signed-off-by: Sujeev Dias --- drivers/bus/mhi/controllers/mhi_arch_qcom.c | 94 ++++++++++++++++++++- drivers/bus/mhi/controllers/mhi_qcom.c | 12 ++- drivers/bus/mhi/controllers/mhi_qcom.h | 4 + 3 files changed, 104 insertions(+), 6 deletions(-) diff --git a/drivers/bus/mhi/controllers/mhi_arch_qcom.c b/drivers/bus/mhi/controllers/mhi_arch_qcom.c index 0de99ee81c88..77d428583c5b 100644 --- a/drivers/bus/mhi/controllers/mhi_arch_qcom.c +++ b/drivers/bus/mhi/controllers/mhi_arch_qcom.c @@ -40,6 +40,8 @@ struct arch_info { async_cookie_t cookie; void *boot_ipc_log; struct mhi_device *boot_dev; + struct mhi_link_info current_link_info; + struct work_struct bw_scale_work; }; /* ipc log markings */ @@ -227,6 +229,74 @@ int mhi_arch_power_up(struct mhi_controller *mhi_cntrl) return 0; } +static int mhi_arch_pcie_scale_bw(struct mhi_controller *mhi_cntrl, + struct pci_dev *pci_dev, + struct mhi_link_info *link_info) +{ + int ret, scale; + + ret = msm_pcie_set_link_bandwidth(pci_dev, link_info->target_link_speed, + link_info->target_link_width); + if (ret) + return ret; + + /* if we switch to low bw release bus scale voting */ + scale = !(link_info->target_link_speed == PCI_EXP_LNKSTA_CLS_2_5GB); + mhi_arch_set_bus_request(mhi_cntrl, scale); + + MHI_VERB("bw changed to speed:0x%x width:0x%x bus_scale:%d\n", + link_info->target_link_speed, link_info->target_link_width, + scale); + + return 0; +} + +static void mhi_arch_pcie_bw_scale_work(struct work_struct *work) +{ + struct arch_info *arch_info = container_of(work, + struct arch_info, + bw_scale_work); + struct mhi_dev *mhi_dev = arch_info->mhi_dev; + struct pci_dev *pci_dev = mhi_dev->pci_dev; + struct device *dev = &pci_dev->dev; + struct mhi_controller *mhi_cntrl = dev_get_drvdata(dev); + struct mhi_link_info mhi_link_info; + struct mhi_link_info *cur_info = &arch_info->current_link_info; + int ret; + + mutex_lock(&mhi_cntrl->pm_mutex); + if (!mhi_dev->powered_on || + pm_runtime_status_suspended(dev) || dev->power.is_suspended) + goto exit_work; + + /* copy the latest speed change */ + write_lock_irq(&mhi_cntrl->pm_lock); + mhi_link_info = mhi_cntrl->mhi_link_info; + write_unlock_irq(&mhi_cntrl->pm_lock); + + /* link is already set to current settings */ + if (cur_info->target_link_speed == mhi_link_info.target_link_speed && + cur_info->target_link_width == mhi_link_info.target_link_width) + goto exit_work; + + ret = mhi_arch_pcie_scale_bw(mhi_cntrl, pci_dev, &mhi_link_info); + if (ret) + goto exit_work; + + *cur_info = mhi_link_info; + +exit_work: + mutex_unlock(&mhi_cntrl->pm_mutex); +} + +static void mhi_arch_pcie_bw_scale_cb(struct mhi_controller *mhi_cntrl, + struct mhi_dev *mhi_dev) +{ + struct arch_info *arch_info = mhi_dev->arch_info; + + schedule_work(&arch_info->bw_scale_work); +} + static int mhi_bl_probe(struct mhi_device *mhi_device, const struct mhi_device_id *id) { @@ -336,6 +406,10 @@ int mhi_arch_pcie_init(struct mhi_controller *mhi_cntrl) arch_info->ref_pcie_state = pci_store_saved_state( mhi_dev->pci_dev); + INIT_WORK(&arch_info->bw_scale_work, + mhi_arch_pcie_bw_scale_work); + mhi_dev->bw_scale = mhi_arch_pcie_bw_scale_cb; + mhi_driver_register(&mhi_bl_driver); } @@ -518,14 +592,18 @@ int mhi_arch_link_on(struct mhi_controller *mhi_cntrl) struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl); struct arch_info *arch_info = mhi_dev->arch_info; struct pci_dev *pci_dev = mhi_dev->pci_dev; + struct mhi_link_info *cur_info = &arch_info->current_link_info; + struct mhi_link_info *updated_info = &mhi_cntrl->mhi_link_info; int ret; MHI_LOG("Entered\n"); - /* request resources and establish link trainning */ - ret = mhi_arch_set_bus_request(mhi_cntrl, 1); - if (ret) - MHI_LOG("Could not set bus frequency, ret:%d\n", ret); + /* request bus scale voting if we're on Gen 2 or higher speed */ + if (cur_info->target_link_speed != PCI_EXP_LNKSTA_CLS_2_5GB) { + ret = mhi_arch_set_bus_request(mhi_cntrl, 1); + if (ret) + MHI_LOG("Could not set bus frequency, ret:%d\n", ret); + } ret = msm_pcie_pm_control(MSM_PCIE_RESUME, mhi_cntrl->bus, pci_dev, NULL, 0); @@ -553,6 +631,14 @@ int mhi_arch_link_on(struct mhi_controller *mhi_cntrl) pci_restore_state(pci_dev); pci_set_master(pci_dev); + /* BW request from device doesn't match current link speed */ + if (cur_info->target_link_speed != updated_info->target_link_speed || + cur_info->target_link_width != updated_info->target_link_width) { + ret = mhi_arch_pcie_scale_bw(mhi_cntrl, pci_dev, updated_info); + if (!ret) + *cur_info = *updated_info; + } + MHI_LOG("Exited\n"); return 0; diff --git a/drivers/bus/mhi/controllers/mhi_qcom.c b/drivers/bus/mhi/controllers/mhi_qcom.c index 88ccb1493548..758306b0ee22 100644 --- a/drivers/bus/mhi/controllers/mhi_qcom.c +++ b/drivers/bus/mhi/controllers/mhi_qcom.c @@ -433,10 +433,18 @@ static void mhi_status_cb(struct mhi_controller *mhi_cntrl, struct mhi_dev *mhi_dev = priv; struct device *dev = &mhi_dev->pci_dev->dev; - if (reason == MHI_CB_IDLE) { - MHI_LOG("Schedule runtime suspend 1\n"); + switch (reason) { + case MHI_CB_IDLE: + MHI_LOG("Schedule runtime suspend\n"); pm_runtime_mark_last_busy(dev); pm_request_autosuspend(dev); + break; + case MHI_CB_BW_REQ: + if (mhi_dev->bw_scale) + mhi_dev->bw_scale(mhi_cntrl, mhi_dev); + break; + default: + MHI_ERR("Unhandled cb:0x%x\n", reason); } } diff --git a/drivers/bus/mhi/controllers/mhi_qcom.h b/drivers/bus/mhi/controllers/mhi_qcom.h index a843c98341b9..a92de13288ad 100644 --- a/drivers/bus/mhi/controllers/mhi_qcom.h +++ b/drivers/bus/mhi/controllers/mhi_qcom.h @@ -38,6 +38,10 @@ struct mhi_dev { dma_addr_t iova_start; dma_addr_t iova_stop; bool lpm_disabled; + + /* if set, soc support dynamic bw scaling */ + void (*bw_scale)(struct mhi_controller *mhi_cntrl, + struct mhi_dev *mhi_dev); }; void mhi_deinit_pci_dev(struct mhi_controller *mhi_cntrl); -- GitLab From 577b474ede735660ef7d0b83fa2ca95078e4af04 Mon Sep 17 00:00:00 2001 From: Sujeev Dias Date: Wed, 27 Feb 2019 14:59:23 -0800 Subject: [PATCH 0545/1121] pci: framework: disable auto suspend link Some endpoint devices do not go into D3hot during suspend. By pass auto suspend if device do not allow D3hot. CRs-Fixed: 2418347 Change-Id: Ida6e4a2b60b7d08932bfff79144afd67787ca0f2 Signed-off-by: Sujeev Dias --- drivers/pci/pci-driver.c | 16 +++++++++++++++- include/linux/pci.h | 1 + 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index ea69b4dbab66..a394ebdc258c 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -799,6 +799,10 @@ static int pci_pm_suspend_noirq(struct device *dev) } } + /* if d3hot is not supported bail out */ + if (pci_dev->no_d3hot) + return 0; + if (!pci_dev->state_saved) { pci_save_state(pci_dev); if (pci_power_manageable(pci_dev)) @@ -831,7 +835,8 @@ static int pci_pm_resume_noirq(struct device *dev) struct device_driver *drv = dev->driver; int error = 0; - pci_pm_default_resume_early(pci_dev); + if (!pci_dev->no_d3hot) + pci_pm_default_resume_early(pci_dev); if (pci_has_legacy_pm_support(pci_dev)) return pci_legacy_resume_early(dev); @@ -1204,6 +1209,10 @@ static int pci_pm_runtime_suspend(struct device *dev) return 0; } + /* if d3hot is not supported bail out */ + if (pci_dev->no_d3hot) + return 0; + if (!pci_dev->state_saved) { pci_save_state(pci_dev); pci_finish_runtime_suspend(pci_dev); @@ -1218,6 +1227,10 @@ static int pci_pm_runtime_resume(struct device *dev) struct pci_dev *pci_dev = to_pci_dev(dev); const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + /* we skipped d3hot processing so skip re-init */ + if (pci_dev->no_d3hot) + goto skip_restore; + /* * Restoring config space is necessary even if the device is not bound * to a driver because although we left it in D0, it may have gone to @@ -1235,6 +1248,7 @@ static int pci_pm_runtime_resume(struct device *dev) pci_enable_wake(pci_dev, PCI_D0, false); pci_fixup_device(pci_fixup_resume, pci_dev); +skip_restore: rc = pm->runtime_resume(dev); pci_dev->runtime_d3cold = false; diff --git a/include/linux/pci.h b/include/linux/pci.h index b1abbcc614cf..95dcc8cfc139 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -337,6 +337,7 @@ struct pci_dev { unsigned int d2_support:1; /* Low power state D2 is supported */ unsigned int no_d1d2:1; /* D1 and D2 are forbidden */ unsigned int no_d3cold:1; /* D3cold is forbidden */ + unsigned int no_d3hot:1; /* D3hot is forbidden */ unsigned int bridge_d3:1; /* Allow D3 for bridge */ unsigned int d3cold_allowed:1; /* D3cold is allowed by user */ unsigned int mmio_always_on:1; /* disallow turning off io/mem -- GitLab From 30fe760074b5973b0ecc55f00fea09797fd2cfae Mon Sep 17 00:00:00 2001 From: Sujeev Dias Date: Fri, 19 Apr 2019 10:48:14 -0700 Subject: [PATCH 0546/1121] mhi: cntrl: qcom: save POR PCIe link speed during probe MHI host could transition into system suspend before receiving any bandwidth change request from device. Without a default link state, host would switch link state into unsupported state and cause a PCIe link down. Avoid this unsupported scenario by explicitly saving the initial link state during probe. CRs-Fixed: 2436570 Change-Id: Icc5c681937a51eeb4f2df3c95914f924311ca388 Signed-off-by: Sujeev Dias --- drivers/bus/mhi/controllers/mhi_arch_qcom.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/bus/mhi/controllers/mhi_arch_qcom.c b/drivers/bus/mhi/controllers/mhi_arch_qcom.c index 77d428583c5b..e8d8d3323d32 100644 --- a/drivers/bus/mhi/controllers/mhi_arch_qcom.c +++ b/drivers/bus/mhi/controllers/mhi_arch_qcom.c @@ -341,9 +341,11 @@ int mhi_arch_pcie_init(struct mhi_controller *mhi_cntrl) struct arch_info *arch_info = mhi_dev->arch_info; char node[32]; int ret; + u16 linkstat; if (!arch_info) { struct msm_pcie_register_event *reg_event; + struct mhi_link_info *cur_link_info; arch_info = devm_kzalloc(&mhi_dev->pci_dev->dev, sizeof(*arch_info), GFP_KERNEL); @@ -410,6 +412,20 @@ int mhi_arch_pcie_init(struct mhi_controller *mhi_cntrl) mhi_arch_pcie_bw_scale_work); mhi_dev->bw_scale = mhi_arch_pcie_bw_scale_cb; + /* store the current bw info */ + ret = pcie_capability_read_word(mhi_dev->pci_dev, + PCI_EXP_LNKSTA, &linkstat); + if (ret) + return ret; + + cur_link_info = &arch_info->current_link_info; + cur_link_info->target_link_speed = + linkstat & PCI_EXP_LNKSTA_CLS; + cur_link_info->target_link_width = + (linkstat & PCI_EXP_LNKSTA_NLW) >> + PCI_EXP_LNKSTA_NLW_SHIFT; + mhi_cntrl->mhi_link_info = *cur_link_info; + mhi_driver_register(&mhi_bl_driver); } -- GitLab From b8087aaab893741c323d3d6af4d8745be55252c1 Mon Sep 17 00:00:00 2001 From: Manaf Meethalavalappu Pallikunhi Date: Wed, 12 Jun 2019 14:40:24 +0530 Subject: [PATCH 0547/1121] ARM: dts: msm: Update quiet-therm thermal zone polling_delay for TRINKET Update polling_delay for quiet-thermal-adc user_space thermal zone for TRINKET. Change-Id: I471644a7628176f3700bb2d1128fdd9177451b7f Signed-off-by: Manaf Meethalavalappu Pallikunhi --- arch/arm64/boot/dts/qcom/trinket-thermal.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/trinket-thermal.dtsi b/arch/arm64/boot/dts/qcom/trinket-thermal.dtsi index 261e9d9d0910..bd964c615005 100644 --- a/arch/arm64/boot/dts/qcom/trinket-thermal.dtsi +++ b/arch/arm64/boot/dts/qcom/trinket-thermal.dtsi @@ -117,7 +117,7 @@ quiet-therm-adc { polling-delay-passive = <0>; - polling-delay = <0>; + polling-delay = <5000>; thermal-governor = "user_space"; thermal-sensors = <&pm6125_adc_tm ADC_AMUX_THM2_PU2>; wake-capable-sensor; -- GitLab From 4234fa74fdda2e39865fefb54d1ec35a37fdafe4 Mon Sep 17 00:00:00 2001 From: Mitul Golani Date: Thu, 9 May 2019 18:13:16 +0530 Subject: [PATCH 0548/1121] serial: msm_geni_serial: Double clock-divider for kona based hw Clock devider needs to get double for kona based HW as sampling rate is half. Change-Id: I7a5d2deeb36df918c009afe871e82c27cdb74e0b Signed-off-by: Mitul Golani --- drivers/platform/msm/qcom-geni-se.c | 3 --- drivers/tty/serial/msm_geni_serial.c | 12 ++++++++++++ include/linux/qcom-geni-se.h | 1 + 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/platform/msm/qcom-geni-se.c b/drivers/platform/msm/qcom-geni-se.c index 145dfd9ad5ad..0e296c313e92 100644 --- a/drivers/platform/msm/qcom-geni-se.c +++ b/drivers/platform/msm/qcom-geni-se.c @@ -127,9 +127,6 @@ struct geni_se_device { bool vote_for_bw; }; -/* Offset of QUPV3 Hardware Version Register */ -#define QUPV3_HW_VER (0x4) - #define HW_VER_MAJOR_MASK GENMASK(31, 28) #define HW_VER_MAJOR_SHFT 28 #define HW_VER_MINOR_MASK GENMASK(27, 16) diff --git a/drivers/tty/serial/msm_geni_serial.c b/drivers/tty/serial/msm_geni_serial.c index a47f873c2659..c8b8cf01af41 100644 --- a/drivers/tty/serial/msm_geni_serial.c +++ b/drivers/tty/serial/msm_geni_serial.c @@ -131,6 +131,8 @@ #define DMA_RX_BUF_SIZE (2048) #define UART_CONSOLE_RX_WM (2) +#define QUP_VER (0x20050000) + struct msm_geni_serial_port { struct uart_port uport; char name[20]; @@ -199,6 +201,11 @@ static atomic_t uart_line_id = ATOMIC_INIT(0); static struct msm_geni_serial_port msm_geni_console_port; static struct msm_geni_serial_port msm_geni_serial_ports[GENI_UART_NR_PORTS]; +static int hw_version_info(void __iomem *base_addr) +{ + return geni_read_reg(base_addr, QUPV3_HW_VER); +} + static void msm_geni_serial_config_port(struct uart_port *uport, int cfg_flags) { if (cfg_flags & UART_CONFIG_TYPE) @@ -1792,6 +1799,7 @@ static void geni_serial_write_term_regs(struct uart_port *uport, u32 loopback, SE_UART_TX_STOP_BIT_LEN); geni_write_reg_nolog(s_clk_cfg, uport->membase, GENI_SER_M_CLK_CFG); geni_write_reg_nolog(s_clk_cfg, uport->membase, GENI_SER_S_CLK_CFG); + geni_read_reg_nolog(uport->membase, GENI_SER_M_CLK_CFG); } static int get_clk_div_rate(unsigned int baud, unsigned long *desired_clk_rate) @@ -1855,6 +1863,8 @@ static void msm_geni_serial_set_termios(struct uart_port *uport, if (clk_div <= 0) goto exit_set_termios; + if (hw_version_info(uport->membase) >= QUP_VER) + clk_div *= 2; uport->uartclk = clk_rate; clk_set_rate(port->serial_rsc.se_clk, clk_rate); ser_clk_cfg |= SER_CLK_EN; @@ -2133,6 +2143,8 @@ msm_geni_serial_earlycon_setup(struct earlycon_device *dev, goto exit_geni_serial_earlyconsetup; } + if (hw_version_info(uport->membase) >= QUP_VER) + clk_div *= 2; s_clk_cfg |= SER_CLK_EN; s_clk_cfg |= (clk_div << CLK_DIV_SHFT); diff --git a/include/linux/qcom-geni-se.h b/include/linux/qcom-geni-se.h index 21aee963e37b..85028238b94a 100644 --- a/include/linux/qcom-geni-se.h +++ b/include/linux/qcom-geni-se.h @@ -138,6 +138,7 @@ struct se_geni_rsc { #define SE_DMA_DEBUG_REG0 (0xE40) #define SLAVE_MODE_EN (BIT(3)) #define START_TRIGGER (BIT(0)) +#define QUPV3_HW_VER (0x4) /* GENI_OUTPUT_CTRL fields */ #define DEFAULT_IO_OUTPUT_CTRL_MSK (GENMASK(6, 0)) -- GitLab From b790b145296302438d1c8de8faab29dba69efa36 Mon Sep 17 00:00:00 2001 From: Ziqi Chen Date: Tue, 11 Jun 2019 15:39:48 +0800 Subject: [PATCH 0549/1121] phy: qcom-ufs-qmp-v3-660: increase the minimum time in hibernate Some UFS devices violate T-HIBERN8_ENTER_TX time when moving Device TX (Host RX) lane-1 from SLEEP to HIBERN8 at the end of burst. M-PHY specification defines max value of 1000 ns for T-HIBERN8_ENTER_TX but these devices drive DIF-N for 3432 ns. This can cause the broken link situation after link starup. This change fixes above issue by increasing host PHY's RX_MIN_HIBERN8_TIME to 8us (we are giving some additional margin though device needs 3.432us). Change-Id: If11d873534a025dca4bb9cea4ab3f76073001dc9 Signed-off-by: Ziqi Chen --- drivers/phy/qualcomm/phy-qcom-ufs-qmp-v3-660.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/phy/qualcomm/phy-qcom-ufs-qmp-v3-660.h b/drivers/phy/qualcomm/phy-qcom-ufs-qmp-v3-660.h index 8d0183d87e20..b7655ea0cd55 100644 --- a/drivers/phy/qualcomm/phy-qcom-ufs-qmp-v3-660.h +++ b/drivers/phy/qualcomm/phy-qcom-ufs-qmp-v3-660.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2016,2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -155,6 +155,7 @@ #define UFS_PHY_RX_MIN_STALL_NOCONFIG_TIME_CAP PHY_OFF(0xCC) #define UFS_PHY_LINECFG_DISABLE PHY_OFF(0x138) #define UFS_PHY_RX_SYM_RESYNC_CTRL PHY_OFF(0x13C) +#define UFS_PHY_RX_MIN_HIBERN8_TIME PHY_OFF(0x140) #define UFS_PHY_RX_SIGDET_CTRL2 PHY_OFF(0x148) #define UFS_PHY_RX_PWM_GEAR_BAND PHY_OFF(0x154) #define UFS_PHY_PCS_READY_STATUS PHY_OFF(0x168) @@ -274,6 +275,7 @@ static struct ufs_qcom_phy_calibration phy_cal_table_rate_A_3_1_1[] = { UFS_QCOM_PHY_CAL_ENTRY(UFS_PHY_TX_SMALL_AMP_DRV_LVL, 0x02), UFS_QCOM_PHY_CAL_ENTRY(UFS_PHY_RX_MIN_STALL_NOCONFIG_TIME_CAP, 0x28), UFS_QCOM_PHY_CAL_ENTRY(UFS_PHY_RX_SYM_RESYNC_CTRL, 0x03), + UFS_QCOM_PHY_CAL_ENTRY(UFS_PHY_RX_MIN_HIBERN8_TIME, 0x9A), /* 8 us */ }; static struct ufs_qcom_phy_calibration phy_cal_table_rate_B[] = { -- GitLab From 512b344bc64bfcc9b7a38f3d3760cde9049e0860 Mon Sep 17 00:00:00 2001 From: YUE CHEN Date: Tue, 4 Jun 2019 11:47:10 +0800 Subject: [PATCH 0550/1121] msm: ais: identify the ife lite Remove hard limit on 3x cameras on IFE lite Change-Id: I6eaf6ab0e45726eae842170cff33bf36ae3219d5 Signed-off-by: YUE CHEN --- .../ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe170.h | 1 + .../ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe175.h | 1 + .../cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe175_130.h | 1 + .../isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe_lite17x.h | 3 ++- .../isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c | 5 ++++- .../isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.h | 1 + 6 files changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe170.h b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe170.h index 61c1e9e01ba2..4c525ff1b5f7 100644 --- a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe170.h +++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe170.h @@ -246,6 +246,7 @@ static struct cam_vfe_bus_ver2_hw_info vfe170_bus_hw_info = { .debug_status_0 = 0x00002270, }, .num_client = 20, + .is_lite = 0, .bus_client_reg = { /* BUS Client 0 */ { diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe175.h b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe175.h index edb595e70ad9..0d0d593bd108 100644 --- a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe175.h +++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe175.h @@ -309,6 +309,7 @@ static struct cam_vfe_bus_ver2_hw_info vfe175_bus_hw_info = { .debug_status_0 = 0x00002270, }, .num_client = 24, + .is_lite = 0, .bus_client_reg = { /* BUS Client 0 */ { diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe175_130.h b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe175_130.h index 3ca5bec71113..eb4c62a632a7 100644 --- a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe175_130.h +++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe175_130.h @@ -410,6 +410,7 @@ static struct cam_vfe_bus_ver2_hw_info vfe175_130_bus_hw_info = { .addr_sync_no_sync = 0x00002084, }, .num_client = 24, + .is_lite = 0, .bus_client_reg = { /* BUS Client 0 */ { diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe_lite17x.h b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe_lite17x.h index 9767f9716581..9733a1fe7515 100644 --- a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe_lite17x.h +++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe_lite17x.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -153,6 +153,7 @@ static struct cam_vfe_bus_ver2_hw_info vfe17x_bus_hw_info = { .addr_sync_no_sync = 0x00002084, }, .num_client = 4, + .is_lite = 1, .bus_client_reg = { /* BUS Client 0 */ { diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c index 61e17ab46565..bf2b33c81313 100644 --- a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c +++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c @@ -199,6 +199,7 @@ struct cam_vfe_bus_ver2_priv { struct cam_vfe_bus_ver2_common_data common_data; uint32_t num_client; uint32_t num_out; + uint32_t is_lite; struct cam_isp_resource_node bus_client[CAM_VFE_BUS_VER2_MAX_CLIENTS]; struct cam_isp_resource_node comp_grp[CAM_VFE_BUS_VER2_COMP_GRP_MAX]; @@ -922,7 +923,8 @@ static int cam_vfe_bus_acquire_wm( CAM_DBG(CAM_ISP, "WM %d width %d height %d", rsrc_data->index, rsrc_data->width, rsrc_data->height); - if (rsrc_data->index < 3) { + if (rsrc_data->index < 3 || + (ver2_bus_priv->is_lite && rsrc_data->index == 3)) { /* Write master 0-2 refers to RDI 0/ RDI 1/RDI 2 */ if ((out_port_info->reserved >> 8) & 0x01) { /* frame based mode as default */ @@ -3420,6 +3422,7 @@ int cam_vfe_bus_ver2_init( bus_priv->num_client = ver2_hw_info->num_client; bus_priv->num_out = ver2_hw_info->num_out; + bus_priv->is_lite = ver2_hw_info->is_lite; bus_priv->common_data.num_sec_out = 0; bus_priv->common_data.secure_mode = CAM_SECURE_MODE_NON_SECURE; bus_priv->common_data.core_index = soc_info->index; diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.h b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.h index 39d8fa561590..7d267fc000f7 100644 --- a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.h +++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.h @@ -203,6 +203,7 @@ struct cam_vfe_bus_ver2_reg_data { struct cam_vfe_bus_ver2_hw_info { struct cam_vfe_bus_ver2_reg_offset_common common_reg; uint32_t num_client; + uint32_t is_lite; struct cam_vfe_bus_ver2_reg_offset_bus_client bus_client_reg[CAM_VFE_BUS_VER2_MAX_CLIENTS]; struct cam_vfe_bus_ver2_reg_offset_comp_grp -- GitLab From c99fc13d74faa833fe52117b149e4e9611719ec5 Mon Sep 17 00:00:00 2001 From: Prudhvi Yarlagadda Date: Tue, 11 Jun 2019 14:46:33 +0530 Subject: [PATCH 0551/1121] slim-msm-ngd: Create a IPC error logging file Create a IPC logging file to log the errors from slimbus. This reduces the logging from slimbus in console logs. Change-Id: I71bf849a7b4c6c4791e2f4f98dba187a5eb833fe Signed-off-by: Prudhvi Yarlagadda --- drivers/slimbus/slim-msm-ngd.c | 16 ++++++++++++++++ drivers/slimbus/slim-msm.h | 24 +++++++++++++++++++----- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/drivers/slimbus/slim-msm-ngd.c b/drivers/slimbus/slim-msm-ngd.c index b53189210027..740dd5d6c3f3 100644 --- a/drivers/slimbus/slim-msm-ngd.c +++ b/drivers/slimbus/slim-msm-ngd.c @@ -1758,6 +1758,7 @@ static int ngd_slim_probe(struct platform_device *pdev) bool rxreg_access = false; bool slim_mdm = false; const char *ext_modem_id = NULL; + char ipc_err_log_name[30]; if (of_device_is_compatible(pdev->dev.of_node, "qcom,iommu-slim-ctrl-cb")) @@ -1824,6 +1825,21 @@ static int ngd_slim_probe(struct platform_device *pdev) SLIM_INFO(dev, "start logging for slim dev %s\n", dev_name(dev->dev)); } + + /* Create Error IPC log context */ + memset(ipc_err_log_name, 0, sizeof(ipc_err_log_name)); + scnprintf(ipc_err_log_name, sizeof(ipc_err_log_name), "%s%s", + dev_name(dev->dev), "_err"); + dev->ipc_slimbus_log_err = + ipc_log_context_create(IPC_SLIMBUS_LOG_PAGES, + ipc_err_log_name, 0); + if (!dev->ipc_slimbus_log_err) + dev_err(&pdev->dev, + "error creating ipc_error_logging context\n"); + else + SLIM_INFO(dev, "start error logging for slim dev %s\n", + ipc_err_log_name); + ret = sysfs_create_file(&dev->dev->kobj, &dev_attr_debug_mask.attr); if (ret) { dev_err(&pdev->dev, "Failed to create dev. attr\n"); diff --git a/drivers/slimbus/slim-msm.h b/drivers/slimbus/slim-msm.h index 44a6759ce4f3..adf2ba314461 100644 --- a/drivers/slimbus/slim-msm.h +++ b/drivers/slimbus/slim-msm.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -321,6 +321,7 @@ struct msm_slim_ctrl { int ipc_log_mask; bool sysfs_created; void *ipc_slimbus_log; + void *ipc_slimbus_log_err; void (*rx_slim)(struct msm_slim_ctrl *dev, u8 *buf); u32 current_rx_buf[10]; int current_count; @@ -376,6 +377,9 @@ enum { if (dev->ipc_slimbus_log && dev->ipc_log_mask >= DBG_LEV) { \ ipc_log_string(dev->ipc_slimbus_log, x); \ } \ + if (dev->ipc_slimbus_log_err && dev->ipc_log_mask == FATAL_LEV) { \ + ipc_log_string(dev->ipc_slimbus_log_err, x); \ + } \ } while (0) #define SLIM_INFO(dev, x...) do { \ @@ -383,26 +387,36 @@ enum { if (dev->ipc_slimbus_log && dev->ipc_log_mask >= INFO_LEV) {\ ipc_log_string(dev->ipc_slimbus_log, x); \ } \ + if (dev->ipc_slimbus_log_err && dev->ipc_log_mask == FATAL_LEV) { \ + ipc_log_string(dev->ipc_slimbus_log_err, x); \ + } \ } while (0) /* warnings and errors show up on console always */ #define SLIM_WARN(dev, x...) do { \ - pr_warn(x); \ - if (dev->ipc_slimbus_log && dev->ipc_log_mask >= WARN_LEV) \ + if (dev->ipc_slimbus_log && dev->ipc_log_mask >= WARN_LEV) { \ + pr_warn(x); \ ipc_log_string(dev->ipc_slimbus_log, x); \ + } \ + if (dev->ipc_slimbus_log_err && dev->ipc_log_mask == FATAL_LEV) { \ + ipc_log_string(dev->ipc_slimbus_log_err, x); \ + } \ } while (0) /* ERROR condition in the driver sets the hs_serial_debug_mask * to ERR_FATAL level, so that this message can be seen - * in IPC logging. Further errors continue to log on the console + * in IPC logging. Further errors continue to log on the error IPC logging. */ #define SLIM_ERR(dev, x...) do { \ - pr_err(x); \ if (dev->ipc_slimbus_log && dev->ipc_log_mask >= ERR_LEV) { \ + pr_err(x); \ ipc_log_string(dev->ipc_slimbus_log, x); \ dev->default_ipc_log_mask = dev->ipc_log_mask; \ dev->ipc_log_mask = FATAL_LEV; \ } \ + if (dev->ipc_slimbus_log_err && dev->ipc_log_mask == FATAL_LEV) { \ + ipc_log_string(dev->ipc_slimbus_log_err, x); \ + } \ } while (0) #define SLIM_RST_LOGLVL(dev) { \ -- GitLab From 5c8e8fc3b1eb8fd167c4b128e5afa908204b2d41 Mon Sep 17 00:00:00 2001 From: Sahitya Tummala Date: Wed, 11 Oct 2017 10:12:19 +0530 Subject: [PATCH 0552/1121] mtd: msm_qpic_nand: Add support for performance stats Add support to collect driver level performance statistics on reads, writes and erases. Below are the commands to enable, reset and read the stats - echo 1 > /sys/module/msm_qpic_nand/parameters/enable_perfstats echo > /sys/devices/platform/1b00000.nand/perf_stats cat /sys/devices/platform/1b00000.nand/perf_stats The module parameter "enable_perfstats" can also be enabled during boot up by adding this to the kernel command line - "msm_qpic_nand.enable_perfstats=1". Change-Id: I20b35219a4bffd90682137969ecd5e854bea9a6b Signed-off-by: Sahitya Tummala Signed-off-by: Pradeep P V K --- drivers/mtd/devices/msm_qpic_nand.c | 203 ++++++++++++++++++++++++++++ drivers/mtd/devices/msm_qpic_nand.h | 23 +++- 2 files changed, 225 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/devices/msm_qpic_nand.c b/drivers/mtd/devices/msm_qpic_nand.c index 982a668c618c..1de9ab22dca2 100644 --- a/drivers/mtd/devices/msm_qpic_nand.c +++ b/drivers/mtd/devices/msm_qpic_nand.c @@ -27,6 +27,183 @@ #define SMEM_AARM_PARTITION_TABLE 9 #define SMEM_APPS 0 static bool enable_euclean; +static bool enable_perfstats; + +static ssize_t msm_nand_attr_perf_stats_show(struct device *dev, + struct device_attribute *attr, + char *buf); +static ssize_t msm_nand_attr_perf_stats_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count); + +static struct device_attribute dev_msm_nand_perf_stats = + __ATTR(perf_stats, 0644, + msm_nand_attr_perf_stats_show, msm_nand_attr_perf_stats_store); + +#define print_sysfs(fmt, ...) \ +{ \ + count += scnprintf(buf + count, PAGE_SIZE - count, \ + fmt, ##__VA_ARGS__); \ +} + +static ssize_t msm_nand_attr_perf_stats_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t count = 0; + struct msm_nand_info *info = dev_get_drvdata(dev); + + if (!enable_perfstats) { + print_sysfs("Performance stats is disabled\n"); + return count; + } + + spin_lock(&info->perf.lock); + print_sysfs("total_read_size = %llu\n", info->perf.total_read_size); + print_sysfs("total_write_size = %llu\n", info->perf.total_write_size); + print_sysfs("total_erase_blks = %llu\n\n", info->perf.total_erase_blks); + + print_sysfs("total_read_time_us = %lld\n", + ktime_to_us(info->perf.total_read_time)); + print_sysfs("total_write_time_us = %lld\n", + ktime_to_us(info->perf.total_write_time)); + print_sysfs("total_erase_time_us = %lld\n\n", + ktime_to_us(info->perf.total_erase_time)); + + print_sysfs("min_read_time_us = %lld\n", + ktime_to_us(info->perf.min_read_time)); + print_sysfs("min_write_time_us = %lld\n", + ktime_to_us(info->perf.min_write_time)); + print_sysfs("min_erase_time_us = %lld\n\n", + ktime_to_us(info->perf.min_erase_time)); + + print_sysfs("max_read_time_us = %lld\n", + ktime_to_us(info->perf.max_read_time)); + print_sysfs("max_write_time_us = %lld\n", + ktime_to_us(info->perf.max_write_time)); + print_sysfs("max_erase_time_us = %lld\n\n", + ktime_to_us(info->perf.max_erase_time)); + + spin_unlock(&info->perf.lock); + return count; +} + +static ssize_t msm_nand_attr_perf_stats_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct msm_nand_info *info = dev_get_drvdata(dev); + + if (!enable_perfstats) { + pr_err("couldn't write as perf stats is disabled\n"); + return -EPERM; + } + + if (count > 1 || (count == 1 && *buf != '\n')) { + pr_err("write not permitted\n"); + return -EPERM; + } + + spin_lock(&info->perf.lock); + info->perf.min_read_time = ktime_set(KTIME_MAX, 0); + info->perf.min_write_time = ktime_set(KTIME_MAX, 0); + info->perf.min_erase_time = ktime_set(KTIME_MAX, 0); + + info->perf.max_read_time = ktime_set(0, 0); + info->perf.max_write_time = ktime_set(0, 0); + info->perf.max_erase_time = ktime_set(0, 0); + + info->perf.total_read_time = ktime_set(0, 0); + info->perf.total_write_time = ktime_set(0, 0); + info->perf.total_erase_time = ktime_set(0, 0); + + info->perf.total_read_size = 0; + info->perf.total_write_size = 0; + info->perf.total_erase_blks = 0; + spin_unlock(&info->perf.lock); + + return count; +} + +static void msm_nand_init_perf_stats(struct msm_nand_info *info) +{ + spin_lock_init(&info->perf.lock); + info->perf.min_read_time = ktime_set(KTIME_MAX, 0); + info->perf.min_write_time = ktime_set(KTIME_MAX, 0); + info->perf.min_erase_time = ktime_set(KTIME_MAX, 0); +} + +static void msm_nand_init_sysfs(struct device *dev) +{ + sysfs_attr_init(&dev_msm_nand_perf_stats); + if (device_create_file(dev, &dev_msm_nand_perf_stats)) + pr_err("Sysfs entry create failed"); +} + +static void msm_nand_cleanup_sysfs(struct device *dev) +{ + device_remove_file(dev, &dev_msm_nand_perf_stats); +} + +static void msm_nand_update_read_perf_stats(struct msm_nand_info *info, + ktime_t start, u32 size) +{ + ktime_t time_delta; + + time_delta = ktime_sub(ktime_get(), start); + + spin_lock(&info->perf.lock); + info->perf.total_read_size += size; + info->perf.total_read_time = ktime_add(info->perf.total_read_time, + time_delta); + if (ktime_after(time_delta, info->perf.max_read_time)) + info->perf.max_read_time = time_delta; + + if (ktime_before(time_delta, info->perf.min_read_time)) + info->perf.min_read_time = time_delta; + + spin_unlock(&info->perf.lock); +} + +static void msm_nand_update_write_perf_stats(struct msm_nand_info *info, + ktime_t start, u32 size) +{ + ktime_t time_delta; + + time_delta = ktime_sub(ktime_get(), start); + + spin_lock(&info->perf.lock); + info->perf.total_write_size += size; + info->perf.total_write_time = ktime_add(info->perf.total_write_time, + time_delta); + if (ktime_after(time_delta, info->perf.max_write_time)) + info->perf.max_write_time = time_delta; + + if (ktime_before(time_delta, info->perf.min_write_time)) + info->perf.min_write_time = time_delta; + + spin_unlock(&info->perf.lock); +} + +static void msm_nand_update_erase_perf_stats(struct msm_nand_info *info, + ktime_t start, u32 count) +{ + ktime_t time_delta; + + time_delta = ktime_sub(ktime_get(), start); + + spin_lock(&info->perf.lock); + info->perf.total_erase_blks += count; + info->perf.total_erase_time = ktime_add(info->perf.total_erase_time, + time_delta); + if (ktime_after(time_delta, info->perf.max_erase_time)) + info->perf.max_erase_time = time_delta; + + if (ktime_before(time_delta, info->perf.min_erase_time)) + info->perf.min_erase_time = time_delta; + + spin_unlock(&info->perf.lock); +} /* * Get the DMA memory for requested amount of size. It returns the pointer @@ -1650,6 +1827,7 @@ static int msm_nand_read_oob(struct mtd_info *mtd, loff_t from, struct sps_iovec iovec_temp; bool erased_page; uint64_t fix_data_in_pages = 0; + ktime_t start; /* * The following 6 commands will be sent only once for the first @@ -1674,6 +1852,9 @@ static int msm_nand_read_oob(struct mtd_info *mtd, loff_t from, } *dma_buffer; struct msm_nand_rw_cmd_desc *cmd_list = NULL; + if (unlikely(enable_perfstats)) + start = ktime_get(); + memset(&rw_params, 0, sizeof(struct msm_nand_rw_params)); err = msm_nand_validate_mtd_params(mtd, true, from, ops, &rw_params); if (err) @@ -1981,6 +2162,8 @@ static int msm_nand_read_oob(struct mtd_info *mtd, loff_t from, err, ops->retlen, ops->oobretlen); pr_debug("========================================================\n"); + if (unlikely(enable_perfstats) && likely(!err)) + msm_nand_update_read_perf_stats(info, start, ops->retlen); return err; } @@ -2201,6 +2384,8 @@ static int msm_nand_write_oob(struct mtd_info *mtd, loff_t to, struct msm_nand_rw_reg_data data; struct sps_iovec *iovec; struct sps_iovec iovec_temp; + ktime_t start; + /* * The following 7 commands will be sent only once : * For first codeword (CW) - addr0, addr1, dev0_cfg0, dev0_cfg1, @@ -2224,6 +2409,9 @@ static int msm_nand_write_oob(struct mtd_info *mtd, loff_t to, } *dma_buffer; struct msm_nand_rw_cmd_desc *cmd_list = NULL; + if (unlikely(enable_perfstats)) + start = ktime_get(); + memset(&rw_params, 0, sizeof(struct msm_nand_rw_params)); err = msm_nand_validate_mtd_params(mtd, false, to, ops, &rw_params); if (err) @@ -2399,6 +2587,8 @@ static int msm_nand_write_oob(struct mtd_info *mtd, loff_t to, err, ops->retlen, ops->oobretlen); pr_debug("================================================\n"); + if (unlikely(enable_perfstats) && likely(!err)) + msm_nand_update_write_perf_stats(info, start, ops->retlen); return err; } @@ -2496,6 +2686,8 @@ static int msm_nand_erase(struct mtd_info *mtd, struct erase_info *instr) struct msm_nand_erase_reg_data data; struct sps_iovec *iovec; struct sps_iovec iovec_temp; + ktime_t start; + /* * The following 9 commands are required to erase a page - * flash, addr0, addr1, cfg0, cfg1, exec, flash_status(read), @@ -2508,6 +2700,9 @@ static int msm_nand_erase(struct mtd_info *mtd, struct erase_info *instr) uint32_t flash_status; } *dma_buffer; + if (unlikely(enable_perfstats)) + start = ktime_get(); + if (mtd->writesize == PAGE_SIZE_2K) page = instr->addr >> 11; @@ -2622,6 +2817,8 @@ static int msm_nand_erase(struct mtd_info *mtd, struct erase_info *instr) mutex_unlock(&info->lock); msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer)); out: + if (unlikely(enable_perfstats) && likely(!err)) + msm_nand_update_erase_perf_stats(info, start, 1); return err; } @@ -3613,6 +3810,8 @@ static int msm_nand_probe(struct platform_device *pdev) info->nand_phys, info->bam_phys, info->bam_irq); pr_info("Allocated DMA buffer at virt_addr 0x%pK, phys_addr 0x%x\n", info->nand_chip.dma_virt_addr, info->nand_chip.dma_phys_addr); + msm_nand_init_sysfs(dev); + msm_nand_init_perf_stats(info); goto out; free_bam: msm_nand_bam_free(info); @@ -3634,6 +3833,7 @@ static int msm_nand_remove(struct platform_device *pdev) { struct msm_nand_info *info = dev_get_drvdata(&pdev->dev); + msm_nand_cleanup_sysfs(&pdev->dev); if (pm_runtime_suspended(&(pdev)->dev)) pm_runtime_resume(&(pdev)->dev); @@ -3678,6 +3878,9 @@ static struct platform_driver msm_nand_driver = { module_param(enable_euclean, bool, 0644); MODULE_PARM_DESC(enable_euclean, "Set this parameter to enable reporting EUCLEAN to upper layer when the correctable bitflips are equal to the max correctable limit."); +module_param(enable_perfstats, bool, 0644); +MODULE_PARM_DESC(enable_perfstats, "Set this parameter to enable collection and reporting of performance data."); + module_platform_driver(msm_nand_driver); MODULE_ALIAS(DRIVER_NAME); diff --git a/drivers/mtd/devices/msm_qpic_nand.h b/drivers/mtd/devices/msm_qpic_nand.h index bb45a400d531..ee0a0f28bdf8 100644 --- a/drivers/mtd/devices/msm_qpic_nand.h +++ b/drivers/mtd/devices/msm_qpic_nand.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2007 Google, Inc. - * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -37,6 +37,9 @@ #include #include #include +#include +#include + #define PAGE_SIZE_2K 2048 #define PAGE_SIZE_4K 4096 @@ -302,6 +305,23 @@ struct msm_nand_clk_data { bool rpmh_clk; }; +struct msm_nand_perf_stats { + u64 total_read_size; + u64 total_write_size; + u64 total_erase_blks; + ktime_t total_read_time; + ktime_t total_write_time; + ktime_t total_erase_time; + ktime_t min_read_time; + ktime_t min_write_time; + ktime_t min_erase_time; + ktime_t max_read_time; + ktime_t max_write_time; + ktime_t max_erase_time; + spinlock_t lock; +}; + + /* Structure that defines NANDc private data. */ struct msm_nand_info { struct mtd_info mtd; @@ -326,6 +346,7 @@ struct msm_nand_info { struct mutex lock; struct flash_identification flash_dev; struct msm_nand_clk_data clk_data; + struct msm_nand_perf_stats perf; u64 dma_mask; }; -- GitLab From 7b1467216c6c8c8c65cd44779397abadd6868955 Mon Sep 17 00:00:00 2001 From: Anuj Date: Fri, 7 Jun 2019 16:34:05 +0530 Subject: [PATCH 0553/1121] defconfig: Adding support for EXT4 filesystem These changes will add support for EXT4 filesystem for SM6150 automotive ADP. Change-Id: I330c70089a45f89ed1d94bcf36625255f214d687 Signed-off-by: Anuj --- arch/arm64/configs/vendor/sdmsteppe-auto-perf_defconfig | 3 +++ arch/arm64/configs/vendor/sdmsteppe-auto_defconfig | 3 +++ 2 files changed, 6 insertions(+) diff --git a/arch/arm64/configs/vendor/sdmsteppe-auto-perf_defconfig b/arch/arm64/configs/vendor/sdmsteppe-auto-perf_defconfig index 2ee606b3211f..c0ef79295fcb 100644 --- a/arch/arm64/configs/vendor/sdmsteppe-auto-perf_defconfig +++ b/arch/arm64/configs/vendor/sdmsteppe-auto-perf_defconfig @@ -639,6 +639,9 @@ CONFIG_ESOC_MDM_DBG_ENG=y CONFIG_MSM_TZ_LOG=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_SECURITY=y +CONFIG_EXT4_ENCRYPTION=y +CONFIG_EXT4_FS_ENCRYPTION=y +CONFIG_EXT4_FS_ICE_ENCRYPTION=y CONFIG_F2FS_FS=y CONFIG_F2FS_FS_SECURITY=y CONFIG_F2FS_FS_ENCRYPTION=y diff --git a/arch/arm64/configs/vendor/sdmsteppe-auto_defconfig b/arch/arm64/configs/vendor/sdmsteppe-auto_defconfig index f6e53d4cf14f..8cb671a4dd1e 100644 --- a/arch/arm64/configs/vendor/sdmsteppe-auto_defconfig +++ b/arch/arm64/configs/vendor/sdmsteppe-auto_defconfig @@ -668,6 +668,9 @@ CONFIG_ESOC_MDM_DBG_ENG=y CONFIG_MSM_TZ_LOG=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_SECURITY=y +CONFIG_EXT4_ENCRYPTION=y +CONFIG_EXT4_FS_ENCRYPTION=y +CONFIG_EXT4_FS_ICE_ENCRYPTION=y CONFIG_F2FS_FS=y CONFIG_F2FS_FS_SECURITY=y CONFIG_F2FS_FS_ENCRYPTION=y -- GitLab From 5dd20fd01ecf3cacab1cdcbe5374d23d34e6928a Mon Sep 17 00:00:00 2001 From: Bojun Pan Date: Tue, 21 May 2019 10:50:19 -0700 Subject: [PATCH 0554/1121] msm: IPA: remove the redundent if-else check We will send IPA_QMI_ERR_INCOMPATIBLE_STATE_V01 no matter why mhi failure. The redundent if-else check is not needed in this case. When 5G ssr happens, mhi APIs may return error in multiple cases and the chan_alloc / vote QMI request from Q6 will fail. It is safe to just simply ignore the error to avoid stability issue in 5g ssr case. Change-Id: I4c08956c8fa2ce77bc45bb82f9faef205caa2646 Signed-off-by: Bojun Pan --- .../platform/msm/ipa/ipa_v3/ipa_mhi_proxy.c | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_mhi_proxy.c b/drivers/platform/msm/ipa/ipa_v3/ipa_mhi_proxy.c index 269aab75a8b0..3fef83623790 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_mhi_proxy.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_mhi_proxy.c @@ -389,12 +389,8 @@ static int __imp_configure_mhi_device( resp->alloc_resp_arr_len = ridx; resp->resp.result = IPA_QMI_RESULT_FAILURE_V01; /* return INCOMPATIBLE_STATE in any case */ - if (mhi_is_active(imp_ctx->md.mhi_dev)) - resp->resp.error = - IPA_QMI_ERR_INCOMPATIBLE_STATE_V01; - else - resp->resp.error = - IPA_QMI_ERR_INCOMPATIBLE_STATE_V01; + resp->resp.error = + IPA_QMI_ERR_INCOMPATIBLE_STATE_V01; return -EINVAL; } @@ -558,10 +554,7 @@ struct ipa_mhi_alloc_channel_resp_msg_v01 *imp_handle_allocate_channel_req( resp->alloc_resp_arr_len++; resp->resp.result = IPA_QMI_RESULT_FAILURE_V01; /* return INCOMPATIBLE_STATE in any case */ - if (mhi_is_active(imp_ctx->md.mhi_dev)) - resp->resp.error = IPA_QMI_ERR_INCOMPATIBLE_STATE_V01; - else - resp->resp.error = IPA_QMI_ERR_INCOMPATIBLE_STATE_V01; + resp->resp.error = IPA_QMI_ERR_INCOMPATIBLE_STATE_V01; goto fail_smmu; } @@ -660,11 +653,7 @@ struct ipa_mhi_clk_vote_resp_msg_v01 IMP_ERR("mhi_sync_get failed %d\n", ret); resp->resp.result = IPA_QMI_RESULT_FAILURE_V01; /* return INCOMPATIBLE_STATE in any case */ - if (mhi_is_active(imp_ctx->md.mhi_dev)) - resp->resp.error = - IPA_QMI_ERR_INCOMPATIBLE_STATE_V01; - else - resp->resp.error = + resp->resp.error = IPA_QMI_ERR_INCOMPATIBLE_STATE_V01; return resp; } -- GitLab From b5e62ef44605e31e9c98412f740f7152bd5e3d1e Mon Sep 17 00:00:00 2001 From: Sujeev Dias Date: Tue, 19 Feb 2019 18:15:42 -0800 Subject: [PATCH 0555/1121] mhi: core: add support for silent suspend and resume For low power mode use case, we allows apps subsystem to go into idle power collapse while device in active state. This change silently transitions MHI host into suspended state without suspending device. CRs-Fixed: 2418347 Change-Id: I23b4c9a981ad39f4a25422ccd569d1181bc2a58e Signed-off-by: Sujeev Dias --- drivers/bus/mhi/core/mhi_init.c | 1 + drivers/bus/mhi/core/mhi_main.c | 14 ++- drivers/bus/mhi/core/mhi_pm.c | 195 +++++++++++++++++++++++++++++++- include/linux/mhi.h | 22 +++- 4 files changed, 223 insertions(+), 9 deletions(-) diff --git a/drivers/bus/mhi/core/mhi_init.c b/drivers/bus/mhi/core/mhi_init.c index 89c1b1de57e9..b3aee33224dc 100644 --- a/drivers/bus/mhi/core/mhi_init.c +++ b/drivers/bus/mhi/core/mhi_init.c @@ -48,6 +48,7 @@ const char * const mhi_state_str[MHI_STATE_MAX] = { [MHI_STATE_M1] = "M1", [MHI_STATE_M2] = "M2", [MHI_STATE_M3] = "M3", + [MHI_STATE_M3_FAST] = "M3_FAST", [MHI_STATE_BHI] = "BHI", [MHI_STATE_SYS_ERR] = "SYS_ERR", }; diff --git a/drivers/bus/mhi/core/mhi_main.c b/drivers/bus/mhi/core/mhi_main.c index 6a19e4e296e0..c82b25d2cde1 100644 --- a/drivers/bus/mhi/core/mhi_main.c +++ b/drivers/bus/mhi/core/mhi_main.c @@ -1368,8 +1368,16 @@ void mhi_ctrl_ev_task(unsigned long data) * pm_state can change from reg access valid to no access while this * therad being executed. */ - if (!MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) + if (!MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) { + /* + * we may have a pending event but not allowed to + * process it since we probably in a suspended state, + * trigger a resume. + */ + mhi_cntrl->runtime_get(mhi_cntrl, mhi_cntrl->priv_data); + mhi_cntrl->runtime_put(mhi_cntrl, mhi_cntrl->priv_data); return; + } /* process ctrl events events */ ret = mhi_event->process_event(mhi_cntrl, mhi_event, U32_MAX); @@ -1827,12 +1835,12 @@ int mhi_debugfs_mhi_states_show(struct seq_file *m, void *d) struct mhi_controller *mhi_cntrl = m->private; seq_printf(m, - "pm_state:%s dev_state:%s EE:%s M0:%u M2:%u M3:%u wake:%d dev_wake:%u alloc_size:%u pending_pkts:%u\n", + "pm_state:%s dev_state:%s EE:%s M0:%u M2:%u M3:%u M3_Fast:%u wake:%d dev_wake:%u alloc_size:%u pending_pkts:%u\n", to_mhi_pm_state_str(mhi_cntrl->pm_state), TO_MHI_STATE_STR(mhi_cntrl->dev_state), TO_MHI_EXEC_STR(mhi_cntrl->ee), mhi_cntrl->M0, mhi_cntrl->M2, mhi_cntrl->M3, - mhi_cntrl->wake_set, + mhi_cntrl->M3_FAST, mhi_cntrl->wake_set, atomic_read(&mhi_cntrl->dev_wake), atomic_read(&mhi_cntrl->alloc_size), atomic_read(&mhi_cntrl->pending_pkts)); diff --git a/drivers/bus/mhi/core/mhi_pm.c b/drivers/bus/mhi/core/mhi_pm.c index 4bf440efe1bd..5356e861076f 100644 --- a/drivers/bus/mhi/core/mhi_pm.c +++ b/drivers/bus/mhi/core/mhi_pm.c @@ -39,6 +39,7 @@ * POR -> M0 -> M2 --> M0 * POR -> FW_DL_ERR * FW_DL_ERR <--> FW_DL_ERR + * M0 <--> M0 * M0 -> FW_DL_ERR * M0 -> M3_ENTER -> M3 -> M3_EXIT --> M0 * L1: SYS_ERR_DETECT -> SYS_ERR_PROCESS --> POR @@ -60,9 +61,9 @@ static struct mhi_pm_transitions const mhi_state_transitions[] = { }, { MHI_PM_M0, - MHI_PM_M2 | MHI_PM_M3_ENTER | MHI_PM_SYS_ERR_DETECT | - MHI_PM_SHUTDOWN_PROCESS | MHI_PM_LD_ERR_FATAL_DETECT | - MHI_PM_FW_DL_ERR + MHI_PM_M0 | MHI_PM_M2 | MHI_PM_M3_ENTER | + MHI_PM_SYS_ERR_DETECT | MHI_PM_SHUTDOWN_PROCESS | + MHI_PM_LD_ERR_FATAL_DETECT | MHI_PM_FW_DL_ERR }, { MHI_PM_M2, @@ -328,7 +329,7 @@ int mhi_pm_m0_transition(struct mhi_controller *mhi_cntrl) } mhi_cntrl->M0++; read_lock_bh(&mhi_cntrl->pm_lock); - mhi_cntrl->wake_get(mhi_cntrl, false); + mhi_cntrl->wake_get(mhi_cntrl, true); /* ring all event rings and CMD ring only if we're in mission mode */ if (MHI_IN_MISSION_MODE(mhi_cntrl->ee)) { @@ -1032,6 +1033,114 @@ int mhi_pm_suspend(struct mhi_controller *mhi_cntrl) } EXPORT_SYMBOL(mhi_pm_suspend); +/** + * mhi_pm_fast_suspend - Faster suspend path where we transition host to + * inactive state w/o suspending device. Useful for cases where we want apps to + * go into power collapse but keep the physical link in active state. + */ +int mhi_pm_fast_suspend(struct mhi_controller *mhi_cntrl, bool notify_client) +{ + int ret; + enum MHI_PM_STATE new_state; + struct mhi_chan *itr, *tmp; + + if (mhi_cntrl->pm_state == MHI_PM_DISABLE) + return -EINVAL; + + if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) + return -EIO; + + /* do a quick check to see if any pending votes to keep us busy */ + if (atomic_read(&mhi_cntrl->pending_pkts)) { + MHI_VERB("Busy, aborting M3\n"); + return -EBUSY; + } + + /* disable ctrl event processing */ + tasklet_disable(&mhi_cntrl->mhi_event->task); + + write_lock_irq(&mhi_cntrl->pm_lock); + + /* + * Check the votes once more to see if we should abort + * suspend. + */ + if (atomic_read(&mhi_cntrl->pending_pkts)) { + MHI_VERB("Busy, aborting M3\n"); + ret = -EBUSY; + goto error_suspend; + } + + /* anytime after this, we will resume thru runtime pm framework */ + MHI_LOG("Allowing Fast M3 transition\n"); + + /* save the current states */ + mhi_cntrl->saved_pm_state = mhi_cntrl->pm_state; + mhi_cntrl->saved_dev_state = mhi_cntrl->dev_state; + + /* If we're in M2, we need to switch back to M0 first */ + if (mhi_cntrl->pm_state == MHI_PM_M2) { + new_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_M0); + if (new_state != MHI_PM_M0) { + MHI_ERR("Error set pm_state to:%s from pm_state:%s\n", + to_mhi_pm_state_str(MHI_PM_M0), + to_mhi_pm_state_str(mhi_cntrl->pm_state)); + ret = -EIO; + goto error_suspend; + } + } + + new_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_M3_ENTER); + if (new_state != MHI_PM_M3_ENTER) { + MHI_ERR("Error setting to pm_state:%s from pm_state:%s\n", + to_mhi_pm_state_str(MHI_PM_M3_ENTER), + to_mhi_pm_state_str(mhi_cntrl->pm_state)); + ret = -EIO; + goto error_suspend; + } + + /* set dev to M3_FAST and host to M3 */ + new_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_M3); + if (new_state != MHI_PM_M3) { + MHI_ERR("Error setting to pm_state:%s from pm_state:%s\n", + to_mhi_pm_state_str(MHI_PM_M3), + to_mhi_pm_state_str(mhi_cntrl->pm_state)); + ret = -EIO; + goto error_suspend; + } + + mhi_cntrl->dev_state = MHI_STATE_M3_FAST; + mhi_cntrl->M3_FAST++; + write_unlock_irq(&mhi_cntrl->pm_lock); + + /* now safe to check ctrl event ring */ + tasklet_enable(&mhi_cntrl->mhi_event->task); + mhi_msi_handlr(0, mhi_cntrl->mhi_event); + + if (!notify_client) + return 0; + + /* notify any clients we enter lpm */ + list_for_each_entry_safe(itr, tmp, &mhi_cntrl->lpm_chans, node) { + mutex_lock(&itr->mutex); + if (itr->mhi_dev) + mhi_notify(itr->mhi_dev, MHI_CB_LPM_ENTER); + mutex_unlock(&itr->mutex); + } + + return 0; + +error_suspend: + write_unlock_irq(&mhi_cntrl->pm_lock); + + /* check ctrl event ring for pending work */ + tasklet_enable(&mhi_cntrl->mhi_event->task); + mhi_msi_handlr(0, mhi_cntrl->mhi_event); + + return ret; +} +EXPORT_SYMBOL(mhi_pm_fast_suspend); + int mhi_pm_resume(struct mhi_controller *mhi_cntrl) { enum MHI_PM_STATE cur_state; @@ -1098,6 +1207,80 @@ int mhi_pm_resume(struct mhi_controller *mhi_cntrl) return 0; } +int mhi_pm_fast_resume(struct mhi_controller *mhi_cntrl, bool notify_client) +{ + struct mhi_chan *itr, *tmp; + struct mhi_event *mhi_event; + int i; + + MHI_LOG("Entered with pm_state:%s dev_state:%s\n", + to_mhi_pm_state_str(mhi_cntrl->pm_state), + TO_MHI_STATE_STR(mhi_cntrl->dev_state)); + + if (mhi_cntrl->pm_state == MHI_PM_DISABLE) + return 0; + + if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) + return -EIO; + + MHI_ASSERT(mhi_cntrl->pm_state != MHI_PM_M3, "mhi_pm_state != M3"); + + /* notify any clients we're about to exit lpm */ + if (notify_client) { + list_for_each_entry_safe(itr, tmp, &mhi_cntrl->lpm_chans, + node) { + mutex_lock(&itr->mutex); + if (itr->mhi_dev) + mhi_notify(itr->mhi_dev, MHI_CB_LPM_EXIT); + mutex_unlock(&itr->mutex); + } + } + + write_lock_irq(&mhi_cntrl->pm_lock); + /* restore the states */ + mhi_cntrl->pm_state = mhi_cntrl->saved_pm_state; + mhi_cntrl->dev_state = mhi_cntrl->saved_dev_state; + write_unlock_irq(&mhi_cntrl->pm_lock); + + switch (mhi_cntrl->pm_state) { + case MHI_PM_M0: + mhi_pm_m0_transition(mhi_cntrl); + case MHI_PM_M2: + read_lock_bh(&mhi_cntrl->pm_lock); + /* + * we're doing a double check of pm_state because by the time we + * grab the pm_lock, device may have already initiate a M0 on + * its own. If that's the case we should not be toggling device + * wake. + */ + if (mhi_cntrl->pm_state == MHI_PM_M2) { + mhi_cntrl->wake_get(mhi_cntrl, true); + mhi_cntrl->wake_put(mhi_cntrl, true); + } + read_unlock_bh(&mhi_cntrl->pm_lock); + } + + /* + * In fast suspend/resume case device is not aware host transition + * to suspend state. So, device could be triggering a interrupt while + * host not accepting MSI. We have to manually check each event ring + * upon resume. + */ + mhi_event = mhi_cntrl->mhi_event; + for (i = 0; i < mhi_cntrl->total_ev_rings; i++, mhi_event++) { + if (mhi_event->offload_ev) + continue; + + mhi_msi_handlr(0, mhi_event); + } + + MHI_LOG("Exit with pm_state:%s dev_state:%s\n", + to_mhi_pm_state_str(mhi_cntrl->pm_state), + TO_MHI_STATE_STR(mhi_cntrl->dev_state)); + + return 0; +} + int __mhi_device_get_sync(struct mhi_controller *mhi_cntrl) { int ret; @@ -1185,6 +1368,10 @@ void mhi_device_put(struct mhi_device *mhi_dev, int vote) if (vote & MHI_VOTE_DEVICE) { atomic_dec(&mhi_dev->dev_vote); read_lock_bh(&mhi_cntrl->pm_lock); + if (MHI_PM_IN_SUSPEND_STATE(mhi_cntrl->pm_state)) { + mhi_cntrl->runtime_get(mhi_cntrl, mhi_cntrl->priv_data); + mhi_cntrl->runtime_put(mhi_cntrl, mhi_cntrl->priv_data); + } mhi_cntrl->wake_put(mhi_cntrl, false); read_unlock_bh(&mhi_cntrl->pm_lock); } diff --git a/include/linux/mhi.h b/include/linux/mhi.h index 0c2bf340ce14..c0b0698f0aa0 100644 --- a/include/linux/mhi.h +++ b/include/linux/mhi.h @@ -109,6 +109,7 @@ enum mhi_dev_state { MHI_STATE_M1 = 0x3, MHI_STATE_M2 = 0x4, MHI_STATE_M3 = 0x5, + MHI_STATE_M3_FAST = 0x6, MHI_STATE_BHI = 0x7, MHI_STATE_SYS_ERR = 0xFF, MHI_STATE_MAX, @@ -245,9 +246,11 @@ struct mhi_controller { bool pre_init; rwlock_t pm_lock; u32 pm_state; + u32 saved_pm_state; /* saved state during fast suspend */ u32 db_access; /* db access only on these states */ enum mhi_ee ee; enum mhi_dev_state dev_state; + enum mhi_dev_state saved_dev_state; bool wake_set; atomic_t dev_wake; atomic_t alloc_size; @@ -257,7 +260,7 @@ struct mhi_controller { spinlock_t wlock; /* debug counters */ - u32 M0, M2, M3; + u32 M0, M2, M3, M3_FAST; /* worker for different state transitions */ struct work_struct st_worker; @@ -603,6 +606,14 @@ void mhi_unprepare_after_power_down(struct mhi_controller *mhi_cntrl); */ int mhi_pm_suspend(struct mhi_controller *mhi_cntrl); +/** + * mhi_pm_fast_suspend - Move host into suspend state while keeping + * the device in active state. + * @mhi_cntrl: MHI controller + * @notify_client: if true, clients will get a notification about lpm transition + */ +int mhi_pm_fast_suspend(struct mhi_controller *mhi_cntrl, bool notify_client); + /** * mhi_pm_resume - Resume MHI from suspended state * Transition to MHI state M0 state from M3 state @@ -610,6 +621,13 @@ int mhi_pm_suspend(struct mhi_controller *mhi_cntrl); */ int mhi_pm_resume(struct mhi_controller *mhi_cntrl); +/** + * mhi_pm_fast_resume - Move host into resume state from fast suspend state + * @mhi_cntrl: MHI controller + * @notify_client: if true, clients will get a notification about lpm transition + */ +int mhi_pm_fast_resume(struct mhi_controller *mhi_cntrl, bool notify_client); + /** * mhi_download_rddm_img - Download ramdump image from device for * debugging purpose. @@ -661,7 +679,7 @@ static inline bool mhi_is_active(struct mhi_device *mhi_dev) struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; return (mhi_cntrl->dev_state >= MHI_STATE_M0 && - mhi_cntrl->dev_state <= MHI_STATE_M3); + mhi_cntrl->dev_state <= MHI_STATE_M3_FAST); } /** -- GitLab From 0c9477785ec12cbe40b3780b16cbe16f470977ca Mon Sep 17 00:00:00 2001 From: Mayank Rana Date: Wed, 29 May 2019 15:10:30 -0700 Subject: [PATCH 0556/1121] dwc3-msm: Add default-bus-vote property to select default USB bus voting On newer platform USB can operate when system into low power saving mode like SVS. Currently driver is always voting for NOMINAL bus voting which would prevent system to go into SVS mode. Hence add default-bus-vote property to select default bus voting on such platform. Change-Id: I493a7dd68964fadaada622e68b7b3c62c46ada6b Signed-off-by: Mayank Rana --- .../devicetree/bindings/usb/msm-ssusb.txt | 1 + drivers/usb/dwc3/dwc3-msm.c | 19 +++++++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/msm-ssusb.txt b/Documentation/devicetree/bindings/usb/msm-ssusb.txt index 12eb1f3ae1d7..2beaa9b8dc3e 100644 --- a/Documentation/devicetree/bindings/usb/msm-ssusb.txt +++ b/Documentation/devicetree/bindings/usb/msm-ssusb.txt @@ -29,6 +29,7 @@ Optional properties : - qcom,msm_bus,num_cases - qcom,msm_bus,num_paths - qcom,msm_bus,vectors +- qcom,default-bus-vote: To use default bus voting other than NOMINAL. Default is NOMINAL. - interrupt-names : Optional interrupt resource entries are: "ss_phy_irq" : Interrupt from super speed phy for wake up notification. "hs_phy_irq" : Interrupt from HS PHY for asynchronous events in LPM. diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index 487d3d231071..b09c96ef5e79 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -281,6 +281,7 @@ struct dwc3_msm { unsigned int max_power; bool charging_disabled; enum dwc3_drd_state drd_state; + enum bus_vote default_bus_vote; enum bus_vote override_bus_vote; u32 bus_perf_client; struct msm_bus_scale_pdata *bus_scale_table; @@ -2361,7 +2362,7 @@ static int dwc3_msm_update_bus_bw(struct dwc3_msm *mdwc, enum bus_vote bv) * from userspace. */ if (bv >= mdwc->bus_scale_table->num_usecases) - bv_index = BUS_VOTE_NOMINAL; + bv_index = mdwc->default_bus_vote; else if (bv == BUS_VOTE_NONE) bv_index = BUS_VOTE_NONE; @@ -2603,7 +2604,7 @@ static int dwc3_msm_resume(struct dwc3_msm *mdwc) if (mdwc->in_host_mode && mdwc->max_rh_port_speed == USB_SPEED_HIGH) dwc3_msm_update_bus_bw(mdwc, BUS_VOTE_SVS); else - dwc3_msm_update_bus_bw(mdwc, BUS_VOTE_NOMINAL); + dwc3_msm_update_bus_bw(mdwc, mdwc->default_bus_vote); /* Vote for TCXO while waking up USB HSPHY */ ret = clk_prepare_enable(mdwc->xo_clk); @@ -3463,7 +3464,7 @@ static ssize_t bus_vote_store(struct device *dev, && (mdwc->max_rh_port_speed == USB_SPEED_HIGH)) bv = BUS_VOTE_SVS; else - bv = BUS_VOTE_NOMINAL; + bv = mdwc->default_bus_vote; dwc3_msm_update_bus_bw(mdwc, bv); } @@ -3745,10 +3746,20 @@ static int dwc3_msm_probe(struct platform_device *pdev) goto put_dwc3; } + /* use default as nominal bus voting */ + mdwc->default_bus_vote = BUS_VOTE_NOMINAL; + ret = of_property_read_u32(node, "qcom,default-bus-vote", + &mdwc->default_bus_vote); + mdwc->bus_scale_table = msm_bus_cl_get_pdata(pdev); if (mdwc->bus_scale_table) { mdwc->bus_perf_client = msm_bus_scale_register_client(mdwc->bus_scale_table); + + /* default_bus_vote is out of range, use nominal bus voting */ + if (mdwc->default_bus_vote >= + mdwc->bus_scale_table->num_usecases) + mdwc->default_bus_vote = BUS_VOTE_NOMINAL; } dwc = platform_get_drvdata(mdwc->dwc3); @@ -4024,7 +4035,7 @@ static int dwc3_msm_host_notifier(struct notifier_block *nb, dev_dbg(mdwc->dev, "set core clk rate %ld\n", mdwc->core_clk_rate); mdwc->max_rh_port_speed = USB_SPEED_UNKNOWN; - dwc3_msm_update_bus_bw(mdwc, BUS_VOTE_NOMINAL); + dwc3_msm_update_bus_bw(mdwc, mdwc->default_bus_vote); } } -- GitLab From 9615d8065aece17265f3ff2e2d7bda5414e8ca45 Mon Sep 17 00:00:00 2001 From: Mayank Rana Date: Wed, 29 May 2019 15:16:17 -0700 Subject: [PATCH 0557/1121] ARM: dts: Use svs bus voting with USB on sdxprairie USB can operate when system is in SVS mode. Hence use svs bus voting instead of nominal bus voting on sdxprairie. Change-Id: Ie33a8b40fc67324c6fdfe0df9ce0d3892cb7602b Signed-off-by: Mayank Rana --- arch/arm64/boot/dts/qcom/sdxprairie-usb.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/qcom/sdxprairie-usb.dtsi b/arch/arm64/boot/dts/qcom/sdxprairie-usb.dtsi index 5ba14bdda6b0..4efd2959c812 100644 --- a/arch/arm64/boot/dts/qcom/sdxprairie-usb.dtsi +++ b/arch/arm64/boot/dts/qcom/sdxprairie-usb.dtsi @@ -77,6 +77,7 @@ , ; + qcom,default-bus-vote = <2>; /* use svs bus voting */ dwc3@a600000 { compatible = "snps,dwc3"; reg = <0x0a600000 0xcd00>; -- GitLab From df513284c667e398179a926a9c87194641f4e7f0 Mon Sep 17 00:00:00 2001 From: Sean Tranchetti Date: Tue, 28 May 2019 14:09:07 -0600 Subject: [PATCH 0558/1121] net: qualcomm: rmnet: Introduce descriptor framework Introduces a generic packet descriptor framework to allow RmNet to avoid allocating intermediate SKBs. Instead, SKBs for the incoming packets will allocated only when all possible forms of coalescing have been performed to avoid unnecessary allocs and frees. Change-Id: Ic3e4c9f174f2129faa2169c3b3f449becd2b5bdf Signed-off-by: Sean Tranchetti --- drivers/net/ethernet/qualcomm/rmnet/Makefile | 1 + .../ethernet/qualcomm/rmnet/rmnet_config.c | 9 + .../ethernet/qualcomm/rmnet/rmnet_config.h | 3 + .../qualcomm/rmnet/rmnet_descriptor.c | 1056 +++++++++++++++++ .../qualcomm/rmnet/rmnet_descriptor.h | 151 +++ .../ethernet/qualcomm/rmnet/rmnet_handlers.c | 34 +- .../net/ethernet/qualcomm/rmnet/rmnet_map.h | 4 + .../qualcomm/rmnet/rmnet_map_command.c | 14 +- 8 files changed, 1239 insertions(+), 33 deletions(-) create mode 100644 drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c create mode 100644 drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.h diff --git a/drivers/net/ethernet/qualcomm/rmnet/Makefile b/drivers/net/ethernet/qualcomm/rmnet/Makefile index 01bddf207cac..b175fbb7f576 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/Makefile +++ b/drivers/net/ethernet/qualcomm/rmnet/Makefile @@ -7,4 +7,5 @@ rmnet-y += rmnet_vnd.o rmnet-y += rmnet_handlers.o rmnet-y += rmnet_map_data.o rmnet-y += rmnet_map_command.o +rmnet-y += rmnet_descriptor.o obj-$(CONFIG_RMNET) += rmnet.o diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c index cec68efac4f0..e85c37348485 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c @@ -22,6 +22,7 @@ #include "rmnet_vnd.h" #include "rmnet_private.h" #include "rmnet_map.h" +#include "rmnet_descriptor.h" #include #include @@ -89,6 +90,8 @@ static int rmnet_unregister_real_device(struct net_device *real_dev, rmnet_map_cmd_exit(port); rmnet_map_tx_aggregate_exit(port); + rmnet_descriptor_deinit(port); + kfree(port); netdev_rx_handler_unregister(real_dev); @@ -126,6 +129,12 @@ static int rmnet_register_real_device(struct net_device *real_dev) for (entry = 0; entry < RMNET_MAX_LOGICAL_EP; entry++) INIT_HLIST_HEAD(&port->muxed_ep[entry]); + rc = rmnet_descriptor_init(port); + if (rc) { + rmnet_descriptor_deinit(port); + return rc; + } + rmnet_map_tx_aggregate_init(port); rmnet_map_cmd_init(port); diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h index 9d89ece3a8bc..2eb323fc48b8 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h @@ -77,6 +77,9 @@ struct rmnet_port { struct list_head dl_list; struct rmnet_port_priv_stats stats; int dl_marker_flush; + + struct rmnet_descriptor *rmnet_desc; + struct rmnet_frag_descriptor_pool *frag_desc_pool; }; extern struct rtnl_link_ops rmnet_link_ops; diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c new file mode 100644 index 000000000000..a644809106fa --- /dev/null +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c @@ -0,0 +1,1056 @@ +/* Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * RMNET Packet Descriptor Framework + * + */ + +#include +#include +#include +#include +#include "rmnet_config.h" +#include "rmnet_descriptor.h" +#include "rmnet_handlers.h" +#include "rmnet_private.h" +#include "rmnet_vnd.h" +#include +#include + +#define RMNET_FRAG_DESCRIPTOR_POOL_SIZE 64 +#define RMNET_DL_IND_HDR_SIZE (sizeof(struct rmnet_map_dl_ind_hdr) + \ + sizeof(struct rmnet_map_header) + \ + sizeof(struct rmnet_map_control_command_header)) +#define RMNET_DL_IND_TRL_SIZE (sizeof(struct rmnet_map_dl_ind_trl) + \ + sizeof(struct rmnet_map_header) + \ + sizeof(struct rmnet_map_control_command_header)) + +typedef void (*rmnet_perf_desc_hook_t)(struct rmnet_frag_descriptor *frag_desc, + struct rmnet_port *port); +typedef void (*rmnet_perf_chain_hook_t)(void); + +struct rmnet_frag_descriptor * +rmnet_get_frag_descriptor(struct rmnet_port *port) +{ + struct rmnet_frag_descriptor_pool *pool = port->frag_desc_pool; + struct rmnet_frag_descriptor *frag_desc; + + if (!list_empty(&pool->free_list)) { + frag_desc = list_first_entry(&pool->free_list, + struct rmnet_frag_descriptor, + list); + list_del_init(&frag_desc->list); + } else { + frag_desc = kzalloc(sizeof(*frag_desc), GFP_ATOMIC); + if (!frag_desc) + return NULL; + + INIT_LIST_HEAD(&frag_desc->list); + INIT_LIST_HEAD(&frag_desc->sub_frags); + pool->pool_size++; + } + + return frag_desc; +} +EXPORT_SYMBOL(rmnet_get_frag_descriptor); + +void rmnet_recycle_frag_descriptor(struct rmnet_frag_descriptor *frag_desc, + struct rmnet_port *port) +{ + struct rmnet_frag_descriptor_pool *pool = port->frag_desc_pool; + + list_del(&frag_desc->list); + put_page(skb_frag_page(&frag_desc->frag)); + + memset(frag_desc, 0, sizeof(*frag_desc)); + INIT_LIST_HEAD(&frag_desc->list); + INIT_LIST_HEAD(&frag_desc->sub_frags); + list_add_tail(&frag_desc->list, &pool->free_list); +} +EXPORT_SYMBOL(rmnet_recycle_frag_descriptor); + +void rmnet_descriptor_add_frag(struct rmnet_port *port, struct page *p, + u32 page_offset, u32 len) +{ + struct rmnet_frag_descriptor *frag_desc; + + frag_desc = rmnet_get_frag_descriptor(port); + if (!frag_desc) + return; + + rmnet_frag_fill(frag_desc, p, page_offset, len); + list_add_tail(&frag_desc->list, &port->rmnet_desc->frags); + port->rmnet_desc->nr_frags++; +} +EXPORT_SYMBOL(rmnet_descriptor_add_frag); + +int rmnet_frag_ipv6_skip_exthdr(struct rmnet_frag_descriptor *frag_desc, + int start, u8 *nexthdrp, __be16 *fragp) +{ + u8 nexthdr = *nexthdrp; + + *fragp = 0; + + while (ipv6_ext_hdr(nexthdr)) { + struct ipv6_opt_hdr *hp; + int hdrlen; + + if (nexthdr == NEXTHDR_NONE) + return -EINVAL; + + hp = rmnet_frag_data_ptr(frag_desc) + start; + + if (nexthdr == NEXTHDR_FRAGMENT) { + __be16 *fp; + + fp = rmnet_frag_data_ptr(frag_desc) + start + + offsetof(struct frag_hdr, frag_off); + *fragp = *fp; + if (ntohs(*fragp) & ~0x7) + break; + hdrlen = 8; + } else if (nexthdr == NEXTHDR_AUTH) { + hdrlen = (hp->hdrlen + 2) << 2; + } else { + hdrlen = ipv6_optlen(hp); + } + + nexthdr = hp->nexthdr; + start += hdrlen; + } + + *nexthdrp = nexthdr; + return start; +} +EXPORT_SYMBOL(rmnet_frag_ipv6_skip_exthdr); + +static u8 rmnet_frag_do_flow_control(struct rmnet_map_header *qmap, + struct rmnet_port *port, + int enable) +{ + struct rmnet_map_control_command *cmd; + struct rmnet_endpoint *ep; + struct net_device *vnd; + u16 ip_family; + u16 fc_seq; + u32 qos_id; + u8 mux_id; + int r; + + mux_id = qmap->mux_id; + cmd = (struct rmnet_map_control_command *) + ((char *)qmap + sizeof(*qmap)); + + if (mux_id >= RMNET_MAX_LOGICAL_EP) + return RX_HANDLER_CONSUMED; + + ep = rmnet_get_endpoint(port, mux_id); + if (!ep) + return RX_HANDLER_CONSUMED; + + vnd = ep->egress_dev; + + ip_family = cmd->flow_control.ip_family; + fc_seq = ntohs(cmd->flow_control.flow_control_seq_num); + qos_id = ntohl(cmd->flow_control.qos_id); + + /* Ignore the ip family and pass the sequence number for both v4 and v6 + * sequence. User space does not support creating dedicated flows for + * the 2 protocols + */ + r = rmnet_vnd_do_flow_control(vnd, enable); + if (r) + return RMNET_MAP_COMMAND_UNSUPPORTED; + else + return RMNET_MAP_COMMAND_ACK; +} + +static void rmnet_frag_send_ack(struct rmnet_map_header *qmap, + unsigned char type, + struct rmnet_port *port) +{ + struct rmnet_map_control_command *cmd; + struct net_device *dev = port->dev; + struct sk_buff *skb; + u16 alloc_len = ntohs(qmap->pkt_len) + sizeof(*qmap); + + skb = alloc_skb(alloc_len, GFP_ATOMIC); + if (!skb) + return; + + skb->protocol = htons(ETH_P_MAP); + skb->dev = dev; + + cmd = rmnet_map_get_cmd_start(skb); + cmd->cmd_type = type & 0x03; + + netif_tx_lock(dev); + dev->netdev_ops->ndo_start_xmit(skb, dev); + netif_tx_unlock(dev); +} + +static void rmnet_frag_process_flow_start(struct rmnet_map_control_command *cmd, + struct rmnet_port *port, + u16 cmd_len) +{ + struct rmnet_map_dl_ind_hdr *dlhdr; + + if (cmd_len < RMNET_DL_IND_HDR_SIZE) + return; + + dlhdr = (struct rmnet_map_dl_ind_hdr *)((char *)cmd + sizeof(*cmd)); + + port->stats.dl_hdr_last_seq = dlhdr->le.seq; + port->stats.dl_hdr_last_bytes = dlhdr->le.bytes; + port->stats.dl_hdr_last_pkts = dlhdr->le.pkts; + port->stats.dl_hdr_last_flows = dlhdr->le.flows; + port->stats.dl_hdr_total_bytes += port->stats.dl_hdr_last_bytes; + port->stats.dl_hdr_total_pkts += port->stats.dl_hdr_last_pkts; + port->stats.dl_hdr_count++; + + rmnet_map_dl_hdr_notify(port, dlhdr); +} + +static void rmnet_frag_process_flow_end(struct rmnet_map_control_command *cmd, + struct rmnet_port *port, + u16 cmd_len) +{ + struct rmnet_map_dl_ind_trl *dltrl; + + if (cmd_len < RMNET_DL_IND_TRL_SIZE) + return; + + dltrl = (struct rmnet_map_dl_ind_trl *)((char *)cmd + sizeof(*cmd)); + + port->stats.dl_trl_last_seq = dltrl->seq_le; + port->stats.dl_trl_count++; + + rmnet_map_dl_trl_notify(port, dltrl); +} + +/* Process MAP command frame and send N/ACK message as appropriate. Message cmd + * name is decoded here and appropriate handler is called. + */ +void rmnet_frag_command(struct rmnet_map_header *qmap, struct rmnet_port *port) +{ + struct rmnet_map_control_command *cmd; + unsigned char command_name; + unsigned char rc = 0; + + cmd = (struct rmnet_map_control_command *) + ((char *)qmap + sizeof(*qmap)); + command_name = cmd->command_name; + + switch (command_name) { + case RMNET_MAP_COMMAND_FLOW_ENABLE: + rc = rmnet_frag_do_flow_control(qmap, port, 1); + break; + + case RMNET_MAP_COMMAND_FLOW_DISABLE: + rc = rmnet_frag_do_flow_control(qmap, port, 0); + break; + + default: + rc = RMNET_MAP_COMMAND_UNSUPPORTED; + break; + } + if (rc == RMNET_MAP_COMMAND_ACK) + rmnet_frag_send_ack(qmap, rc, port); +} + +int rmnet_frag_flow_command(struct rmnet_map_header *qmap, + struct rmnet_port *port, u16 pkt_len) +{ + struct rmnet_map_control_command *cmd; + unsigned char command_name; + + cmd = (struct rmnet_map_control_command *) + ((char *)qmap + sizeof(*qmap)); + command_name = cmd->command_name; + + switch (command_name) { + case RMNET_MAP_COMMAND_FLOW_START: + rmnet_frag_process_flow_start(cmd, port, pkt_len); + break; + + case RMNET_MAP_COMMAND_FLOW_END: + rmnet_frag_process_flow_end(cmd, port, pkt_len); + break; + + default: + return 1; + } + + return 0; +} +EXPORT_SYMBOL(rmnet_frag_flow_command); + +void rmnet_frag_deaggregate(skb_frag_t *frag, struct rmnet_port *port) +{ + struct rmnet_map_header *maph; + u8 *data = skb_frag_address(frag); + u32 offset = 0; + u32 packet_len; + + while (offset < skb_frag_size(frag)) { + maph = (struct rmnet_map_header *)data; + packet_len = ntohs(maph->pkt_len); + + /* Some hardware can send us empty frames. Catch them */ + if (packet_len == 0) + return; + + packet_len += sizeof(*maph); + + if (port->data_format & RMNET_FLAGS_INGRESS_MAP_CKSUMV4) { + packet_len += sizeof(struct rmnet_map_dl_csum_trailer); + } else if (port->data_format & + (RMNET_FLAGS_INGRESS_MAP_CKSUMV5 | + RMNET_FLAGS_INGRESS_COALESCE) && !maph->cd_bit) { + u32 hsize = 0; + u8 type; + + type = ((struct rmnet_map_v5_coal_header *) + (data + sizeof(*maph)))->header_type; + switch (type) { + case RMNET_MAP_HEADER_TYPE_COALESCING: + hsize = sizeof(struct rmnet_map_v5_coal_header); + break; + case RMNET_MAP_HEADER_TYPE_CSUM_OFFLOAD: + hsize = sizeof(struct rmnet_map_v5_csum_header); + break; + } + + packet_len += hsize; + } + + if ((int)skb_frag_size(frag) - (int)packet_len < 0) + return; + + rmnet_descriptor_add_frag(port, skb_frag_page(frag), + frag->page_offset + offset, + packet_len); + + offset += packet_len; + data += packet_len; + } +} + +/* Fill in GSO metadata to allow the SKB to be segmented by the NW stack + * if needed (i.e. forwarding, UDP GRO) + */ +static void rmnet_frag_gso_stamp(struct sk_buff *skb, + struct rmnet_frag_descriptor *frag_desc) +{ + struct skb_shared_info *shinfo = skb_shinfo(skb); + struct iphdr *iph = (struct iphdr *)skb->data; + __sum16 pseudo; + u16 pkt_len = skb->len - frag_desc->ip_len; + bool ipv4 = frag_desc->ip_proto == 4; + + if (ipv4) { + iph->tot_len = htons(skb->len); + iph->check = 0; + iph->check = ip_fast_csum(iph, iph->ihl); + pseudo = ~csum_tcpudp_magic(iph->saddr, iph->daddr, + pkt_len, frag_desc->trans_proto, + 0); + } else { + struct ipv6hdr *ip6h = (struct ipv6hdr *)iph; + + /* Payload length includes any extension headers */ + ip6h->payload_len = htons(skb->len - sizeof(*ip6h)); + pseudo = ~csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, + pkt_len, frag_desc->trans_proto, 0); + } + + if (frag_desc->trans_proto == IPPROTO_TCP) { + struct tcphdr *tp = (struct tcphdr *) + ((u8 *)iph + frag_desc->ip_len); + + tp->check = pseudo; + shinfo->gso_type = (ipv4) ? SKB_GSO_TCPV4 : SKB_GSO_TCPV6; + skb->csum_offset = offsetof(struct tcphdr, check); + } else { + struct udphdr *up = (struct udphdr *) + ((u8 *)iph + frag_desc->ip_len); + + up->len = htons(pkt_len); + up->check = pseudo; + shinfo->gso_type = SKB_GSO_UDP_L4; + skb->csum_offset = offsetof(struct udphdr, check); + } + + skb->ip_summed = CHECKSUM_PARTIAL; + skb->csum_start = (u8 *)iph + frag_desc->ip_len - skb->head; + shinfo->gso_size = frag_desc->gso_size; + shinfo->gso_segs = frag_desc->gso_segs; +} + +/* Allocate and populate an skb to contain the packet represented by the + * frag descriptor. + */ +static struct sk_buff *rmnet_alloc_skb(struct rmnet_frag_descriptor *frag_desc, + struct rmnet_port *port) +{ + struct sk_buff *head_skb, *current_skb, *skb; + struct skb_shared_info *shinfo; + struct rmnet_frag_descriptor *sub_frag, *tmp; + + /* Use the exact sizes if we know them (i.e. RSB/RSC, rmnet_perf) */ + if (frag_desc->hdrs_valid) { + u16 hdr_len = frag_desc->ip_len + frag_desc->trans_len; + + head_skb = alloc_skb(hdr_len, GFP_ATOMIC); + if (!head_skb) + return NULL; + + skb_put_data(head_skb, frag_desc->hdr_ptr, hdr_len); + skb_reset_network_header(head_skb); + if (frag_desc->trans_len) + skb_set_transport_header(head_skb, frag_desc->ip_len); + + /* Packets that have no data portion don't need any frags */ + if (hdr_len == skb_frag_size(&frag_desc->frag)) + goto skip_frags; + + /* If the headers we added are the start of the page, + * we don't want to add them twice + */ + if (frag_desc->hdr_ptr == rmnet_frag_data_ptr(frag_desc)) + rmnet_frag_pull(frag_desc, port, hdr_len); + } else { + /* Allocate enough space to avoid penalties in the stack + * from __pskb_pull_tail() + */ + head_skb = alloc_skb(256, GFP_ATOMIC); + if (!head_skb) + return NULL; + } + + /* Add main fragment */ + get_page(skb_frag_page(&frag_desc->frag)); + skb_add_rx_frag(head_skb, 0, skb_frag_page(&frag_desc->frag), + frag_desc->frag.page_offset, + skb_frag_size(&frag_desc->frag), + skb_frag_size(&frag_desc->frag)); + + shinfo = skb_shinfo(head_skb); + current_skb = head_skb; + + /* Add in any frags from rmnet_perf */ + list_for_each_entry_safe(sub_frag, tmp, &frag_desc->sub_frags, list) { + skb_frag_t *frag; + u32 frag_size; + + frag = &sub_frag->frag; + frag_size = skb_frag_size(frag); + +add_frag: + if (shinfo->nr_frags < MAX_SKB_FRAGS) { + get_page(skb_frag_page(frag)); + skb_add_rx_frag(current_skb, shinfo->nr_frags, + skb_frag_page(frag), frag->page_offset, + frag_size, frag_size); + if (current_skb != head_skb) { + head_skb->len += frag_size; + head_skb->data_len += frag_size; + } + } else { + /* Alloc a new skb and try again */ + skb = alloc_skb(0, GFP_ATOMIC); + if (!skb) + break; + + if (current_skb == head_skb) + shinfo->frag_list = skb; + else + current_skb->next = skb; + + current_skb = skb; + shinfo = skb_shinfo(current_skb); + goto add_frag; + } + + rmnet_recycle_frag_descriptor(sub_frag, port); + } + +skip_frags: + head_skb->dev = frag_desc->dev; + rmnet_set_skb_proto(head_skb); + + /* Handle any header metadata that needs to be updated after RSB/RSC + * segmentation + */ + if (frag_desc->ip_id_set) { + struct iphdr *iph; + + iph = (struct iphdr *)rmnet_map_data_ptr(head_skb); + csum_replace2(&iph->check, iph->id, frag_desc->ip_id); + iph->id = frag_desc->ip_id; + } + + if (frag_desc->tcp_seq_set) { + struct tcphdr *th; + + th = (struct tcphdr *) + (rmnet_map_data_ptr(head_skb) + frag_desc->ip_len); + th->seq = frag_desc->tcp_seq; + } + + /* Handle csum offloading */ + if (frag_desc->csum_valid) + head_skb->ip_summed = CHECKSUM_UNNECESSARY; + + /* Handle any rmnet_perf metadata */ + if (frag_desc->hash) { + head_skb->hash = frag_desc->hash; + head_skb->sw_hash = 1; + } + + if (frag_desc->flush_shs) + head_skb->cb[0] = 1; + + /* Handle coalesced packets */ + if (frag_desc->gso_segs > 1) + rmnet_frag_gso_stamp(head_skb, frag_desc); + + return head_skb; +} + +/* Deliver the packets contained within a frag descriptor */ +void rmnet_frag_deliver(struct rmnet_frag_descriptor *frag_desc, + struct rmnet_port *port) +{ + struct sk_buff *skb; + + skb = rmnet_alloc_skb(frag_desc, port); + if (skb) + rmnet_deliver_skb(skb, port); + rmnet_recycle_frag_descriptor(frag_desc, port); +} +EXPORT_SYMBOL(rmnet_frag_deliver); + +static void __rmnet_frag_segment_data(struct rmnet_frag_descriptor *coal_desc, + struct rmnet_port *port, + struct list_head *list, + u8 pkt_id) +{ + struct rmnet_priv *priv = netdev_priv(coal_desc->dev); + struct rmnet_frag_descriptor *new_frag; + u8 *hdr_start = rmnet_frag_data_ptr(coal_desc); + + new_frag = rmnet_get_frag_descriptor(port); + if (!new_frag) + return; + + /* Header information and most metadata is the same as the original */ + memcpy(new_frag, coal_desc, sizeof(*coal_desc)); + INIT_LIST_HEAD(&new_frag->list); + INIT_LIST_HEAD(&new_frag->sub_frags); + rmnet_frag_fill(new_frag, skb_frag_page(&coal_desc->frag), + coal_desc->frag.page_offset + coal_desc->data_offset, + coal_desc->gso_size * coal_desc->gso_segs); + + if (coal_desc->trans_proto == IPPROTO_TCP) { + struct tcphdr *th; + + th = (struct tcphdr *)(hdr_start + coal_desc->ip_len); + new_frag->tcp_seq_set = 1; + new_frag->tcp_seq = htonl(ntohl(th->seq) + + coal_desc->data_offset); + } + + if (coal_desc->ip_proto == 4) { + struct iphdr *iph; + + iph = (struct iphdr *)hdr_start; + new_frag->ip_id_set = 1; + new_frag->ip_id = htons(ntohs(iph->id) + coal_desc->pkt_id); + } + + new_frag->hdr_ptr = hdr_start; + new_frag->csum_valid = true; + priv->stats.coal.coal_reconstruct++; + + /* Update meta information to move past the data we just segmented */ + coal_desc->data_offset += coal_desc->gso_size * coal_desc->gso_segs; + coal_desc->pkt_id = pkt_id + 1; + coal_desc->gso_segs = 0; + + list_add_tail(&new_frag->list, list); +} + +/* Converts the coalesced frame into a list of descriptors. + * NLOs containing csum erros will not be included. + */ +static void +rmnet_frag_segment_coal_data(struct rmnet_frag_descriptor *coal_desc, + u64 nlo_err_mask, struct rmnet_port *port, + struct list_head *list) +{ + struct iphdr *iph; + struct rmnet_priv *priv = netdev_priv(coal_desc->dev); + struct rmnet_map_v5_coal_header *coal_hdr; + u16 pkt_len; + u8 pkt, total_pkt = 0; + u8 nlo; + bool gro = coal_desc->dev->features & NETIF_F_GRO_HW; + + /* Pull off the headers we no longer need */ + rmnet_frag_pull(coal_desc, port, sizeof(struct rmnet_map_header)); + coal_hdr = (struct rmnet_map_v5_coal_header *) + rmnet_frag_data_ptr(coal_desc); + rmnet_frag_pull(coal_desc, port, sizeof(*coal_hdr)); + + iph = (struct iphdr *)rmnet_frag_data_ptr(coal_desc); + + if (iph->version == 4) { + coal_desc->ip_proto = 4; + coal_desc->ip_len = iph->ihl * 4; + coal_desc->trans_proto = iph->protocol; + + /* Don't allow coalescing of any packets with IP options */ + if (iph->ihl != 5) + gro = false; + } else if (iph->version == 6) { + struct ipv6hdr *ip6h = (struct ipv6hdr *)iph; + __be16 frag_off; + u8 protocol = ip6h->nexthdr; + + coal_desc->ip_proto = 6; + coal_desc->ip_len = rmnet_frag_ipv6_skip_exthdr(coal_desc, + sizeof(*ip6h), + &protocol, + &frag_off); + coal_desc->trans_proto = protocol; + + /* If we run into a problem, or this has a fragment header + * (which should technically not be possible, if the HW + * works as intended...), bail. + */ + if (coal_desc->ip_len < 0 || frag_off) { + priv->stats.coal.coal_ip_invalid++; + return; + } else if (coal_desc->ip_len > sizeof(*ip6h)) { + /* Don't allow coalescing of any packets with IPv6 + * extension headers. + */ + gro = false; + } + } else { + priv->stats.coal.coal_ip_invalid++; + return; + } + + if (coal_desc->trans_proto == IPPROTO_TCP) { + struct tcphdr *th; + + th = (struct tcphdr *)((u8 *)iph + coal_desc->ip_len); + coal_desc->trans_len = th->doff * 4; + } else if (coal_desc->trans_proto == IPPROTO_UDP) { + coal_desc->trans_len = sizeof(struct udphdr); + } else { + priv->stats.coal.coal_trans_invalid++; + return; + } + + coal_desc->hdrs_valid = 1; + for (nlo = 0; nlo < coal_hdr->num_nlos; nlo++) { + pkt_len = ntohs(coal_hdr->nl_pairs[nlo].pkt_len); + pkt_len -= coal_desc->ip_len + coal_desc->trans_len; + coal_desc->gso_size = pkt_len; + for (pkt = 0; pkt < coal_hdr->nl_pairs[nlo].num_packets; + pkt++, total_pkt++) { + nlo_err_mask <<= 1; + if (nlo_err_mask & (1ULL << 63)) { + priv->stats.coal.coal_csum_err++; + + /* Segment out the good data */ + if (gro && coal_desc->gso_segs) + __rmnet_frag_segment_data(coal_desc, + port, + list, + total_pkt); + + /* skip over bad packet */ + coal_desc->data_offset += pkt_len; + coal_desc->pkt_id = total_pkt + 1; + } else { + coal_desc->gso_segs++; + + /* Segment the packet if we aren't sending the + * larger packet up the stack. + */ + if (!gro) + __rmnet_frag_segment_data(coal_desc, + port, + list, + total_pkt); + } + } + + /* If we're switching NLOs, we need to send out everything from + * the previous one, if we haven't done so. NLOs only switch + * when the packet length changes. + */ + if (gro && coal_desc->gso_segs) { + /* Fast forward the (hopefully) common case. + * Frames with only one NLO (i.e. one packet length) and + * no checksum errors don't need to be segmented here. + * We can just pass off the original skb. + */ + if (coal_desc->gso_size * coal_desc->gso_segs == + skb_frag_size(&coal_desc->frag) - + coal_desc->ip_len - coal_desc->trans_len) { + coal_desc->hdr_ptr = + rmnet_frag_data_ptr(coal_desc); + coal_desc->csum_valid = true; + list_add_tail(&coal_desc->list, list); + return; + } + + __rmnet_frag_segment_data(coal_desc, port, list, + total_pkt); + } + } +} + +/* Record reason for coalescing pipe closure */ +static void rmnet_frag_data_log_close_stats(struct rmnet_priv *priv, u8 type, + u8 code) +{ + struct rmnet_coal_close_stats *stats = &priv->stats.coal.close; + + switch (type) { + case RMNET_MAP_COAL_CLOSE_NON_COAL: + stats->non_coal++; + break; + case RMNET_MAP_COAL_CLOSE_IP_MISS: + stats->ip_miss++; + break; + case RMNET_MAP_COAL_CLOSE_TRANS_MISS: + stats->trans_miss++; + break; + case RMNET_MAP_COAL_CLOSE_HW: + switch (code) { + case RMNET_MAP_COAL_CLOSE_HW_NL: + stats->hw_nl++; + break; + case RMNET_MAP_COAL_CLOSE_HW_PKT: + stats->hw_pkt++; + break; + case RMNET_MAP_COAL_CLOSE_HW_BYTE: + stats->hw_byte++; + break; + case RMNET_MAP_COAL_CLOSE_HW_TIME: + stats->hw_time++; + break; + case RMNET_MAP_COAL_CLOSE_HW_EVICT: + stats->hw_evict++; + break; + default: + break; + } + break; + case RMNET_MAP_COAL_CLOSE_COAL: + stats->coal++; + break; + default: + break; + } +} + +/* Check if the coalesced header has any incorrect values, in which case, the + * entire coalesced frame must be dropped. Then check if there are any + * checksum issues + */ +static int +rmnet_frag_data_check_coal_header(struct rmnet_frag_descriptor *frag_desc, + u64 *nlo_err_mask) +{ + struct rmnet_map_v5_coal_header *coal_hdr; + unsigned char *data = rmnet_frag_data_ptr(frag_desc); + struct rmnet_priv *priv = netdev_priv(frag_desc->dev); + u64 mask = 0; + int i; + u8 veid, pkts = 0; + + coal_hdr = (struct rmnet_map_v5_coal_header *) + (data + sizeof(struct rmnet_map_header)); + veid = coal_hdr->virtual_channel_id; + + if (coal_hdr->num_nlos == 0 || + coal_hdr->num_nlos > RMNET_MAP_V5_MAX_NLOS) { + priv->stats.coal.coal_hdr_nlo_err++; + return -EINVAL; + } + + for (i = 0; i < RMNET_MAP_V5_MAX_NLOS; i++) { + /* If there is a checksum issue, we need to split + * up the skb. Rebuild the full csum error field + */ + u8 err = coal_hdr->nl_pairs[i].csum_error_bitmap; + u8 pkt = coal_hdr->nl_pairs[i].num_packets; + + mask |= ((u64)err) << (7 - i) * 8; + + /* Track total packets in frame */ + pkts += pkt; + if (pkts > RMNET_MAP_V5_MAX_PACKETS) { + priv->stats.coal.coal_hdr_pkt_err++; + return -EINVAL; + } + } + + /* Track number of packets we get inside of coalesced frames */ + priv->stats.coal.coal_pkts += pkts; + + /* Update ethtool stats */ + rmnet_frag_data_log_close_stats(priv, + coal_hdr->close_type, + coal_hdr->close_value); + if (veid < RMNET_MAX_VEID) + priv->stats.coal.coal_veid[veid]++; + + *nlo_err_mask = mask; + + return 0; +} + +/* Process a QMAPv5 packet header */ +int rmnet_frag_process_next_hdr_packet(struct rmnet_frag_descriptor *frag_desc, + struct rmnet_port *port, + struct list_head *list, + u16 len) +{ + struct rmnet_priv *priv = netdev_priv(frag_desc->dev); + u64 nlo_err_mask; + int rc = 0; + + switch (rmnet_frag_get_next_hdr_type(frag_desc)) { + case RMNET_MAP_HEADER_TYPE_COALESCING: + priv->stats.coal.coal_rx++; + rc = rmnet_frag_data_check_coal_header(frag_desc, + &nlo_err_mask); + if (rc) + return rc; + + rmnet_frag_segment_coal_data(frag_desc, nlo_err_mask, port, + list); + if (list_first_entry(list, struct rmnet_frag_descriptor, + list) != frag_desc) + rmnet_recycle_frag_descriptor(frag_desc, port); + break; + case RMNET_MAP_HEADER_TYPE_CSUM_OFFLOAD: + if (rmnet_frag_get_csum_valid(frag_desc)) { + priv->stats.csum_ok++; + frag_desc->csum_valid = true; + } else { + priv->stats.csum_valid_unset++; + } + + rmnet_frag_pull(frag_desc, port, + sizeof(struct rmnet_map_header) + + sizeof(struct rmnet_map_v5_csum_header)); + frag_desc->hdr_ptr = rmnet_frag_data_ptr(frag_desc); + + /* Remove padding only for csum offload packets. + * Coalesced packets should never have padding. + */ + rmnet_frag_trim(frag_desc, port, len); + list_del_init(&frag_desc->list); + list_add_tail(&frag_desc->list, list); + break; + default: + rc = -EINVAL; + break; + } + + return rc; +} + +/* Perf hook handler */ +rmnet_perf_desc_hook_t rmnet_perf_desc_entry __rcu __read_mostly; +EXPORT_SYMBOL(rmnet_perf_desc_entry); + +static void +__rmnet_frag_ingress_handler(struct rmnet_frag_descriptor *frag_desc, + struct rmnet_port *port) +{ + rmnet_perf_desc_hook_t rmnet_perf_ingress; + struct rmnet_map_header *qmap; + struct rmnet_endpoint *ep; + struct rmnet_frag_descriptor *frag, *tmp; + LIST_HEAD(segs); + u16 len, pad; + u8 mux_id; + + qmap = (struct rmnet_map_header *)skb_frag_address(&frag_desc->frag); + mux_id = qmap->mux_id; + pad = qmap->pad_len; + len = ntohs(qmap->pkt_len) - pad; + + if (qmap->cd_bit) { + qmi_rmnet_set_dl_msg_active(port); + if (port->data_format & RMNET_INGRESS_FORMAT_DL_MARKER) { + rmnet_frag_flow_command(qmap, port, len); + goto recycle; + } + + if (port->data_format & RMNET_FLAGS_INGRESS_MAP_COMMANDS) + rmnet_frag_command(qmap, port); + + goto recycle; + } + + if (mux_id >= RMNET_MAX_LOGICAL_EP) + goto recycle; + + ep = rmnet_get_endpoint(port, mux_id); + if (!ep) + goto recycle; + + frag_desc->dev = ep->egress_dev; + + /* Handle QMAPv5 packet */ + if (qmap->next_hdr && + (port->data_format & (RMNET_FLAGS_INGRESS_COALESCE | + RMNET_FLAGS_INGRESS_MAP_CKSUMV5))) { + if (rmnet_frag_process_next_hdr_packet(frag_desc, port, &segs, + len)) + goto recycle; + } else { + /* We only have the main QMAP header to worry about */ + rmnet_frag_pull(frag_desc, port, sizeof(*qmap)); + frag_desc->hdr_ptr = rmnet_frag_data_ptr(frag_desc); + + rmnet_frag_trim(frag_desc, port, len); + list_add_tail(&frag_desc->list, &segs); + } + + if (port->data_format & RMNET_INGRESS_FORMAT_PS) + qmi_rmnet_work_maybe_restart(port); + + rcu_read_lock(); + rmnet_perf_ingress = rcu_dereference(rmnet_perf_desc_entry); + if (rmnet_perf_ingress) { + list_for_each_entry_safe(frag, tmp, &segs, list) { + list_del_init(&frag->list); + rmnet_perf_ingress(frag, port); + } + rcu_read_unlock(); + return; + } + rcu_read_unlock(); + + list_for_each_entry_safe(frag, tmp, &segs, list) { + list_del_init(&frag->list); + rmnet_frag_deliver(frag, port); + } + return; + +recycle: + rmnet_recycle_frag_descriptor(frag_desc, port); +} + +/* Notify perf at the end of SKB chain */ +rmnet_perf_chain_hook_t rmnet_perf_chain_end __rcu __read_mostly; +EXPORT_SYMBOL(rmnet_perf_chain_end); + +void rmnet_frag_ingress_handler(struct sk_buff *skb, + struct rmnet_port *port) +{ + rmnet_perf_chain_hook_t rmnet_perf_opt_chain_end; + + /* Deaggregation and freeing of HW originating + * buffers is done within here + */ + while (skb) { + struct sk_buff *skb_frag; + + rmnet_frag_deaggregate(skb_shinfo(skb)->frags, port); + if (port->rmnet_desc->nr_frags) { + struct rmnet_frag_descriptor *frag_desc, *tmp; + + list_for_each_entry_safe(frag_desc, tmp, + &port->rmnet_desc->frags, + list) { + list_del_init(&frag_desc->list); + __rmnet_frag_ingress_handler(frag_desc, port); + } + } + + port->rmnet_desc->nr_frags = 0; + skb_frag = skb_shinfo(skb)->frag_list; + skb_shinfo(skb)->frag_list = NULL; + consume_skb(skb); + skb = skb_frag; + } + + rcu_read_lock(); + rmnet_perf_opt_chain_end = rcu_dereference(rmnet_perf_chain_end); + if (rmnet_perf_opt_chain_end) + rmnet_perf_opt_chain_end(); + rcu_read_unlock(); +} + +void rmnet_descriptor_deinit(struct rmnet_port *port) +{ + struct rmnet_frag_descriptor_pool *pool; + struct rmnet_frag_descriptor *frag_desc, *tmp; + + pool = port->frag_desc_pool; + + list_for_each_entry_safe(frag_desc, tmp, &pool->free_list, list) { + kfree(frag_desc); + pool->pool_size--; + } + + kfree(pool); + kfree(port->rmnet_desc); +} + +int rmnet_descriptor_init(struct rmnet_port *port) +{ + struct rmnet_descriptor *rmnet_desc; + struct rmnet_frag_descriptor_pool *pool; + int i; + + rmnet_desc = kzalloc(sizeof(*rmnet_desc), GFP_ATOMIC); + if (!rmnet_desc) + return -ENOMEM; + + INIT_LIST_HEAD(&rmnet_desc->frags); + port->rmnet_desc = rmnet_desc; + + pool = kzalloc(sizeof(*pool), GFP_ATOMIC); + if (!pool) + return -ENOMEM; + + INIT_LIST_HEAD(&pool->free_list); + port->frag_desc_pool = pool; + + for (i = 0; i < RMNET_FRAG_DESCRIPTOR_POOL_SIZE; i++) { + struct rmnet_frag_descriptor *frag_desc; + + frag_desc = kzalloc(sizeof(*frag_desc), GFP_ATOMIC); + if (!frag_desc) + return -ENOMEM; + + INIT_LIST_HEAD(&frag_desc->list); + INIT_LIST_HEAD(&frag_desc->sub_frags); + list_add_tail(&frag_desc->list, &pool->free_list); + pool->pool_size++; + } + + return 0; +} diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.h b/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.h new file mode 100644 index 000000000000..da4192320921 --- /dev/null +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.h @@ -0,0 +1,151 @@ +/* Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * RMNET Packet Descriptor Framework + * + */ + +#ifndef _RMNET_DESCRIPTOR_H_ +#define _RMNET_DESCRIPTOR_H_ + +#include +#include +#include +#include "rmnet_config.h" +#include "rmnet_map.h" + +struct rmnet_frag_descriptor_pool { + struct list_head free_list; + u32 pool_size; +}; + +struct rmnet_frag_descriptor { + struct list_head list; + struct list_head sub_frags; + skb_frag_t frag; + u8 *hdr_ptr; + struct net_device *dev; + u32 hash; + __be32 tcp_seq; + __be16 ip_id; + u16 data_offset; + u16 gso_size; + u16 gso_segs; + u16 ip_len; + u16 trans_len; + u8 ip_proto; + u8 trans_proto; + u8 pkt_id; + u8 csum_valid:1, + hdrs_valid:1, + ip_id_set:1, + tcp_seq_set:1, + flush_shs:1, + reserved:3; +}; + +struct rmnet_descriptor { + struct list_head frags; + u8 nr_frags; +}; + +/* Descriptor management */ +struct rmnet_frag_descriptor * +rmnet_get_frag_descriptor(struct rmnet_port *port); +void rmnet_recycle_frag_descriptor(struct rmnet_frag_descriptor *frag_desc, + struct rmnet_port *port); +void rmnet_descriptor_add_frag(struct rmnet_port *port, struct page *p, + u32 page_offset, u32 len); +int rmnet_frag_ipv6_skip_exthdr(struct rmnet_frag_descriptor *frag_desc, + int start, u8 *nexthdrp, __be16 *fragp); + +/* QMAP command packets */ +void rmnet_frag_command(struct rmnet_map_header *qmap, struct rmnet_port *port); +int rmnet_frag_flow_command(struct rmnet_map_header *qmap, + struct rmnet_port *port, u16 pkt_len); + +/* Ingress data handlers */ +void rmnet_frag_deaggregate(skb_frag_t *frag, struct rmnet_port *port); +void rmnet_frag_deliver(struct rmnet_frag_descriptor *frag_desc, + struct rmnet_port *port); +int rmnet_frag_process_next_hdr_packet(struct rmnet_frag_descriptor *frag_desc, + struct rmnet_port *port, + struct list_head *list, + u16 len); +void rmnet_frag_ingress_handler(struct sk_buff *skb, + struct rmnet_port *port); + +int rmnet_descriptor_init(struct rmnet_port *port); +void rmnet_descriptor_deinit(struct rmnet_port *port); + +static inline void *rmnet_frag_data_ptr(struct rmnet_frag_descriptor *frag_desc) +{ + return skb_frag_address(&frag_desc->frag); +} + +static inline void *rmnet_frag_pull(struct rmnet_frag_descriptor *frag_desc, + struct rmnet_port *port, + unsigned int size) +{ + if (size >= skb_frag_size(&frag_desc->frag)) { + rmnet_recycle_frag_descriptor(frag_desc, port); + return NULL; + } + + frag_desc->frag.page_offset += size; + skb_frag_size_sub(&frag_desc->frag, size); + + return rmnet_frag_data_ptr(frag_desc); +} + +static inline void *rmnet_frag_trim(struct rmnet_frag_descriptor *frag_desc, + struct rmnet_port *port, + unsigned int size) +{ + if (!size) { + rmnet_recycle_frag_descriptor(frag_desc, port); + return NULL; + } + + if (size < skb_frag_size(&frag_desc->frag)) + skb_frag_size_set(&frag_desc->frag, size); + + return rmnet_frag_data_ptr(frag_desc); +} + +static inline void rmnet_frag_fill(struct rmnet_frag_descriptor *frag_desc, + struct page *p, u32 page_offset, u32 len) +{ + get_page(p); + __skb_frag_set_page(&frag_desc->frag, p); + skb_frag_size_set(&frag_desc->frag, len); + frag_desc->frag.page_offset = page_offset; +} + +static inline u8 +rmnet_frag_get_next_hdr_type(struct rmnet_frag_descriptor *frag_desc) +{ + unsigned char *data = rmnet_frag_data_ptr(frag_desc); + + data += sizeof(struct rmnet_map_header); + return ((struct rmnet_map_v5_coal_header *)data)->header_type; +} + +static inline bool +rmnet_frag_get_csum_valid(struct rmnet_frag_descriptor *frag_desc) +{ + unsigned char *data = rmnet_frag_data_ptr(frag_desc); + + data += sizeof(struct rmnet_map_header); + return ((struct rmnet_map_v5_csum_header *)data)->csum_valid_required; +} + +#endif /* _RMNET_DESCRIPTOR_H_ */ diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c index a21b9360bb9e..8b79b52f2988 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c @@ -25,6 +25,7 @@ #include "rmnet_vnd.h" #include "rmnet_map.h" #include "rmnet_handlers.h" +#include "rmnet_descriptor.h" #include #include @@ -86,11 +87,6 @@ void rmnet_set_skb_proto(struct sk_buff *skb) } EXPORT_SYMBOL(rmnet_set_skb_proto); -/* Perf hook handler */ -void (*rmnet_perf_skb_entry)(struct sk_buff *skb, - struct rmnet_port *port) __rcu __read_mostly; -EXPORT_SYMBOL(rmnet_perf_skb_entry); - /* Shs hook handler */ int (*rmnet_shs_skb_entry)(struct sk_buff *skb, struct rmnet_port *port) __rcu __read_mostly; @@ -106,8 +102,6 @@ EXPORT_SYMBOL(rmnet_shs_skb_entry_wq); void rmnet_deliver_skb(struct sk_buff *skb, struct rmnet_port *port) { - void (*rmnet_perf_ingress)(struct sk_buff *skb, - struct rmnet_port *port); int (*rmnet_shs_stamp)(struct sk_buff *skb, struct rmnet_port *port); struct rmnet_priv *priv = netdev_priv(skb->dev); @@ -121,13 +115,6 @@ rmnet_deliver_skb(struct sk_buff *skb, struct rmnet_port *port) skb_set_mac_header(skb, 0); rcu_read_lock(); - rmnet_perf_ingress = rcu_dereference(rmnet_perf_skb_entry); - if (rmnet_perf_ingress) { - rmnet_perf_ingress(skb, port); - rcu_read_unlock(); - return; - } - rmnet_shs_stamp = rcu_dereference(rmnet_shs_skb_entry); if (rmnet_shs_stamp) { rmnet_shs_stamp(skb, port); @@ -302,10 +289,6 @@ int (*rmnet_perf_deag_entry)(struct sk_buff *skb, struct rmnet_port *port) __rcu __read_mostly; EXPORT_SYMBOL(rmnet_perf_deag_entry); -/* Notify perf at the end of SKB chain */ -void (*rmnet_perf_chain_end)(void) __rcu __read_mostly; -EXPORT_SYMBOL(rmnet_perf_chain_end); - static void rmnet_map_ingress_handler(struct sk_buff *skb, struct rmnet_port *port) @@ -313,7 +296,6 @@ rmnet_map_ingress_handler(struct sk_buff *skb, struct sk_buff *skbn; int (*rmnet_perf_core_deaggregate)(struct sk_buff *skb, struct rmnet_port *port); - void (*rmnet_perf_opt_chain_end)(void); if (skb->dev->type == ARPHRD_ETHER) { if (pskb_expand_head(skb, ETH_HLEN, 0, GFP_KERNEL)) { @@ -324,6 +306,14 @@ rmnet_map_ingress_handler(struct sk_buff *skb, skb_push(skb, ETH_HLEN); } + if (port->data_format & (RMNET_FLAGS_INGRESS_COALESCE | + RMNET_FLAGS_INGRESS_MAP_CKSUMV5)) { + if (skb_is_nonlinear(skb)) { + rmnet_frag_ingress_handler(skb, port); + return; + } + } + /* No aggregation. Pass the frame on as is */ if (!(port->data_format & RMNET_FLAGS_INGRESS_DEAGGREGATION)) { __rmnet_map_ingress_handler(skb, port); @@ -358,12 +348,6 @@ rmnet_map_ingress_handler(struct sk_buff *skb, next_skb: skb = skb_frag; } - - rcu_read_lock(); - rmnet_perf_opt_chain_end = rcu_dereference(rmnet_perf_chain_end); - if (rmnet_perf_opt_chain_end) - rmnet_perf_opt_chain_end(); - rcu_read_unlock(); } static int rmnet_map_egress_handler(struct sk_buff *skb, diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h index b5b1cfaf9135..17d8252500df 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h @@ -255,6 +255,10 @@ int rmnet_map_tx_agg_skip(struct sk_buff *skb, int offset); void rmnet_map_tx_aggregate(struct sk_buff *skb, struct rmnet_port *port); void rmnet_map_tx_aggregate_init(struct rmnet_port *port); void rmnet_map_tx_aggregate_exit(struct rmnet_port *port); +void rmnet_map_dl_hdr_notify(struct rmnet_port *port, + struct rmnet_map_dl_ind_hdr *dl_hdr); +void rmnet_map_dl_trl_notify(struct rmnet_port *port, + struct rmnet_map_dl_ind_trl *dltrl); int rmnet_map_flow_command(struct sk_buff *skb, struct rmnet_port *port, bool rmnet_perf); diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_command.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_command.c index 67a4e1ca508c..38415228cd1b 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_command.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_command.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -96,8 +96,8 @@ static void rmnet_map_send_ack(struct sk_buff *skb, netif_tx_unlock(dev); } -static void rmnet_map_dl_hdr_notify(struct rmnet_port *port, - struct rmnet_map_dl_ind_hdr *dlhdr) +void rmnet_map_dl_hdr_notify(struct rmnet_port *port, + struct rmnet_map_dl_ind_hdr *dlhdr) { struct rmnet_map_dl_ind *tmp; @@ -107,8 +107,8 @@ static void rmnet_map_dl_hdr_notify(struct rmnet_port *port, tmp->dl_hdr_handler(dlhdr); } -static void rmnet_map_dl_trl_notify(struct rmnet_port *port, - struct rmnet_map_dl_ind_trl *dltrl) +void rmnet_map_dl_trl_notify(struct rmnet_port *port, + struct rmnet_map_dl_ind_trl *dltrl) { struct rmnet_map_dl_ind *tmp; struct napi_struct *napi; @@ -154,12 +154,11 @@ static void rmnet_map_process_flow_start(struct sk_buff *skb, pull_size += sizeof(struct rmnet_map_dl_csum_trailer); pskb_pull(skb, pull_size); } - } static void rmnet_map_process_flow_end(struct sk_buff *skb, struct rmnet_port *port, - bool rmnet_perf) + bool rmnet_perf) { struct rmnet_map_dl_ind_trl *dltrl; @@ -182,7 +181,6 @@ static void rmnet_map_process_flow_end(struct sk_buff *skb, pull_size += sizeof(struct rmnet_map_dl_csum_trailer); pskb_pull(skb, pull_size); } - } /* Process MAP command frame and send N/ACK message as appropriate. Message cmd -- GitLab From fc2cb62d662c787073de007d46876a43af5e55fd Mon Sep 17 00:00:00 2001 From: Sujeev Dias Date: Fri, 26 Apr 2019 17:37:06 -0700 Subject: [PATCH 0559/1121] mhi: core: mark MHI interrupts as IRQF_NO_SUSPEND Since we allow apps to suspend while device in active state, we can receive completion data event during system suspend. MHI interrupts needs to enable during system suspend, therefore mark it as IRQF_NO_SUSPEND. CRs-Fixed: 2443135 Change-Id: I969312b50374465c8304f6cc6313ca529f7f4abf Signed-off-by: Sujeev Dias --- drivers/bus/mhi/core/mhi_init.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/bus/mhi/core/mhi_init.c b/drivers/bus/mhi/core/mhi_init.c index da5df8d84661..6be780b4f397 100644 --- a/drivers/bus/mhi/core/mhi_init.c +++ b/drivers/bus/mhi/core/mhi_init.c @@ -119,7 +119,8 @@ int mhi_init_irq_setup(struct mhi_controller *mhi_cntrl) /* for BHI INTVEC msi */ ret = request_threaded_irq(mhi_cntrl->irq[0], mhi_intvec_handlr, - mhi_intvec_threaded_handlr, IRQF_ONESHOT, + mhi_intvec_threaded_handlr, + IRQF_ONESHOT | IRQF_NO_SUSPEND, "mhi", mhi_cntrl); if (ret) return ret; @@ -129,8 +130,8 @@ int mhi_init_irq_setup(struct mhi_controller *mhi_cntrl) continue; ret = request_irq(mhi_cntrl->irq[mhi_event->msi], - mhi_msi_handlr, IRQF_SHARED, "mhi", - mhi_event); + mhi_msi_handlr, IRQF_SHARED | IRQF_NO_SUSPEND, + "mhi", mhi_event); if (ret) { MHI_ERR("Error requesting irq:%d for ev:%d\n", mhi_cntrl->irq[mhi_event->msi], i); -- GitLab From aaba47a049a9e1298887a9a60f2ea71a94ef847a Mon Sep 17 00:00:00 2001 From: Sreelakshmi Gownipalli Date: Thu, 14 Mar 2019 01:16:06 -0700 Subject: [PATCH 0560/1121] Revert "diag: Clear memory device entries during mhi disconnect" Clear the entries in the memory device table during the mhi remove call for diag channels. Change-Id: Ie44003993782c8080aa5c2d70ada680bbd50bc9e Signed-off-by: Sreelakshmi Gownipalli --- drivers/char/diag/diag_memorydevice.c | 10 ++-------- drivers/char/diag/diag_mux.c | 14 -------------- drivers/char/diag/diag_mux.h | 1 - drivers/char/diag/diagfwd_bridge.c | 3 --- 4 files changed, 2 insertions(+), 26 deletions(-) diff --git a/drivers/char/diag/diag_memorydevice.c b/drivers/char/diag/diag_memorydevice.c index 87e6862ec2ae..3d2bcf7dc9dd 100644 --- a/drivers/char/diag/diag_memorydevice.c +++ b/drivers/char/diag/diag_memorydevice.c @@ -288,19 +288,13 @@ int diag_md_copy_to_user(char __user *buf, int *pret, size_t buf_size, if (!ch->md_info_inited) continue; for (j = 0; j < ch->num_tbl_entries && !err; j++) { - spin_lock_irqsave(&ch->lock, flags); entry = &ch->tbl[j]; - if (entry->len <= 0 || entry->buf == NULL) { - spin_unlock_irqrestore(&ch->lock, flags); + if (entry->len <= 0 || entry->buf == NULL) continue; - } peripheral = diag_md_get_peripheral(entry->ctx); - if (peripheral < 0) { - spin_unlock_irqrestore(&ch->lock, flags); + if (peripheral < 0) goto drop_data; - } - spin_unlock_irqrestore(&ch->lock, flags); session_info = diag_md_session_get_peripheral(i, peripheral); if (!session_info) diff --git a/drivers/char/diag/diag_mux.c b/drivers/char/diag/diag_mux.c index 4cc02803b3ff..441d28c2558e 100644 --- a/drivers/char/diag/diag_mux.c +++ b/drivers/char/diag/diag_mux.c @@ -293,20 +293,6 @@ int diag_mux_close_peripheral(int proc, uint8_t peripheral) return 0; } -int diag_mux_close_device(int proc) -{ - struct diag_logger_t *logger = NULL; - - if (!diag_mux) - return -EIO; - - logger = diag_mux->logger[proc]; - - if (logger && logger->log_ops && logger->log_ops->close_device) - logger->log_ops->close_device(proc); - return 0; -} - int diag_mux_switch_logging(int proc, int *req_mode, int *peripheral_mask) { unsigned int new_mask = 0; diff --git a/drivers/char/diag/diag_mux.h b/drivers/char/diag/diag_mux.h index 3bafa8864dce..c4d5bbd4c4a7 100644 --- a/drivers/char/diag/diag_mux.h +++ b/drivers/char/diag/diag_mux.h @@ -71,7 +71,6 @@ int diag_mux_register(int proc, int ctx, struct diag_mux_ops *ops); int diag_mux_queue_read(int proc); int diag_mux_write(int proc, unsigned char *buf, int len, int ctx); int diag_mux_close_peripheral(int proc, uint8_t peripheral); -int diag_mux_close_device(int proc); int diag_mux_open_all(struct diag_logger_t *logger); int diag_mux_close_all(void); int diag_pcie_register_ops(int proc, int ctx, struct diag_mux_ops *ops); diff --git a/drivers/char/diag/diagfwd_bridge.c b/drivers/char/diag/diagfwd_bridge.c index 0caa7405587b..27f7aacc4825 100644 --- a/drivers/char/diag/diagfwd_bridge.c +++ b/drivers/char/diag/diagfwd_bridge.c @@ -176,10 +176,7 @@ int diag_remote_dev_open(int id) void diag_remote_dev_close(int id) { - if (id < 0 || id >= NUM_REMOTE_DEV) - return; - diag_mux_close_device(BRIDGE_TO_MUX(id)); } int diag_remote_dev_read_done(int id, unsigned char *buf, int len) -- GitLab From 4604fd9d494c05845d176d06152eed07b7504691 Mon Sep 17 00:00:00 2001 From: Zhiqiang Tu Date: Thu, 13 Jun 2019 11:13:28 +0800 Subject: [PATCH 0561/1121] ARM: dts: msm: Enable NVMe device on sa8155 adp star Enable NVMe device tree to use SMMU configuration in NVMe driver. Change-Id: If1effca6bd44c7ae5106582eb90f533583413ad6 Signed-off-by: Zhiqiang Tu --- arch/arm64/boot/dts/qcom/sa8155-adp-star.dtsi | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sa8155-adp-star.dtsi b/arch/arm64/boot/dts/qcom/sa8155-adp-star.dtsi index 340c9edb7747..b1f546fbfc68 100644 --- a/arch/arm64/boot/dts/qcom/sa8155-adp-star.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8155-adp-star.dtsi @@ -13,3 +13,40 @@ #include "sa8155-adp-common.dtsi" #include "sa8155-adp-star-display.dtsi" +&pcie1 { + qcom,boot-option = <0x0>; +}; + +&pcie_rc1 { + nvme_x8: qcom,nvme@pcie_rc1 { + reg = <0 0 0 0 0>; + compatible = "qcom,nvme"; + pci-ids = + "8086:0953", + "8086:0a54", + "8086:0a55", + "8086:f1a5", + "8086:f1a5", + "1c58:0003", + "1c58:0023", + "1c5c:1327", + "1c5f:0540", + "144d:a821", + "144d:a822", + "144d:a808", + "1d1d:1f1f", + "1d1d:2807", + "1d1d:2601", + "106b:2001", + "106b:2003", + "1179:0115", + "1179:0116"; + + qcom,smmu; + qcom,smmu-iova-base = /bits/ 64 <0x20000000>; + qcom,smmu-iova-size = /bits/ 64 <0x40000000>; + + qcom,smmu-attr-atomic; + qcom,smmu-attr-s1-bypass; + }; +}; -- GitLab From 8b897f184a7a7fd54a9892362aa1502230c235d9 Mon Sep 17 00:00:00 2001 From: Ashay Jaiswal Date: Wed, 12 Jun 2019 15:06:48 +0530 Subject: [PATCH 0562/1121] power: step-chg-jeita: update jeita/step ranges to support signed threshold Currently software JEITA uses unsigned variable to store threshold data and thus fails to support negative temperature ranges, fix this by using signed variable to store threshold data. Change-Id: Ia888610e9e4ee4606333a07a3f338a494ec0392e Signed-off-by: Ashay Jaiswal --- drivers/power/supply/qcom/fg-alg.c | 2 +- drivers/power/supply/qcom/step-chg-jeita.c | 2 +- drivers/power/supply/qcom/step-chg-jeita.h | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/power/supply/qcom/fg-alg.c b/drivers/power/supply/qcom/fg-alg.c index b2237a4c405d..a382d60299d9 100644 --- a/drivers/power/supply/qcom/fg-alg.c +++ b/drivers/power/supply/qcom/fg-alg.c @@ -1110,7 +1110,7 @@ static int get_time_to_full_locked(struct ttf *ttf, int *val) /* Calculate OCV for each window */ if (power_approx) { - i_step = pbatt_avg / max((u32)MILLI_UNIT, + i_step = pbatt_avg / max(MILLI_UNIT, (step_chg_cfg[i].high_threshold / MILLI_UNIT)); } else { diff --git a/drivers/power/supply/qcom/step-chg-jeita.c b/drivers/power/supply/qcom/step-chg-jeita.c index a37af0a407fe..ab8eeb897745 100644 --- a/drivers/power/supply/qcom/step-chg-jeita.c +++ b/drivers/power/supply/qcom/step-chg-jeita.c @@ -158,7 +158,7 @@ static bool is_input_present(struct step_chg_info *chip) int read_range_data_from_node(struct device_node *node, const char *prop_str, struct range_data *ranges, - u32 max_threshold, u32 max_value) + int max_threshold, u32 max_value) { int rc = 0, i, length, per_tuple_length, tuples; diff --git a/drivers/power/supply/qcom/step-chg-jeita.h b/drivers/power/supply/qcom/step-chg-jeita.h index 229f2980ab37..26e74ed484e9 100644 --- a/drivers/power/supply/qcom/step-chg-jeita.h +++ b/drivers/power/supply/qcom/step-chg-jeita.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -23,8 +23,8 @@ struct step_chg_jeita_param { }; struct range_data { - u32 low_threshold; - u32 high_threshold; + int low_threshold; + int high_threshold; u32 value; }; @@ -33,5 +33,5 @@ int qcom_step_chg_init(struct device *dev, void qcom_step_chg_deinit(void); int read_range_data_from_node(struct device_node *node, const char *prop_str, struct range_data *ranges, - u32 max_threshold, u32 max_value); + int max_threshold, u32 max_value); #endif /* __STEP_CHG_H__ */ -- GitLab From 2d5cf9e37e35bdb58e50d7d11ce88ebab5d3b7c6 Mon Sep 17 00:00:00 2001 From: Suraj Jaiswal Date: Tue, 11 Jun 2019 15:18:49 +0530 Subject: [PATCH 0563/1121] net: phy: Fix WOL in Micrel phy Generic Phy Resume/Suspend API's already hold the mutex and holding the mutex in Micrel will cause a deadlock. Make a change to remove the mutex locks in Micrel code. Change-Id: Ib3bd976dc70f7669ee1e34658b565921d6704e25 Signed-off-by: Suraj Jaiswal --- drivers/net/phy/micrel.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 2fa2bd56edfa..a44b004086b7 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -926,8 +926,6 @@ static int ksz9031_suspend(struct phy_device *phydev) int wol_enabled; u32 reg_value; - mutex_lock(&phydev->lock); - reg_value = ksz9031_extended_read( phydev, OP_DATA, 0x2, MII_KSZPHY_OMSO_REG); wol_enabled = reg_value & MII_KSZPHY_OMSO_PME_N2; @@ -939,7 +937,6 @@ static int ksz9031_suspend(struct phy_device *phydev) value |= BMCR_PDOWN; phy_write(phydev, MII_BMCR, value); - mutex_unlock(&phydev->lock); return 0; } @@ -948,14 +945,10 @@ static int ksz9031_resume(struct phy_device *phydev) { int value; - mutex_lock(&phydev->lock); - value = phy_read(phydev, MII_BMCR); value &= ~(BMCR_PDOWN | BMCR_ISOLATE); phy_write(phydev, MII_BMCR, value); - mutex_unlock(&phydev->lock); - return 0; } -- GitLab From e55b7ac8005a1b7a8070dacd39a67646c4327ca5 Mon Sep 17 00:00:00 2001 From: Shadul Shaikh Date: Thu, 30 May 2019 11:13:56 +0530 Subject: [PATCH 0564/1121] msm: camera: Increase CCI timeout To generate the halt-ack interrupt after halting the execution of commands from I2C master(s) queue is taking more time. To avoid halt-ack miss, increased CCI wait timeout. Change-Id: I574c1f14c11a74a24ff52313f08de16d997a2e7f Signed-off-by: Shadul Shaikh --- drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c index ed011f236e7d..fe15782812d2 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c +++ b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -32,7 +32,7 @@ #define CYCLES_PER_MICRO_SEC_DEFAULT 4915 #define CCI_MAX_DELAY 1000000 -#define CCI_TIMEOUT msecs_to_jiffies(100) +#define CCI_TIMEOUT msecs_to_jiffies(500) /* TODO move this somewhere else */ #define MSM_CCI_DRV_NAME "msm_cci" -- GitLab From 1fe3affc4e4b1591d12932ac6391e7cad6ef0f50 Mon Sep 17 00:00:00 2001 From: Han Lu Date: Tue, 11 Jun 2019 11:42:48 +0800 Subject: [PATCH 0565/1121] ARM: dts: msm: add hostless QUIN TDM configuration Add hostless quinary TDM to its group TDM configuration with tdm-quin-tx-7 and tdm-quin-rx-7 Change-Id: Iba440bdbd50380040bcd1362a85c1a376e6e6ab0 Signed-off-by: Han Lu --- arch/arm64/boot/dts/qcom/sa8155-audio.dtsi | 34 +++++++++++++++------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sa8155-audio.dtsi b/arch/arm64/boot/dts/qcom/sa8155-audio.dtsi index b18164fa69df..b3cc219732fe 100644 --- a/arch/arm64/boot/dts/qcom/sa8155-audio.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8155-audio.dtsi @@ -367,8 +367,9 @@ qcom,msm-dai-tdm-quin-rx { compatible = "qcom,msm-dai-tdm"; qcom,msm-cpudai-tdm-group-id = <37184>; - qcom,msm-cpudai-tdm-group-num-ports = <4>; - qcom,msm-cpudai-tdm-group-port-id = <36928 36930 36932 36934>; + qcom,msm-cpudai-tdm-group-num-ports = <5>; + qcom,msm-cpudai-tdm-group-port-id = <36928 36930 36932 + 36934 36942>; qcom,msm-cpudai-tdm-clk-rate = <24576000>; qcom,msm-cpudai-tdm-clk-internal = <1>; qcom,msm-cpudai-tdm-sync-mode = <1>; @@ -402,13 +403,19 @@ qcom,msm-cpudai-tdm-dev-id = <36934>; qcom,msm-cpudai-tdm-data-align = <0>; }; + dai_quin_tdm_rx_7: qcom,msm-dai-q6-tdm-quin-rx-7 { + compatible = "qcom,msm-dai-q6-tdm"; + qcom,msm-cpudai-tdm-dev-id = <36942>; + qcom,msm-cpudai-tdm-data-align = <0>; + }; }; qcom,msm-dai-tdm-quin-tx { compatible = "qcom,msm-dai-tdm"; qcom,msm-cpudai-tdm-group-id = <37185>; - qcom,msm-cpudai-tdm-group-num-ports = <4>; - qcom,msm-cpudai-tdm-group-port-id = <36929 36931 36933 36935>; + qcom,msm-cpudai-tdm-group-num-ports = <5>; + qcom,msm-cpudai-tdm-group-port-id = <36929 36931 36933 + 36935 36943>; qcom,msm-cpudai-tdm-clk-rate = <24576000>; qcom,msm-cpudai-tdm-clk-internal = <1>; qcom,msm-cpudai-tdm-sync-mode = <1>; @@ -442,6 +449,11 @@ qcom,msm-cpudai-tdm-dev-id = <36935>; qcom,msm-cpudai-tdm-data-align = <0>; }; + dai_quin_tdm_tx_7: qcom,msm-dai-q6-tdm-quin-tx-7 { + compatible = "qcom,msm-dai-q6-tdm"; + qcom,msm-cpudai-tdm-dev-id = <36943>; + qcom,msm-cpudai-tdm-data-align = <0>; + }; }; dai_pri_auxpcm: qcom,msm-pri-auxpcm { @@ -518,9 +530,10 @@ <&dai_quat_tdm_tx_2>, <&dai_quat_tdm_tx_3>, <&dai_quat_tdm_tx_7>, <&dai_quin_tdm_rx_0>, <&dai_quin_tdm_rx_1>, <&dai_quin_tdm_rx_2>, - <&dai_quin_tdm_rx_3>, <&dai_quin_tdm_tx_0>, - <&dai_quin_tdm_tx_1>, <&dai_quin_tdm_tx_2>, - <&dai_quin_tdm_tx_3>; + <&dai_quin_tdm_rx_3>, <&dai_quin_tdm_rx_7>, + <&dai_quin_tdm_tx_0>, <&dai_quin_tdm_tx_1>, + <&dai_quin_tdm_tx_2>, <&dai_quin_tdm_tx_3>, + <&dai_quin_tdm_tx_7>; asoc-cpu-names = "msm-dai-q6-hdmi.8", "msm-dai-q6-dp.24608", "msm-dai-q6-mi2s.0", "msm-dai-q6-mi2s.1", "msm-dai-q6-mi2s.2", "msm-dai-q6-mi2s.3", @@ -552,9 +565,10 @@ "msm-dai-q6-tdm.36917", "msm-dai-q6-tdm.36919", "msm-dai-q6-tdm.36927", "msm-dai-q6-tdm.36928", "msm-dai-q6-tdm.36930", "msm-dai-q6-tdm.36932", - "msm-dai-q6-tdm.36934", "msm-dai-q6-tdm.36929", - "msm-dai-q6-tdm.36931", "msm-dai-q6-tdm.36933", - "msm-dai-q6-tdm.36935"; + "msm-dai-q6-tdm.36934", "msm-dai-q6-tdm.36942", + "msm-dai-q6-tdm.36929", "msm-dai-q6-tdm.36931", + "msm-dai-q6-tdm.36933", "msm-dai-q6-tdm.36935", + "msm-dai-q6-tdm.36943"; asoc-codec = <&stub_codec>; asoc-codec-names = "msm-stub-codec.1"; qcom,msm_audio_ssr_devs = <&audio_apr>, <&q6core>; -- GitLab From 5487daabfa7ce97740d759dd2100dfdadd65e824 Mon Sep 17 00:00:00 2001 From: vagdhan kumar kanukurthi Date: Mon, 13 May 2019 11:31:24 +0530 Subject: [PATCH 0566/1121] clk: qcom: Add sa6155 pcie support for virtual clock Add sa6155 pcie clocks in virtual clock driver. Change-Id: I9052a96a0be1cc5b6ef18aea596f62352cca5765 Signed-off-by: Vagdhan Kanukurthi --- drivers/clk/qcom/clk-virt-sm6150.c | 74 ++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/drivers/clk/qcom/clk-virt-sm6150.c b/drivers/clk/qcom/clk-virt-sm6150.c index 5af572c6e9ac..cb747efec1b1 100644 --- a/drivers/clk/qcom/clk-virt-sm6150.c +++ b/drivers/clk/qcom/clk-virt-sm6150.c @@ -25,6 +25,8 @@ static struct virt_reset_map sm6150_gcc_virt_resets[] = { [GCC_USB20_SEC_BCR] = { "gcc_usb20_sec_master_clk" }, [GCC_USB3_PHY_PRIM_SP0_BCR] = { "gcc_usb3_phy_prim_sp0_bcr" }, [GCC_USB3PHY_PHY_PRIM_SP0_BCR] = { "gcc_usb3phy_phy_prim_sp0_bcr" }, + [GCC_PCIE_0_BCR] = { "gcc_pcie_0_mstr_axi_clk" }, + [GCC_PCIE_0_PHY_BCR] = { "gcc_pcie_0_phy_bcr" }, }; static struct clk_virt gcc_qupv3_wrap0_s0_clk = { @@ -216,6 +218,69 @@ static struct clk_virt gcc_usb3_prim_phy_com_aux_clk = { }, }; +static struct clk_virt gcc_pcie_0_pipe_clk = { + .hw.init = &(struct clk_init_data) { + .ops = &clk_virt_ops, + .name = "gcc_pcie_0_pipe_clk", + }, +}; + +static struct clk_virt gcc_pcie_0_aux_clk = { + .hw.init = &(struct clk_init_data) { + .ops = &clk_virt_ops, + .name = "gcc_pcie_0_aux_clk", + }, +}; + +static struct clk_virt gcc_pcie_0_cfg_ahb_clk = { + .hw.init = &(struct clk_init_data) { + .ops = &clk_virt_ops, + .name = "gcc_pcie_0_cfg_ahb_clk", + }, +}; + +static struct clk_virt gcc_pcie_0_mstr_axi_clk = { + .hw.init = &(struct clk_init_data) { + .ops = &clk_virt_ops, + .name = "gcc_pcie_0_mstr_axi_clk", + }, +}; + +static struct clk_virt gcc_pcie_0_slv_axi_clk = { + .hw.init = &(struct clk_init_data) { + .ops = &clk_virt_ops, + .name = "gcc_pcie_0_slv_axi_clk", + }, +}; + +static struct clk_virt gcc_pcie_0_clkref_clk = { + .hw.init = &(struct clk_init_data) { + .ops = &clk_virt_ops, + .name = "gcc_pcie_0_clkref_en", + }, +}; + +static struct clk_virt gcc_pcie_0_slv_q2a_axi_clk = { + .hw.init = &(struct clk_init_data) { + .ops = &clk_virt_ops, + .name = "gcc_pcie_0_slv_q2a_axi_clk", + }, +}; + +static struct clk_virt gcc_pcie0_phy_refgen_clk = { + .hw.init = &(struct clk_init_data) { + .ops = &clk_virt_ops, + .name = "gcc_pcie0_phy_refgen_clk", + }, +}; + +static struct clk_virt gcc_pcie_phy_aux_clk = { + .hw.init = &(struct clk_init_data) { + .ops = &clk_virt_ops, + .name = "gcc_pcie_phy_aux_clk", + }, +}; + static struct clk_hw *sm6150_gcc_virt_clocks[] = { [GCC_QUPV3_WRAP0_S0_CLK] = &gcc_qupv3_wrap0_s0_clk.hw, [GCC_QUPV3_WRAP0_S1_CLK] = &gcc_qupv3_wrap0_s1_clk.hw, @@ -244,6 +309,15 @@ static struct clk_hw *sm6150_gcc_virt_clocks[] = { [GCC_USB3_PRIM_CLKREF_CLK] = &gcc_usb3_prim_clkref_clk.hw, [GCC_USB3_PRIM_PHY_COM_AUX_CLK] = &gcc_usb3_prim_phy_com_aux_clk.hw, [GCC_AHB2PHY_WEST_CLK] = &gcc_ahb2phy_west_clk.hw, + [GCC_PCIE_0_PIPE_CLK] = &gcc_pcie_0_pipe_clk.hw, + [GCC_PCIE_0_AUX_CLK] = &gcc_pcie_0_aux_clk.hw, + [GCC_PCIE_0_CFG_AHB_CLK] = &gcc_pcie_0_cfg_ahb_clk.hw, + [GCC_PCIE_0_MSTR_AXI_CLK] = &gcc_pcie_0_mstr_axi_clk.hw, + [GCC_PCIE_0_SLV_AXI_CLK] = &gcc_pcie_0_slv_axi_clk.hw, + [GCC_PCIE_0_CLKREF_CLK] = &gcc_pcie_0_clkref_clk.hw, + [GCC_PCIE_0_SLV_Q2A_AXI_CLK] = &gcc_pcie_0_slv_q2a_axi_clk.hw, + [GCC_PCIE0_PHY_REFGEN_CLK] = &gcc_pcie0_phy_refgen_clk.hw, + [GCC_PCIE_PHY_AUX_CLK] = &gcc_pcie_phy_aux_clk.hw, }; const struct clk_virt_desc clk_virt_sm6150_gcc = { -- GitLab From 2e12f31b217d930c628506f3c356a4a7021bf05e Mon Sep 17 00:00:00 2001 From: Tejas Prajapati Date: Thu, 13 Jun 2019 16:17:40 +0530 Subject: [PATCH 0567/1121] msm: camera: isp: Halt device with the command parsed In shutdown case rdi and ipp device should be closed immediately instead of at frame boundary because in shutdown sensor would close first and closing of ipp and rdi at frame boundary will resuly in timeout. Change-Id: Idad0304c6ce0a9ab4f9399753bbcf87bf8941c8b Signed-off-by: Tejas Prajapati --- .../platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c index a228df5f9cd7..3d394c69368f 100644 --- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c @@ -2637,7 +2637,7 @@ static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args) /* Stop the master CSID path first */ cam_ife_mgr_csid_stop_hw(ctx, &ctx->res_list_ife_csid, - master_base_idx, CAM_CSID_HALT_AT_FRAME_BOUNDARY); + master_base_idx, csid_halt_type); /* stop rest of the CSID paths */ for (i = 0; i < ctx->num_base; i++) { @@ -2647,7 +2647,7 @@ static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args) ctx->base[i].idx, i, master_base_idx); cam_ife_mgr_csid_stop_hw(ctx, &ctx->res_list_ife_csid, - ctx->base[i].idx, CAM_CSID_HALT_AT_FRAME_BOUNDARY); + ctx->base[i].idx, csid_halt_type); } CAM_DBG(CAM_ISP, "Stopping master CID idx %d", master_base_idx); -- GitLab From 74b22b6a0174524d86c3cc3926c69a342f44c30f Mon Sep 17 00:00:00 2001 From: Maulik Shah Date: Thu, 13 Jun 2019 17:24:40 +0530 Subject: [PATCH 0568/1121] irqchip: pdc: Iterate for actual available pdc regs during hibernation Current implementation iterates through maximum possible registers of PDC to save status during hibernation. However some targets have limited PDC registers available. Fix this by counting during init time. Change-Id: I37b048e0edf12cc81efca2087f92c867acb4ed93 Signed-off-by: Maulik Shah --- drivers/irqchip/qcom/pdc.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/irqchip/qcom/pdc.c b/drivers/irqchip/qcom/pdc.c index ac2b6380a27a..3f8e8aa5bb12 100644 --- a/drivers/irqchip/qcom/pdc.c +++ b/drivers/irqchip/qcom/pdc.c @@ -33,7 +33,8 @@ #include "trace/events/pdc.h" #define MAX_IRQS 126 -#define MAX_ENABLE_REGS ((MAX_IRQS/32) + 1) +#define IRQS_PER_REG 32 +#define MAX_ENABLE_REGS ((MAX_IRQS/IRQS_PER_REG) + 1) #define CLEAR_INTR(reg, intr) (reg & ~(1 << intr)) #define ENABLE_INTR(reg, intr) (reg | (1 << intr)) @@ -48,7 +49,7 @@ struct pdc_type_info { }; static struct pdc_type_info pdc_type_config[MAX_IRQS]; static u32 pdc_enabled[MAX_ENABLE_REGS]; - +static u32 max_enable_regs; static DEFINE_SPINLOCK(pdc_lock); static void __iomem *pdc_base; @@ -292,7 +293,7 @@ static int pdc_suspend(void) { int i; - for (i = 0; i < MAX_ENABLE_REGS; i++) + for (i = 0; i < max_enable_regs; i++) pdc_enabled[i] = readl_relaxed(pdc_base + IRQ_ENABLE_BANK + (i * sizeof(uint32_t))); @@ -319,7 +320,7 @@ static void pdc_resume(void) } } - for (i = 0; i < MAX_ENABLE_REGS; i++) + for (i = 0; i < max_enable_regs; i++) writel_relaxed(pdc_enabled[i], pdc_base + IRQ_ENABLE_BANK + (i * sizeof(uint32_t))); } @@ -340,8 +341,9 @@ int qcom_pdc_init(struct device_node *node, struct device_node *parent, void *data) { struct irq_domain *parent_domain; - int ret; + int i, ret, pin_count = 0; struct irq_domain *pdc_domain; + struct pdc_pin *pdc_data = (struct pdc_pin *) data; pdc_base = of_iomap(node, 0); if (!pdc_base) { @@ -364,6 +366,13 @@ int qcom_pdc_init(struct device_node *node, goto failure; } + for (i = 0; pdc_data[i].pin >= 0; i++) + pin_count++; + + max_enable_regs = pin_count / IRQS_PER_REG; + if (pin_count % IRQS_PER_REG) + max_enable_regs++; + pdc_domain->name = "qcom,pdc"; return 0; -- GitLab From 80af187c8bcd5ebc4f2a802a629900abcc24e0c1 Mon Sep 17 00:00:00 2001 From: Sean Tranchetti Date: Tue, 28 May 2019 12:22:54 -0600 Subject: [PATCH 0569/1121] udp: Avoid post-GRO UDP checksum recalculation Currently, when resegmenting an unexpected UDP GRO packet, the full UDP checksum will be calculated for every new SKB created by skb_segment() because the netdev features passed in by udp_rcv_segment() lack any information about checksum offload capabilities. Usually, we have no need to perform this calculation again, as 1) The GRO implementation guarantees that any packets making it to the udp_rcv_segment() function had correct checksums, and, more importantly, 2) Upon the successful return of udp_rcv_segment(), we immediately pull the UDP header off and either queue the segment to the socket or hand it off to a new protocol handler. Unless userspace has set the IP_CHECKSUM sockopt to indicate that they want the final checksum values, we can pass the needed netdev feature flags to __skb_gso_segment() to avoid checksumming each segment in skb_segment(). Change-Id: I7071f126b634516dc37791958e6effc0bb926ee6 Fixes: cf329aa42b66 ("udp: cope with UDP GRO packet misdirection") Cc: Paolo Abeni Cc: Subash Abhinov Kasiviswanathan Signed-off-by: Sean Tranchetti Acked-by: Paolo Abeni Signed-off-by: David S. Miller Git-commit: f2696099c6c619aec4fe2b9691f0a81429957e65 Git-repo: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git --- include/net/udp.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/include/net/udp.h b/include/net/udp.h index 47ca7e8aa260..8058ca671c73 100644 --- a/include/net/udp.h +++ b/include/net/udp.h @@ -461,12 +461,19 @@ void udpv6_encap_enable(void); static inline struct sk_buff *udp_rcv_segment(struct sock *sk, struct sk_buff *skb, bool ipv4) { + netdev_features_t features = NETIF_F_SG; struct sk_buff *segs; + /* Avoid csum recalculation by skb_segment unless userspace explicitly + * asks for the final checksum values + */ + if (!inet_get_convert_csum(sk)) + features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; + /* the GSO CB lays after the UDP one, no need to save and restore any * CB fragment */ - segs = __skb_gso_segment(skb, NETIF_F_SG, false); + segs = __skb_gso_segment(skb, features, false); if (unlikely(IS_ERR_OR_NULL(segs))) { int segs_nr = skb_shinfo(skb)->gso_segs; -- GitLab From 06c8d20c27df3b38efb27264591d46fffae38edc Mon Sep 17 00:00:00 2001 From: Bojun Pan Date: Thu, 23 May 2019 21:01:37 -0700 Subject: [PATCH 0570/1121] msm: IPA: uC debug stats for MHIP and USB New code support on uC debug stats for gsi offloading protocols. This change is specific to MHIP and USB support. Change-Id: I9cb0543330a8c66b52dbedbbc1059f3dc17ec705 Signed-off-by: Bojun Pan --- .../platform/msm/ipa/ipa_clients/ipa_usb.c | 47 +++++++ drivers/platform/msm/ipa/ipa_v3/ipa_client.c | 53 +++++++- drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c | 128 ++++++++++++++++++ drivers/platform/msm/ipa/ipa_v3/ipa_i.h | 30 +++- drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c | 49 ++++++- drivers/platform/msm/ipa/ipa_v3/ipa_uc.c | 10 ++ .../msm/ipa/ipa_v3/ipa_uc_offload_i.h | 2 + drivers/platform/msm/ipa/ipa_v3/ipa_utils.c | 47 +++++++ 8 files changed, 361 insertions(+), 5 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_clients/ipa_usb.c b/drivers/platform/msm/ipa/ipa_clients/ipa_usb.c index 8a1d1a7201d8..394c5a854c5c 100644 --- a/drivers/platform/msm/ipa/ipa_clients/ipa_usb.c +++ b/drivers/platform/msm/ipa/ipa_clients/ipa_usb.c @@ -3213,6 +3213,53 @@ static void ipa3_usb_exit(void) kfree(ipa3_usb_ctx); } +/** + * ipa3_get_usb_gsi_stats() - Query USB gsi stats from uc + * @stats: [inout] stats blob from client populated by driver + * + * Returns: 0 on success, negative on failure + * + * @note Cannot be called from atomic context + * + */ +int ipa3_get_usb_gsi_stats(struct ipa3_uc_dbg_ring_stats *stats) +{ + int i; + + if (!ipa3_ctx->usb_ctx.dbg_stats.uc_dbg_stats_mmio) { + IPAERR("bad parms NULL usb_gsi_stats_mmio\n"); + return -EINVAL; + } + IPA_ACTIVE_CLIENTS_INC_SIMPLE(); + for (i = 0; i < MAX_CH_STATS_SUPPORTED; i++) { + stats->ring[i].ringFull = ioread32( + ipa3_ctx->usb_ctx.dbg_stats.uc_dbg_stats_mmio + + i * IPA3_UC_DEBUG_STATS_OFF + + IPA3_UC_DEBUG_STATS_RINGFULL_OFF); + stats->ring[i].ringEmpty = ioread32( + ipa3_ctx->usb_ctx.dbg_stats.uc_dbg_stats_mmio + + i * IPA3_UC_DEBUG_STATS_OFF + + IPA3_UC_DEBUG_STATS_RINGEMPTY_OFF); + stats->ring[i].ringUsageHigh = ioread32( + ipa3_ctx->usb_ctx.dbg_stats.uc_dbg_stats_mmio + + i * IPA3_UC_DEBUG_STATS_OFF + + IPA3_UC_DEBUG_STATS_RINGUSAGEHIGH_OFF); + stats->ring[i].ringUsageLow = ioread32( + ipa3_ctx->usb_ctx.dbg_stats.uc_dbg_stats_mmio + + i * IPA3_UC_DEBUG_STATS_OFF + + IPA3_UC_DEBUG_STATS_RINGUSAGELOW_OFF); + stats->ring[i].RingUtilCount = ioread32( + ipa3_ctx->usb_ctx.dbg_stats.uc_dbg_stats_mmio + + i * IPA3_UC_DEBUG_STATS_OFF + + IPA3_UC_DEBUG_STATS_RINGUTILCOUNT_OFF); + } + IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); + + + return 0; +} + + arch_initcall(ipa3_usb_init); module_exit(ipa3_usb_exit); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c index 35c2742eca54..89f228e259c1 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c @@ -1534,6 +1534,8 @@ int ipa3_start_gsi_channel(u32 clnt_hdl) struct ipa3_ep_context *ep; int result = -EFAULT; enum gsi_status gsi_res; + enum ipa_client_type client_type; + struct IpaHwOffloadStatsAllocCmdData_t *gsi_info; IPADBG("entry\n"); if (clnt_hdl >= ipa3_ctx->ipa_num_pipes || @@ -1543,9 +1545,9 @@ int ipa3_start_gsi_channel(u32 clnt_hdl) } ep = &ipa3_ctx->ep[clnt_hdl]; - + client_type = ipa3_get_client_mapping(clnt_hdl); if (!ep->keep_ipa_awake) - IPA_ACTIVE_CLIENTS_INC_EP(ipa3_get_client_mapping(clnt_hdl)); + IPA_ACTIVE_CLIENTS_INC_EP(client_type); gsi_res = gsi_start_channel(ep->gsi_chan_hdl); if (gsi_res != GSI_STATUS_SUCCESS) { @@ -1553,8 +1555,53 @@ int ipa3_start_gsi_channel(u32 clnt_hdl) goto start_chan_fail; } + /* start uC gsi dbg stats monitor */ + if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5) { + switch (client_type) { + case IPA_CLIENT_MHI_PRIME_TETH_PROD: + gsi_info = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_MHIP]; + gsi_info->ch_id_info[0].ch_id = ep->gsi_chan_hdl; + gsi_info->ch_id_info[0].dir = DIR_PRODUCER; + ipa3_uc_debug_stats_alloc(*gsi_info); + break; + case IPA_CLIENT_MHI_PRIME_TETH_CONS: + gsi_info = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_MHIP]; + gsi_info->ch_id_info[1].ch_id = ep->gsi_chan_hdl; + gsi_info->ch_id_info[1].dir = DIR_CONSUMER; + ipa3_uc_debug_stats_alloc(*gsi_info); + break; + case IPA_CLIENT_MHI_PRIME_RMNET_PROD: + gsi_info = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_MHIP]; + gsi_info->ch_id_info[2].ch_id = ep->gsi_chan_hdl; + gsi_info->ch_id_info[2].dir = DIR_PRODUCER; + ipa3_uc_debug_stats_alloc(*gsi_info); + break; + case IPA_CLIENT_MHI_PRIME_RMNET_CONS: + gsi_info = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_MHIP]; + gsi_info->ch_id_info[3].ch_id = ep->gsi_chan_hdl; + gsi_info->ch_id_info[3].dir = DIR_CONSUMER; + ipa3_uc_debug_stats_alloc(*gsi_info); + break; + case IPA_CLIENT_USB_PROD: + gsi_info = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_USB]; + gsi_info->ch_id_info[0].ch_id = ep->gsi_chan_hdl; + gsi_info->ch_id_info[0].dir = DIR_PRODUCER; + ipa3_uc_debug_stats_alloc(*gsi_info); + break; + case IPA_CLIENT_USB_CONS: + gsi_info = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_USB]; + gsi_info->ch_id_info[0].ch_id = ep->gsi_chan_hdl; + gsi_info->ch_id_info[0].dir = DIR_CONSUMER; + ipa3_uc_debug_stats_alloc(*gsi_info); + break; + default: + IPADBG("client_type %d not supported\n", + client_type); + } + } + if (!ep->keep_ipa_awake) - IPA_ACTIVE_CLIENTS_DEC_EP(ipa3_get_client_mapping(clnt_hdl)); + IPA_ACTIVE_CLIENTS_DEC_EP(client_type); IPADBG("exit\n"); return 0; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c index 878549531629..ded52a01e5ff 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c @@ -2111,6 +2111,126 @@ static ssize_t ipa3_read_aqc_gsi_stats(struct file *file, return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt); } +static ssize_t ipa3_read_mhip_gsi_stats(struct file *file, + char __user *ubuf, size_t count, loff_t *ppos) +{ + struct ipa3_uc_dbg_ring_stats stats; + int nbytes; + int cnt = 0; + + if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_5) { + nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN, + "This feature only support on IPA4.5+\n"); + cnt += nbytes; + goto done; + } + if (!ipa3_get_mhip_gsi_stats(&stats)) { + nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN, + "IPA_CLIENT_MHI_PRIME_TETH_CONS ringFull=%u\n" + "IPA_CLIENT_MHI_PRIME_TETH_CONS ringEmpty=%u\n" + "IPA_CLIENT_MHI_PRIME_TETH_CONS ringUsageHigh=%u\n" + "IPA_CLIENT_MHI_PRIME_TETH_CONS ringUsageLow=%u\n" + "IPA_CLIENT_MHI_PRIME_TETH_CONS RingUtilCount=%u\n", + stats.ring[1].ringFull, + stats.ring[1].ringEmpty, + stats.ring[1].ringUsageHigh, + stats.ring[1].ringUsageLow, + stats.ring[1].RingUtilCount); + cnt += nbytes; + nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt, + "IPA_CLIENT_MHI_PRIME_TETH_PROD ringFull=%u\n" + "IPA_CLIENT_MHI_PRIME_TETH_PROD ringEmpty=%u\n" + "IPA_CLIENT_MHI_PRIME_TETH_PROD ringUsageHigh=%u\n" + "IPA_CLIENT_MHI_PRIME_TETH_PROD ringUsageLow=%u\n" + "IPA_CLIENT_MHI_PRIME_TETH_PROD RingUtilCount=%u\n", + stats.ring[0].ringFull, + stats.ring[0].ringEmpty, + stats.ring[0].ringUsageHigh, + stats.ring[0].ringUsageLow, + stats.ring[0].RingUtilCount); + cnt += nbytes; + nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt, + "IPA_CLIENT_MHI_PRIME_RMNET_CONS ringFull=%u\n" + "IPA_CLIENT_MHI_PRIME_RMNET_CONS ringEmpty=%u\n" + "IPA_CLIENT_MHI_PRIME_RMNET_CONS ringUsageHigh=%u\n" + "IPA_CLIENT_MHI_PRIME_RMNET_CONS ringUsageLow=%u\n" + "IPA_CLIENT_MHI_PRIME_RMNET_CONS RingUtilCount=%u\n", + stats.ring[3].ringFull, + stats.ring[3].ringEmpty, + stats.ring[3].ringUsageHigh, + stats.ring[3].ringUsageLow, + stats.ring[3].RingUtilCount); + cnt += nbytes; + nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt, + "IPA_CLIENT_MHI_PRIME_RMNET_PROD ringFull=%u\n" + "IPA_CLIENT_MHI_PRIME_RMNET_PROD ringEmpty=%u\n" + "IPA_CLIENT_MHI_PRIME_RMNET_PROD ringUsageHigh=%u\n" + "IPA_CLIENT_MHI_PRIME_RMNET_PROD ringUsageLow=%u\n" + "IPA_CLIENT_MHI_PRIME_RMNET_PROD RingUtilCount=%u\n", + stats.ring[2].ringFull, + stats.ring[2].ringEmpty, + stats.ring[2].ringUsageHigh, + stats.ring[2].ringUsageLow, + stats.ring[2].RingUtilCount); + cnt += nbytes; + } else { + nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN, + "Fail to read WDI GSI stats\n"); + cnt += nbytes; + } + +done: + return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt); +} + +static ssize_t ipa3_read_usb_gsi_stats(struct file *file, + char __user *ubuf, size_t count, loff_t *ppos) +{ + struct ipa3_uc_dbg_ring_stats stats; + int nbytes; + int cnt = 0; + + if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_5) { + nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN, + "This feature only support on IPA4.5+\n"); + cnt += nbytes; + goto done; + } + if (!ipa3_get_usb_gsi_stats(&stats)) { + nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN, + "TX ringFull=%u\n" + "TX ringEmpty=%u\n" + "TX ringUsageHigh=%u\n" + "TX ringUsageLow=%u\n" + "TX RingUtilCount=%u\n", + stats.ring[1].ringFull, + stats.ring[1].ringEmpty, + stats.ring[1].ringUsageHigh, + stats.ring[1].ringUsageLow, + stats.ring[1].RingUtilCount); + cnt += nbytes; + nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt, + "RX ringFull=%u\n" + "RX ringEmpty=%u\n" + "RX ringUsageHigh=%u\n" + "RX ringUsageLow=%u\n" + "RX RingUtilCount=%u\n", + stats.ring[0].ringFull, + stats.ring[0].ringEmpty, + stats.ring[0].ringUsageHigh, + stats.ring[0].ringUsageLow, + stats.ring[0].RingUtilCount); + cnt += nbytes; + } else { + nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN, + "Fail to read WDI GSI stats\n"); + cnt += nbytes; + } + +done: + return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt); +} + static void ipa_dump_status(struct ipahal_pkt_status *status) { IPA_DUMP_STATUS_FIELD(status_opcode); @@ -2401,6 +2521,14 @@ static const struct ipa3_debugfs_file debugfs_files[] = { "aqc_gsi_stats", IPA_READ_ONLY_MODE, NULL, { .read = ipa3_read_aqc_gsi_stats, } + }, { + "mhip_gsi_stats", IPA_READ_ONLY_MODE, NULL, { + .read = ipa3_read_mhip_gsi_stats, + } + }, { + "usb_gsi_stats", IPA_READ_ONLY_MODE, NULL, { + .read = ipa3_read_usb_gsi_stats, + } } }; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index e745e3a8a140..d8caa5fa835c 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -1484,6 +1484,20 @@ struct ipa3_wdi3_ctx { struct ipa3_uc_dbg_stats dbg_stats; }; +/** + * struct ipa3_usb_ctx - IPA usb context + */ +struct ipa3_usb_ctx { + struct ipa3_uc_dbg_stats dbg_stats; +}; + +/** + * struct ipa3_mhip_ctx - IPA mhip context + */ +struct ipa3_mhip_ctx { + struct ipa3_uc_dbg_stats dbg_stats; +}; + /** * struct ipa3_transport_pm - transport power management related members * @transport_pm_mutex: Mutex to protect the transport_pm functionality. @@ -1882,6 +1896,8 @@ struct ipa3_context { struct ipa3_wdi2_ctx wdi2_ctx; struct ipa3_pc_mbox_data pc_mbox; struct ipa3_wdi3_ctx wdi3_ctx; + struct ipa3_usb_ctx usb_ctx; + struct ipa3_mhip_ctx mhip_ctx; atomic_t ipa_clk_vote; int gsi_chk_intset_value; int uc_mailbox17_chk; @@ -2474,6 +2490,8 @@ int ipa3_resume_wdi_pipe(u32 clnt_hdl); int ipa3_resume_gsi_wdi_pipe(u32 clnt_hdl); int ipa3_suspend_wdi_pipe(u32 clnt_hdl); int ipa3_get_wdi_gsi_stats(struct ipa3_uc_dbg_ring_stats *stats); +int ipa3_get_wdi3_gsi_stats(struct ipa3_uc_dbg_ring_stats *stats); +int ipa3_get_usb_gsi_stats(struct ipa3_uc_dbg_ring_stats *stats); int ipa3_get_wdi_stats(struct IpaHwStatsWDIInfoData_t *stats); u16 ipa3_get_smem_restr_bytes(void); int ipa3_broadcast_wdi_quota_reach_ind(uint32_t fid, uint64_t num_bytes); @@ -2784,7 +2802,6 @@ int ipa3_write_qmapid_wdi_pipe(u32 clnt_hdl, u8 qmap_id); int ipa3_write_qmapid_wdi3_gsi_pipe(u32 clnt_hdl, u8 qmap_id); int ipa3_tag_process(struct ipa3_desc *desc, int num_descs, unsigned long timeout); -int ipa3_get_wdi3_gsi_stats(struct ipa3_uc_dbg_ring_stats *stats); void ipa3_q6_pre_shutdown_cleanup(void); void ipa3_q6_post_shutdown_cleanup(void); @@ -2995,6 +3012,7 @@ int ipa3_is_mhip_offload_enabled(void); int ipa_mpm_reset_dma_mode(enum ipa_client_type src_pipe, enum ipa_client_type dst_pipe); int ipa_mpm_panic_handler(char *buf, int size); +int ipa3_get_mhip_gsi_stats(struct ipa3_uc_dbg_ring_stats *stats); #else static inline int ipa_mpm_mhip_xdci_pipe_enable( enum ipa_usb_teth_prot prot) @@ -3030,6 +3048,16 @@ static inline int ipa_mpm_panic_handler(char *buf, int size) return 0; } +static inline int ipa3_get_mhip_gsi_stats(struct ipa3_uc_dbg_ring_stats *stats) +{ + return 0; +} + +static inline void *alloc_and_init(u32 size, u32 init_val) +{ + return 0; +} + #endif /* CONFIG_IPA3_MHI_PRIME_MANAGER */ /* query ipa APQ mode*/ diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c b/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c index 1093daf8723a..3462442f53ce 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c @@ -990,7 +990,6 @@ static int ipa_mpm_connect_mhip_gsi_pipe(enum ipa_client_type mhip_client, ipa_mpm_change_gsi_state(mhi_idx, IPA_MPM_MHIP_CHAN_UL, GSI_ALLOCATED); - result = ipa3_start_gsi_channel(ipa_ep_idx); if (result) { IPA_MPM_ERR("start MHIP channel %d failed\n", mhip_client); @@ -2784,6 +2783,54 @@ int ipa_mpm_panic_handler(char *buf, int size) } return cnt; } + +/** + * ipa3_get_mhip_gsi_stats() - Query MHIP gsi stats from uc + * @stats: [inout] stats blob from client populated by driver + * + * Returns: 0 on success, negative on failure + * + * @note Cannot be called from atomic context + * + */ +int ipa3_get_mhip_gsi_stats(struct ipa3_uc_dbg_ring_stats *stats) +{ + int i; + + if (!ipa3_ctx->mhip_ctx.dbg_stats.uc_dbg_stats_mmio) { + IPAERR("bad parms NULL mhip_gsi_stats_mmio\n"); + return -EINVAL; + } + IPA_ACTIVE_CLIENTS_INC_SIMPLE(); + for (i = 0; i < MAX_CH_STATS_SUPPORTED; i++) { + stats->ring[i].ringFull = ioread32( + ipa3_ctx->mhip_ctx.dbg_stats.uc_dbg_stats_mmio + + i * IPA3_UC_DEBUG_STATS_OFF + + IPA3_UC_DEBUG_STATS_RINGFULL_OFF); + stats->ring[i].ringEmpty = ioread32( + ipa3_ctx->mhip_ctx.dbg_stats.uc_dbg_stats_mmio + + i * IPA3_UC_DEBUG_STATS_OFF + + IPA3_UC_DEBUG_STATS_RINGEMPTY_OFF); + stats->ring[i].ringUsageHigh = ioread32( + ipa3_ctx->mhip_ctx.dbg_stats.uc_dbg_stats_mmio + + i * IPA3_UC_DEBUG_STATS_OFF + + IPA3_UC_DEBUG_STATS_RINGUSAGEHIGH_OFF); + stats->ring[i].ringUsageLow = ioread32( + ipa3_ctx->mhip_ctx.dbg_stats.uc_dbg_stats_mmio + + i * IPA3_UC_DEBUG_STATS_OFF + + IPA3_UC_DEBUG_STATS_RINGUSAGELOW_OFF); + stats->ring[i].RingUtilCount = ioread32( + ipa3_ctx->mhip_ctx.dbg_stats.uc_dbg_stats_mmio + + i * IPA3_UC_DEBUG_STATS_OFF + + IPA3_UC_DEBUG_STATS_RINGUTILCOUNT_OFF); + } + IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); + + + return 0; +} + + late_initcall(ipa_mpm_init); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("MHI Proxy Manager Driver"); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_uc.c b/drivers/platform/msm/ipa/ipa_v3/ipa_uc.c index 2bb9d9b3456d..85f7e0bef7e0 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_uc.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_uc.c @@ -257,6 +257,16 @@ static void ipa3_uc_save_dbg_stats(u32 size) break; case IPA_HW_PROTOCOL_ETH: break; + case IPA_HW_PROTOCOL_MHIP: + ipa3_ctx->mhip_ctx.dbg_stats.uc_dbg_stats_size = size; + ipa3_ctx->mhip_ctx.dbg_stats.uc_dbg_stats_ofst = addr_offset; + ipa3_ctx->mhip_ctx.dbg_stats.uc_dbg_stats_mmio = mmio; + break; + case IPA_HW_PROTOCOL_USB: + ipa3_ctx->usb_ctx.dbg_stats.uc_dbg_stats_size = size; + ipa3_ctx->usb_ctx.dbg_stats.uc_dbg_stats_ofst = addr_offset; + ipa3_ctx->usb_ctx.dbg_stats.uc_dbg_stats_mmio = mmio; + break; default: IPAERR("unknown protocols %d\n", protocol_id); } diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_offload_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_offload_i.h index cd908921f1fb..d20d412fe8bb 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_offload_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_offload_i.h @@ -86,6 +86,8 @@ enum ipa4_hw_protocol { IPA_HW_PROTOCOL_WDI = 0x3, IPA_HW_PROTOCOL_WDI3 = 0x4, IPA_HW_PROTOCOL_ETH = 0x5, + IPA_HW_PROTOCOL_MHIP = 0x6, + IPA_HW_PROTOCOL_USB = 0x7, IPA_HW_PROTOCOL_MAX }; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c index 9788d13ce9e2..bd12c7fa6137 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c @@ -7139,6 +7139,8 @@ static int __ipa3_stop_gsi_channel(u32 clnt_hdl) int res = 0; int i; struct ipa3_ep_context *ep; + enum ipa_client_type client_type; + struct IpaHwOffloadStatsAllocCmdData_t *gsi_info; if (clnt_hdl >= ipa3_ctx->ipa_num_pipes || ipa3_ctx->ep[clnt_hdl].valid == 0) { @@ -7147,8 +7149,53 @@ static int __ipa3_stop_gsi_channel(u32 clnt_hdl) } ep = &ipa3_ctx->ep[clnt_hdl]; + client_type = ipa3_get_client_mapping(clnt_hdl); memset(&mem, 0, sizeof(mem)); + /* start uC gsi dbg stats monitor */ + if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5) { + switch (client_type) { + case IPA_CLIENT_MHI_PRIME_TETH_PROD: + gsi_info = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_MHIP]; + gsi_info->ch_id_info[0].ch_id = ep->gsi_chan_hdl; + gsi_info->ch_id_info[0].dir = DIR_PRODUCER; + ipa3_uc_debug_stats_alloc(*gsi_info); + break; + case IPA_CLIENT_MHI_PRIME_TETH_CONS: + gsi_info = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_MHIP]; + gsi_info->ch_id_info[1].ch_id = ep->gsi_chan_hdl; + gsi_info->ch_id_info[1].dir = DIR_CONSUMER; + ipa3_uc_debug_stats_alloc(*gsi_info); + break; + case IPA_CLIENT_MHI_PRIME_RMNET_PROD: + gsi_info = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_MHIP]; + gsi_info->ch_id_info[2].ch_id = ep->gsi_chan_hdl; + gsi_info->ch_id_info[2].dir = DIR_PRODUCER; + ipa3_uc_debug_stats_alloc(*gsi_info); + break; + case IPA_CLIENT_MHI_PRIME_RMNET_CONS: + gsi_info = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_MHIP]; + gsi_info->ch_id_info[3].ch_id = ep->gsi_chan_hdl; + gsi_info->ch_id_info[3].dir = DIR_CONSUMER; + ipa3_uc_debug_stats_alloc(*gsi_info); + break; + case IPA_CLIENT_USB_PROD: + gsi_info = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_USB]; + gsi_info->ch_id_info[0].ch_id = ep->gsi_chan_hdl; + gsi_info->ch_id_info[0].dir = DIR_PRODUCER; + ipa3_uc_debug_stats_alloc(*gsi_info); + break; + case IPA_CLIENT_USB_CONS: + gsi_info = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_USB]; + gsi_info->ch_id_info[0].ch_id = ep->gsi_chan_hdl; + gsi_info->ch_id_info[0].dir = DIR_CONSUMER; + ipa3_uc_debug_stats_alloc(*gsi_info); + break; + default: + IPADBG("client_type %d not supported\n", + client_type); + } + } if (IPA_CLIENT_IS_PROD(ep->client)) { IPADBG("Calling gsi_stop_channel ch:%lu\n", ep->gsi_chan_hdl); -- GitLab From ca08bf77af1889ea827005d3a080da31385855b8 Mon Sep 17 00:00:00 2001 From: Bojun Pan Date: Tue, 11 Jun 2019 16:18:50 -0700 Subject: [PATCH 0571/1121] msm: IPA: uC debug stats channel update Update MAX channel on query for uC debug stats protocols. Change-Id: I7a913f2cb60a1dccbacf2bbbfc25a2a823897992 Signed-off-by: Bojun Pan --- drivers/platform/msm/ipa/ipa_clients/ipa_usb.c | 2 +- drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c | 2 +- drivers/platform/msm/ipa/ipa_v3/ipa_uc_offload_i.h | 6 ++++++ drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c | 6 ++---- drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c | 6 ++---- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_clients/ipa_usb.c b/drivers/platform/msm/ipa/ipa_clients/ipa_usb.c index 394c5a854c5c..ee7c1ad72883 100644 --- a/drivers/platform/msm/ipa/ipa_clients/ipa_usb.c +++ b/drivers/platform/msm/ipa/ipa_clients/ipa_usb.c @@ -3231,7 +3231,7 @@ int ipa3_get_usb_gsi_stats(struct ipa3_uc_dbg_ring_stats *stats) return -EINVAL; } IPA_ACTIVE_CLIENTS_INC_SIMPLE(); - for (i = 0; i < MAX_CH_STATS_SUPPORTED; i++) { + for (i = 0; i < MAX_USB_CHANNELS; i++) { stats->ring[i].ringFull = ioread32( ipa3_ctx->usb_ctx.dbg_stats.uc_dbg_stats_mmio + i * IPA3_UC_DEBUG_STATS_OFF + diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c b/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c index 3462442f53ce..1e64df86b403 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c @@ -2802,7 +2802,7 @@ int ipa3_get_mhip_gsi_stats(struct ipa3_uc_dbg_ring_stats *stats) return -EINVAL; } IPA_ACTIVE_CLIENTS_INC_SIMPLE(); - for (i = 0; i < MAX_CH_STATS_SUPPORTED; i++) { + for (i = 0; i < MAX_MHIP_CHANNELS; i++) { stats->ring[i].ringFull = ioread32( ipa3_ctx->mhip_ctx.dbg_stats.uc_dbg_stats_mmio + i * IPA3_UC_DEBUG_STATS_OFF + diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_offload_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_offload_i.h index d20d412fe8bb..8a31fb8e6b6a 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_offload_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_offload_i.h @@ -30,6 +30,12 @@ #define DIR_CONSUMER 0 #define DIR_PRODUCER 1 +#define MAX_AQC_CHANNELS 2 +#define MAX_11AD_CHANNELS 5 +#define MAX_WDI2_CHANNELS 2 +#define MAX_WDI3_CHANNELS 2 +#define MAX_MHIP_CHANNELS 4 +#define MAX_USB_CHANNELS 2 /** * @brief Enum value determined based on the feature it diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c index fe083401ec91..7cef724ba88f 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c @@ -427,17 +427,15 @@ static void ipa3_uc_wdi_event_handler(struct IpaHwSharedMemCommonMapping_t */ int ipa3_get_wdi_gsi_stats(struct ipa3_uc_dbg_ring_stats *stats) { - int i, num_chs; + int i; if (!ipa3_ctx->wdi2_ctx.dbg_stats.uc_dbg_stats_mmio) { IPAERR("bad NULL parms for wdi_gsi_stats\n"); return -EINVAL; } - num_chs = ipa3_ctx->wdi2_ctx.dbg_stats.uc_dbg_stats_size - / sizeof(struct IpaHwRingStats_t); IPA_ACTIVE_CLIENTS_INC_SIMPLE(); - for (i = 0; i < num_chs; i++) { + for (i = 0; i < MAX_WDI2_CHANNELS; i++) { stats->ring[i].ringFull = ioread32( ipa3_ctx->wdi2_ctx.dbg_stats.uc_dbg_stats_mmio + i * IPA3_UC_DEBUG_STATS_OFF + diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c b/drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c index 77e9281ad639..f5aa6698df80 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c @@ -930,17 +930,15 @@ int ipa3_write_qmapid_wdi3_gsi_pipe(u32 clnt_hdl, u8 qmap_id) */ int ipa3_get_wdi3_gsi_stats(struct ipa3_uc_dbg_ring_stats *stats) { - int i, num_chs; + int i; if (!ipa3_ctx->wdi3_ctx.dbg_stats.uc_dbg_stats_mmio) { IPAERR("bad NULL parms for wdi3_gsi_stats\n"); return -EINVAL; } - num_chs = ipa3_ctx->wdi3_ctx.dbg_stats.uc_dbg_stats_size - / sizeof(struct IpaHwRingStats_t); IPA_ACTIVE_CLIENTS_INC_SIMPLE(); - for (i = 0; i < num_chs; i++) { + for (i = 0; i < MAX_WDI3_CHANNELS; i++) { stats->ring[i].ringFull = ioread32( ipa3_ctx->wdi3_ctx.dbg_stats.uc_dbg_stats_mmio + i * IPA3_UC_DEBUG_STATS_OFF + -- GitLab From 83e904981458c1b2a7454759dd1c9683d241283d Mon Sep 17 00:00:00 2001 From: Sujeev Dias Date: Fri, 22 Mar 2019 21:31:01 -0700 Subject: [PATCH 0572/1121] mhi: cntrl: add support for advanced power management featues Add support to allow system suspend while PCIe link is in active state, allow host to initiate automatic suspend whenever PCIe link is in idle state by taking advantage of L1ss inactivity timer, and add support for drv handoff if soc supports it. CRs-Fixed: 2418347 Change-Id: I02b66d790e7b8b625d186431d89f4d6bda5268d4 Signed-off-by: Sujeev Dias --- drivers/bus/mhi/controllers/mhi_arch_qcom.c | 133 +++++++++++++++---- drivers/bus/mhi/controllers/mhi_qcom.c | 135 ++++++++++++++++---- drivers/bus/mhi/controllers/mhi_qcom.h | 20 ++- 3 files changed, 230 insertions(+), 58 deletions(-) diff --git a/drivers/bus/mhi/controllers/mhi_arch_qcom.c b/drivers/bus/mhi/controllers/mhi_arch_qcom.c index e8d8d3323d32..bb6639ffedda 100644 --- a/drivers/bus/mhi/controllers/mhi_arch_qcom.c +++ b/drivers/bus/mhi/controllers/mhi_arch_qcom.c @@ -82,7 +82,8 @@ static void mhi_arch_pci_link_state_cb(struct msm_pcie_notify *notify) struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl); struct pci_dev *pci_dev = mhi_dev->pci_dev; - if (notify->event == MSM_PCIE_EVENT_WAKEUP) { + switch (notify->event) { + case MSM_PCIE_EVENT_WAKEUP: MHI_LOG("Received MSM_PCIE_EVENT_WAKE signal\n"); /* bring link out of d3cold */ @@ -90,6 +91,15 @@ static void mhi_arch_pci_link_state_cb(struct msm_pcie_notify *notify) pm_runtime_get(&pci_dev->dev); pm_runtime_put_noidle(&pci_dev->dev); } + break; + case MSM_PCIE_EVENT_L1SS_TIMEOUT: + MHI_VERB("Received MSM_PCIE_EVENT_L1SS_TIMEOUT signal\n"); + + pm_runtime_mark_last_busy(&pci_dev->dev); + pm_request_autosuspend(&pci_dev->dev); + break; + default: + MHI_ERR("Unhandled event 0x%x\n", notify->event); } } @@ -133,6 +143,22 @@ static int mhi_arch_esoc_ops_power_on(void *priv, unsigned int flags) return mhi_pci_probe(pci_dev, NULL); } +static void mhi_arch_link_off(struct mhi_controller *mhi_cntrl) +{ + struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl); + struct pci_dev *pci_dev = mhi_dev->pci_dev; + + MHI_LOG("Entered\n"); + + pci_set_power_state(pci_dev, PCI_D3hot); + + /* release the resources */ + msm_pcie_pm_control(MSM_PCIE_SUSPEND, mhi_cntrl->bus, pci_dev, NULL, 0); + mhi_arch_set_bus_request(mhi_cntrl, 0); + + MHI_LOG("Exited\n"); +} + static void mhi_arch_esoc_ops_power_off(void *priv, unsigned int flags) { struct mhi_controller *mhi_cntrl = priv; @@ -156,7 +182,7 @@ static void mhi_arch_esoc_ops_power_off(void *priv, unsigned int flags) /* turn the link off */ mhi_deinit_pci_dev(mhi_cntrl); - mhi_arch_link_off(mhi_cntrl, false); + mhi_arch_link_off(mhi_cntrl); /* wait for boot monitor to exit */ async_synchronize_cookie(arch_info->cookie + 1); @@ -213,9 +239,16 @@ static void mhi_boot_monitor(void *data, async_cookie_t cookie) TO_MHI_EXEC_STR(mhi_cntrl->ee)); /* if we successfully booted to amss disable boot log channel */ - boot_dev = arch_info->boot_dev; - if (boot_dev && mhi_cntrl->ee == MHI_EE_AMSS) - mhi_unprepare_from_transfer(boot_dev); + if (mhi_cntrl->ee == MHI_EE_AMSS) { + boot_dev = arch_info->boot_dev; + if (boot_dev) + mhi_unprepare_from_transfer(boot_dev); + + /* enable link inactivity timer to start auto suspend */ + msm_pcie_l1ss_timeout_enable(mhi_dev->pci_dev); + + pm_runtime_allow(&mhi_dev->pci_dev->dev); + } } int mhi_arch_power_up(struct mhi_controller *mhi_cntrl) @@ -265,8 +298,7 @@ static void mhi_arch_pcie_bw_scale_work(struct work_struct *work) int ret; mutex_lock(&mhi_cntrl->pm_mutex); - if (!mhi_dev->powered_on || - pm_runtime_status_suspended(dev) || dev->power.is_suspended) + if (!mhi_dev->powered_on || MHI_IS_SUSPENDED(mhi_dev->suspend_mode)) goto exit_work; /* copy the latest speed change */ @@ -353,6 +385,7 @@ int mhi_arch_pcie_init(struct mhi_controller *mhi_cntrl) return -ENOMEM; mhi_dev->arch_info = arch_info; + arch_info->mhi_dev = mhi_dev; snprintf(node, sizeof(node), "mhi_%04x_%02u.%02u.%02u", mhi_cntrl->dev_id, mhi_cntrl->domain, mhi_cntrl->bus, @@ -374,7 +407,9 @@ int mhi_arch_pcie_init(struct mhi_controller *mhi_cntrl) /* register with pcie rc for WAKE# events */ reg_event = &arch_info->pcie_reg_event; - reg_event->events = MSM_PCIE_EVENT_WAKEUP; + reg_event->events = + MSM_PCIE_EVENT_WAKEUP | MSM_PCIE_EVENT_L1SS_TIMEOUT; + reg_event->user = mhi_dev->pci_dev; reg_event->callback = mhi_arch_pci_link_state_cb; reg_event->notify.data = mhi_cntrl; @@ -407,6 +442,13 @@ int mhi_arch_pcie_init(struct mhi_controller *mhi_cntrl) /* save reference state for pcie config space */ arch_info->ref_pcie_state = pci_store_saved_state( mhi_dev->pci_dev); + /* + * MHI host driver has full autonomy to manage power state. + * Disable all automatic power collapse features + */ + msm_pcie_pm_control(MSM_PCIE_DISABLE_PC, mhi_cntrl->bus, + mhi_dev->pci_dev, NULL, 0); + mhi_dev->pci_dev->no_d3hot = true; INIT_WORK(&arch_info->bw_scale_work, mhi_arch_pcie_bw_scale_work); @@ -566,50 +608,58 @@ void mhi_arch_iommu_deinit(struct mhi_controller *mhi_cntrl) mhi_cntrl->dev = NULL; } -int mhi_arch_link_off(struct mhi_controller *mhi_cntrl, bool graceful) +int mhi_arch_link_suspend(struct mhi_controller *mhi_cntrl) { struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl); struct arch_info *arch_info = mhi_dev->arch_info; struct pci_dev *pci_dev = mhi_dev->pci_dev; - int ret; + int ret = 0; MHI_LOG("Entered\n"); - if (graceful) { + /* disable inactivity timer */ + msm_pcie_l1ss_timeout_disable(pci_dev); + + switch (mhi_dev->suspend_mode) { + case MHI_DEFAULT_SUSPEND: pci_clear_master(pci_dev); ret = pci_save_state(mhi_dev->pci_dev); if (ret) { MHI_ERR("Failed with pci_save_state, ret:%d\n", ret); - return ret; + goto exit_suspend; } arch_info->pcie_state = pci_store_saved_state(pci_dev); pci_disable_device(pci_dev); - } - /* - * We will always attempt to put link into D3hot, however - * link down may have happened due to error fatal, so - * ignoring the return code - */ - pci_set_power_state(pci_dev, PCI_D3hot); + pci_set_power_state(pci_dev, PCI_D3hot); + + /* release the resources */ + msm_pcie_pm_control(MSM_PCIE_SUSPEND, mhi_cntrl->bus, pci_dev, + NULL, 0); + mhi_arch_set_bus_request(mhi_cntrl, 0); + break; + case MHI_FAST_LINK_OFF: + case MHI_ACTIVE_STATE: + case MHI_FAST_LINK_ON:/* keeping link on do nothing */ + break; + } - /* release the resources */ - msm_pcie_pm_control(MSM_PCIE_SUSPEND, mhi_cntrl->bus, pci_dev, NULL, 0); - mhi_arch_set_bus_request(mhi_cntrl, 0); +exit_suspend: + if (ret) + msm_pcie_l1ss_timeout_enable(pci_dev); - MHI_LOG("Exited\n"); + MHI_LOG("Exited with ret:%d\n", ret); - return 0; + return ret; } -int mhi_arch_link_on(struct mhi_controller *mhi_cntrl) +static int __mhi_arch_link_resume(struct mhi_controller *mhi_cntrl) { struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl); struct arch_info *arch_info = mhi_dev->arch_info; struct pci_dev *pci_dev = mhi_dev->pci_dev; struct mhi_link_info *cur_info = &arch_info->current_link_info; - struct mhi_link_info *updated_info = &mhi_cntrl->mhi_link_info; int ret; MHI_LOG("Entered\n"); @@ -647,6 +697,35 @@ int mhi_arch_link_on(struct mhi_controller *mhi_cntrl) pci_restore_state(pci_dev); pci_set_master(pci_dev); + return 0; +} + +int mhi_arch_link_resume(struct mhi_controller *mhi_cntrl) +{ + struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl); + struct arch_info *arch_info = mhi_dev->arch_info; + struct pci_dev *pci_dev = mhi_dev->pci_dev; + struct mhi_link_info *cur_info = &arch_info->current_link_info; + struct mhi_link_info *updated_info = &mhi_cntrl->mhi_link_info; + int ret = 0; + + MHI_LOG("Entered\n"); + + switch (mhi_dev->suspend_mode) { + case MHI_DEFAULT_SUSPEND: + ret = __mhi_arch_link_resume(mhi_cntrl); + break; + case MHI_FAST_LINK_OFF: + case MHI_ACTIVE_STATE: + case MHI_FAST_LINK_ON: + break; + } + + if (ret) { + MHI_ERR("Link training failed, ret:%d\n", ret); + return ret; + } + /* BW request from device doesn't match current link speed */ if (cur_info->target_link_speed != updated_info->target_link_speed || cur_info->target_link_width != updated_info->target_link_width) { @@ -655,6 +734,8 @@ int mhi_arch_link_on(struct mhi_controller *mhi_cntrl) *cur_info = *updated_info; } + msm_pcie_l1ss_timeout_enable(pci_dev); + MHI_LOG("Exited\n"); return 0; diff --git a/drivers/bus/mhi/controllers/mhi_qcom.c b/drivers/bus/mhi/controllers/mhi_qcom.c index 758306b0ee22..45982a73345e 100644 --- a/drivers/bus/mhi/controllers/mhi_qcom.c +++ b/drivers/bus/mhi/controllers/mhi_qcom.c @@ -195,7 +195,43 @@ static int mhi_init_pci_dev(struct mhi_controller *mhi_cntrl) static int mhi_runtime_suspend(struct device *dev) { - return -EBUSY; + int ret = 0; + struct mhi_controller *mhi_cntrl = dev_get_drvdata(dev); + struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl); + + MHI_LOG("Enter\n"); + + mutex_lock(&mhi_cntrl->pm_mutex); + + if (!mhi_dev->powered_on) { + MHI_LOG("Not fully powered, return success\n"); + mutex_unlock(&mhi_cntrl->pm_mutex); + return 0; + } + + ret = mhi_pm_suspend(mhi_cntrl); + + if (ret) { + MHI_LOG("Abort due to ret:%d\n", ret); + goto exit_runtime_suspend; + } + + mhi_dev->suspend_mode = MHI_DEFAULT_SUSPEND; + + ret = mhi_arch_link_suspend(mhi_cntrl); + + /* failed suspending link abort mhi suspend */ + if (ret) { + MHI_LOG("Failed to suspend link, abort suspend\n"); + mhi_pm_resume(mhi_cntrl); + mhi_dev->suspend_mode = MHI_ACTIVE_STATE; + } + +exit_runtime_suspend: + mutex_unlock(&mhi_cntrl->pm_mutex); + MHI_LOG("Exited with ret:%d\n", ret); + + return ret; } static int mhi_runtime_idle(struct device *dev) @@ -236,12 +272,18 @@ static int mhi_runtime_resume(struct device *dev) } /* turn on link */ - ret = mhi_arch_link_on(mhi_cntrl); + ret = mhi_arch_link_resume(mhi_cntrl); if (ret) goto rpm_resume_exit; - /* enter M0 state */ - ret = mhi_pm_resume(mhi_cntrl); + + /* transition to M0 state */ + if (mhi_dev->suspend_mode == MHI_DEFAULT_SUSPEND) + ret = mhi_pm_resume(mhi_cntrl); + else + ret = mhi_pm_fast_resume(mhi_cntrl, MHI_FAST_LINK_ON); + + mhi_dev->suspend_mode = MHI_ACTIVE_STATE; rpm_resume_exit: mutex_unlock(&mhi_cntrl->pm_mutex); @@ -252,41 +294,81 @@ static int mhi_runtime_resume(struct device *dev) static int mhi_system_resume(struct device *dev) { - int ret = 0; - struct mhi_controller *mhi_cntrl = dev_get_drvdata(dev); - - ret = mhi_runtime_resume(dev); - if (ret) { - MHI_ERR("Failed to resume link\n"); - } else { - pm_runtime_set_active(dev); - pm_runtime_enable(dev); - } - - return ret; + return mhi_runtime_resume(dev); } int mhi_system_suspend(struct device *dev) { struct mhi_controller *mhi_cntrl = dev_get_drvdata(dev); + struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl); int ret; MHI_LOG("Entered\n"); - /* if rpm status still active then force suspend */ - if (!pm_runtime_status_suspended(dev)) { - ret = mhi_runtime_suspend(dev); - if (ret) { - MHI_LOG("suspend failed ret:%d\n", ret); - return ret; + mutex_lock(&mhi_cntrl->pm_mutex); + + if (!mhi_dev->powered_on) { + MHI_LOG("Not fully powered, return success\n"); + mutex_unlock(&mhi_cntrl->pm_mutex); + return 0; + } + + /* + * pci framework always makes a dummy vote to rpm + * framework to resume before calling system suspend + * hence usage count is minimum one + */ + if (atomic_read(&dev->power.usage_count) > 1) { + /* + * clients have requested to keep link on, try + * fast suspend. No need to notify clients since + * we will not be turning off the pcie link + */ + ret = mhi_pm_fast_suspend(mhi_cntrl, false); + mhi_dev->suspend_mode = MHI_FAST_LINK_ON; + } else { + /* try normal suspend */ + mhi_dev->suspend_mode = MHI_DEFAULT_SUSPEND; + ret = mhi_pm_suspend(mhi_cntrl); + + /* + * normal suspend failed because we're busy, try + * fast suspend before aborting system suspend. + * this could happens if client has disabled + * device lpm but no active vote for PCIe from + * apps processor + */ + if (ret == -EBUSY) { + ret = mhi_pm_fast_suspend(mhi_cntrl, true); + mhi_dev->suspend_mode = MHI_FAST_LINK_ON; } } - pm_runtime_set_suspended(dev); - pm_runtime_disable(dev); + if (ret) { + MHI_LOG("Abort due to ret:%d\n", ret); + mhi_dev->suspend_mode = MHI_ACTIVE_STATE; + goto exit_system_suspend; + } + + ret = mhi_arch_link_suspend(mhi_cntrl); - MHI_LOG("Exit\n"); - return 0; + /* failed suspending link abort mhi suspend */ + if (ret) { + MHI_LOG("Failed to suspend link, abort suspend\n"); + if (mhi_dev->suspend_mode == MHI_DEFAULT_SUSPEND) + mhi_pm_resume(mhi_cntrl); + else + mhi_pm_fast_resume(mhi_cntrl, MHI_FAST_LINK_OFF); + + mhi_dev->suspend_mode = MHI_ACTIVE_STATE; + } + +exit_system_suspend: + mutex_unlock(&mhi_cntrl->pm_mutex); + + MHI_LOG("Exit with ret:%d\n", ret); + + return ret; } /* checks if link is down */ @@ -658,7 +740,6 @@ int mhi_pci_probe(struct pci_dev *pci_dev, } pm_runtime_mark_last_busy(&pci_dev->dev); - pm_runtime_allow(&pci_dev->dev); MHI_LOG("Return successful\n"); diff --git a/drivers/bus/mhi/controllers/mhi_qcom.h b/drivers/bus/mhi/controllers/mhi_qcom.h index a92de13288ad..f9d6a4cab05f 100644 --- a/drivers/bus/mhi/controllers/mhi_qcom.h +++ b/drivers/bus/mhi/controllers/mhi_qcom.h @@ -29,8 +29,18 @@ extern const char * const mhi_ee_str[MHI_EE_MAX]; #define TO_MHI_EXEC_STR(ee) (ee >= MHI_EE_MAX ? "INVALID_EE" : mhi_ee_str[ee]) +enum mhi_suspend_mode { + MHI_ACTIVE_STATE, + MHI_DEFAULT_SUSPEND, + MHI_FAST_LINK_OFF, + MHI_FAST_LINK_ON, +}; + +#define MHI_IS_SUSPENDED(mode) (mode) + struct mhi_dev { struct pci_dev *pci_dev; + bool drv_supported; u32 smmu_cfg; int resn; void *arch_info; @@ -38,6 +48,7 @@ struct mhi_dev { dma_addr_t iova_start; dma_addr_t iova_stop; bool lpm_disabled; + enum mhi_suspend_mode suspend_mode; /* if set, soc support dynamic bw scaling */ void (*bw_scale)(struct mhi_controller *mhi_cntrl, @@ -55,8 +66,8 @@ int mhi_arch_pcie_init(struct mhi_controller *mhi_cntrl); void mhi_arch_pcie_deinit(struct mhi_controller *mhi_cntrl); int mhi_arch_iommu_init(struct mhi_controller *mhi_cntrl); void mhi_arch_iommu_deinit(struct mhi_controller *mhi_cntrl); -int mhi_arch_link_off(struct mhi_controller *mhi_cntrl, bool graceful); -int mhi_arch_link_on(struct mhi_controller *mhi_cntrl); +int mhi_arch_link_suspend(struct mhi_controller *mhi_cntrl); +int mhi_arch_link_resume(struct mhi_controller *mhi_cntrl); #else @@ -82,13 +93,12 @@ static inline void mhi_arch_pcie_deinit(struct mhi_controller *mhi_cntrl) { } -static inline int mhi_arch_link_off(struct mhi_controller *mhi_cntrl, - bool graceful) +static inline int mhi_arch_link_suspend(struct mhi_controller *mhi_cntrl) { return 0; } -static inline int mhi_arch_link_on(struct mhi_controller *mhi_cntrl) +static inline int mhi_arch_link_resume(struct mhi_controller *mhi_cntrl) { return 0; } -- GitLab From 121fd71fe0c353d23fd1607c30ecb0befdb1fad2 Mon Sep 17 00:00:00 2001 From: Sujeev Dias Date: Fri, 19 Apr 2019 18:26:02 -0700 Subject: [PATCH 0573/1121] mhi: cntrl: qcom: disable pcie low power mode during bw scaling Keep the PCIe link in L0 state during bandwidth scaling based on speed switching requirements. Add a disable depth counter to ensure all votes are considered before changing low power state as multiple callers can toggle the state. CRs-Fixed: 2439952 Change-Id: I826936d7b16375adb461db65fb58356fa5dda113 Acked-by: Bhaumik Vasav Bhatt Signed-off-by: Sujeev Dias --- drivers/bus/mhi/controllers/mhi_arch_qcom.c | 3 ++ drivers/bus/mhi/controllers/mhi_qcom.c | 59 ++++++++++++++++----- drivers/bus/mhi/controllers/mhi_qcom.h | 4 +- 3 files changed, 51 insertions(+), 15 deletions(-) diff --git a/drivers/bus/mhi/controllers/mhi_arch_qcom.c b/drivers/bus/mhi/controllers/mhi_arch_qcom.c index bb6639ffedda..ebfc8e3b4198 100644 --- a/drivers/bus/mhi/controllers/mhi_arch_qcom.c +++ b/drivers/bus/mhi/controllers/mhi_arch_qcom.c @@ -268,8 +268,11 @@ static int mhi_arch_pcie_scale_bw(struct mhi_controller *mhi_cntrl, { int ret, scale; + mhi_cntrl->lpm_disable(mhi_cntrl, mhi_cntrl->priv_data); ret = msm_pcie_set_link_bandwidth(pci_dev, link_info->target_link_speed, link_info->target_link_width); + mhi_cntrl->lpm_enable(mhi_cntrl, mhi_cntrl->priv_data); + if (ret) return ret; diff --git a/drivers/bus/mhi/controllers/mhi_qcom.c b/drivers/bus/mhi/controllers/mhi_qcom.c index 45982a73345e..00c8b264377c 100644 --- a/drivers/bus/mhi/controllers/mhi_qcom.c +++ b/drivers/bus/mhi/controllers/mhi_qcom.c @@ -79,6 +79,10 @@ void mhi_deinit_pci_dev(struct mhi_controller *mhi_cntrl) pm_runtime_mark_last_busy(&pci_dev->dev); pm_runtime_dont_use_autosuspend(&pci_dev->dev); pm_runtime_disable(&pci_dev->dev); + + /* reset counter for lpm state changes */ + mhi_dev->lpm_disable_depth = 0; + pci_free_irq_vectors(pci_dev); kfree(mhi_cntrl->irq); mhi_cntrl->irq = NULL; @@ -391,26 +395,38 @@ static int mhi_lpm_disable(struct mhi_controller *mhi_cntrl, void *priv) struct pci_dev *pci_dev = mhi_dev->pci_dev; int lnkctl = pci_dev->pcie_cap + PCI_EXP_LNKCTL; u8 val; - int ret; + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&mhi_dev->lpm_lock, flags); + + /* L1 is already disabled */ + if (mhi_dev->lpm_disable_depth) { + mhi_dev->lpm_disable_depth++; + goto lpm_disable_exit; + } ret = pci_read_config_byte(pci_dev, lnkctl, &val); if (ret) { MHI_ERR("Error reading LNKCTL, ret:%d\n", ret); - return ret; + goto lpm_disable_exit; } - /* L1 is not supported or already disabled */ - if (!(val & PCI_EXP_LNKCTL_ASPM_L1)) - return 0; + /* L1 is not supported, do not increment lpm_disable_depth */ + if (unlikely(!(val & PCI_EXP_LNKCTL_ASPM_L1))) + goto lpm_disable_exit; val &= ~PCI_EXP_LNKCTL_ASPM_L1; ret = pci_write_config_byte(pci_dev, lnkctl, val); if (ret) { MHI_ERR("Error writing LNKCTL to disable LPM, ret:%d\n", ret); - return ret; + goto lpm_disable_exit; } - mhi_dev->lpm_disabled = true; + mhi_dev->lpm_disable_depth++; + +lpm_disable_exit: + spin_unlock_irqrestore(&mhi_dev->lpm_lock, flags); return ret; } @@ -422,26 +438,40 @@ static int mhi_lpm_enable(struct mhi_controller *mhi_cntrl, void *priv) struct pci_dev *pci_dev = mhi_dev->pci_dev; int lnkctl = pci_dev->pcie_cap + PCI_EXP_LNKCTL; u8 val; - int ret; + unsigned long flags; + int ret = 0; - /* L1 is not supported or already disabled */ - if (!mhi_dev->lpm_disabled) - return 0; + spin_lock_irqsave(&mhi_dev->lpm_lock, flags); + + /* + * Exit if L1 is not supported or is already disabled or + * decrementing lpm_disable_depth still keeps it above 0 + */ + if (!mhi_dev->lpm_disable_depth) + goto lpm_enable_exit; + + if (mhi_dev->lpm_disable_depth > 1) { + mhi_dev->lpm_disable_depth--; + goto lpm_enable_exit; + } ret = pci_read_config_byte(pci_dev, lnkctl, &val); if (ret) { MHI_ERR("Error reading LNKCTL, ret:%d\n", ret); - return ret; + goto lpm_enable_exit; } val |= PCI_EXP_LNKCTL_ASPM_L1; ret = pci_write_config_byte(pci_dev, lnkctl, val); if (ret) { MHI_ERR("Error writing LNKCTL to enable LPM, ret:%d\n", ret); - return ret; + goto lpm_enable_exit; } - mhi_dev->lpm_disabled = false; + mhi_dev->lpm_disable_depth = 0; + +lpm_enable_exit: + spin_unlock_irqrestore(&mhi_dev->lpm_lock, flags); return ret; } @@ -659,6 +689,7 @@ static struct mhi_controller *mhi_register_controller(struct pci_dev *pci_dev) mhi_cntrl->of_node = of_node; mhi_dev->pci_dev = pci_dev; + spin_lock_init(&mhi_dev->lpm_lock); /* setup power management apis */ mhi_cntrl->status_cb = mhi_status_cb; diff --git a/drivers/bus/mhi/controllers/mhi_qcom.h b/drivers/bus/mhi/controllers/mhi_qcom.h index f9d6a4cab05f..4b0cbfff3901 100644 --- a/drivers/bus/mhi/controllers/mhi_qcom.h +++ b/drivers/bus/mhi/controllers/mhi_qcom.h @@ -47,12 +47,14 @@ struct mhi_dev { bool powered_on; dma_addr_t iova_start; dma_addr_t iova_stop; - bool lpm_disabled; enum mhi_suspend_mode suspend_mode; /* if set, soc support dynamic bw scaling */ void (*bw_scale)(struct mhi_controller *mhi_cntrl, struct mhi_dev *mhi_dev); + unsigned int lpm_disable_depth; + /* lock to toggle low power modes */ + spinlock_t lpm_lock; }; void mhi_deinit_pci_dev(struct mhi_controller *mhi_cntrl); -- GitLab From 837a1c17db9c6dd744e43e4a39cc4dadc5ddcaa4 Mon Sep 17 00:00:00 2001 From: Sahitya Tummala Date: Fri, 14 Jun 2019 09:41:26 +0530 Subject: [PATCH 0574/1121] ext4: allow move extents ioctl for HW FBE The limitation of EXT4_IOC_MOVE_EXT ioctl for handling encrypted files is only applicable for SW FBE but not for HW FBE. Hence, enable this ioctl for HW FBE so that tools such as e4defrag can make use of it on such devices. Change-Id: I4bd08185a14b03cb9bcda49d1955d0c95701515c Signed-off-by: Sahitya Tummala --- fs/ext4/move_extent.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c index cd8d481e0c48..c15d0c29b232 100644 --- a/fs/ext4/move_extent.c +++ b/fs/ext4/move_extent.c @@ -602,11 +602,14 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp, __u64 orig_blk, return -EOPNOTSUPP; } - if (ext4_encrypted_inode(orig_inode) || - ext4_encrypted_inode(donor_inode)) { - ext4_msg(orig_inode->i_sb, KERN_ERR, - "Online defrag not supported for encrypted files"); - return -EOPNOTSUPP; + if (!fscrypt_using_hardware_encryption(orig_inode) || + !fscrypt_using_hardware_encryption(donor_inode)) { + if (ext4_encrypted_inode(orig_inode) || + ext4_encrypted_inode(donor_inode)) { + ext4_msg(orig_inode->i_sb, KERN_ERR, + "Online defrag not supported for encrypted files"); + return -EOPNOTSUPP; + } } /* Protect orig and donor inodes against a truncate */ -- GitLab From 3629393ab0c7b6d39271678cc0cdbb9601577752 Mon Sep 17 00:00:00 2001 From: Manoj Prabhu B Date: Fri, 14 Jun 2019 10:08:52 +0530 Subject: [PATCH 0575/1121] diag: dci: Correct out of bounds check in processing dci pkt rsp Correct the out of bounds check and prevent moving the temp pointer further than out of bounds check which is not necessary while processing dci pkt rsp. Change-Id: I01f8cd7454aff81b24c986eade35c79724976151 Signed-off-by: Manoj Prabhu B --- drivers/char/diag/diag_dci.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c index 8d67d98e5396..32566697f599 100644 --- a/drivers/char/diag/diag_dci.c +++ b/drivers/char/diag/diag_dci.c @@ -1952,7 +1952,7 @@ static int diag_process_dci_pkt_rsp(unsigned char *buf, int len) if (!buf) return -EIO; - if (len <= (sizeof(struct dci_pkt_req_t) + + if (len < (sizeof(struct dci_pkt_req_t) + sizeof(struct diag_pkt_header_t)) || len > DCI_REQ_BUF_SIZE) { pr_err("diag: dci: Invalid length %d len in %s", len, __func__); @@ -1965,7 +1965,6 @@ static int diag_process_dci_pkt_rsp(unsigned char *buf, int len) req_len -= sizeof(struct dci_pkt_req_t); req_buf = temp; /* Start of the Request */ header = (struct diag_pkt_header_t *)temp; - temp += sizeof(struct diag_pkt_header_t); read_len += sizeof(struct diag_pkt_header_t); if (read_len >= DCI_REQ_BUF_SIZE) { pr_err("diag: dci: In %s, invalid read_len: %d\n", __func__, -- GitLab From 912c0464572ccb59b08f535b158fdab3b0a34b15 Mon Sep 17 00:00:00 2001 From: Prakash Gupta Date: Fri, 14 Jun 2019 11:11:55 +0530 Subject: [PATCH 0576/1121] iommu/io-pgtable-arm: sync map update before page table walk 'commit 87a91b15d691 ("iommu/io-pgtable-arm: Centralise sync points")' added barrier at the end of map so in the case of a coherent IOMMU, to ensure the page table updates are fully synchronized against a subsequent page table walk. map_sg would also need the same support. Change-Id: I3dc3e5cdc133f3b5fc312784fdc98a287e3c83fd Signed-off-by: Prakash Gupta --- drivers/iommu/io-pgtable-arm.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c index 8ee91150f488..009ab23cc097 100644 --- a/drivers/iommu/io-pgtable-arm.c +++ b/drivers/iommu/io-pgtable-arm.c @@ -694,6 +694,12 @@ static int arm_lpae_map_sg(struct io_pgtable_ops *ops, unsigned long iova, ms.num_pte * sizeof(*ms.pte_start), DMA_TO_DEVICE); + /* + * Synchronise all PTE updates for the new mapping before there's + * a chance for anything to kick off a table walk for the new iova. + */ + wmb(); + return mapped; out_err: -- GitLab From 4e92aa2594ab1b1e19d6d798691ae6969d3c9b51 Mon Sep 17 00:00:00 2001 From: Lin Bai Date: Fri, 14 Jun 2019 16:07:21 +0800 Subject: [PATCH 0577/1121] cnss2: Sanity check plat_priv before using If pointer plat_priv is NULL, return properly. Change-Id: I644d49bec96445db77356b3aa37c5ef5c46ea7da Signed-off-by: Lin Bai --- drivers/net/wireless/cnss2/main.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/net/wireless/cnss2/main.c b/drivers/net/wireless/cnss2/main.c index 86eb7850c63f..a1221dee7a24 100644 --- a/drivers/net/wireless/cnss2/main.c +++ b/drivers/net/wireless/cnss2/main.c @@ -241,6 +241,9 @@ int cnss_wlan_enable(struct device *dev, struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev); int ret = 0; + if (!plat_priv) + return -ENODEV; + if (plat_priv->device_id == QCA6174_DEVICE_ID) return 0; @@ -276,6 +279,9 @@ int cnss_wlan_disable(struct device *dev, enum cnss_driver_mode mode) { struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev); + if (!plat_priv) + return -ENODEV; + if (plat_priv->device_id == QCA6174_DEVICE_ID) return 0; @@ -348,6 +354,9 @@ int cnss_set_fw_log_mode(struct device *dev, u8 fw_log_mode) { struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev); + if (!plat_priv) + return -ENODEV; + if (plat_priv->device_id == QCA6174_DEVICE_ID) return 0; -- GitLab From fc1343a0ff5dc4e3c7fb75daea8b0bc3023c78de Mon Sep 17 00:00:00 2001 From: Kui Wang Date: Tue, 28 May 2019 19:05:49 +0800 Subject: [PATCH 0578/1121] msm: camera: core: Fix context release timing issue When sync object is invalid and num_in_map > 1, it will lead to context ref leak. Check sync object first, then register sync call back. Change-Id: I79ad09ae9d7ce8c627d72207085cfe58fb6649dc Signed-off-by: Kui Wang --- .../msm/camera/cam_core/cam_context_utils.c | 19 ++++++++--- .../platform/msm/camera/cam_sync/cam_sync.c | 32 +++++++++++++++++++ .../msm/camera/cam_sync/cam_sync_api.h | 11 ++++++- 3 files changed, 57 insertions(+), 5 deletions(-) diff --git a/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c b/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c index f79af9b0c71f..4f317191101a 100644 --- a/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c +++ b/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c @@ -459,6 +459,17 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx, "[%s][%d] : Moving req[%llu] from free_list to pending_list", ctx->dev_name, ctx->ctx_id, req->request_id); + for (j = 0; j < req->num_in_map_entries; j++) { + rc = cam_sync_check_valid( + req->in_map_entries[j].sync_id); + if (rc) { + CAM_ERR(CAM_CTXT, + "invalid in map sync object %d", + req->in_map_entries[j].sync_id); + goto put_ref; + } + } + for (j = 0; j < req->num_in_map_entries; j++) { cam_context_getref(ctx); rc = cam_sync_register_callback( @@ -480,7 +491,9 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx, ctx->dev_name, ctx->ctx_id, req->request_id); - goto put_ctx_ref; + cam_context_putref(ctx); + goto put_ref; + } CAM_DBG(CAM_CTXT, "register in fence cb: %d ret = %d", req->in_map_entries[j].sync_id, rc); @@ -492,9 +505,7 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx, ctx->dev_name, ctx->ctx_id); return rc; -put_ctx_ref: - for (j; j >= 0; j--) - cam_context_putref(ctx); + put_ref: for (--i; i >= 0; i--) { if (cam_sync_put_obj_ref(req->out_map_entries[i].sync_id)) diff --git a/drivers/media/platform/msm/camera/cam_sync/cam_sync.c b/drivers/media/platform/msm/camera/cam_sync/cam_sync.c index 84acb71707e2..b53eeebe7eb4 100644 --- a/drivers/media/platform/msm/camera/cam_sync/cam_sync.c +++ b/drivers/media/platform/msm/camera/cam_sync/cam_sync.c @@ -288,6 +288,7 @@ int cam_sync_merge(int32_t *sync_obj, uint32_t num_objs, int32_t *merged_obj) int rc; long idx = 0; bool bit; + int i = 0; if (!sync_obj || !merged_obj) { CAM_ERR(CAM_SYNC, "Invalid pointer(s)"); @@ -305,6 +306,14 @@ int cam_sync_merge(int32_t *sync_obj, uint32_t num_objs, int32_t *merged_obj) return -EINVAL; } + for (i = 0; i < num_objs; i++) { + rc = cam_sync_check_valid(sync_obj[i]); + if (rc) { + CAM_ERR(CAM_SYNC, "Sync_obj[%d] %d valid check fail", + i, sync_obj[i]); + return rc; + } + } do { idx = find_first_zero_bit(sync_dev->bitmap, CAM_SYNC_MAX_OBJS); if (idx >= CAM_SYNC_MAX_OBJS) @@ -376,6 +385,29 @@ int cam_sync_destroy(int32_t sync_obj) return cam_sync_deinit_object(sync_dev->sync_table, sync_obj); } +int cam_sync_check_valid(int32_t sync_obj) +{ + struct sync_table_row *row = NULL; + + if (sync_obj >= CAM_SYNC_MAX_OBJS || sync_obj <= 0) + return -EINVAL; + + row = sync_dev->sync_table + sync_obj; + + if (!test_bit(sync_obj, sync_dev->bitmap)) { + CAM_ERR(CAM_SYNC, "Error: Released sync obj received %d", + sync_obj); + return -EINVAL; + } + + if (row->state == CAM_SYNC_STATE_INVALID) { + CAM_ERR(CAM_SYNC, + "Error: accessing an uninitialized sync obj = %d", + sync_obj); + return -EINVAL; + } + return 0; +} int cam_sync_wait(int32_t sync_obj, uint64_t timeout_ms) { unsigned long timeleft; diff --git a/drivers/media/platform/msm/camera/cam_sync/cam_sync_api.h b/drivers/media/platform/msm/camera/cam_sync/cam_sync_api.h index c735d51fe462..f2f67cb3eb7b 100644 --- a/drivers/media/platform/msm/camera/cam_sync/cam_sync_api.h +++ b/drivers/media/platform/msm/camera/cam_sync/cam_sync_api.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -147,5 +147,14 @@ int cam_sync_destroy(int32_t sync_obj); */ int cam_sync_wait(int32_t sync_obj, uint64_t timeout_ms); +/** + * @brief: Check if sync object is valid + * + * @param sync_obj: int referencing the sync object to be checked + * + * @return 0 upon success, -EINVAL if sync object is in bad state or arguments + * are invalid + */ +int cam_sync_check_valid(int32_t sync_obj); #endif /* __CAM_SYNC_API_H__ */ -- GitLab From ee75dcd35e470a3a70ca83cab28f3dd9c685dc97 Mon Sep 17 00:00:00 2001 From: Barani Muthukumaran Date: Fri, 22 Mar 2019 18:17:02 -0700 Subject: [PATCH 0579/1121] scsi:ufs: Allow ICE calls for UFS_STORAGE type Command type for UFS HCE version 2.0 and greater is UTP_CMD_TYPE_UFS_STORAGE, ensure ICE calls are invoked on these versions as well. Change-Id: I461e646ebd2a600e602674884dd1c21cbabb96a7 Signed-off-by: Barani Muthukumaran --- drivers/scsi/ufs/ufs-qcom.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c index 2f68809abacc..3587dbbd3a0a 100644 --- a/drivers/scsi/ufs/ufs-qcom.c +++ b/drivers/scsi/ufs/ufs-qcom.c @@ -969,7 +969,9 @@ int ufs_qcom_crytpo_engine_cfg_start(struct ufs_hba *hba, unsigned int task_tag) int err = 0; if (!host->ice.pdev || - !lrbp->cmd || lrbp->command_type != UTP_CMD_TYPE_SCSI) + !lrbp->cmd || + (lrbp->command_type != UTP_CMD_TYPE_SCSI && + lrbp->command_type != UTP_CMD_TYPE_UFS_STORAGE)) goto out; err = ufs_qcom_ice_cfg_start(host, lrbp->cmd); @@ -984,7 +986,8 @@ int ufs_qcom_crytpo_engine_cfg_end(struct ufs_hba *hba, struct ufs_qcom_host *host = ufshcd_get_variant(hba); int err = 0; - if (!host->ice.pdev || lrbp->command_type != UTP_CMD_TYPE_SCSI) + if (!host->ice.pdev || (lrbp->command_type != UTP_CMD_TYPE_SCSI && + lrbp->command_type != UTP_CMD_TYPE_UFS_STORAGE)) goto out; err = ufs_qcom_ice_cfg_end(host, req); -- GitLab From 7972301a40461e9775ee5c4667ca1fca8d2ffe8b Mon Sep 17 00:00:00 2001 From: Terence Ho Date: Wed, 12 Jun 2019 17:25:22 -0400 Subject: [PATCH 0580/1121] msm: ais: Fastforward ais to camera PC386 Fastforward to latest camera commit 53a55fb72a89 ("msm: camera: eeprom: Fix OOB read/write in EEPROM") Change-Id: Ifa83411fccec2d2329d8ba12afce10245ef0f054 Signed-off-by: Terence Ho --- .../media/platform/msm/ais/cam_cdm/cam_cdm.h | 13 +- .../msm/ais/cam_cdm/cam_cdm_hw_core.c | 39 +++++ .../msm/ais/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c | 9 + .../msm/ais/cam_icp/cam_icp_context.c | 16 ++ .../icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c | 127 ++++++++++++-- .../ais/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c | 51 +++++- .../ais/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h | 69 ++++---- .../isp_hw/ife_csid_hw/cam_ife_csid_core.c | 133 ++++++--------- .../isp_hw_mgr/isp_hw/include/cam_isp_hw.h | 1 + .../isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c | 1 + .../vfe_hw/vfe_top/cam_vfe_camif_ver2.c | 37 +++++ .../isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c | 17 ++ .../ais/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c | 6 + .../cam_csiphy/cam_csiphy_core.c | 73 +++++++- .../cam_csiphy/cam_csiphy_dev.h | 43 ++++- .../cam_csiphy/cam_csiphy_soc.c | 71 +++++++- .../cam_csiphy/cam_csiphy_soc.h | 3 +- .../cam_csiphy/include/cam_csiphy_1_2_hwreg.h | 157 +++++++++++++++--- .../cam_eeprom/cam_eeprom_core.c | 19 ++- .../platform/msm/ais/cam_sync/cam_sync.c | 26 ++- .../msm/ais/cam_sync/cam_sync_private.h | 4 +- 21 files changed, 741 insertions(+), 174 deletions(-) diff --git a/drivers/media/platform/msm/ais/cam_cdm/cam_cdm.h b/drivers/media/platform/msm/ais/cam_cdm/cam_cdm.h index ff8be3570bc5..178d33dee308 100644 --- a/drivers/media/platform/msm/ais/cam_cdm/cam_cdm.h +++ b/drivers/media/platform/msm/ais/cam_cdm/cam_cdm.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -251,6 +251,17 @@ struct cam_cdm_intf_mgr { int32_t refcount; }; +/** + * struct cam_cdm_debugfs_entry : debugfs entry struct + * + * @dentry : entry of debugfs + * @dump_register : flag to dump registers + */ +struct cam_cdm_debugfs_entry { + struct dentry *dentry; + bool dump_register; +}; + int cam_cdm_intf_register_hw_cdm(struct cam_hw_intf *hw, struct cam_cdm_private_dt_data *data, enum cam_cdm_type type, uint32_t *index); diff --git a/drivers/media/platform/msm/ais/cam_cdm/cam_cdm_hw_core.c b/drivers/media/platform/msm/ais/cam_cdm/cam_cdm_hw_core.c index 19413d6ebbc1..af83aba7a0bc 100644 --- a/drivers/media/platform/msm/ais/cam_cdm/cam_cdm_hw_core.c +++ b/drivers/media/platform/msm/ais/cam_cdm/cam_cdm_hw_core.c @@ -38,6 +38,8 @@ static void cam_hw_cdm_work(struct work_struct *work); +static struct cam_cdm_debugfs_entry debugfs_entry; + /* DT match table entry for all CDM variants*/ static const struct of_device_id msm_cam_hw_cdm_dt_match[] = { { @@ -69,6 +71,31 @@ int cam_hw_cdm_bl_fifo_pending_bl_rb(struct cam_hw_info *cdm_hw, return rc; } +static int cam_hw_cdm_create_debugfs_entry(void) +{ + int rc = 0; + + debugfs_entry.dentry = debugfs_create_dir("camera_cdm", NULL); + if (!debugfs_entry.dentry) + return -ENOMEM; + + if (!debugfs_create_bool("dump_register", + 0644, + debugfs_entry.dentry, + &debugfs_entry.dump_register)) { + CAM_ERR(CAM_CDM, + "failed to create dump_register entry"); + rc = -ENOMEM; + goto err; + } + + return rc; +err: + debugfs_remove_recursive(debugfs_entry.dentry); + debugfs_entry.dentry = NULL; + return rc; +} + static int cam_hw_cdm_enable_bl_done_irq(struct cam_hw_info *cdm_hw, bool enable) { @@ -186,6 +213,9 @@ void cam_hw_cdm_dump_core_debug_registers( { uint32_t dump_reg, core_dbg, loop_cnt; + if (!debugfs_entry.dump_register) + return; + mutex_lock(&cdm_hw->hw_mutex); cam_cdm_read_hw_reg(cdm_hw, CDM_CFG_CORE_EN, &dump_reg); CAM_ERR(CAM_CDM, "CDM HW core status=%x", dump_reg); @@ -482,6 +512,14 @@ int cam_hw_cdm_submit_bl(struct cam_hw_info *cdm_hw, if ((!rc) && (hw_vaddr_ptr) && (len) && (len >= cdm_cmd->cmd[i].offset)) { + + if ((len - cdm_cmd->cmd[i].offset) < + cdm_cmd->cmd[i].len) { + CAM_ERR(CAM_CDM, "Not enough buffer"); + rc = -EINVAL; + break; + } + CAM_DBG(CAM_CDM, "Got the HW VA"); if (core->bl_tag >= (CAM_CDM_HWFIFO_SIZE - 1)) @@ -1012,6 +1050,7 @@ int cam_hw_cdm_probe(struct platform_device *pdev) } cdm_hw->open_count--; mutex_unlock(&cdm_hw->hw_mutex); + cam_hw_cdm_create_debugfs_entry(); CAM_DBG(CAM_CDM, "CDM%d probe successful", cdm_hw_intf->hw_idx); diff --git a/drivers/media/platform/msm/ais/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c b/drivers/media/platform/msm/ais/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c index 54f82eef44a5..b2838b4a902f 100644 --- a/drivers/media/platform/msm/ais/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c +++ b/drivers/media/platform/msm/ais/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c @@ -596,6 +596,15 @@ static int cam_fd_mgr_util_prepare_io_buf_info(int32_t iommu_hdl, return -ENOMEM; } + if (io_cfg[i].offsets[plane] >= size) { + CAM_ERR(CAM_FD, + "Invalid cpu buf %d %d %d", + io_cfg[i].direction, + io_cfg[i].resource_type, plane); + rc = -EINVAL; + goto rel_cpu_buf; + } + io_addr[plane] += io_cfg[i].offsets[plane]; } diff --git a/drivers/media/platform/msm/ais/cam_icp/cam_icp_context.c b/drivers/media/platform/msm/ais/cam_icp/cam_icp_context.c index fa9b44289803..41d175188d85 100644 --- a/drivers/media/platform/msm/ais/cam_icp/cam_icp_context.c +++ b/drivers/media/platform/msm/ais/cam_icp/cam_icp_context.c @@ -45,6 +45,14 @@ static int cam_icp_context_dump_active_request(void *data, unsigned long iova, return -EINVAL; } + mutex_lock(&ctx->ctx_mutex); + + if (ctx->state < CAM_CTX_ACQUIRED || ctx->state > CAM_CTX_ACTIVATED) { + CAM_ERR(CAM_ICP, "Invalid state icp ctx %d state %d", + ctx->ctx_id, ctx->state); + goto end; + } + CAM_INFO(CAM_ICP, "iommu fault for icp ctx %d state %d", ctx->ctx_id, ctx->state); @@ -63,6 +71,8 @@ static int cam_icp_context_dump_active_request(void *data, unsigned long iova, req->request_id, rc); } +end: + mutex_unlock(&ctx->ctx_mutex); return rc; } @@ -137,6 +147,12 @@ static int __cam_icp_config_dev_in_ready(struct cam_context *ctx, return rc; } + if ((len < sizeof(struct cam_packet)) || + (cmd->offset >= (len - sizeof(struct cam_packet)))) { + CAM_ERR(CAM_CTXT, "Not enough buf"); + return -EINVAL; + } + packet = (struct cam_packet *) ((uint8_t *)packet_addr + (uint32_t)cmd->offset); diff --git a/drivers/media/platform/msm/ais/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c b/drivers/media/platform/msm/ais/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c index cf4e93c07a27..4ffb3aa052ed 100644 --- a/drivers/media/platform/msm/ais/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c +++ b/drivers/media/platform/msm/ais/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c @@ -64,6 +64,37 @@ static struct cam_icp_hw_mgr icp_hw_mgr; static void cam_icp_mgr_process_dbg_buf(unsigned int debug_lvl); +static int cam_icp_dump_io_cfg(struct cam_icp_hw_ctx_data *ctx_data, + int32_t buf_handle) +{ + uintptr_t vaddr_ptr; + uint32_t *ptr; + size_t len; + int rc, i; + char buf[512]; + int used = 0; + + rc = cam_mem_get_cpu_buf(buf_handle, &vaddr_ptr, &len); + if (rc) { + CAM_ERR(CAM_ICP, "Unable to get io_cfg buf address for %d", + ctx_data->ctx_id); + return rc; + } + + len = len / sizeof(uint32_t); + ptr = (uint32_t *)vaddr_ptr; + for (i = 0; i < len; i++) { + used += snprintf(buf + used, + sizeof(buf) - used, "0X%08X-", ptr[i]); + if (!(i % 8)) { + CAM_INFO(CAM_ICP, "%s: %s", __func__, buf); + used = 0; + } + } + + return rc; +} + static int cam_icp_send_ubwc_cfg(struct cam_icp_hw_mgr *hw_mgr) { struct cam_hw_intf *a5_dev_intf = NULL; @@ -1262,6 +1293,44 @@ static int cam_icp_mgr_ipe_bps_power_collapse(struct cam_icp_hw_mgr *hw_mgr, return rc; } +static int cam_icp_mgr_ipe_bps_get_gdsc_control( + struct cam_icp_hw_mgr *hw_mgr) +{ + int rc = 0; + struct cam_hw_intf *ipe0_dev_intf = NULL; + struct cam_hw_intf *ipe1_dev_intf = NULL; + struct cam_hw_intf *bps_dev_intf = NULL; + + ipe0_dev_intf = hw_mgr->ipe0_dev_intf; + ipe1_dev_intf = hw_mgr->ipe1_dev_intf; + bps_dev_intf = hw_mgr->bps_dev_intf; + + if ((!ipe0_dev_intf) || (!bps_dev_intf)) { + CAM_ERR(CAM_ICP, "dev intfs are wrong"); + return -EINVAL; + } + + if (icp_hw_mgr.ipe_bps_pc_flag) { + rc = bps_dev_intf->hw_ops.process_cmd( + bps_dev_intf->hw_priv, + CAM_ICP_BPS_CMD_POWER_COLLAPSE, + NULL, 0); + + rc = ipe0_dev_intf->hw_ops.process_cmd( + ipe0_dev_intf->hw_priv, + CAM_ICP_IPE_CMD_POWER_COLLAPSE, NULL, 0); + + if (ipe1_dev_intf) { + rc = ipe1_dev_intf->hw_ops.process_cmd( + ipe1_dev_intf->hw_priv, + CAM_ICP_IPE_CMD_POWER_COLLAPSE, + NULL, 0); + } + } + + return rc; +} + static int cam_icp_set_dbg_default_clk(void *data, u64 val) { icp_hw_mgr.icp_debug_clk = val; @@ -1786,27 +1855,31 @@ static int cam_icp_ipebps_reset(struct cam_icp_hw_mgr *hw_mgr) ipe1_dev_intf = hw_mgr->ipe1_dev_intf; bps_dev_intf = hw_mgr->bps_dev_intf; - rc = bps_dev_intf->hw_ops.process_cmd( - bps_dev_intf->hw_priv, - CAM_ICP_BPS_CMD_RESET, - NULL, 0); - if (rc) - CAM_ERR(CAM_ICP, "bps reset failed"); - - rc = ipe0_dev_intf->hw_ops.process_cmd( - ipe0_dev_intf->hw_priv, - CAM_ICP_IPE_CMD_RESET, - NULL, 0); - if (rc) - CAM_ERR(CAM_ICP, "ipe0 reset failed"); + if (hw_mgr->bps_ctxt_cnt) { + rc = bps_dev_intf->hw_ops.process_cmd( + bps_dev_intf->hw_priv, + CAM_ICP_BPS_CMD_RESET, + NULL, 0); + if (rc) + CAM_ERR(CAM_ICP, "bps reset failed"); + } - if (ipe1_dev_intf) { - rc = ipe1_dev_intf->hw_ops.process_cmd( - ipe1_dev_intf->hw_priv, + if (hw_mgr->ipe_ctxt_cnt) { + rc = ipe0_dev_intf->hw_ops.process_cmd( + ipe0_dev_intf->hw_priv, CAM_ICP_IPE_CMD_RESET, NULL, 0); if (rc) - CAM_ERR(CAM_ICP, "ipe1 reset failed"); + CAM_ERR(CAM_ICP, "ipe0 reset failed"); + + if (ipe1_dev_intf) { + rc = ipe1_dev_intf->hw_ops.process_cmd( + ipe1_dev_intf->hw_priv, + CAM_ICP_IPE_CMD_RESET, + NULL, 0); + if (rc) + CAM_ERR(CAM_ICP, "ipe1 reset failed"); + } } return 0; @@ -1827,6 +1900,7 @@ static int cam_icp_mgr_trigger_recovery(struct cam_icp_hw_mgr *hw_mgr) sfr_buffer = (struct sfr_buf *)icp_hw_mgr.hfi_mem.sfr_buf.kva; CAM_WARN(CAM_ICP, "SFR:%s", sfr_buffer->msg); + cam_icp_mgr_ipe_bps_get_gdsc_control(hw_mgr); cam_icp_ipebps_reset(hw_mgr); atomic_set(&hw_mgr->recovery, 1); @@ -3449,6 +3523,17 @@ static int cam_icp_mgr_process_cmd_desc(struct cam_icp_hw_mgr *hw_mgr, goto rel_cmd_buf; } *fw_cmd_buf_iova_addr = addr; + + if (cmd_desc[i].offset >= len || + ((len - cmd_desc[i].offset) < + cmd_desc[i].size)){ + CAM_ERR(CAM_ICP, + "Invalid offset/length, i %d offset 0x%x len 0x%x size 0x%x", + i, cmd_desc[i].offset, + len, cmd_desc[i].size); + goto rel_cmd_buf; + } + *fw_cmd_buf_iova_addr = (*fw_cmd_buf_iova_addr + cmd_desc[i].offset); rc = cam_mem_get_cpu_buf(cmd_desc[i].mem_handle, @@ -4052,8 +4137,12 @@ static int cam_icp_mgr_prepare_hw_update(void *hw_mgr_priv, packet = prepare_args->packet; - if (cam_packet_util_validate_packet(packet, prepare_args->remain_len)) + if (cam_packet_util_validate_packet(packet, prepare_args->remain_len)) { + mutex_unlock(&ctx_data->ctx_mutex); + CAM_ERR(CAM_ICP, "ctx id: %u packet req id %lld validate fail", + ctx_data->ctx_id, packet->header.request_id); return -EINVAL; + } rc = cam_icp_mgr_pkt_validation(packet); if (rc) { @@ -4674,6 +4763,8 @@ static int cam_icp_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args) rc = cam_icp_mgr_send_config_io(ctx_data, io_buf_addr); if (rc) { CAM_ERR(CAM_ICP, "IO Config command failed %d", rc); + cam_icp_dump_io_cfg(ctx_data, + icp_dev_acquire_info->io_config_cmd_handle); goto ioconfig_failed; } diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c index 38ce6386c57d..779f5f5264a5 100644 --- a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c @@ -2968,6 +2968,7 @@ static int cam_ife_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args) } } + ctx->dual_ife_irq_mismatch_cnt = 0; /* Start IFE root node: do nothing */ CAM_DBG(CAM_ISP, "Start success for ctx id:%d", ctx->ctx_index); @@ -3050,6 +3051,7 @@ static int cam_ife_mgr_release_hw(void *hw_mgr_priv, ctx->is_rdi_only_context = 0; ctx->cdm_handle = 0; ctx->cdm_ops = NULL; + ctx->dual_ife_irq_mismatch_cnt = 0; atomic_set(&ctx->overflow_pending, 0); for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) { ctx->sof_cnt[i] = 0; @@ -4062,6 +4064,36 @@ static void cam_ife_mgr_print_io_bufs(struct cam_packet *packet, } } +static void cam_ife_mgr_ctx_irq_dump(struct cam_ife_hw_mgr_ctx *ctx) +{ + struct cam_ife_hw_mgr_res *hw_mgr_res; + struct cam_hw_intf *hw_intf; + struct cam_isp_hw_get_cmd_update cmd_update; + int i = 0; + + list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_src, list) { + if (hw_mgr_res->res_type == CAM_IFE_HW_MGR_RES_UNINIT) + continue; + for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { + if (!hw_mgr_res->hw_res[i]) + continue; + switch (hw_mgr_res->hw_res[i]->res_id) { + case CAM_ISP_HW_VFE_IN_CAMIF: + hw_intf = hw_mgr_res->hw_res[i]->hw_intf; + cmd_update.res = hw_mgr_res->hw_res[i]; + cmd_update.cmd_type = + CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP; + hw_intf->hw_ops.process_cmd(hw_intf->hw_priv, + CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP, + &cmd_update, sizeof(cmd_update)); + break; + default: + break; + } + } + } +} + static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args) { int rc = 0; @@ -4732,11 +4764,26 @@ static int cam_ife_hw_mgr_check_irq_for_dual_vfe( (event_cnt[core_idx1] && (event_cnt[core_idx1] - event_cnt[core_idx0] > 1))) { + if (ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt > 10) { + rc = -1; + return rc; + } + CAM_ERR_RATE_LIMIT(CAM_ISP, "One of the VFE could not generate hw event %d", hw_event_type); - rc = -1; - return rc; + if (event_cnt[core_idx0] >= 2) { + event_cnt[core_idx0]--; + ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt++; + } + if (event_cnt[core_idx1] >= 2) { + event_cnt[core_idx1]--; + ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt++; + } + + if (ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt == 1) + cam_ife_mgr_ctx_irq_dump(ife_hw_mgr_ctx); + rc = 0; } CAM_DBG(CAM_ISP, "Only one core_index has given hw event %d", diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h index bf5f1527caa4..0e6d79b75232 100644 --- a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h +++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h @@ -102,38 +102,42 @@ struct cam_ife_hw_mgr_debug { /** * struct cam_vfe_hw_mgr_ctx - IFE HW manager Context object * - * @list: used by the ctx list. - * @common: common acquired context data - * @ctx_index: acquired context id. - * @hw_mgr: IFE hw mgr which owns this context - * @ctx_in_use: flag to tell whether context is active - * @res_list_ife_in: Starting resource(TPG,PHY0, PHY1...) Can only be - * one. - * @res_list_csid: CSID resource list - * @res_list_ife_src: IFE input resource list - * @res_list_ife_in_rd IFE input resource list for read path - * @res_list_ife_out: IFE output resoruces array - * @free_res_list: Free resources list for the branch node - * @res_pool: memory storage for the free resource list - * @irq_status0_mask: irq_status0_mask for the context - * @irq_status1_mask: irq_status1_mask for the context - * @base device base index array contain the all IFE HW - * instance associated with this context. - * @num_base number of valid base data in the base array - * @cdm_handle cdm hw acquire handle - * @cdm_ops cdm util operation pointer for building - * cdm commands - * @cdm_cmd cdm base and length request pointer - * @sof_cnt sof count value per core, used for dual VFE - * @epoch_cnt epoch count value per core, used for dual VFE - * @eof_cnt eof count value per core, used for dual VFE - * @overflow_pending flat to specify the overflow is pending for the - * context - * @is_rdi_only_context flag to specify the context has only rdi resource - * @config_done_complete indicator for configuration complete - * @init_done indicate whether init hw is done - * @is_fe_enable indicate whether fetch engine\read path is enabled - * @res_bitmap fill resource bitmap for which rup to be set + * @list: used by the ctx list. + * @common: common acquired context data + * @ctx_index: acquired context id. + * @hw_mgr: IFE hw mgr which owns this context + * @ctx_in_use: flag to tell whether context is active + * @res_list_ife_in: Starting resource(TPG,PHY0, PHY1...) Can only be + * one. + * @res_list_csid: CSID resource list + * @res_list_ife_src: IFE input resource list + * @res_list_ife_in_rd IFE input resource list for read path + * @res_list_ife_out: IFE output resoruces array + * @free_res_list: Free resources list for the branch node + * @res_pool: memory storage for the free resource list + * @irq_status0_mask: irq_status0_mask for the context + * @irq_status1_mask: irq_status1_mask for the context + * @base device base index array contain the all IFE HW + * instance associated with this context. + * @num_base number of valid base data in the base array + * @cdm_handle cdm hw acquire handle + * @cdm_ops cdm util operation pointer for building + * cdm commands + * @cdm_cmd cdm base and length request pointer + * @sof_cnt sof count value per core, used for dual VFE + * @epoch_cnt epoch count value per core, used for dual VFE + * @eof_cnt eof count value per core, used for dual VFE + * @overflow_pending flat to specify the overflow is pending + * for the context + * @is_rdi_only_context flag to specify the context has only rdi + * resource + * @config_done_complete indicator for configuration complete + * @init_done indicate whether init hw is done + * @is_fe_enable indicate whether fetch engine\read path + * is enabled + * @res_bitmap fill resource bitmap for which rup to be set + * @dual_ife_irq_mismatch_cnt irq mismatch count value per core, used for + * dual VFE */ struct cam_ife_hw_mgr_ctx { struct list_head list; @@ -171,6 +175,7 @@ struct cam_ife_hw_mgr_ctx { bool init_done; bool is_fe_enable; unsigned long res_bitmap; + uint32_t dual_ife_irq_mismatch_cnt; }; /** diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c index e2f7ae4d5d59..bbcf9af64150 100644 --- a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c +++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c @@ -46,7 +46,7 @@ #define CAM_CSID_IRQ_SOF_DEBUG_CNT_MAX 12 /* Max CSI Rx irq error count threshold value */ -#define CAM_IFE_CSID_MAX_IRQ_ERROR_COUNT 100 +#define CAM_IFE_CSID_MAX_IRQ_ERROR_COUNT 5 static int cam_ife_csid_is_ipp_ppp_format_supported( uint32_t in_format) @@ -1477,15 +1477,13 @@ static void cam_ife_csid_halt_csi2( csid_reg = csid_hw->csid_info->csid_reg; soc_info = &csid_hw->hw_info->soc_info; - CAM_INFO(CAM_ISP, "CSID: %d cnt: %d Halt csi2 rx", - csid_hw->hw_intf->hw_idx, csid_hw->csi2_cfg_cnt); /* Disable the CSI2 rx inerrupts */ - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + + cam_io_w(0, soc_info->reg_map[0].mem_base + csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr); /* Reset the Rx CFG registers */ - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + + cam_io_w(0, soc_info->reg_map[0].mem_base + csid_reg->csi2_reg->csid_csi2_rx_cfg0_addr); cam_io_w_mb(0, soc_info->reg_map[0].mem_base + csid_reg->csi2_reg->csid_csi2_rx_cfg1_addr); @@ -3046,13 +3044,11 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data) cam_io_w_mb(1, soc_info->reg_map[0].mem_base + csid_reg->cmn_reg->csid_irq_cmd_addr); - CAM_DBG(CAM_ISP, "irq_status_top = 0x%x", irq_status_top); - CAM_DBG(CAM_ISP, "irq_status_rx = 0x%x", irq_status_rx); - CAM_DBG(CAM_ISP, "irq_status_ipp = 0x%x", irq_status_ipp); - CAM_DBG(CAM_ISP, "irq_status_ppp = 0x%x", irq_status_ppp); - CAM_DBG(CAM_ISP, "irq_status_rdi0= 0x%x", irq_status_rdi[0]); - CAM_DBG(CAM_ISP, "irq_status_rdi1= 0x%x", irq_status_rdi[1]); - CAM_DBG(CAM_ISP, "irq_status_rdi2= 0x%x", irq_status_rdi[2]); + CAM_DBG(CAM_ISP, + "CSID %d irq status 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", + csid_hw->hw_intf->hw_idx, irq_status_top, + irq_status_rx, irq_status_ipp, irq_status_ppp, + irq_status_rdi[0], irq_status_rdi[1], irq_status_rdi[2]); if (irq_status_rx & BIT(csid_reg->csi2_reg->csi2_rst_done_shift_val)) { CAM_DBG(CAM_ISP, "csi rx reset complete"); @@ -3062,71 +3058,38 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data) spin_lock_irqsave(&csid_hw->lock_state, flags); if (csid_hw->device_enabled == 1) { if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE0_FIFO_OVERFLOW) { - CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 0 over flow", - csid_hw->hw_intf->hw_idx); fatal_err_detected = true; + goto handle_fatal_error; } if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE1_FIFO_OVERFLOW) { - CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 1 over flow", - csid_hw->hw_intf->hw_idx); fatal_err_detected = true; + goto handle_fatal_error; } if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE2_FIFO_OVERFLOW) { - CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 2 over flow", - csid_hw->hw_intf->hw_idx); fatal_err_detected = true; + goto handle_fatal_error; } if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE3_FIFO_OVERFLOW) { - CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 3 over flow", - csid_hw->hw_intf->hw_idx); fatal_err_detected = true; + goto handle_fatal_error; } if (irq_status_rx & CSID_CSI2_RX_ERROR_TG_FIFO_OVERFLOW) { - CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d TG OVER FLOW", - csid_hw->hw_intf->hw_idx); fatal_err_detected = true; + goto handle_fatal_error; } if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_EOT_RECEPTION) { - CAM_ERR_RATE_LIMIT(CAM_ISP, - "CSID:%d CPHY_EOT_RECEPTION", - csid_hw->hw_intf->hw_idx); csid_hw->error_irq_count++; } if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_SOT_RECEPTION) { - CAM_ERR_RATE_LIMIT(CAM_ISP, - "CSID:%d CPHY_SOT_RECEPTION", - csid_hw->hw_intf->hw_idx); csid_hw->error_irq_count++; } - if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_PH_CRC) { - CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d CPHY_PH_CRC", - csid_hw->hw_intf->hw_idx); - } - if (irq_status_rx & CSID_CSI2_RX_ERROR_CRC) { - CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d ERROR_CRC", - csid_hw->hw_intf->hw_idx); - } - if (irq_status_rx & CSID_CSI2_RX_ERROR_ECC) { - CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d ERROR_ECC", - csid_hw->hw_intf->hw_idx); - } - if (irq_status_rx & CSID_CSI2_RX_ERROR_MMAPPED_VC_DT) { - CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d MMAPPED_VC_DT", - csid_hw->hw_intf->hw_idx); - } if (irq_status_rx & CSID_CSI2_RX_ERROR_STREAM_UNDERFLOW) { - CAM_ERR_RATE_LIMIT(CAM_ISP, - "CSID:%d ERROR_STREAM_UNDERFLOW", - csid_hw->hw_intf->hw_idx); csid_hw->error_irq_count++; } if (irq_status_rx & CSID_CSI2_RX_ERROR_UNBOUNDED_FRAME) { - CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d UNBOUNDED_FRAME", - csid_hw->hw_intf->hw_idx); csid_hw->error_irq_count++; } } - spin_unlock_irqrestore(&csid_hw->lock_state, flags); if (csid_hw->error_irq_count > CAM_IFE_CSID_MAX_IRQ_ERROR_COUNT) { @@ -3134,8 +3097,15 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data) csid_hw->error_irq_count = 0; } - if (fatal_err_detected) +handle_fatal_error: + spin_unlock_irqrestore(&csid_hw->lock_state, flags); + if (fatal_err_detected) { + CAM_INFO(CAM_ISP, + "CSID: %d cnt: %d Halt csi2 rx irq_status_rx:0x%x", + csid_hw->hw_intf->hw_idx, csid_hw->csi2_cfg_cnt, + irq_status_rx); cam_ife_csid_halt_csi2(csid_hw); + } if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOT_IRQ) { if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL0_EOT_CAPTURED) { @@ -3236,7 +3206,6 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data) /* IPP reset done bit */ if (irq_status_ipp & BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) { - CAM_DBG(CAM_ISP, "CSID IPP reset complete"); complete(&csid_hw->csid_ipp_complete); } @@ -3253,19 +3222,17 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data) CAM_INFO_RATE_LIMIT(CAM_ISP, "CSID:%d IPP EOF received", csid_hw->hw_intf->hw_idx); - if ((irq_status_ipp & CSID_PATH_ERROR_CCIF_VIOLATION)) - CAM_INFO_RATE_LIMIT(CAM_ISP, - "CSID:%d IPP CCIF violation", - csid_hw->hw_intf->hw_idx); - - if (irq_status_ipp & CSID_PATH_ERROR_FIFO_OVERFLOW) { + if ((irq_status_ipp & CSID_PATH_ERROR_CCIF_VIOLATION) || + (irq_status_ipp & CSID_PATH_ERROR_FIFO_OVERFLOW)) { CAM_ERR_RATE_LIMIT(CAM_ISP, - "CSID:%d IPP fifo over flow", - csid_hw->hw_intf->hw_idx); - /* Stop IPP path immediately */ - cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY, - soc_info->reg_map[0].mem_base + - csid_reg->ipp_reg->csid_pxl_ctrl_addr); + "CSID:%d irq_status_ipp:0x%x", + csid_hw->hw_intf->hw_idx, irq_status_ipp); + if (irq_status_ipp & CSID_PATH_ERROR_FIFO_OVERFLOW) { + /* Stop IPP path immediately */ + cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY, + soc_info->reg_map[0].mem_base + + csid_reg->ipp_reg->csid_pxl_ctrl_addr); + } } } @@ -3274,7 +3241,6 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data) /* PPP reset done bit */ if (irq_status_ppp & BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) { - CAM_DBG(CAM_ISP, "CSID PPP reset complete"); complete(&csid_hw->csid_ppp_complete); } @@ -3291,26 +3257,23 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data) CAM_INFO_RATE_LIMIT(CAM_ISP, "CSID:%d PPP EOF received", csid_hw->hw_intf->hw_idx); - if ((irq_status_ipp & CSID_PATH_ERROR_CCIF_VIOLATION)) - CAM_INFO_RATE_LIMIT(CAM_ISP, - "CSID:%d PPP CCIF violation", - csid_hw->hw_intf->hw_idx); - - if (irq_status_ppp & CSID_PATH_ERROR_FIFO_OVERFLOW) { + if ((irq_status_ppp & CSID_PATH_ERROR_CCIF_VIOLATION) || + (irq_status_ppp & CSID_PATH_ERROR_FIFO_OVERFLOW)) { CAM_ERR_RATE_LIMIT(CAM_ISP, - "CSID:%d PPP fifo over flow", - csid_hw->hw_intf->hw_idx); - /* Stop PPP path immediately */ - cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY, - soc_info->reg_map[0].mem_base + - csid_reg->ppp_reg->csid_pxl_ctrl_addr); + "CSID:%d irq_status_ppp:0x%x", + csid_hw->hw_intf->hw_idx, irq_status_ppp); + if (irq_status_ppp & CSID_PATH_ERROR_FIFO_OVERFLOW) { + /* Stop PPP path immediately */ + cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY, + soc_info->reg_map[0].mem_base + + csid_reg->ppp_reg->csid_pxl_ctrl_addr); + } } } for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) { if (irq_status_rdi[i] & BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) { - CAM_DBG(CAM_ISP, "CSID RDI%d reset complete", i); complete(&csid_hw->csid_rdin_complete[i]); } @@ -3327,14 +3290,14 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data) CAM_INFO_RATE_LIMIT(CAM_ISP, "CSID RDI:%d EOF received", i); - if ((irq_status_rdi[i] & CSID_PATH_ERROR_CCIF_VIOLATION)) - CAM_INFO_RATE_LIMIT(CAM_ISP, - "CSIDi RDI :%d CCIF violation", i); - - if (irq_status_rdi[i] & CSID_PATH_ERROR_FIFO_OVERFLOW) { + if ((irq_status_rdi[i] & CSID_PATH_ERROR_CCIF_VIOLATION) || + (irq_status_rdi[i] & CSID_PATH_ERROR_FIFO_OVERFLOW)) { CAM_ERR_RATE_LIMIT(CAM_ISP, - "CSID:%d RDI fifo over flow", - csid_hw->hw_intf->hw_idx); + "CSID:%d irq_status_rdi[%d]:0x%x", + csid_hw->hw_intf->hw_idx, i, + irq_status_rdi[i]); + } + if (irq_status_rdi[i] & CSID_PATH_ERROR_FIFO_OVERFLOW) { /* Stop RDI path immediately */ cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY, soc_info->reg_map[0].mem_base + diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h index 9792ac5f0f98..185d0f595673 100644 --- a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h +++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h @@ -103,6 +103,7 @@ enum cam_isp_hw_cmd_type { CAM_ISP_HW_CMD_CSID_CLOCK_UPDATE, CAM_ISP_HW_CMD_FE_UPDATE_IN_RD, CAM_ISP_HW_CMD_FE_UPDATE_BUS_RD, + CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP, CAM_ISP_HW_CMD_MAX, }; diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c index 2bd6db9954f1..a26c11264d2c 100644 --- a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c +++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c @@ -760,6 +760,7 @@ int cam_vfe_process_cmd(void *hw_priv, uint32_t cmd_type, case CAM_ISP_HW_CMD_CLOCK_UPDATE: case CAM_ISP_HW_CMD_BW_UPDATE: case CAM_ISP_HW_CMD_BW_CONTROL: + case CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP: rc = core_info->vfe_top->hw_ops.process_cmd( core_info->vfe_top->top_priv, cmd_type, cmd_args, arg_size); diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c index 13b588fe34d1..3ed45ee530e8 100644 --- a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c +++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c @@ -422,6 +422,40 @@ static int cam_vfe_camif_reg_dump_bh( return 0; } +static int cam_vfe_camif_irq_reg_dump( + struct cam_isp_resource_node *camif_res) +{ + struct cam_vfe_mux_camif_data *camif_priv; + struct cam_vfe_soc_private *soc_private; + int rc = 0; + + if (!camif_res) { + CAM_ERR(CAM_ISP, "Error! Invalid input arguments\n"); + return -EINVAL; + } + + if ((camif_res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) || + (camif_res->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE)) { + CAM_ERR(CAM_ISP, "Error! Invalid state\n"); + return 0; + } + + camif_priv = (struct cam_vfe_mux_camif_data *)camif_res->res_priv; + soc_private = camif_priv->soc_info->soc_private; + + CAM_INFO(CAM_ISP, + "Core Id =%d Mask reg: offset 0x%x val 0x%x offset 0x%x val 0x%x", + camif_priv->hw_intf->hw_idx, + 0x5c, cam_io_r_mb(camif_priv->mem_base + 0x5c), + 0x60, cam_io_r_mb(camif_priv->mem_base + 0x60)); + CAM_INFO(CAM_ISP, + "Core Id =%d Status reg: offset 0x%x val 0x%x offset 0x%x val 0x%x", + camif_priv->hw_intf->hw_idx, + 0x6c, cam_io_r_mb(camif_priv->mem_base + 0x6c), + 0x70, cam_io_r_mb(camif_priv->mem_base + 0x70)); + return rc; +} + static int cam_vfe_camif_resource_stop( struct cam_isp_resource_node *camif_res) { @@ -509,6 +543,9 @@ static int cam_vfe_camif_process_cmd(struct cam_isp_resource_node *rsrc_node, (struct cam_vfe_mux_camif_data *)rsrc_node->res_priv; camif_priv->camif_debug = *((uint32_t *)cmd_args); break; + case CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP: + rc = cam_vfe_camif_irq_reg_dump(rsrc_node); + break; default: CAM_ERR(CAM_ISP, "unsupported process command:%d", cmd_type); diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c index 4dcad9cfc5d0..d512128b28e5 100644 --- a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c +++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c @@ -438,6 +438,19 @@ static int cam_vfe_top_mux_get_reg_update( return -EINVAL; } +static int cam_vfe_get_irq_register_dump( + struct cam_vfe_top_ver2_priv *top_priv, + void *cmd_args, uint32_t arg_size) +{ + struct cam_isp_hw_get_cmd_update *cmd_update = cmd_args; + + if (cmd_update->res->process_cmd) + cmd_update->res->process_cmd(cmd_update->res, + CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP, cmd_args, arg_size); + + return 0; +} + int cam_vfe_top_get_hw_caps(void *device_priv, void *get_hw_cap_args, uint32_t arg_size) { @@ -723,6 +736,10 @@ int cam_vfe_top_process_cmd(void *device_priv, uint32_t cmd_type, case CAM_ISP_HW_CMD_BW_CONTROL: rc = cam_vfe_top_bw_control(top_priv, cmd_args, arg_size); break; + case CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP: + rc = cam_vfe_get_irq_register_dump(top_priv, + cmd_args, arg_size); + break; default: rc = -EINVAL; CAM_ERR(CAM_ISP, "Error! Invalid cmd:%d", cmd_type); diff --git a/drivers/media/platform/msm/ais/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c b/drivers/media/platform/msm/ais/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c index 9e4578d294d8..9ea8e3f5b7d1 100644 --- a/drivers/media/platform/msm/ais/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c +++ b/drivers/media/platform/msm/ais/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c @@ -157,6 +157,12 @@ static int cam_jpeg_mgr_process_irq(void *priv, void *data) cmd_buf_kaddr = (uint32_t *)kaddr; + if ((p_cfg_req->hw_cfg_args.hw_update_entries[CAM_JPEG_PARAM].offset / + sizeof(uint32_t)) >= cmd_buf_len) { + CAM_ERR(CAM_JPEG, "Not enough buf"); + return -EINVAL; + } + cmd_buf_kaddr = (cmd_buf_kaddr + (p_cfg_req->hw_cfg_args.hw_update_entries[CAM_JPEG_PARAM].offset diff --git a/drivers/media/platform/msm/ais/cam_sensor_module/cam_csiphy/cam_csiphy_core.c b/drivers/media/platform/msm/ais/cam_sensor_module/cam_csiphy/cam_csiphy_core.c index ab83346c1f54..a8088caa73e0 100644 --- a/drivers/media/platform/msm/ais/cam_sensor_module/cam_csiphy/cam_csiphy_core.c +++ b/drivers/media/platform/msm/ais/cam_sensor_module/cam_csiphy/cam_csiphy_core.c @@ -232,13 +232,18 @@ int32_t cam_cmd_buf_parser(struct csiphy_device *csiphy_dev, csiphy_dev->csiphy_info.csiphy_3phase = cam_cmd_csiphy_info->csiphy_3phase; csiphy_dev->csiphy_info.combo_mode |= cam_cmd_csiphy_info->combo_mode; - if (cam_cmd_csiphy_info->combo_mode == 1) + if (cam_cmd_csiphy_info->combo_mode == 1) { csiphy_dev->csiphy_info.settle_time_combo_sensor = cam_cmd_csiphy_info->settle_time; - else + csiphy_dev->csiphy_info.data_rate_combo_sensor = + cam_cmd_csiphy_info->data_rate; + } else { csiphy_dev->csiphy_info.settle_time = cam_cmd_csiphy_info->settle_time; - csiphy_dev->csiphy_info.data_rate = cam_cmd_csiphy_info->data_rate; + csiphy_dev->csiphy_info.data_rate = + cam_cmd_csiphy_info->data_rate; + } + if (cam_cmd_csiphy_info->secure_mode == 1) cam_csiphy_update_secure_info(csiphy_dev, @@ -269,6 +274,65 @@ void cam_csiphy_cphy_irq_config(struct csiphy_device *csiphy_dev) csiphy_dev->ctrl_reg->csiphy_irq_reg[i].reg_addr); } +void cam_csiphy_cphy_data_rate_config(struct csiphy_device *csiphy_device) +{ + int i = 0, j = 0; + uint64_t phy_data_rate = 0; + void __iomem *csiphybase = NULL; + ssize_t num_table_entries = 0; + struct data_rate_settings_t *settings_table = NULL; + + if ((csiphy_device == NULL) || + (csiphy_device->ctrl_reg == NULL) || + (csiphy_device->ctrl_reg->data_rates_settings_table == NULL)) { + CAM_DBG(CAM_CSIPHY, + "Data rate specific register table not found"); + return; + } + + phy_data_rate = csiphy_device->csiphy_info.data_rate; + csiphybase = + csiphy_device->soc_info.reg_map[0].mem_base; + settings_table = + csiphy_device->ctrl_reg->data_rates_settings_table; + num_table_entries = + settings_table->num_data_rate_settings; + + CAM_DBG(CAM_CSIPHY, "required data rate : %llu", phy_data_rate); + for (i = 0; i < num_table_entries; i++) { + struct data_rate_reg_info_t *drate_settings = + settings_table->data_rate_settings; + uint64_t bandwidth = + drate_settings[i].bandwidth; + ssize_t num_reg_entries = + drate_settings[i].data_rate_reg_array_size; + + if (phy_data_rate > bandwidth) { + CAM_DBG(CAM_CSIPHY, + "Skipping table [%d] %llu required: %llu", + i, bandwidth, phy_data_rate); + continue; + } + + CAM_DBG(CAM_CSIPHY, + "table[%d] BW : %llu Selected", i, bandwidth); + for (j = 0; j < num_reg_entries; j++) { + uint32_t reg_addr = + drate_settings[i].csiphy_data_rate_regs[j].reg_addr; + + uint32_t reg_data = + drate_settings[i].csiphy_data_rate_regs[j].reg_data; + + CAM_DBG(CAM_CSIPHY, + "writing reg : %x val : %x", + reg_addr, reg_data); + cam_io_w_mb(reg_data, + csiphybase + reg_addr); + } + break; + } +} + void cam_csiphy_cphy_irq_disable(struct csiphy_device *csiphy_dev) { int32_t i; @@ -475,6 +539,9 @@ int32_t cam_csiphy_config_dev(struct csiphy_device *csiphy_dev) lane_pos++; } + if (csiphy_dev->csiphy_info.csiphy_3phase) + cam_csiphy_cphy_data_rate_config(csiphy_dev); + cam_csiphy_cphy_irq_config(csiphy_dev); return rc; diff --git a/drivers/media/platform/msm/ais/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h b/drivers/media/platform/msm/ais/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h index 51cf9e953a41..cf81924d970a 100644 --- a/drivers/media/platform/msm/ais/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h +++ b/drivers/media/platform/msm/ais/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h @@ -44,8 +44,10 @@ #define MAX_CSIPHY_REG_ARRAY 70 #define MAX_CSIPHY_CMN_REG_ARRAY 5 -#define MAX_LANES 5 -#define MAX_SETTINGS_PER_LANE 43 +#define MAX_LANES 5 +#define MAX_SETTINGS_PER_LANE 43 +#define MAX_DATA_RATES 3 +#define MAX_DATA_RATE_REGS 30 #define MAX_REGULATOR 5 #define CAMX_CSIPHY_DEV_NAME "cam-csiphy-driver" @@ -155,6 +157,32 @@ struct csiphy_reg_t { uint32_t csiphy_param_type; }; +struct csiphy_device; + +/* + * struct data_rate_reg_info_t + * @bandwidth: max bandwidth supported by this reg settings + * @data_rate_reg_array_size: number of reg value pairs in the array + * @csiphy_data_rate_regs: array of data rate specific reg value pairs + */ +struct data_rate_reg_info_t { + uint64_t bandwidth; + ssize_t data_rate_reg_array_size; + struct csiphy_reg_t csiphy_data_rate_regs[MAX_DATA_RATE_REGS]; +}; + +/** + * struct data_rate_settings_t + * @num_data_rate_settings: number of valid settings + * present in the data rate settings array + * @data_rate_settings: array of regsettings which are specific to + * data rate + */ +struct data_rate_settings_t { + ssize_t num_data_rate_settings; + struct data_rate_reg_info_t data_rate_settings[MAX_DATA_RATES]; +}; + /** * struct csiphy_ctrl_t * @csiphy_reg: Register address @@ -166,6 +194,12 @@ struct csiphy_reg_t { * @csiphy_3ph_reg: 3phase register set * @csiphy_2ph_3ph_mode_reg: * 2 phase 3phase combo register set + * @getclockvoting: function pointer which + * is used to find the clock voting + * for the sensor output data rate + * @data_rate_settings_table: + * Table which maintains the resgister + * settings specific to data rate */ struct csiphy_ctrl_t { struct csiphy_reg_parms_t csiphy_reg; @@ -176,6 +210,8 @@ struct csiphy_ctrl_t { struct csiphy_reg_t (*csiphy_2ph_combo_mode_reg)[MAX_SETTINGS_PER_LANE]; struct csiphy_reg_t (*csiphy_3ph_reg)[MAX_SETTINGS_PER_LANE]; struct csiphy_reg_t (*csiphy_2ph_3ph_mode_reg)[MAX_SETTINGS_PER_LANE]; + enum cam_vote_level (*getclockvoting)(struct csiphy_device *phy_dev); + struct data_rate_settings_t *data_rates_settings_table; }; /** @@ -190,6 +226,8 @@ struct csiphy_ctrl_t { * @settle_time : Settling time in ms * @settle_time_combo_sensor : Settling time in ms * @data_rate : Data rate in mbps + * @data_rate_combo_sensor: data rate of combo sensor + * in the the same phy * */ struct cam_csiphy_param { @@ -202,6 +240,7 @@ struct cam_csiphy_param { uint64_t settle_time; uint64_t settle_time_combo_sensor; uint64_t data_rate; + uint64_t data_rate_combo_sensor; }; /** diff --git a/drivers/media/platform/msm/ais/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c b/drivers/media/platform/msm/ais/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c index 0902601cebd5..0bf5aac2f090 100644 --- a/drivers/media/platform/msm/ais/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c +++ b/drivers/media/platform/msm/ais/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -17,6 +17,9 @@ #include "include/cam_csiphy_1_2_hwreg.h" #include "include/cam_csiphy_2_0_hwreg.h" +#define CSIPHY_3PH_DIVISOR 16 +#define CSIPHY_3PH_DIVISOR_12 32 +#define CSIPHY_2PH_DIVISOR 8 #define BYTES_PER_REGISTER 4 #define NUM_REGISTER_PER_LINE 4 #define REG_OFFSET(__start, __i) ((__start) + ((__i) * BYTES_PER_REGISTER)) @@ -79,10 +82,62 @@ int32_t cam_csiphy_mem_dmp(struct cam_hw_soc_info *soc_info) return rc; } +enum cam_vote_level get_clk_vote_default(struct csiphy_device *csiphy_dev) +{ + CAM_DBG(CAM_CSIPHY, "voting for SVS"); + return CAM_SVS_VOTE; +} + +enum cam_vote_level get_clk_voting_dynamic(struct csiphy_device *csiphy_dev) +{ + uint32_t cam_vote_level = 0; + uint32_t last_valid_vote = 0; + struct cam_hw_soc_info *soc_info; + uint64_t phy_data_rate = csiphy_dev->csiphy_info.data_rate; + + soc_info = &csiphy_dev->soc_info; + + if (csiphy_dev->is_acquired_dev_combo_mode) + phy_data_rate = max(phy_data_rate, + csiphy_dev->csiphy_info.data_rate_combo_sensor); + + if (csiphy_dev->csiphy_info.csiphy_3phase) { + if (csiphy_dev->is_csiphy_3phase_hw == CSI_3PHASE_HW_12) + do_div(phy_data_rate, CSIPHY_3PH_DIVISOR_12); + else + do_div(phy_data_rate, CSIPHY_3PH_DIVISOR); + } else { + do_div(phy_data_rate, CSIPHY_2PH_DIVISOR); + } + + /* round off to next integer */ + phy_data_rate += 1; + + for (cam_vote_level = 0; + cam_vote_level < CAM_MAX_VOTE; cam_vote_level++) { + if (soc_info->clk_level_valid[cam_vote_level] != true) + continue; + + if (soc_info->clk_rate[cam_vote_level][0] > + phy_data_rate) { + CAM_DBG(CAM_CSIPHY, + "match detected %s : %llu:%d level : %d", + soc_info->clk_name[0], + phy_data_rate, + soc_info->clk_rate[cam_vote_level][0], + cam_vote_level); + return cam_vote_level; + } + last_valid_vote = cam_vote_level; + } + return last_valid_vote; +} + int32_t cam_csiphy_enable_hw(struct csiphy_device *csiphy_dev) { int32_t rc = 0; struct cam_hw_soc_info *soc_info; + enum cam_vote_level vote_level = CAM_SVS_VOTE; soc_info = &csiphy_dev->soc_info; @@ -92,8 +147,9 @@ int32_t cam_csiphy_enable_hw(struct csiphy_device *csiphy_dev) return rc; } + vote_level = csiphy_dev->ctrl_reg->getclockvoting(csiphy_dev); rc = cam_soc_util_enable_platform_resource(soc_info, true, - CAM_SVS_VOTE, ENABLE_IRQ); + vote_level, ENABLE_IRQ); if (rc < 0) { CAM_ERR(CAM_CSIPHY, "failed to enable platform resources %d", rc); @@ -174,9 +230,11 @@ int32_t cam_csiphy_parse_dt_info(struct platform_device *pdev, csiphy_dev->ctrl_reg->csiphy_common_reg = csiphy_common_reg_1_0; csiphy_dev->ctrl_reg->csiphy_reset_reg = csiphy_reset_reg_1_0; csiphy_dev->ctrl_reg->csiphy_reg = csiphy_v1_0; + csiphy_dev->ctrl_reg->getclockvoting = get_clk_vote_default; csiphy_dev->hw_version = CSIPHY_VERSION_V10; csiphy_dev->is_csiphy_3phase_hw = CSI_3PHASE_HW; csiphy_dev->clk_lane = 0; + csiphy_dev->ctrl_reg->data_rates_settings_table = NULL; } else if (of_device_is_compatible(soc_info->dev->of_node, "qcom,csiphy-v1.1")) { csiphy_dev->ctrl_reg->csiphy_2ph_reg = csiphy_2ph_v1_1_reg; @@ -191,9 +249,11 @@ int32_t cam_csiphy_parse_dt_info(struct platform_device *pdev, csiphy_dev->ctrl_reg->csiphy_reset_reg = csiphy_reset_reg_1_1; csiphy_dev->ctrl_reg->csiphy_reg = csiphy_v1_1; + csiphy_dev->ctrl_reg->getclockvoting = get_clk_vote_default; csiphy_dev->is_csiphy_3phase_hw = CSI_3PHASE_HW; csiphy_dev->hw_version = CSIPHY_VERSION_V11; csiphy_dev->clk_lane = 0; + csiphy_dev->ctrl_reg->data_rates_settings_table = NULL; } else if (of_device_is_compatible(soc_info->dev->of_node, "qcom,csiphy-v1.2")) { csiphy_dev->ctrl_reg->csiphy_2ph_reg = csiphy_2ph_v1_2_reg; @@ -206,10 +266,13 @@ int32_t cam_csiphy_parse_dt_info(struct platform_device *pdev, csiphy_common_reg_1_2; csiphy_dev->ctrl_reg->csiphy_reset_reg = csiphy_reset_reg_1_2; + csiphy_dev->ctrl_reg->getclockvoting = get_clk_voting_dynamic; csiphy_dev->ctrl_reg->csiphy_reg = csiphy_v1_2; - csiphy_dev->is_csiphy_3phase_hw = CSI_3PHASE_HW; + csiphy_dev->is_csiphy_3phase_hw = CSI_3PHASE_HW_12; csiphy_dev->hw_version = CSIPHY_VERSION_V12; csiphy_dev->clk_lane = 0; + csiphy_dev->ctrl_reg->data_rates_settings_table = + &data_rate_delta_table; } else if (of_device_is_compatible(soc_info->dev->of_node, "qcom,csiphy-v2.0")) { csiphy_dev->ctrl_reg->csiphy_2ph_reg = csiphy_2ph_v2_0_reg; @@ -221,9 +284,11 @@ int32_t cam_csiphy_parse_dt_info(struct platform_device *pdev, csiphy_dev->ctrl_reg->csiphy_common_reg = csiphy_common_reg_2_0; csiphy_dev->ctrl_reg->csiphy_reset_reg = csiphy_reset_reg_2_0; csiphy_dev->ctrl_reg->csiphy_reg = csiphy_v2_0; + csiphy_dev->ctrl_reg->getclockvoting = get_clk_vote_default; csiphy_dev->hw_version = CSIPHY_VERSION_V20; csiphy_dev->is_csiphy_3phase_hw = CSI_3PHASE_HW; csiphy_dev->clk_lane = 0; + csiphy_dev->ctrl_reg->data_rates_settings_table = NULL; } else { CAM_ERR(CAM_CSIPHY, "invalid hw version : 0x%x", csiphy_dev->hw_version); diff --git a/drivers/media/platform/msm/ais/cam_sensor_module/cam_csiphy/cam_csiphy_soc.h b/drivers/media/platform/msm/ais/cam_sensor_module/cam_csiphy/cam_csiphy_soc.h index 68ca68ced31b..64d05616d2e3 100644 --- a/drivers/media/platform/msm/ais/cam_sensor_module/cam_csiphy/cam_csiphy_soc.h +++ b/drivers/media/platform/msm/ais/cam_sensor_module/cam_csiphy/cam_csiphy_soc.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -34,6 +34,7 @@ #define CDBG(fmt, args...) pr_debug(fmt, ##args) #define CSI_3PHASE_HW 1 +#define CSI_3PHASE_HW_12 0x12 #define CSIPHY_VERSION_V35 0x35 #define CSIPHY_VERSION_V10 0x10 #define CSIPHY_VERSION_V11 0x11 diff --git a/drivers/media/platform/msm/ais/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h b/drivers/media/platform/msm/ais/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h index 945910e96a55..67653e81fde1 100644 --- a/drivers/media/platform/msm/ais/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h +++ b/drivers/media/platform/msm/ais/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h @@ -19,10 +19,10 @@ struct csiphy_reg_parms_t csiphy_v1_2 = { .mipi_csiphy_interrupt_status0_addr = 0x8B0, .mipi_csiphy_interrupt_clear0_addr = 0x858, .mipi_csiphy_glbl_irq_cmd_addr = 0x828, - .csiphy_common_array_size = 4, + .csiphy_common_array_size = 6, .csiphy_reset_array_size = 5, .csiphy_2ph_config_array_size = 21, - .csiphy_3ph_config_array_size = 31, + .csiphy_3ph_config_array_size = 38, .csiphy_2ph_clock_lane = 0x1, .csiphy_2ph_combo_ck_ln = 0x10, }; @@ -30,8 +30,10 @@ struct csiphy_reg_parms_t csiphy_v1_2 = { struct csiphy_reg_t csiphy_common_reg_1_2[] = { {0x0814, 0xd5, 0x00, CSIPHY_LANE_ENABLE}, {0x0818, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x081C, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x081C, 0x02, 0x00, CSIPHY_2PH_REGS}, + {0x081C, 0x52, 0x00, CSIPHY_3PH_REGS}, + {0x0800, 0x02, 0x00, CSIPHY_2PH_REGS}, + {0x0800, 0x0E, 0x00, CSIPHY_3PH_REGS}, }; struct csiphy_reg_t csiphy_reset_reg_1_2[] = { @@ -297,7 +299,7 @@ struct csiphy_reg_t struct csiphy_reg_t csiphy_3ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { { - {0x015C, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x015C, 0x66, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0990, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0994, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0998, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, @@ -305,10 +307,10 @@ csiphy_reg_t csiphy_3ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { {0x0994, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0998, 0x1A, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x098C, 0xAF, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0168, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x016C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0168, 0xAC, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x016C, 0xAD, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0104, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x010C, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x010C, 0x07, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, {0x0108, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE}, {0x0114, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0150, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, @@ -321,27 +323,34 @@ csiphy_reg_t csiphy_3ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { {0x0124, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0128, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x012C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0144, 0x30, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0144, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0160, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x01CC, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0164, 0x33, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x01DC, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x09C0, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x09C4, 0x7D, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x09C8, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0984, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0988, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0980, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x09B0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x09B4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0800, 0x0E, 0x00, CSIPHY_DEFAULT_PARAMS}, }, { - {0x035C, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x035C, 0x66, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0A90, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0A94, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0A98, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0A90, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0A94, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0A98, 0x1A, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0A8C, 0xAF, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0368, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x036C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A94, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A98, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A8C, 0xBF, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0368, 0xAC, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x036C, 0xAD, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0304, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x030C, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x030C, 0x07, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, {0x0308, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE}, {0x0314, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0350, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, @@ -354,16 +363,23 @@ csiphy_reg_t csiphy_3ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { {0x0324, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0328, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x032C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0344, 0x30, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0344, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0360, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x03CC, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0364, 0x33, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x03DC, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0AB0, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0AC0, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0AC4, 0x7D, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0AC8, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A84, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A88, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A80, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0AB0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0AB4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0800, 0x0E, 0x00, CSIPHY_DEFAULT_PARAMS}, }, { - {0x055C, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x055C, 0x66, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0B90, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0B94, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0B98, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, @@ -371,10 +387,10 @@ csiphy_reg_t csiphy_3ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { {0x0B94, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0B98, 0x1A, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0B8C, 0xAF, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0568, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x056C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0568, 0xAC, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x056C, 0xAD, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0504, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x050C, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x050C, 0x07, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, {0x0508, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE}, {0x0514, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0550, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, @@ -387,14 +403,107 @@ csiphy_reg_t csiphy_3ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { {0x0524, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0528, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x052C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0544, 0x30, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0544, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0560, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x05CC, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0564, 0x33, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x05DC, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0BB0, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0BC0, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0BC4, 0x7D, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0BC8, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B84, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B88, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B80, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0BB0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0BB4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0800, 0x0E, 0x00, CSIPHY_DEFAULT_PARAMS}, }, }; +struct data_rate_settings_t data_rate_delta_table = { + .num_data_rate_settings = 3, + .data_rate_settings = { + { + /* (2.5 * 10**3 * 2.28) rounded value*/ + .bandwidth = 5700000000, + .data_rate_reg_array_size = 12, + .csiphy_data_rate_regs = { + {0x15C, 0x66, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x35C, 0x66, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x55C, 0x66, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x9B4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0xAB4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0xBB4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x144, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x344, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x544, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x16C, 0xAD, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x36C, 0xAD, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x56C, 0xAD, 0x00, CSIPHY_DEFAULT_PARAMS}, + } + }, + { + /* (3.5 * 10**3 * 2.28) rounded value */ + .bandwidth = 7980000000, + .data_rate_reg_array_size = 24, + .csiphy_data_rate_regs = { + {0x15C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x35C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x55C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x9B4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0xAB4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0xBB4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x9B0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0xAB0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0xBB0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x144, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x344, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x544, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x13C, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x33C, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x53C, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x140, 0x81, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x340, 0x81, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x540, 0x81, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x168, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x368, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x568, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x16C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x36C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x56C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + }, + }, + { + /* (4.5 * 10**3 * 2.28) rounded value */ + .bandwidth = 10260000000, + .data_rate_reg_array_size = 24, + .csiphy_data_rate_regs = { + {0x15C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x35C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x55C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x9B4, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0xAB4, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0xBB4, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x9B0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0xAB0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0xBB0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x144, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x344, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x544, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x13C, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x33C, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x53C, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x140, 0x81, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x340, 0x81, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x540, 0x81, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x168, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x368, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x568, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x16C, 0x1D, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x36C, 0x1D, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x56C, 0x1D, 0x00, CSIPHY_DEFAULT_PARAMS}, + }, + } + } +}; #endif /* _CAM_CSIPHY_1_2_HWREG_H_ */ diff --git a/drivers/media/platform/msm/ais/cam_sensor_module/cam_eeprom/cam_eeprom_core.c b/drivers/media/platform/msm/ais/cam_sensor_module/cam_eeprom/cam_eeprom_core.c index faece709dea4..209daa2064d9 100644 --- a/drivers/media/platform/msm/ais/cam_sensor_module/cam_eeprom/cam_eeprom_core.c +++ b/drivers/media/platform/msm/ais/cam_sensor_module/cam_eeprom/cam_eeprom_core.c @@ -438,17 +438,29 @@ static int32_t cam_eeprom_parse_memory_map( else if (cmm_hdr->cmd_type == CAMERA_SENSOR_CMD_TYPE_WAIT) validate_size = sizeof(struct cam_cmd_unconditional_wait); - if (remain_buf_len < validate_size) { + if (remain_buf_len < validate_size || + *num_map >= MSM_EEPROM_MAX_MEM_MAP_CNT) { CAM_ERR(CAM_EEPROM, "not enough buffer"); return -EINVAL; } switch (cmm_hdr->cmd_type) { case CAMERA_SENSOR_CMD_TYPE_I2C_RNDM_WR: i2c_random_wr = (struct cam_cmd_i2c_random_wr *)cmd_buf; + + if (i2c_random_wr->header.count == 0 || + i2c_random_wr->header.count >= MSM_EEPROM_MAX_MEM_MAP_CNT || + (size_t)*num_map > U16_MAX - i2c_random_wr->header.count) { + CAM_ERR(CAM_EEPROM, "OOB Error"); + return -EINVAL; + } cmd_length_in_bytes = sizeof(struct cam_cmd_i2c_random_wr) + ((i2c_random_wr->header.count - 1) * sizeof(struct i2c_random_wr_payload)); + if (cmd_length_in_bytes > remain_buf_len) { + CAM_ERR(CAM_EEPROM, "Not enough buffer remaining"); + return -EINVAL; + } for (cnt = 0; cnt < (i2c_random_wr->header.count); cnt++) { map[*num_map + cnt].page.addr = @@ -471,6 +483,11 @@ static int32_t cam_eeprom_parse_memory_map( i2c_cont_rd = (struct cam_cmd_i2c_continuous_rd *)cmd_buf; cmd_length_in_bytes = sizeof(struct cam_cmd_i2c_continuous_rd); + if (i2c_cont_rd->header.count >= U32_MAX - data->num_data) { + CAM_ERR(CAM_EEPROM, + "int overflow on eeprom memory block"); + return -EINVAL; + } map[*num_map].mem.addr = i2c_cont_rd->reg_addr; map[*num_map].mem.addr_type = i2c_cont_rd->header.addr_type; map[*num_map].mem.data_type = i2c_cont_rd->header.data_type; diff --git a/drivers/media/platform/msm/ais/cam_sync/cam_sync.c b/drivers/media/platform/msm/ais/cam_sync/cam_sync.c index d3f62d6a3e20..84acb71707e2 100644 --- a/drivers/media/platform/msm/ais/cam_sync/cam_sync.c +++ b/drivers/media/platform/msm/ais/cam_sync/cam_sync.c @@ -29,6 +29,20 @@ struct sync_device *sync_dev; */ static bool trigger_cb_without_switch; +void cam_sync_print_fence_table(void) +{ + int cnt; + + for (cnt = 0; cnt < CAM_SYNC_MAX_OBJS; cnt++) { + CAM_INFO(CAM_SYNC, "%d, %s, %d, %d, %d", + sync_dev->sync_table[cnt].sync_id, + sync_dev->sync_table[cnt].name, + sync_dev->sync_table[cnt].type, + sync_dev->sync_table[cnt].state, + sync_dev->sync_table[cnt].ref_cnt); + } +} + int cam_sync_create(int32_t *sync_obj, const char *name) { int rc; @@ -37,8 +51,15 @@ int cam_sync_create(int32_t *sync_obj, const char *name) do { idx = find_first_zero_bit(sync_dev->bitmap, CAM_SYNC_MAX_OBJS); - if (idx >= CAM_SYNC_MAX_OBJS) + if (idx >= CAM_SYNC_MAX_OBJS) { + CAM_ERR(CAM_SYNC, + "Error: Unable to Create Sync Idx = %d Reached Max!!", + idx); + sync_dev->err_cnt++; + if (sync_dev->err_cnt == 1) + cam_sync_print_fence_table(); return -ENOMEM; + } CAM_DBG(CAM_SYNC, "Index location available at idx: %ld", idx); bit = test_and_set_bit(idx, sync_dev->bitmap); } while (bit); @@ -765,6 +786,7 @@ static int cam_sync_open(struct file *filep) CAM_ERR(CAM_SYNC, "Sync device NULL"); return -ENODEV; } + sync_dev->err_cnt = 0; mutex_lock(&sync_dev->table_lock); if (sync_dev->open_cnt >= 1) { @@ -797,6 +819,7 @@ static int cam_sync_close(struct file *filep) rc = -ENODEV; return rc; } + sync_dev->err_cnt = 0; mutex_lock(&sync_dev->table_lock); sync_dev->open_cnt--; if (!sync_dev->open_cnt) { @@ -972,6 +995,7 @@ static int cam_sync_probe(struct platform_device *pdev) if (!sync_dev) return -ENOMEM; + sync_dev->err_cnt = 0; mutex_init(&sync_dev->table_lock); spin_lock_init(&sync_dev->cam_sync_eventq_lock); diff --git a/drivers/media/platform/msm/ais/cam_sync/cam_sync_private.h b/drivers/media/platform/msm/ais/cam_sync/cam_sync_private.h index eb2fb34fc33c..c3cb345a13fa 100644 --- a/drivers/media/platform/msm/ais/cam_sync/cam_sync_private.h +++ b/drivers/media/platform/msm/ais/cam_sync/cam_sync_private.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -184,6 +184,7 @@ struct cam_signalable_info { * @work_queue : Work queue used for dispatching kernel callbacks * @cam_sync_eventq : Event queue used to dispatch user payloads to user space * @bitmap : Bitmap representation of all sync objects + * @err_cnt : Error counter to dump fence table */ struct sync_device { struct video_device *vdev; @@ -197,6 +198,7 @@ struct sync_device { struct v4l2_fh *cam_sync_eventq; spinlock_t cam_sync_eventq_lock; DECLARE_BITMAP(bitmap, CAM_SYNC_MAX_OBJS); + int err_cnt; }; -- GitLab From 7e442017a740140d410a0b57f4840f373fa5f6c8 Mon Sep 17 00:00:00 2001 From: Rishabh Bhatnagar Date: Fri, 24 May 2019 17:00:58 -0700 Subject: [PATCH 0581/1121] esoc: Change the toggle delay for external modem. Minimum toggle delay needed to ensure reset occurs correctly is 120ms. Change the minimum bound of usleep_range to 120ms. Change-Id: I3a2a4301787ff5032698adc979cbf57153ecacfc Signed-off-by: Rishabh Bhatnagar --- drivers/esoc/esoc-mdm-pon.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/esoc/esoc-mdm-pon.c b/drivers/esoc/esoc-mdm-pon.c index e1e335226867..6e75fb5a4dbd 100644 --- a/drivers/esoc/esoc-mdm-pon.c +++ b/drivers/esoc/esoc-mdm-pon.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2015, 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2015, 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -62,7 +62,7 @@ static int sdx50m_toggle_soft_reset(struct mdm_ctrl *mdm, bool atomic) * Allow PS hold assert to be detected */ if (!atomic) - usleep_range(80000,180000); + usleep_range(120000, 180000); else /* * The flow falls through this path as a part of the -- GitLab From b632009cc386a28efa9e56db428b8b5319fc30d3 Mon Sep 17 00:00:00 2001 From: Nirmal Kumar Date: Fri, 14 Jun 2019 09:01:22 -0700 Subject: [PATCH 0582/1121] ARM: dts: msm: fix compile warning related to mhi node Fix avoid_default_addr_size warning by setting address and size for device tree property. Change-Id: I90d625e6c8289f3b1e54c9502c066e47a7777540 Signed-off-by: Nirmal Kumar Venkatesan --- arch/arm64/boot/dts/qcom/sm8150-mhi.dtsi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sm8150-mhi.dtsi b/arch/arm64/boot/dts/qcom/sm8150-mhi.dtsi index f59f5e7f4769..9f53e564ccdf 100644 --- a/arch/arm64/boot/dts/qcom/sm8150-mhi.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150-mhi.dtsi @@ -13,6 +13,8 @@ &pcie_rc1 { reg = <0 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; mhi_0: qcom,mhi@0 { reg = <0 0 0 0 0 >; @@ -399,6 +401,9 @@ }; mhi_events { + #address-cells = <1>; + #size-cells = <0>; + mhi_event@0 { mhi,num-elements = <32>; mhi,intmod = <1>; @@ -547,6 +552,8 @@ &pcie_rc0 { reg = <0 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; mhi_1: qcom,mhi@0 { reg = <0 0 0 0 0 >; @@ -940,6 +947,9 @@ }; mhi_events { + #address-cells = <1>; + #size-cells = <0>; + mhi_event@0 { mhi,num-elements = <32>; mhi,intmod = <1>; -- GitLab From 9831fedf9eb5040e17141fb51e8cce255bd6e6ff Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Fri, 31 May 2019 18:53:38 +0530 Subject: [PATCH 0583/1121] ARM: msm: dts: Add reset clocks for sm8150 The clocks are used to reset the ahb2axi bridge in video hardware. Change-Id: Id8984201a7b3c093919ec946bd1de61b711b7f80 Signed-off-by: Manikanta Kanamarlapudi --- arch/arm64/boot/dts/qcom/sm8150-vidc.dtsi | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sm8150-vidc.dtsi b/arch/arm64/boot/dts/qcom/sm8150-vidc.dtsi index 359ef4332885..371859ade666 100644 --- a/arch/arm64/boot/dts/qcom/sm8150-vidc.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150-vidc.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018 - 2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -45,8 +45,11 @@ "core_clk", "vcodec_clk", "cvp_clk"; resets = <&clock_gcc GCC_VIDEO_AXIC_CLK_BCR>, - <&clock_videocc VIDEO_CC_MVSC_CORE_CLK_BCR>; - reset-names = "video_axi_reset", "video_core_reset"; + <&clock_videocc VIDEO_CC_MVSC_CORE_CLK_BCR>, + <&clock_gcc GCC_VIDEO_AXI0_CLK_BCR>, + <&clock_gcc GCC_VIDEO_AXI1_CLK_BCR>; + reset-names = "video_axi_reset", "video_core_reset", + "video_axi0_reset", "video_axi1_reset"; qcom,clock-configs = <0x0 0x0 0x0 0x1 0x1 0x1>; qcom,allowed-clock-rates = <225000000 300000000 -- GitLab From e59be603bce240a2d21092a151e69cdafb2938f2 Mon Sep 17 00:00:00 2001 From: Jhansi Konathala Date: Thu, 9 May 2019 12:23:01 +0530 Subject: [PATCH 0584/1121] ARM: dts: msm: Add soundcard device node in sdxprairie dtsi files Add soundcard device node in sdxprairie-cdp-cpe.dtsi and pinctrl change in sdxprairie-wcd.dtsi. CRs-Fixed: 2438905 Change-Id: I9d73e6bf069804c91671dfe5c7ff9a534fb26e62 Signed-off-by: Jhansi Konathala --- arch/arm64/boot/dts/qcom/sdxprairie-cdp-cpe.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdxprairie-cdp-cpe.dtsi b/arch/arm64/boot/dts/qcom/sdxprairie-cdp-cpe.dtsi index f4f6843b16e4..2a33ad562530 100644 --- a/arch/arm64/boot/dts/qcom/sdxprairie-cdp-cpe.dtsi +++ b/arch/arm64/boot/dts/qcom/sdxprairie-cdp-cpe.dtsi @@ -16,3 +16,7 @@ &qnand_1 { status = "ok"; }; + +&wsa881x_0214 { + qcom,spkr-sd-n-node = <&wsa_spkr_wcd_sd1>; +}; -- GitLab From 111c3ba044d188e749c6c47aa77b9286bf35d4d5 Mon Sep 17 00:00:00 2001 From: Ghanim Fodi Date: Tue, 11 Jun 2019 15:34:38 +0300 Subject: [PATCH 0585/1121] msm: ipa: Save GSI 2.0 test bus information GSI 2.0 added more test buses that can be saved on panic handler. This change saves them. Change-Id: I1ea693bf5f5f4c5c144df054fe1aa35df3a8dd4b Signed-off-by: Ghanim Fodi --- drivers/platform/msm/ipa/ipa_v3/dump/ipa_reg_dump.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/platform/msm/ipa/ipa_v3/dump/ipa_reg_dump.h b/drivers/platform/msm/ipa/ipa_v3/dump/ipa_reg_dump.h index 29b7a7256b85..5fe97e4c2981 100644 --- a/drivers/platform/msm/ipa/ipa_v3/dump/ipa_reg_dump.h +++ b/drivers/platform/msm/ipa/ipa_v3/dump/ipa_reg_dump.h @@ -83,6 +83,8 @@ #define HWIO_GSI_DEBUG_TEST_BUS_SELECTOR_RD_WR_2 (0x35) #define HWIO_GSI_DEBUG_TEST_BUS_SELECTOR_RD_WR_3 (0x36) #define HWIO_GSI_DEBUG_TEST_BUS_SELECTOR_CSR (0x3A) +#define HWIO_GSI_DEBUG_TEST_BUS_SELECTOR_SDMA_0 (0x3C) +#define HWIO_GSI_DEBUG_TEST_BUS_SELECTOR_SDMA_1 (0x3D) #define IPA_DEBUG_TESTBUS_DEF_EXTERNAL 50 #define IPA_DEBUG_TESTBUS_DEF_INTERNAL 6 @@ -937,6 +939,8 @@ static u32 ipa_reg_save_gsi_ch_test_bus_selector_array[] = { HWIO_GSI_DEBUG_TEST_BUS_SELECTOR_RD_WR_2, HWIO_GSI_DEBUG_TEST_BUS_SELECTOR_RD_WR_3, HWIO_GSI_DEBUG_TEST_BUS_SELECTOR_CSR, + HWIO_GSI_DEBUG_TEST_BUS_SELECTOR_SDMA_0, + HWIO_GSI_DEBUG_TEST_BUS_SELECTOR_SDMA_1, }; /* -- GitLab From 5cc2fd9f7ab7a00bc0e6778d168b96059e834dd6 Mon Sep 17 00:00:00 2001 From: Sahil Chandna Date: Wed, 24 Apr 2019 19:07:16 +0530 Subject: [PATCH 0586/1121] power_supply: Add properties to support PPS constant current(CC) mode Add power supply properties to support PPS CC mode charging for dual charge pumps with MID-VBAT configuration, these properties are set from user space. Change-Id: Ia2d467255818dbaaf2d87f56aae39584368772ce Signed-off-by: Sahil Chandna --- drivers/power/supply/power_supply_sysfs.c | 4 ++++ include/linux/power_supply.h | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/drivers/power/supply/power_supply_sysfs.c b/drivers/power/supply/power_supply_sysfs.c index 34ec8a565d89..760923cef852 100644 --- a/drivers/power/supply/power_supply_sysfs.c +++ b/drivers/power/supply/power_supply_sysfs.c @@ -399,6 +399,10 @@ static struct device_attribute power_supply_attrs[] = { POWER_SUPPLY_ATTR(voltage_max_limit), POWER_SUPPLY_ATTR(real_capacity), POWER_SUPPLY_ATTR(esr_sw_control), + POWER_SUPPLY_ATTR(force_main_icl), + POWER_SUPPLY_ATTR(force_main_fcc), + POWER_SUPPLY_ATTR(comp_clamp_level), + POWER_SUPPLY_ATTR(adapter_cc_mode), /* Charge pump properties */ POWER_SUPPLY_ATTR(cp_status1), POWER_SUPPLY_ATTR(cp_status2), diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h index 8ae999f3f218..34de20f36285 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h @@ -337,6 +337,10 @@ enum power_supply_property { POWER_SUPPLY_PROP_VOLTAGE_MAX_LIMIT, POWER_SUPPLY_PROP_REAL_CAPACITY, POWER_SUPPLY_PROP_ESR_SW_CONTROL, + POWER_SUPPLY_PROP_FORCE_MAIN_ICL, + POWER_SUPPLY_PROP_FORCE_MAIN_FCC, + POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL, + POWER_SUPPLY_PROP_ADAPTER_CC_MODE, /* Charge pump properties */ POWER_SUPPLY_PROP_CP_STATUS1, POWER_SUPPLY_PROP_CP_STATUS2, -- GitLab From 742e2dd3c09a1fe99b0acebf0dec8fabf3759383 Mon Sep 17 00:00:00 2001 From: Akhil P Oommen Date: Fri, 7 Jun 2019 15:27:52 +0530 Subject: [PATCH 0587/1121] msm: kgsl: Improve GMU firmware loading time Doing a regwrite of one dword with barrier over a loop is very inefficient for block writes to an I/O mapped memory. Use memcpy_toio() to improve this since it is better for block copy to io memory. Profiled data of load_gmu_fw() over 400 iterations: Old:- min:3.6ms max:35ms mean:21ms New:- min:0.55ms max:1.11ms mean:1.02ms Change-Id: I21aa6145caeeb777f27b90fe091c50af49948722 Signed-off-by: Akhil P Oommen --- drivers/gpu/msm/adreno_a6xx_gmu.c | 14 +++----------- drivers/gpu/msm/kgsl_gmu_core.c | 18 +++++++++++++++++- drivers/gpu/msm/kgsl_gmu_core.h | 12 +++++++++++- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/msm/adreno_a6xx_gmu.c b/drivers/gpu/msm/adreno_a6xx_gmu.c index 28cf1812d2ac..cd17a35bacc6 100644 --- a/drivers/gpu/msm/adreno_a6xx_gmu.c +++ b/drivers/gpu/msm/adreno_a6xx_gmu.c @@ -478,15 +478,12 @@ static int _load_legacy_gmu_fw(struct kgsl_device *device, struct gmu_device *gmu) { const struct firmware *fw = gmu->fw_image; - u32 *fwptr = (u32 *)fw->data; - int i; if (fw->size > MAX_GMUFW_SIZE) return -EINVAL; - for (i = 0; i < (fw->size >> 2); i++) - gmu_core_regwrite(device, - A6XX_GMU_CM3_ITCM_START + i, fwptr[i]); + gmu_core_blkwrite(device, A6XX_GMU_CM3_ITCM_START, fw->data, + fw->size); /* Proceed only after the FW is written */ wmb(); @@ -497,7 +494,6 @@ static int load_gmu_fw(struct kgsl_device *device) { struct gmu_device *gmu = KGSL_GMU_DEVICE(device); uint8_t *fw = (uint8_t *)gmu->fw_image->data; - int j; int tcm_addr; struct gmu_block_header *blk; struct gmu_memdesc *md; @@ -523,8 +519,6 @@ static int load_gmu_fw(struct kgsl_device *device) } if (md->mem_type == GMU_ITCM || md->mem_type == GMU_DTCM) { - uint32_t *fwptr = (uint32_t *)fw; - tcm_addr = (blk->addr - (uint32_t)md->gmuaddr) / sizeof(uint32_t); @@ -533,9 +527,7 @@ static int load_gmu_fw(struct kgsl_device *device) else tcm_addr += A6XX_GMU_CM3_DTCM_START; - for (j = 0; j < blk->size / sizeof(uint32_t); j++) - gmu_core_regwrite(device, tcm_addr + j, - fwptr[j]); + gmu_core_blkwrite(device, tcm_addr, fw, blk->size); } else { uint32_t offset = blk->addr - (uint32_t)md->gmuaddr; diff --git a/drivers/gpu/msm/kgsl_gmu_core.c b/drivers/gpu/msm/kgsl_gmu_core.c index 6e98bb5eead1..dfea370220e9 100644 --- a/drivers/gpu/msm/kgsl_gmu_core.c +++ b/drivers/gpu/msm/kgsl_gmu_core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -243,6 +243,22 @@ void gmu_core_regwrite(struct kgsl_device *device, unsigned int offsetwords, __raw_writel(value, reg); } +void gmu_core_blkwrite(struct kgsl_device *device, unsigned int offsetwords, + const void *buffer, size_t size) +{ + void __iomem *base; + + if (!gmu_core_is_register_offset(device, offsetwords)) { + WARN(1, "Out of bounds register write: 0x%x\n", offsetwords); + return; + } + + offsetwords -= device->gmu_core.gmu2gpu_offset; + base = device->gmu_core.reg_virt + (offsetwords << 2); + + memcpy_toio(base, buffer, size); +} + void gmu_core_regrmw(struct kgsl_device *device, unsigned int offsetwords, unsigned int mask, unsigned int bits) diff --git a/drivers/gpu/msm/kgsl_gmu_core.h b/drivers/gpu/msm/kgsl_gmu_core.h index 52395b76b995..23a711865ad5 100644 --- a/drivers/gpu/msm/kgsl_gmu_core.h +++ b/drivers/gpu/msm/kgsl_gmu_core.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -209,6 +209,16 @@ void gmu_core_regread(struct kgsl_device *device, unsigned int offsetwords, unsigned int *value); void gmu_core_regwrite(struct kgsl_device *device, unsigned int offsetwords, unsigned int value); + +/** + * gmu_core_blkwrite() - Do a bulk I/O write to GMU + * @device: Pointer to the kgsl device + * @offsetwords: Destination dword offset + * @buffer: Pointer to the source buffer + * @size: Number of bytes to copy + */ +void gmu_core_blkwrite(struct kgsl_device *device, unsigned int offsetwords, + const void *buffer, size_t size); void gmu_core_regrmw(struct kgsl_device *device, unsigned int offsetwords, unsigned int mask, unsigned int bits); const char *gmu_core_oob_type_str(enum oob_request req); -- GitLab From 3ae54832749de26d2aa904ce6ecab505df9d90e8 Mon Sep 17 00:00:00 2001 From: vagdhan kumar kanukurthi Date: Mon, 13 May 2019 10:48:54 +0530 Subject: [PATCH 0588/1121] ARM: dts: msm: Add pcie0 for sa6155p vm Add pcie0 for WLAN on sa6155p virtual machine. Change-Id: I38deb15161abf3ba065745f91a5571a8aaf66df9 Signed-off-by: Vagdhan Kanukurthi --- arch/arm64/boot/dts/qcom/sa6155p-vm-pcie.dtsi | 245 ++++++++++++++++++ arch/arm64/boot/dts/qcom/sa6155p-vm.dts | 8 + arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi | 59 +++++ 3 files changed, 312 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/sa6155p-vm-pcie.dtsi diff --git a/arch/arm64/boot/dts/qcom/sa6155p-vm-pcie.dtsi b/arch/arm64/boot/dts/qcom/sa6155p-vm-pcie.dtsi new file mode 100644 index 000000000000..ff0e56593e78 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sa6155p-vm-pcie.dtsi @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +&soc { + pcie0: qcom,pcie@1c08000 { + compatible = "qcom,pci-msm"; + cell-index = <0>; + + reg = <0x1c08000 0x4000>, + <0x1c0e000 0x1000>, + <0x40000000 0xf1d>, + <0x40000f20 0xa8>, + <0x40001000 0x1000>, + <0x40100000 0x100000>, + <0x40200000 0x100000>, + <0x40300000 0x1fd00000>; + + reg-names = "parf", "phy", "dm_core", "elbi", + "iatu", "conf", "io", "bars"; + + #address-cells = <3>; + #size-cells = <2>; + ranges = <0x01000000 0x0 0x40200000 0x40200000 0x0 0x100000>, + <0x02000000 0x0 0x40300000 0x40300000 0x0 0x1fd00000>; + interrupts = <0 140 0>, <0 149 0>, <0 150 0>, <0 151 0>, + <0 152 0>; + interrupt-names = "int_global_int", "int_a", "int_b", "int_c", + "int_d"; + + qcom,phy-sequence = <0x0800 0x01 0x0 + 0x0804 0x03 0x0 + 0x0034 0x18 0x0 + 0x0038 0x10 0x0 + 0x0294 0x06 0x0 + 0x00c8 0x01 0x0 + 0x0128 0x00 0x0 + 0x0144 0xff 0x0 + 0x0148 0x1f 0x0 + 0x0070 0x0f 0x0 + 0x0048 0x0f 0x0 + 0x0178 0x00 0x0 + 0x019c 0x01 0x0 + 0x018c 0x20 0x0 + 0x0184 0x0a 0x0 + 0x00b4 0x20 0x0 + 0x000c 0x09 0x0 + 0x00ac 0x04 0x0 + 0x00d0 0x82 0x0 + 0x00e4 0x03 0x0 + 0x00e0 0x55 0x0 + 0x00dc 0x55 0x0 + 0x0054 0x00 0x0 + 0x0050 0x0d 0x0 + 0x004c 0x04 0x0 + 0x0174 0x33 0x0 + 0x003c 0x02 0x0 + 0x0040 0x1f 0x0 + 0x0078 0x0b 0x0 + 0x0084 0x16 0x0 + 0x0090 0x28 0x0 + 0x010c 0x00 0x0 + 0x0108 0x80 0x0 + 0x0010 0x01 0x0 + 0x001c 0x31 0x0 + 0x0020 0x01 0x0 + 0x0014 0x02 0x0 + 0x0018 0x00 0x0 + 0x0024 0x2f 0x0 + 0x0028 0x19 0x0 + 0x0268 0x45 0x0 + 0x0194 0x06 0x0 + 0x024c 0x02 0x0 + 0x02ac 0x12 0x0 + 0x0510 0x1c 0x0 + 0x051c 0x14 0x0 + 0x04d8 0x01 0x0 + 0x04dc 0x00 0x0 + 0x04e0 0xdb 0x0 + 0x0448 0x4b 0x0 + 0x041c 0x04 0x0 + 0x0410 0x04 0x0 + 0x0074 0x19 0x0 + 0x0854 0x04 0x0 + 0x09ac 0x00 0x0 + 0x08a0 0x40 0x0 + 0x09e0 0x00 0x0 + 0x09dc 0x40 0x0 + 0x09a8 0x00 0x0 + 0x08a4 0x40 0x0 + 0x08a8 0x73 0x0 + 0x0518 0x99 0x0 + 0x0824 0x15 0x0 + 0x0828 0x0e 0x0 + 0x09b0 0x07 0x0 + 0x0800 0x00 0x0 + 0x0808 0x03 0x0>; + + pinctrl-names = "default"; + pinctrl-0 = <&pcie0_clkreq_default + &pcie0_perst_default + &pcie0_wake_default>; + + perst-gpio = <&tlmm 101 0>; + wake-gpio = <&tlmm 100 0>; + + gdsc-vdd-supply = <&pcie_0_gdsc>; + vreg-1.8-supply = <&pm6155_1_l12>; + vreg-0.9-supply = <&pm6155_1_l5>; + + vreg-cx-supply = <&VDD_CX_LEVEL>; + + qcom,vreg-1.8-voltage-level = <1800000 1800000 24000>; + qcom,vreg-0.9-voltage-level = <925000 925000 24000>; + qcom,vreg-cx-voltage-level = ; + + msi-parent = <&pcie0_msi>; + + qcom,no-l0s-supported; + qcom,no-l1-supported; + qcom,no-l1ss-supported; + qcom,no-aux-clk-sync; + + qcom,max-link-speed = <0x2>; + + qcom,ep-latency = <10>; + + qcom,slv-addr-space-size = <0x20000000>; + + qcom,phy-status-offset = <0x974>; + qcom,phy-status-bit = <6>; + qcom,phy-power-down-offset = <0x804>; + + qcom,boot-option = <0x1>; + + linux,pci-domain = <0>; + + qcom,pcie-phy-ver = <0x10>; + qcom,use-19p2mhz-aux-clk; + + qcom,smmu-sid-base = <0x0400>; + + iommu-map = <0x0 &apps_smmu 0x0400 0x1>, + <0x100 &apps_smmu 0x0401 0x1>, + <0x200 &apps_smmu 0x0402 0x1>, + <0x300 &apps_smmu 0x0403 0x1>, + <0x400 &apps_smmu 0x0404 0x1>, + <0x500 &apps_smmu 0x0405 0x1>, + <0x600 &apps_smmu 0x0406 0x1>, + <0x700 &apps_smmu 0x0407 0x1>, + <0x800 &apps_smmu 0x0408 0x1>, + <0x900 &apps_smmu 0x0409 0x1>, + <0xa00 &apps_smmu 0x040a 0x1>, + <0xb00 &apps_smmu 0x040b 0x1>, + <0xc00 &apps_smmu 0x040c 0x1>, + <0xd00 &apps_smmu 0x040d 0x1>, + <0xe00 &apps_smmu 0x040e 0x1>, + <0xf00 &apps_smmu 0x040f 0x1>; + + qcom,msm-bus,name = "pcie0"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <45 512 0 0>, + <45 512 500 800>; + + clocks = <&clock_virt GCC_PCIE_0_PIPE_CLK>, + <&clock_rpmh RPMH_CXO_CLK>, + <&clock_virt GCC_PCIE_0_AUX_CLK>, + <&clock_virt GCC_PCIE_0_CFG_AHB_CLK>, + <&clock_virt GCC_PCIE_0_MSTR_AXI_CLK>, + <&clock_virt GCC_PCIE_0_SLV_AXI_CLK>, + <&clock_virt GCC_PCIE_0_CLKREF_CLK>, + <&clock_virt GCC_PCIE_0_SLV_Q2A_AXI_CLK>, + <&clock_virt GCC_PCIE0_PHY_REFGEN_CLK>, + <&clock_virt GCC_PCIE_PHY_AUX_CLK>; + + clock-names = "pcie_0_pipe_clk", "pcie_0_ref_clk_src", + "pcie_0_aux_clk", "pcie_0_cfg_ahb_clk", + "pcie_0_mstr_axi_clk", "pcie_0_slv_axi_clk", + "pcie_0_ldo", "pcie_0_slv_q2a_axi_clk", + "pcie_phy_refgen_clk", "pcie_phy_aux_clk"; + + max-clock-frequency-hz = <0>, <0>, <19200000>, <0>, <0>, <0>, + <0>, <0>, <0>, <0>, <100000000>, <0>; + + resets = <&clock_virt GCC_PCIE_0_BCR>, + <&clock_virt GCC_PCIE_0_PHY_BCR>; + + reset-names = "pcie_0_core_reset", + "pcie_0_phy_reset"; + status = "disabled"; + }; + + pcie0_msi: qcom,pcie0_msi@17a00040 { + compatible = "qcom,pci-msi"; + msi-controller; + reg = <0x17a00040 0x0>; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + status = "disabled"; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/sa6155p-vm.dts b/arch/arm64/boot/dts/qcom/sa6155p-vm.dts index 743ddf095a7d..3c98b8ac0a0c 100644 --- a/arch/arm64/boot/dts/qcom/sa6155p-vm.dts +++ b/arch/arm64/boot/dts/qcom/sa6155p-vm.dts @@ -37,3 +37,11 @@ &qusb_phy0 { status = "ok"; }; + +&pcie0_msi { + status = "ok"; +}; + +&pcie0 { + status = "ok"; +}; diff --git a/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi b/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi index 2fd175bb358a..9a271d717613 100644 --- a/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi @@ -14,6 +14,7 @@ #include "skeleton64.dtsi" #include #include +#include #include / { @@ -21,6 +22,10 @@ qcom,msm-name = "SA6155P"; qcom,msm-id = <377 0x0>; + aliases { + pci-domain0 = &pcie0; /* PCIe0 domain */ + }; + psci { compatible = "arm,psci-1.0"; method = "smc"; @@ -116,6 +121,11 @@ #reset-cells = <1>; }; + clock_rpmh: qcom,rpmh { + compatible = "qcom,dummycc"; + #clock-cells = <1>; + }; + qcom,ion { compatible = "qcom,msm-ion"; #address-cells = <1>; @@ -347,6 +357,54 @@ qcom,no-clock-support; qcom,qsee-reentrancy-support = <2>; }; + + pm6155_1_l10: regulator-pm6155-1-l10 { + compatible = "qcom,stub-regulator"; + regulator-name = "pm6155_1_l10"; + regulator-min-microvolt = <2950000>; + regulator-max-microvolt = <3312000>; + status = "ok"; + }; + + pm6155_1_l2: regulator-pm6155-1-l2 { + compatible = "qcom,stub-regulator"; + regulator-name = "pm6155_1_l2"; + regulator-min-microvolt = <1650000>; + regulator-max-microvolt = <3100000>; + status = "ok"; + }; + + pm6155_1_l12: regulator-pm6155-1-l12 { + compatible = "qcom,stub-regulator"; + regulator-name = "pm6155_1_l12"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1890000>; + status = "ok"; + }; + + pm6155_1_l5: regulator-pm6155-1-l5 { + compatible = "qcom,stub-regulator"; + regulator-name = "pm6155_1_l5"; + regulator-min-microvolt = <875000>; + regulator-max-microvolt = <975000>; + status = "ok"; + }; + + VDD_CX_LEVEL: VDD_MX_LEVEL: S2A_LEVEL: + pm6155_1_s2_level: regulator-pm6155-1-s2-level { + compatible = "qcom,stub-regulator"; + regulator-name = "pm6155_1_s2_level"; + regulator-min-microvolt + = ; + regulator-max-microvolt + = ; + }; + + pcie_0_gdsc: pcie_0_gdsc { + compatible = "qcom,stub-regulator"; + regulator-name = "pcie_0_gdsc"; + status = "okay"; + }; }; #include "sa6155p-vm-pinctrl.dtsi" @@ -354,3 +412,4 @@ #include "sa6155p-vm-qupv3.dtsi" #include "sa6155p-vm-usb.dtsi" #include "sa8155-vm-audio.dtsi" +#include "sa6155p-vm-pcie.dtsi" -- GitLab From f63596bf70de68a07e1d357e92beb06e3153b5fe Mon Sep 17 00:00:00 2001 From: Srikanth Uyyala Date: Fri, 14 Jun 2019 17:56:16 +0530 Subject: [PATCH 0589/1121] mm-camera2:isp2: Remove the lock during the stream config Buffer manager lock is acquired during stream config, core lock is enough during stream configuration. Change-Id: I5686c9f16afbf83e711998d8617d34efb81b7bf8 Signed-off-by: Srikanth Uyyala --- drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c index 5afb8b70eb33..e38cf5eb1081 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c @@ -912,9 +912,7 @@ static long msm_isp_ioctl_unlocked(struct v4l2_subdev *sd, case VIDIOC_MSM_ISP_CFG_STREAM: mutex_lock(&vfe_dev->core_mutex); MSM_ISP_DUAL_VFE_MUTEX_LOCK(vfe_dev); - mutex_lock(&vfe_dev->buf_mgr->lock); rc = msm_isp_cfg_axi_stream(vfe_dev, arg); - mutex_unlock(&vfe_dev->buf_mgr->lock); MSM_ISP_DUAL_VFE_MUTEX_UNLOCK(vfe_dev); mutex_unlock(&vfe_dev->core_mutex); break; @@ -1031,9 +1029,7 @@ static long msm_isp_ioctl_unlocked(struct v4l2_subdev *sd, case VIDIOC_MSM_ISP_CFG_STATS_STREAM: mutex_lock(&vfe_dev->core_mutex); MSM_ISP_DUAL_VFE_MUTEX_LOCK(vfe_dev); - mutex_lock(&vfe_dev->buf_mgr->lock); rc = msm_isp_cfg_stats_stream(vfe_dev, arg); - mutex_unlock(&vfe_dev->buf_mgr->lock); MSM_ISP_DUAL_VFE_MUTEX_UNLOCK(vfe_dev); mutex_unlock(&vfe_dev->core_mutex); break; -- GitLab From b95f2ce745465ae45c5bb0b22b86755331448dad Mon Sep 17 00:00:00 2001 From: Pavankumar Kondeti Date: Mon, 17 Jun 2019 15:33:34 +0530 Subject: [PATCH 0590/1121] sched/fair: Prevent tick path active migration to the same CPU The misfit task running on the lower capacity CPUs are migrated to higher capacity CPUs from the tick path. It is not guaranteed that find_energy_efficient_cpu() returns a higher capacity CPU for the tick path active migration. It may return the previous CPU or another CPU that has the same capacity as the previous CPU. There is an explicit check in check_for_migration() to allow the migration from lower capacity CPU to higher capacity CPU. However there is a remote possibility of previous CPU capacity being changed at the same time and we end up queueing the active migration work on the previous CPU. This results in a kernel panic later when the migration work actually runs. Prevent this by explicitly checking the new_cpu against the previous CPU. Change-Id: I20b25799f388ff609bff7390cd280cf17790adb7 Signed-off-by: Pavankumar Kondeti --- kernel/sched/fair.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 42379e6979da..26998ea05d8b 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -13016,13 +13016,13 @@ void check_for_migration(struct rq *rq, struct task_struct *p) rcu_read_lock(); new_cpu = find_energy_efficient_cpu(sd, p, cpu, prev_cpu, 0); rcu_read_unlock(); - if ((new_cpu != -1) && - (capacity_orig_of(new_cpu) > capacity_orig_of(cpu))) { + if ((new_cpu != prev_cpu) && (capacity_orig_of(new_cpu) > + capacity_orig_of(prev_cpu))) { active_balance = kick_active_balance(rq, p, new_cpu); if (active_balance) { mark_reserved(new_cpu); raw_spin_unlock(&migration_lock); - stop_one_cpu_nowait(cpu, + stop_one_cpu_nowait(prev_cpu, active_load_balance_cpu_stop, rq, &rq->active_balance_work); return; -- GitLab From 296af98c53d1cd6afbf2feca45d36886862bb000 Mon Sep 17 00:00:00 2001 From: Mao Jinlong Date: Wed, 12 Jun 2019 13:10:24 +0530 Subject: [PATCH 0591/1121] ARM: dts: msm: Remove s1 bypass for atoll Remove s1 bypass for atoll to make smmu function work. And add the mask for the sid. Change-Id: Ia30a201fa62a2332d7d231c393ea10cc13aa0976 Signed-off-by: Mao Jinlong --- arch/arm64/boot/dts/qcom/atoll-coresight.dtsi | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/atoll-coresight.dtsi b/arch/arm64/boot/dts/qcom/atoll-coresight.dtsi index feac82b9d69e..c9367930754e 100644 --- a/arch/arm64/boot/dts/qcom/atoll-coresight.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll-coresight.dtsi @@ -2250,9 +2250,8 @@ <0x6064000 0x15000>; reg-names = "tmc-base", "bam-base"; - qcom,smmu-s1-bypass; - iommus = <&apps_smmu 0x04a0 0>, - <&apps_smmu 0x0480 0>; + iommus = <&apps_smmu 0x04a0 0x20>, + <&apps_smmu 0x0480 0x20>; coresight-ctis = <&cti0 &cti0>; coresight-csr = <&csr>; -- GitLab From 5f84f4ada195bf49b6972bcc8f2d4eff7025b1c3 Mon Sep 17 00:00:00 2001 From: Dinesh K Garg Date: Sun, 16 Jun 2019 18:35:26 -0700 Subject: [PATCH 0592/1121] msm: mink: handle interrupt while waiting for cb response Currently, CB request thread blocks interrupts while waiting for response to come. This causes problem when client is killed focibly. Allowing interrupts to come and handle interruption gracefully. Change-Id: Id1a9a594b7c8ab1b10d5c9a895889ce3666bd862 Signed-off-by: Dinesh K Garg --- drivers/soc/qcom/smcinvoke.c | 39 ++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/drivers/soc/qcom/smcinvoke.c b/drivers/soc/qcom/smcinvoke.c index 7f95bb279de3..ef899cd55526 100644 --- a/drivers/soc/qcom/smcinvoke.c +++ b/drivers/soc/qcom/smcinvoke.c @@ -209,6 +209,7 @@ struct smcinvoke_cb_txn { size_t cb_req_bytes; struct file **filp_to_release; struct hlist_node hash; + struct kref ref_cnt; }; struct smcinvoke_server_info { @@ -456,6 +457,15 @@ static void release_tzhandles(const int32_t *tzhandles, size_t len) mutex_unlock(&g_smcinvoke_lock); } +static void delete_cb_txn(struct kref *kref) +{ + struct smcinvoke_cb_txn *cb_txn = container_of(kref, + struct smcinvoke_cb_txn, ref_cnt); + + kfree(cb_txn->cb_req); + kfree(cb_txn); +} + static struct smcinvoke_cb_txn *find_cbtxn_locked( struct smcinvoke_server_info *server, uint32_t txn_id, int32_t state) @@ -470,6 +480,7 @@ static struct smcinvoke_cb_txn *find_cbtxn_locked( if (state == SMCINVOKE_REQ_PLACED) { /* pick up 1st req */ hash_for_each(server->reqs_table, i, cb_txn, hash) { + kref_get(&cb_txn->ref_cnt); hash_del(&cb_txn->hash); return cb_txn; } @@ -477,6 +488,7 @@ static struct smcinvoke_cb_txn *find_cbtxn_locked( hash_for_each_possible( server->responses_table, cb_txn, hash, txn_id) { if (cb_txn->txn_id == txn_id) { + kref_get(&cb_txn->ref_cnt); hash_del(&cb_txn->hash); return cb_txn; } @@ -833,7 +845,13 @@ static void process_tzcb_req(void *buf, size_t buf_len, struct file **arr_filp) if (buf_len < sizeof(struct smcinvoke_tzcb_req)) return; - cb_req = buf; + cb_req = kzalloc(buf_len, GFP_KERNEL); + if (!cb_req) { + ret = OBJECT_ERROR_KMEM; + goto out; + } + memcpy(cb_req, buf, buf_len); + /* check whether it is to be served by kernel or userspace */ if (TZHANDLE_IS_KERNEL_OBJ(cb_req->hdr.tzhandle)) { return process_kernel_obj(buf, buf_len); @@ -854,6 +872,7 @@ static void process_tzcb_req(void *buf, size_t buf_len, struct file **arr_filp) cb_txn->cb_req = cb_req; cb_txn->cb_req_bytes = buf_len; cb_txn->filp_to_release = arr_filp; + kref_init(&cb_txn->ref_cnt); mutex_lock(&g_smcinvoke_lock); srvr_info = find_cb_server_locked( @@ -867,9 +886,11 @@ static void process_tzcb_req(void *buf, size_t buf_len, struct file **arr_filp) hash_add(srvr_info->reqs_table, &cb_txn->hash, cb_txn->txn_id); mutex_unlock(&g_smcinvoke_lock); wake_up_interruptible(&srvr_info->req_wait_q); - wait_event(srvr_info->rsp_wait_q, + ret = wait_event_interruptible(srvr_info->rsp_wait_q, (cb_txn->state == SMCINVOKE_REQ_PROCESSED) || (srvr_info->state == SMCINVOKE_SERVER_STATE_DEFUNCT)); + if (ret) + pr_err("%s wait_event interrupted: ret = %d\n", __func__, ret); out: /* * If we are here, either req is processed or not @@ -877,17 +898,19 @@ static void process_tzcb_req(void *buf, size_t buf_len, struct file **arr_filp) * if not processed, we should set result with ret which should have * correct value that TZ/TA can understand */ + mutex_lock(&g_smcinvoke_lock); if (!cb_txn || (cb_txn->state != SMCINVOKE_REQ_PROCESSED)) { cb_req->result = ret; if (srvr_info && srvr_info->state == SMCINVOKE_SERVER_STATE_DEFUNCT && OBJECT_OP_METHODID(cb_req->hdr.op) == OBJECT_OP_RELEASE) { - mutex_lock(&g_smcinvoke_lock); release_tzhandle_locked(cb_req->hdr.tzhandle); - mutex_unlock(&g_smcinvoke_lock); } } - kfree(cb_txn); + hash_del(&cb_txn->hash); + memcpy(buf, cb_req, buf_len); + kref_put(&cb_txn->ref_cnt, delete_cb_txn); + mutex_unlock(&g_smcinvoke_lock); } static int marshal_out_invoke_req(const uint8_t *buf, uint32_t buf_size, @@ -1431,6 +1454,7 @@ static long process_accept_req(struct file *filp, unsigned int cmd, release_tzhandles(&cb_txn->cb_req->hdr.tzhandle, 1); cb_txn->state = SMCINVOKE_REQ_PROCESSED; + kref_put(&cb_txn->ref_cnt, delete_cb_txn); wake_up(&server_info->rsp_wait_q); /* * if marshal_out fails, we should let userspace release @@ -1447,7 +1471,8 @@ static long process_accept_req(struct file *filp, unsigned int cmd, ret = wait_event_interruptible(server_info->req_wait_q, !hash_empty(server_info->reqs_table)); if (ret) { - destroy_cb_server(server_obj->server_id); + pr_err("%s wait_event interrupted: ret = %d\n", + __func__, ret); goto out; } @@ -1463,12 +1488,14 @@ static long process_accept_req(struct file *filp, unsigned int cmd, if (ret) { cb_txn->cb_req->result = OBJECT_ERROR_UNAVAIL; cb_txn->state = SMCINVOKE_REQ_PROCESSED; + kref_put(&cb_txn->ref_cnt, delete_cb_txn); wake_up_interruptible(&server_info->rsp_wait_q); continue; } mutex_lock(&g_smcinvoke_lock); hash_add(server_info->responses_table, &cb_txn->hash, cb_txn->txn_id); + kref_put(&cb_txn->ref_cnt, delete_cb_txn); mutex_unlock(&g_smcinvoke_lock); ret = copy_to_user((void __user *)arg, &user_args, sizeof(struct smcinvoke_accept)); -- GitLab From 65e6fa5cbf17c033dd289d7fa5794a56c9ab90bc Mon Sep 17 00:00:00 2001 From: Ghanim Fodi Date: Mon, 17 Jun 2019 22:03:55 +0300 Subject: [PATCH 0593/1121] msm: ipa: Change qtimer gran_2 resolution to 1ms gran_2 is used for DPL time stamping where 1ms is needed. Change-Id: I299bc814778d19ca71c00e3ec118dca470abfbee Signed-off-by: Ghanim Fodi --- drivers/platform/msm/ipa/ipa_v3/ipa_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c index bd12c7fa6137..d9e33fc3a23e 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c @@ -3528,7 +3528,7 @@ static void ipa_cfg_qtime(void) memset(&gran_cfg, 0, sizeof(gran_cfg)); gran_cfg.gran_0 = IPA_TIMERS_TIME_GRAN_100_USEC; gran_cfg.gran_1 = IPA_TIMERS_TIME_GRAN_1_MSEC; - gran_cfg.gran_2 = IPA_TIMERS_TIME_GRAN_10_USEC; + gran_cfg.gran_2 = IPA_TIMERS_TIME_GRAN_1_MSEC; val = ipahal_read_reg(IPA_TIMERS_PULSE_GRAN_CFG); IPADBG("timer pulse granularity before cfg: 0x%x\n", val); ipahal_write_reg_fields(IPA_TIMERS_PULSE_GRAN_CFG, &gran_cfg); -- GitLab From 95817dd5aeecda9c9c9d5d9fb96d3f0957e581ae Mon Sep 17 00:00:00 2001 From: Subash Abhinov Kasiviswanathan Date: Mon, 17 Jun 2019 13:49:35 -0600 Subject: [PATCH 0594/1121] net: qualcomm: rmnet: Add headroom for all skbs queued to stack Packets in some path may have some header insertion required which is not supported if there is not enough headroom. Fixes the following splat- [ 254.966133] skbuff: skb_under_panic: text:ffffff9a73ed5e58 len:103 put:14 head:ffffffef13451a00 data:ffffffef134519fa tail:0x61 end:0x80 dev:wlan0 [ 254.967224] kernel BUG at net/core/skbuff.c:104! [ 254.967429] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP [ 254.967858] pc : skb_panic+0x48/0x50 [ 254.967883] lr : skb_panic+0x48/0x50 [ 254.968885] Call trace: [ 254.968901] skb_panic+0x48/0x50 [ 254.968913] skb_under_panic+0x14/0x18 [ 254.968924] skb_under_panic+0x0/0x18 [ 254.968941] eth_header+0x30/0xc8 [ 254.968959] neigh_resolve_output+0x134/0x188 [ 254.968978] ip6_finish_output2+0x464/0x658 [ 254.968989] ip6_finish_output+0x190/0x210 [ 254.968999] ip6_output+0xc0/0x1a8 [ 254.969018] ip6_local_out+0xe8/0x128 [ 254.969031] nf_dup_ipv6+0x220/0x230 [ 254.969049] tee_tg6+0x38/0x48 [ 254.969062] ip6t_do_table+0x2e4/0x648 [ 254.969077] ip6table_mangle_hook+0x148/0x180 [ 254.969091] nf_hook_slow+0x48/0xd8 [ 254.969101] ipv6_rcv+0x384/0x548 [ 254.969117] __netif_receive_skb_core+0x9c0/0xb80 [ 254.969129] process_backlog+0x14c/0x278 [ 254.969140] net_rx_action+0x114/0x470 [ 254.969159] __do_softirq+0x1f8/0x3ac [ 254.969176] irq_exit+0xd0/0xe0 [ 254.969191] handle_IPI+0x188/0x2a0 [ 254.969201] gic_handle_irq+0x130/0x1c0 [ 254.969213] el1_irq+0xb0/0x124 [ 254.969231] lpm_cpuidle_enter+0x4b0/0x4f8 [ 254.969243] cpuidle_enter_state+0x1cc/0x350 [ 254.969253] cpuidle_enter+0x18/0x20 [ 254.969268] do_idle+0x174/0x268 [ 254.969279] cpu_startup_entry+0x20/0x28 [ 254.969290] secondary_start_kernel+0x12c/0x138 CRs-fixed: 2469907 Change-Id: Id4c3f0092151b84593beccb4bae24495ae9f83c0 Signed-off-by: Subash Abhinov Kasiviswanathan --- drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c index a644809106fa..99206372e0d8 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c @@ -409,10 +409,12 @@ static struct sk_buff *rmnet_alloc_skb(struct rmnet_frag_descriptor *frag_desc, if (frag_desc->hdrs_valid) { u16 hdr_len = frag_desc->ip_len + frag_desc->trans_len; - head_skb = alloc_skb(hdr_len, GFP_ATOMIC); + head_skb = alloc_skb(hdr_len + RMNET_MAP_DEAGGR_HEADROOM, + GFP_ATOMIC); if (!head_skb) return NULL; + skb_reserve(head_skb, RMNET_MAP_DEAGGR_HEADROOM); skb_put_data(head_skb, frag_desc->hdr_ptr, hdr_len); skb_reset_network_header(head_skb); if (frag_desc->trans_len) @@ -431,9 +433,12 @@ static struct sk_buff *rmnet_alloc_skb(struct rmnet_frag_descriptor *frag_desc, /* Allocate enough space to avoid penalties in the stack * from __pskb_pull_tail() */ - head_skb = alloc_skb(256, GFP_ATOMIC); + head_skb = alloc_skb(256 + RMNET_MAP_DEAGGR_HEADROOM, + GFP_ATOMIC); if (!head_skb) return NULL; + + skb_reserve(head_skb, RMNET_MAP_DEAGGR_HEADROOM); } /* Add main fragment */ -- GitLab From 7cd9c57c0edc786c88994f62ba863cc0c646c7ee Mon Sep 17 00:00:00 2001 From: Conner Huff Date: Fri, 31 May 2019 12:00:06 -0700 Subject: [PATCH 0595/1121] net: qualcomm: rmnet: Dl marker v2 callbacks Modify the callbacks for Dl marker so that they can handle new qcmd field in dl marker v2 variant of. Accompanying rmnet modules will now register to the v2 callback interface variant. Change-Id: Ic242b2cdd9048f77864d514a846160aa08506de6 Signed-off-by: Conner Huff --- .../ethernet/qualcomm/rmnet/rmnet_config.h | 3 + .../net/ethernet/qualcomm/rmnet/rmnet_map.h | 30 +++++-- .../qualcomm/rmnet/rmnet_map_command.c | 89 ++++++++++++++++--- .../ethernet/qualcomm/rmnet/rmnet_private.h | 9 +- .../net/ethernet/qualcomm/rmnet/rmnet_vnd.c | 3 + 5 files changed, 115 insertions(+), 19 deletions(-) diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h index 2eb323fc48b8..c7a2e8a0f4d3 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h @@ -29,6 +29,9 @@ struct rmnet_endpoint { }; struct rmnet_port_priv_stats { + u64 dl_hdr_last_qmap_vers; + u64 dl_hdr_last_ep_id; + u64 dl_hdr_last_trans_id; u64 dl_hdr_last_seq; u64 dl_hdr_last_bytes; u64 dl_hdr_last_pkts; diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h index 17d8252500df..07164d952384 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h @@ -127,10 +127,12 @@ struct rmnet_map_ul_csum_header { } __aligned(1); struct rmnet_map_control_command_header { - u8 command_name; - u8 cmd_type:2; - u8 reserved:6; - u16 reserved2; + u8 command_name; + u8 cmd_type:2; + u8 reserved:5; + u8 e:1; + u16 source_id:15; + u16 ext:1; u32 transaction_id; } __aligned(1); @@ -176,8 +178,18 @@ struct rmnet_map_dl_ind_trl { struct rmnet_map_dl_ind { u8 priority; - void (*dl_hdr_handler)(struct rmnet_map_dl_ind_hdr *); - void (*dl_trl_handler)(struct rmnet_map_dl_ind_trl *); + union { + void (*dl_hdr_handler)(struct rmnet_map_dl_ind_hdr *); + void (*dl_hdr_handler_v2)(struct rmnet_map_dl_ind_hdr *, + struct + rmnet_map_control_command_header *); + } __aligned(1); + union { + void (*dl_trl_handler)(struct rmnet_map_dl_ind_trl *); + void (*dl_trl_handler_v2)(struct rmnet_map_dl_ind_trl *, + struct + rmnet_map_control_command_header *); + } __aligned(1); struct list_head list; }; @@ -257,8 +269,14 @@ void rmnet_map_tx_aggregate_init(struct rmnet_port *port); void rmnet_map_tx_aggregate_exit(struct rmnet_port *port); void rmnet_map_dl_hdr_notify(struct rmnet_port *port, struct rmnet_map_dl_ind_hdr *dl_hdr); +void rmnet_map_dl_hdr_notify_v2(struct rmnet_port *port, + struct rmnet_map_dl_ind_hdr *dl_hdr, + struct rmnet_map_control_command_header *qcmd); void rmnet_map_dl_trl_notify(struct rmnet_port *port, struct rmnet_map_dl_ind_trl *dltrl); +void rmnet_map_dl_trl_notify_v2(struct rmnet_port *port, + struct rmnet_map_dl_ind_trl *dltrl, + struct rmnet_map_control_command_header *qcmd); int rmnet_map_flow_command(struct sk_buff *skb, struct rmnet_port *port, bool rmnet_perf); diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_command.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_command.c index 38415228cd1b..158f6918e4d7 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_command.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_command.c @@ -96,8 +96,22 @@ static void rmnet_map_send_ack(struct sk_buff *skb, netif_tx_unlock(dev); } -void rmnet_map_dl_hdr_notify(struct rmnet_port *port, - struct rmnet_map_dl_ind_hdr *dlhdr) +void +rmnet_map_dl_hdr_notify_v2(struct rmnet_port *port, + struct rmnet_map_dl_ind_hdr *dlhdr, + struct rmnet_map_control_command_header *qcmd) +{ + struct rmnet_map_dl_ind *tmp; + + port->dl_marker_flush = 0; + + list_for_each_entry(tmp, &port->dl_list, list) + tmp->dl_hdr_handler_v2(dlhdr, qcmd); +} + +void +rmnet_map_dl_hdr_notify(struct rmnet_port *port, + struct rmnet_map_dl_ind_hdr *dlhdr) { struct rmnet_map_dl_ind *tmp; @@ -107,8 +121,28 @@ void rmnet_map_dl_hdr_notify(struct rmnet_port *port, tmp->dl_hdr_handler(dlhdr); } -void rmnet_map_dl_trl_notify(struct rmnet_port *port, - struct rmnet_map_dl_ind_trl *dltrl) +void +rmnet_map_dl_trl_notify_v2(struct rmnet_port *port, + struct rmnet_map_dl_ind_trl *dltrl, + struct rmnet_map_control_command_header *qcmd) +{ + struct rmnet_map_dl_ind *tmp; + struct napi_struct *napi; + + list_for_each_entry(tmp, &port->dl_list, list) + tmp->dl_trl_handler_v2(dltrl, qcmd); + + if (port->dl_marker_flush) { + napi = get_current_napi_context(); + napi_gro_flush(napi, false); + } + + port->dl_marker_flush = -1; +} + +void +rmnet_map_dl_trl_notify(struct rmnet_port *port, + struct rmnet_map_dl_ind_trl *dltrl) { struct rmnet_map_dl_ind *tmp; struct napi_struct *napi; @@ -129,11 +163,26 @@ static void rmnet_map_process_flow_start(struct sk_buff *skb, bool rmnet_perf) { struct rmnet_map_dl_ind_hdr *dlhdr; + struct rmnet_map_control_command_header *qcmd; + u32 data_format; + bool is_dl_mark_v2; if (skb->len < RMNET_DL_IND_HDR_SIZE) return; - pskb_pull(skb, RMNET_MAP_CMD_SIZE); + data_format = port->data_format; + is_dl_mark_v2 = data_format & RMNET_INGRESS_FORMAT_DL_MARKER_V2; + if (is_dl_mark_v2) { + pskb_pull(skb, sizeof(struct rmnet_map_header)); + qcmd = (struct rmnet_map_control_command_header *) + rmnet_map_data_ptr(skb); + port->stats.dl_hdr_last_ep_id = qcmd->source_id; + port->stats.dl_hdr_last_qmap_vers = qcmd->reserved; + port->stats.dl_hdr_last_trans_id = qcmd->transaction_id; + pskb_pull(skb, sizeof(struct rmnet_map_control_command_header)); + } else { + pskb_pull(skb, RMNET_MAP_CMD_SIZE); + } dlhdr = (struct rmnet_map_dl_ind_hdr *)rmnet_map_data_ptr(skb); @@ -145,12 +194,16 @@ static void rmnet_map_process_flow_start(struct sk_buff *skb, port->stats.dl_hdr_total_pkts += port->stats.dl_hdr_last_pkts; port->stats.dl_hdr_count++; - rmnet_map_dl_hdr_notify(port, dlhdr); + if (is_dl_mark_v2) + rmnet_map_dl_hdr_notify_v2(port, dlhdr, qcmd); + else + rmnet_map_dl_hdr_notify(port, dlhdr); + if (rmnet_perf) { unsigned int pull_size; pull_size = sizeof(struct rmnet_map_dl_ind_hdr); - if (port->data_format & RMNET_FLAGS_INGRESS_MAP_CKSUMV4) + if (data_format & RMNET_FLAGS_INGRESS_MAP_CKSUMV4) pull_size += sizeof(struct rmnet_map_dl_csum_trailer); pskb_pull(skb, pull_size); } @@ -161,23 +214,39 @@ static void rmnet_map_process_flow_end(struct sk_buff *skb, bool rmnet_perf) { struct rmnet_map_dl_ind_trl *dltrl; + struct rmnet_map_control_command_header *qcmd; + u32 data_format; + bool is_dl_mark_v2; if (skb->len < RMNET_DL_IND_TRL_SIZE) return; - pskb_pull(skb, RMNET_MAP_CMD_SIZE); + data_format = port->data_format; + is_dl_mark_v2 = data_format & RMNET_INGRESS_FORMAT_DL_MARKER_V2; + if (is_dl_mark_v2) { + pskb_pull(skb, sizeof(struct rmnet_map_header)); + qcmd = (struct rmnet_map_control_command_header *) + rmnet_map_data_ptr(skb); + pskb_pull(skb, sizeof(struct rmnet_map_control_command_header)); + } else { + pskb_pull(skb, RMNET_MAP_CMD_SIZE); + } dltrl = (struct rmnet_map_dl_ind_trl *)rmnet_map_data_ptr(skb); port->stats.dl_trl_last_seq = dltrl->seq_le; port->stats.dl_trl_count++; - rmnet_map_dl_trl_notify(port, dltrl); + if (is_dl_mark_v2) + rmnet_map_dl_trl_notify_v2(port, dltrl, qcmd); + else + rmnet_map_dl_trl_notify(port, dltrl); + if (rmnet_perf) { unsigned int pull_size; pull_size = sizeof(struct rmnet_map_dl_ind_trl); - if (port->data_format & RMNET_FLAGS_INGRESS_MAP_CKSUMV4) + if (data_format & RMNET_FLAGS_INGRESS_MAP_CKSUMV4) pull_size += sizeof(struct rmnet_map_dl_csum_trailer); pskb_pull(skb, pull_size); } diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_private.h b/drivers/net/ethernet/qualcomm/rmnet/rmnet_private.h index 009954a74f88..70ab2137bc19 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_private.h +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_private.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014, 2016-2018 The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2014, 2016-2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -20,8 +20,11 @@ /* Constants */ #define RMNET_EGRESS_FORMAT_AGGREGATION BIT(31) -#define RMNET_INGRESS_FORMAT_DL_MARKER BIT(30) -#define RMNET_INGRESS_FORMAT_RPS_STAMP BIG(29) +#define RMNET_INGRESS_FORMAT_DL_MARKER_V1 BIT(30) +#define RMNET_INGRESS_FORMAT_DL_MARKER_V2 BIT(29) + +#define RMNET_INGRESS_FORMAT_DL_MARKER (RMNET_INGRESS_FORMAT_DL_MARKER_V1 |\ +RMNET_INGRESS_FORMAT_DL_MARKER_V2) /* Power save feature*/ #define RMNET_INGRESS_FORMAT_PS BIT(27) diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c index ed4152927545..cd857726e193 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c @@ -224,6 +224,9 @@ static const char rmnet_gstrings_stats[][ETH_GSTRING_LEN] = { }; static const char rmnet_port_gstrings_stats[][ETH_GSTRING_LEN] = { + "MAP Cmd last version", + "MAP Cmd last ep id", + "MAP Cmd last transaction id", "DL header last seen sequence", "DL header last seen bytes", "DL header last seen packets", -- GitLab From 8fe87370078dfc0c6ff1a14820773613893260d9 Mon Sep 17 00:00:00 2001 From: "Thomas (Wonyoung) Yun" Date: Fri, 14 Jun 2019 12:46:07 -0400 Subject: [PATCH 0596/1121] msm: Fix UCHE to GMEM VA align and SVM base addr UCHE to GMEM access requires 1MB alignment and SVM base address for 32bit needs to be updated based on UCHE GMEM size. Change-Id: I8ccf3abbaaac4ca830d4e36c70af89654d1a989e Signed-off-by: Thomas (Wonyoung) Yun --- drivers/gpu/msm/adreno.c | 12 +++++++++++- drivers/gpu/msm/kgsl_iommu.c | 10 +++++----- drivers/gpu/msm/kgsl_mmu.h | 4 +++- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index 6b8573c952bd..09f05db649fd 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -834,7 +834,10 @@ adreno_identify_gpu(struct adreno_device *adreno_dev) */ adreno_dev->gmem_size = adreno_dev->gpucore->gmem_size; - adreno_dev->uche_gmem_base = ALIGN(adreno_dev->gmem_size, SZ_4K); + + /* UCHE to GMEM base address requires 1MB alignment */ + adreno_dev->uche_gmem_base = ALIGN(adreno_dev->gmem_size, SZ_1M); + /* * Initialize uninitialzed gpu registers, only needs to be done once * Make all offsets that are not initialized to ADRENO_REG_UNUSED @@ -1379,6 +1382,13 @@ static int adreno_probe(struct platform_device *pdev) /* Default to 4K alignment (in other words, no additional padding) */ device->mmu.va_padding = PAGE_SIZE; + /* + * SVM start va can be calculated based on UCHE GMEM size. + * UCHE_GMEM_MAX < (SP LOCAL & PRIVATE) < MMU SVA + */ + device->mmu.svm_base32 = KGSL_IOMMU_SVM_BASE32 + + ((ALIGN(adreno_dev->gmem_size, SZ_1M) - SZ_1M) << 1); + if (adreno_dev->gpucore->va_padding) { device->mmu.features |= KGSL_MMU_PAD_VA; device->mmu.va_padding = adreno_dev->gpucore->va_padding; diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c index abfe984b1c26..af617e70f1f1 100644 --- a/drivers/gpu/msm/kgsl_iommu.c +++ b/drivers/gpu/msm/kgsl_iommu.c @@ -1081,7 +1081,7 @@ static void setup_64bit_pagetable(struct kgsl_mmu *mmu, pt->va_start = KGSL_IOMMU_SECURE_BASE(mmu); pt->va_end = KGSL_IOMMU_SECURE_END(mmu); } else { - pt->compat_va_start = KGSL_IOMMU_SVM_BASE32; + pt->compat_va_start = mmu->svm_base32; pt->compat_va_end = KGSL_IOMMU_SECURE_BASE(mmu); pt->va_start = KGSL_IOMMU_VA_BASE64; pt->va_end = KGSL_IOMMU_VA_END64; @@ -1090,7 +1090,7 @@ static void setup_64bit_pagetable(struct kgsl_mmu *mmu, if (pagetable->name != KGSL_MMU_GLOBAL_PT && pagetable->name != KGSL_MMU_SECURE_PT) { if (kgsl_is_compat_task()) { - pt->svm_start = KGSL_IOMMU_SVM_BASE32; + pt->svm_start = mmu->svm_base32; pt->svm_end = KGSL_IOMMU_SECURE_BASE(mmu); } else { pt->svm_start = KGSL_IOMMU_SVM_BASE64; @@ -1110,13 +1110,13 @@ static void setup_32bit_pagetable(struct kgsl_mmu *mmu, pt->va_start = KGSL_IOMMU_SECURE_BASE(mmu); pt->va_end = KGSL_IOMMU_SECURE_END(mmu); } else { - pt->va_start = KGSL_IOMMU_SVM_BASE32; + pt->va_start = mmu->svm_base32; pt->va_end = KGSL_IOMMU_SECURE_BASE(mmu); pt->compat_va_start = pt->va_start; pt->compat_va_end = pt->va_end; } } else { - pt->va_start = KGSL_IOMMU_SVM_BASE32; + pt->va_start = mmu->svm_base32; pt->va_end = KGSL_IOMMU_GLOBAL_MEM_BASE(mmu); pt->compat_va_start = pt->va_start; pt->compat_va_end = pt->va_end; @@ -1124,7 +1124,7 @@ static void setup_32bit_pagetable(struct kgsl_mmu *mmu, if (pagetable->name != KGSL_MMU_GLOBAL_PT && pagetable->name != KGSL_MMU_SECURE_PT) { - pt->svm_start = KGSL_IOMMU_SVM_BASE32; + pt->svm_start = mmu->svm_base32; pt->svm_end = KGSL_IOMMU_SVM_END32; } } diff --git a/drivers/gpu/msm/kgsl_mmu.h b/drivers/gpu/msm/kgsl_mmu.h index 4b06654fc21a..a0d6785f0987 100644 --- a/drivers/gpu/msm/kgsl_mmu.h +++ b/drivers/gpu/msm/kgsl_mmu.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2002,2007-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2002,2007-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -154,6 +154,7 @@ struct kgsl_mmu_pt_ops { * @feature: Static list of MMU features * @secure_aligned_mask: Mask that secure buffers need to be aligned to * @va_padding: Size to pad VA mappings to + * @svm_base32: MMU 32bit VA start address * @priv: Union of sub-device specific members */ struct kgsl_mmu { @@ -166,6 +167,7 @@ struct kgsl_mmu { unsigned long features; unsigned int secure_align_mask; uint64_t va_padding; + unsigned int svm_base32; union { struct kgsl_iommu iommu; } priv; -- GitLab From d8454870feb1b4954e1b2ec5c23f038b31e0d535 Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Mon, 17 Jun 2019 16:31:14 -0700 Subject: [PATCH 0597/1121] pinctrl: qcom: Update offsets on the SOUTH tile for the sdmshrike target Correct the offsets for GPIOs 177-189 on the sdmshrike target. Change-Id: I1337956910ae44dce7683b07926ec9c9306f6f92 Signed-off-by: Anant Goel --- drivers/pinctrl/qcom/pinctrl-sdmshrike.c | 27 ++++++++++++------------ 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/pinctrl/qcom/pinctrl-sdmshrike.c b/drivers/pinctrl/qcom/pinctrl-sdmshrike.c index e37d0f68890d..2212eb334f41 100644 --- a/drivers/pinctrl/qcom/pinctrl-sdmshrike.c +++ b/drivers/pinctrl/qcom/pinctrl-sdmshrike.c @@ -27,6 +27,7 @@ #define NORTH 0x900000 /* dummy tile info */ #define SOUTH 0xD00000 +#define SOUTH1 0xD1E000 /* dummy tile info */ #define WEST 0x100000 #define EAST 0x500000 #define DUMMY 0x0 @@ -2212,27 +2213,27 @@ static const struct msm_pingroup sdmshrike_groups[] = { [175] = PINGROUP(175, SOUTH, pci_e2, NA, NA, NA, NA, NA, NA, NA, NA), [176] = PINGROUP(176, SOUTH, pci_e2, cci_async, NA, NA, NA, NA, NA, NA, NA), - [177] = PINGROUP(177, SOUTH, NA, NA, NA, NA, NA, NA, NA, NA, NA), - [178] = PINGROUP(178, SOUTH, pci_e3, cci_timer4, NA, NA, NA, NA, NA, + [177] = PINGROUP(177, SOUTH1, NA, NA, NA, NA, NA, NA, NA, NA, NA), + [178] = PINGROUP(178, SOUTH1, pci_e3, cci_timer4, NA, NA, NA, NA, NA, NA, NA), - [179] = PINGROUP(179, SOUTH, pci_e3, cam_mclk, NA, NA, NA, NA, NA, NA, + [179] = PINGROUP(179, SOUTH1, pci_e3, cam_mclk, NA, NA, NA, NA, NA, NA, NA), - [180] = PINGROUP(180, SOUTH, cam_mclk, NA, NA, NA, NA, NA, NA, NA, NA), - [181] = PINGROUP(181, SOUTH, qup19, cam_mclk, NA, NA, NA, NA, NA, NA, + [180] = PINGROUP(180, SOUTH1, cam_mclk, NA, NA, NA, NA, NA, NA, NA, NA), + [181] = PINGROUP(181, SOUTH1, qup19, cam_mclk, NA, NA, NA, NA, NA, NA, NA), - [182] = PINGROUP(182, SOUTH, qup19, cci_timer5, gcc_gp4, NA, NA, NA, + [182] = PINGROUP(182, SOUTH1, qup19, cci_timer5, gcc_gp4, NA, NA, NA, NA, NA, NA), - [183] = PINGROUP(183, SOUTH, qup19, cci_timer6, gcc_gp5, NA, NA, NA, + [183] = PINGROUP(183, SOUTH1, qup19, cci_timer6, gcc_gp5, NA, NA, NA, NA, NA, NA), - [184] = PINGROUP(184, SOUTH, qup19, cci_timer7, NA, NA, NA, NA, NA, NA, + [184] = PINGROUP(184, SOUTH1, qup19, cci_timer7, NA, NA, NA, NA, NA, NA, NA), - [185] = PINGROUP(185, SOUTH, cci_timer8, cci_async, NA, NA, NA, NA, NA, + [185] = PINGROUP(185, SOUTH1, cci_timer8, cci_async, NA, NA, NA, NA, NA, NA, NA), - [186] = PINGROUP(186, SOUTH, cci_timer9, cci_async, NA, NA, NA, NA, NA, + [186] = PINGROUP(186, SOUTH1, cci_timer9, cci_async, NA, NA, NA, NA, NA, NA, NA), - [187] = PINGROUP(187, SOUTH, NA, NA, NA, NA, NA, NA, NA, NA, NA), - [188] = PINGROUP(188, SOUTH, NA, NA, NA, NA, NA, NA, NA, NA, NA), - [189] = PINGROUP(189, SOUTH, dp_hot, NA, NA, NA, NA, NA, NA, NA, NA), + [187] = PINGROUP(187, SOUTH1, NA, NA, NA, NA, NA, NA, NA, NA, NA), + [188] = PINGROUP(188, SOUTH1, NA, NA, NA, NA, NA, NA, NA, NA, NA), + [189] = PINGROUP(189, SOUTH1, dp_hot, NA, NA, NA, NA, NA, NA, NA, NA), [190] = SDC_QDSD_PINGROUP(sdc2_clk, 0x9b2000, 14, 6), [191] = SDC_QDSD_PINGROUP(sdc2_cmd, 0x9b2000, 11, 3), [192] = SDC_QDSD_PINGROUP(sdc2_data, 0x9b2000, 9, 0), -- GitLab From 0816b2876e90108e9e2f5882f1a78b85bcdee813 Mon Sep 17 00:00:00 2001 From: Mayank Grover Date: Mon, 10 Jun 2019 18:18:29 +0530 Subject: [PATCH 0598/1121] ARM: dts: msm: Add initial idp support for atoll Add device tree support for atoll on idp platforms. Change-Id: Ibdc9b654c27e7923938ac8f94511feedeee9312e Signed-off-by: Mayank Grover --- .../devicetree/bindings/arm/msm/msm.txt | 1 + arch/arm64/boot/dts/qcom/Makefile | 7 ++++-- .../arm64/boot/dts/qcom/atoll-idp-overlay.dts | 25 +++++++++++++++++++ arch/arm64/boot/dts/qcom/atoll-idp.dts | 22 ++++++++++++++++ arch/arm64/boot/dts/qcom/atoll-idp.dtsi | 14 +++++++++++ 5 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 arch/arm64/boot/dts/qcom/atoll-idp-overlay.dts create mode 100644 arch/arm64/boot/dts/qcom/atoll-idp.dts create mode 100644 arch/arm64/boot/dts/qcom/atoll-idp.dtsi diff --git a/Documentation/devicetree/bindings/arm/msm/msm.txt b/Documentation/devicetree/bindings/arm/msm/msm.txt index 72f246712541..85f746cee2c2 100644 --- a/Documentation/devicetree/bindings/arm/msm/msm.txt +++ b/Documentation/devicetree/bindings/arm/msm/msm.txt @@ -221,5 +221,6 @@ compatible = "qcom,trinket-rumi" compatible = "qcom,trinket-idp" compatible = "qcom,trinket-qrd" compatible = "qcom,atoll-rumi" +compatible = "qcom,atoll-idp" compatible = "qcom,qcs610-iot" compatible = "qcom,qcs410-iot" diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index 61fd9d0296e1..a48dcbb01b01 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -244,11 +244,14 @@ endif ifeq ($(CONFIG_BUILD_ARM64_DT_OVERLAY),y) dtbo-$(CONFIG_ARCH_ATOLL) += \ - atoll-rumi-overlay.dtbo\ + atoll-idp-overlay.dtbo\ + atoll-rumi-overlay.dtbo +atoll-idp-overlay.dtbo-base := atoll.dtb atoll-rumi-overlay.dtbo-base := atoll.dtb else -dtb-$(CONFIG_ARCH_ATOLL) += atoll-rumi.dtb +dtb-$(CONFIG_ARCH_ATOLL) += atoll-idp.dtb\ + atoll-rumi.dtb endif dtb-$(CONFIG_ARCH_SDXPRAIRIE) += sdxprairie-rumi.dtb \ diff --git a/arch/arm64/boot/dts/qcom/atoll-idp-overlay.dts b/arch/arm64/boot/dts/qcom/atoll-idp-overlay.dts new file mode 100644 index 000000000000..46b35d146ce3 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/atoll-idp-overlay.dts @@ -0,0 +1,25 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; +/plugin/; + +#include + +#include "atoll-idp.dtsi" + +/ { + model = "IDP"; + compatible = "qcom,atoll-idp", "qcom,atoll", "qcom,idp"; + qcom,msm-id = <407 0x0>; + qcom,board-id = <34 0>; +}; diff --git a/arch/arm64/boot/dts/qcom/atoll-idp.dts b/arch/arm64/boot/dts/qcom/atoll-idp.dts new file mode 100644 index 000000000000..ff2b4c4266c9 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/atoll-idp.dts @@ -0,0 +1,22 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "atoll.dtsi" +#include "atoll-idp.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. ATOLL PM6150 IDP"; + compatible = "qcom,atoll-idp", "qcom,atoll", "qcom,idp"; + qcom,board-id = <34 0>; +}; diff --git a/arch/arm64/boot/dts/qcom/atoll-idp.dtsi b/arch/arm64/boot/dts/qcom/atoll-idp.dtsi new file mode 100644 index 000000000000..9132ac26e635 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/atoll-idp.dtsi @@ -0,0 +1,14 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { +}; -- GitLab From 157161d9162cf61b2a8e0092c576548dc720d277 Mon Sep 17 00:00:00 2001 From: Trishansh Bhardwaj Date: Tue, 4 Jun 2019 18:17:35 +0530 Subject: [PATCH 0599/1121] Revert "msm: camera: Skip cache CPU SYNC for non-secure buffers" This reverts commit 4a5eec4c6399554ac38deaf13031ab93534d2c23. Do cache ops during map/ummap of the buffer. This helps to ensure cache ops happen properly. Change-Id: I1d5ae6c3c8273b9252175c73f44e362c99b3edac Signed-off-by: Trishansh Bhardwaj --- drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c b/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c index c690cf8e3a88..2cca56255de0 100644 --- a/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c +++ b/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c @@ -1022,9 +1022,6 @@ static int cam_smmu_map_buffer_and_add_to_list(int idx, int ion_fd, goto err_put; } - /* cache flush/invalidation is done by buffer provider */ - attach->dma_map_attrs |= DMA_ATTR_SKIP_CPU_SYNC; - table = dma_buf_map_attachment(attach, dma_dir); if (IS_ERR_OR_NULL(table)) { rc = PTR_ERR(table); @@ -1107,9 +1104,6 @@ static int cam_smmu_unmap_buf_and_remove_from_list( return -EINVAL; } - /* skip cache operations */ - mapping_info->attach->dma_map_attrs |= DMA_ATTR_SKIP_CPU_SYNC; - /* iommu buffer clean up */ dma_buf_unmap_attachment(mapping_info->attach, mapping_info->table, mapping_info->dir); -- GitLab From f8f02a449021578e0e52bc0f3776f2d008a7ab2e Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Mon, 5 Nov 2018 11:40:10 -0800 Subject: [PATCH 0600/1121] dt-bindings: clk: Introduce 'protected-clocks' property Add a generic clk property for clks which are not intended to be used by the OS due to security restrictions put in place by firmware. For example, on some Qualcomm firmwares reading or writing certain clk registers causes the entire system to reboot, but on other firmwares reading and writing those same registers is required to make devices like QSPI work. Rather than adding one-off properties each time a new set of clks appears to be protected, let's add a generic clk property to describe any set of clks that shouldn't be touched by the OS. This way we never need to register the clks or use them in certain firmware configurations. Change-Id: I2bff08473ccd79ed3579262c2f3a3199b27162bb Cc: Rob Herring Cc: Bjorn Andersson Cc: Taniya Das Signed-off-by: Stephen Boyd Reviewed-by: Bjorn Andersson Reviewed-by: Rob Herring Git-commit: 48d7f160b10711f014bf07b574c73452646c9fdd Git-repo: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/ Signed-off-by: Stephen Boyd Signed-off-by: Taniya Das --- .../devicetree/bindings/clock/clock-bindings.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/clock-bindings.txt b/Documentation/devicetree/bindings/clock/clock-bindings.txt index 2ec489eebe72..b646bbcf7f92 100644 --- a/Documentation/devicetree/bindings/clock/clock-bindings.txt +++ b/Documentation/devicetree/bindings/clock/clock-bindings.txt @@ -168,3 +168,19 @@ a shared clock is forbidden. Configuration of common clocks, which affect multiple consumer devices can be similarly specified in the clock provider node. + +==Protected clocks== + +Some platforms or firmwares may not fully expose all the clocks to the OS, such +as in situations where those clks are used by drivers running in ARM secure +execution levels. Such a configuration can be specified in device tree with the +protected-clocks property in the form of a clock specifier list. This property should +only be specified in the node that is providing the clocks being protected: + + clock-controller@a000f000 { + compatible = "vendor,clk95; + reg = <0xa000f000 0x1000> + #clocks-cells = <1>; + ... + protected-clocks = , ; + }; -- GitLab From 7674e8f6a77ed281f2f382f3dcfbabdc9ecead4e Mon Sep 17 00:00:00 2001 From: Pratham Pratap Date: Tue, 11 Jun 2019 19:26:35 +0530 Subject: [PATCH 0601/1121] usb: f_gsi: Don't enable IPA data path if connect channel fails ipa_connect_channels can return failure if gsi prepare trbs fail or start xfer fails. But currently driver is not checking for the failure and goes ahead to enable IPA data path. This leads the controller to access faulty addresses which cause kernel panic. Fix this by checking the failure returned from ipa_connect_channels. Also cleanup the error handling path. Change-Id: Ia1e8e17381e12231d8d78224ba3b07081f143212 Signed-off-by: Pratham Pratap --- drivers/usb/gadget/function/f_gsi.c | 60 +++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 17 deletions(-) diff --git a/drivers/usb/gadget/function/f_gsi.c b/drivers/usb/gadget/function/f_gsi.c index 5e222e30b22d..eea1bd5d20f8 100644 --- a/drivers/usb/gadget/function/f_gsi.c +++ b/drivers/usb/gadget/function/f_gsi.c @@ -565,7 +565,7 @@ static int ipa_connect_channels(struct gsi_data_port *d_port) if (ret) { log_event_err("%s: GSI_EP_OP_STARTXFER failed: %d\n", __func__, ret); - return ret; + goto free_trb_ep_in; } d_port->in_xfer_rsc_index = usb_gsi_ep_op(d_port->in_ep, NULL, @@ -613,7 +613,7 @@ static int ipa_connect_channels(struct gsi_data_port *d_port) if (ret) { log_event_err("%s: GSI_EP_OP_PREPARE_TRBS failed: %d\n", __func__, ret); - return ret; + goto end_xfer_ep_in; } ret = usb_gsi_ep_op(d_port->out_ep, &d_port->out_request, @@ -621,7 +621,7 @@ static int ipa_connect_channels(struct gsi_data_port *d_port) if (ret) { log_event_err("%s: GSI_EP_OP_STARTXFER failed: %d\n", __func__, ret); - return ret; + goto free_trb_ep_out; } d_port->out_xfer_rsc_index = @@ -705,7 +705,7 @@ static int ipa_connect_channels(struct gsi_data_port *d_port) conn_params); if (ret) { log_event_err("%s: IPA connect failed %d", __func__, ret); - return ret; + goto end_xfer_ep_out; } log_event_dbg("%s: xdci_connect done", __func__); @@ -733,6 +733,21 @@ static int ipa_connect_channels(struct gsi_data_port *d_port) d_port->out_request.db_reg_phs_addr_msb = ipa_out_channel_out_params.db_reg_phs_addr_msb; } + + return ret; + +end_xfer_ep_out: + usb_gsi_ep_op(d_port->out_ep, NULL, + GSI_EP_OP_ENDXFER); +free_trb_ep_out: + usb_gsi_ep_op(d_port->out_ep, &d_port->out_request, + GSI_EP_OP_FREE_TRBS); +end_xfer_ep_in: + usb_gsi_ep_op(d_port->in_ep, NULL, + GSI_EP_OP_ENDXFER); +free_trb_ep_in: + usb_gsi_ep_op(d_port->in_ep, &d_port->in_request, + GSI_EP_OP_FREE_TRBS); return ret; } @@ -936,14 +951,26 @@ static void ipa_work_handler(struct work_struct *w) if (ret) { log_event_err("%s: gsi_alloc_trb_failed\n", __func__); + usb_gadget_autopm_put_async(d_port->gadget); break; } d_port->sm_state = STATE_CONNECT_IN_PROGRESS; log_event_dbg("%s: ST_INIT_EVT_CONN_IN_PROG", __func__); - if (peek_event(d_port) != EVT_DISCONNECTED) - ipa_connect_channels(d_port); + if (peek_event(d_port) != EVT_DISCONNECTED) { + ret = ipa_connect_channels(d_port); + if (ret) { + log_event_err("%s: ipa_connect_channels failed\n", + __func__); + gsi_free_trb_buffer(gsi); + usb_gadget_autopm_put_async( + d_port->gadget); + d_port->sm_state = STATE_INITIALIZED; + break; + } + } + } else if (event == EVT_HOST_READY) { /* * When in a composition such as RNDIS + ADB, @@ -963,10 +990,19 @@ static void ipa_work_handler(struct work_struct *w) if (ret) { log_event_err("%s: gsi_alloc_trb_failed\n", __func__); + usb_gadget_autopm_put_async(d_port->gadget); + break; + } + + ret = ipa_connect_channels(d_port); + if (ret) { + log_event_err("%s: ipa_connect_channels failed\n", + __func__); + gsi_free_trb_buffer(gsi); + usb_gadget_autopm_put_async(d_port->gadget); break; } - ipa_connect_channels(d_port); ipa_data_path_enable(d_port); d_port->sm_state = STATE_CONNECTED; log_event_dbg("%s: ST_INIT_EVT_HOST_READY", __func__); @@ -1078,16 +1114,6 @@ static void ipa_work_handler(struct work_struct *w) log_event_dbg("%s: ST_CON_EVT_CON", __func__); } break; - case STATE_DISCONNECTED: - if (event == EVT_CONNECT_IN_PROGRESS) { - ipa_connect_channels(d_port); - d_port->sm_state = STATE_CONNECT_IN_PROGRESS; - log_event_dbg("%s: ST_DIS_EVT_CON_IN_PROG", __func__); - } else if (event == EVT_UNINITIALIZED) { - d_port->sm_state = STATE_UNINITIALIZED; - log_event_dbg("%s: ST_DIS_EVT_UNINIT", __func__); - } - break; case STATE_SUSPEND_IN_PROGRESS: if (event == EVT_IPA_SUSPEND) { d_port->sm_state = STATE_SUSPENDED; -- GitLab From 44fccfd17f43c93c6a10a060b6c75e2ccf1bb3ab Mon Sep 17 00:00:00 2001 From: Prakash Gupta Date: Wed, 12 Jun 2019 14:32:03 +0530 Subject: [PATCH 0602/1121] iommu: iommu-debug: Add support for page table dump Add support for page table dump for test domain. eg: cd /d/iommu/tests/soc:apps_iommu_test_device echo 1 > attach echo 0x20000,0x80000000,0x10000,0x1 > map echo 0x21000,0x1000 > unmap echo 0x24000,0x1000 > unmap cat iommu_page_tables ---[ start ]--- 0x0000000000020000-0x0000000000021000 4K PTE USR ro x AF NG DEVICE/nGnRnE 0x0000000000022000-0x0000000000024000 8K PTE USR ro x AF NG DEVICE/nGnRnE 0x0000000000025000-0x0000000000030000 44K PTE USR ro x AF NG DEVICE/nGnRnE Change-Id: I56ac2615c4aa30dd75a2cdc1cf46de042e681cdc Signed-off-by: Prakash Gupta --- drivers/iommu/Kconfig | 1 + drivers/iommu/iommu-debug.c | 53 +++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index 9f0df503cd76..88a038bada6f 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -462,6 +462,7 @@ config IOMMU_DEBUG_TRACKING config IOMMU_TESTS bool "Interactive IOMMU performance/functional tests" select IOMMU_API + select ARM64_PTDUMP_CORE help Enables a suite of IOMMU unit tests. The tests are runnable through debugfs. Unlike the IOMMU_DEBUG_TRACKING option, the diff --git a/drivers/iommu/iommu-debug.c b/drivers/iommu/iommu-debug.c index a4b35c3a3782..3c2f2a447d53 100644 --- a/drivers/iommu/iommu-debug.c +++ b/drivers/iommu/iommu-debug.c @@ -28,6 +28,10 @@ #include #include +#ifdef CONFIG_ARM64_PTDUMP_CORE +#include +#endif + #if defined(CONFIG_IOMMU_TESTS) static const char *iommu_debug_attr_to_string(enum iommu_attr attr) @@ -173,6 +177,9 @@ struct iommu_debug_device { struct mutex clk_lock; unsigned int clk_count; struct mutex debug_dev_lock; +#ifdef CONFIG_ARM64_PTDUMP_CORE + struct ptdump_info pt_info; +#endif }; static int iommu_debug_build_phoney_sg_table(struct device *dev, @@ -2271,6 +2278,43 @@ static const struct file_operations iommu_debug_trigger_fault_fops = { .write = iommu_debug_trigger_fault_write, }; +#ifdef CONFIG_ARM64_PTDUMP_CORE +static int ptdump_show(struct seq_file *s, void *v) +{ + struct iommu_debug_device *ddev = s->private; + struct ptdump_info *info = &(ddev->pt_info); + struct mm_struct mm; + phys_addr_t phys; + + info->markers = (struct addr_marker[]){ + { 0, "start" }, + }; + info->base_addr = 0; + info->mm = &mm; + + if (ddev->domain) { + iommu_domain_get_attr(ddev->domain, DOMAIN_ATTR_PT_BASE_ADDR, + &(phys)); + + info->mm->pgd = (pgd_t *)phys_to_virt(phys); + ptdump_walk_pgd(s, info); + } + return 0; +} + +static int ptdump_open(struct inode *inode, struct file *file) +{ + return single_open(file, ptdump_show, inode->i_private); +} + +static const struct file_operations ptdump_fops = { + .open = ptdump_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; +#endif + /* * The following will only work for drivers that implement the generic * device tree bindings described in @@ -2445,6 +2489,15 @@ static int snarf_iommu_devices(struct device *dev, void *ignored) goto err_rmdir; } +#ifdef CONFIG_ARM64_PTDUMP_CORE + if (!debugfs_create_file("iommu_page_tables", 0200, dir, ddev, + &ptdump_fops)) { + pr_err_ratelimited("Couldn't create iommu/devices/%s/trigger-fault debugfs file\n", + dev_name(dev)); + goto err_rmdir; + } +#endif + list_add(&ddev->list, &iommu_debug_devices); return 0; -- GitLab From 6a6b145092888bb9996a97422017bfe39057e0f9 Mon Sep 17 00:00:00 2001 From: Om Parkash Date: Fri, 17 May 2019 17:24:22 +0530 Subject: [PATCH 0603/1121] msm: camera: Add IR-LED and IR-cut filter driver Add driver for PWM based IR-LED and IR-CUT filter in camera to be used to capture very low light scenario. It takes IR mode and IRLED Intensity from UMD configures IRLED and IR CUT filter accordingly. Change-Id: I97328b14c177a05f9f48a37d3198193e2204acd8 Signed-off-by: Om Parkash --- .../msm/camera/cam_sensor_module/Makefile | 1 + .../cam_sensor_module/cam_ir_led/Makefile | 10 + .../cam_ir_led/cam_ir_led_core.c | 54 ++ .../cam_ir_led/cam_ir_led_core.h | 20 + .../cam_ir_led/cam_ir_led_dev.c | 583 ++++++++++++++++++ .../cam_ir_led/cam_ir_led_dev.h | 164 +++++ .../cam_ir_led/cam_ir_led_soc.c | 57 ++ .../cam_ir_led/cam_ir_led_soc.h | 21 + .../cam_sensor/cam_sensor_core.c | 2 + .../cam_sensor/cam_sensor_soc.c | 17 +- .../cam_sensor_utils/cam_sensor_cmn_header.h | 3 +- .../msm/camera/cam_utils/cam_debug_util.c | 5 +- .../msm/camera/cam_utils/cam_debug_util.h | 1 + include/uapi/media/cam_req_mgr.h | 1 + include/uapi/media/cam_sensor.h | 31 + 15 files changed, 967 insertions(+), 3 deletions(-) create mode 100644 drivers/media/platform/msm/camera/cam_sensor_module/cam_ir_led/Makefile create mode 100644 drivers/media/platform/msm/camera/cam_sensor_module/cam_ir_led/cam_ir_led_core.c create mode 100644 drivers/media/platform/msm/camera/cam_sensor_module/cam_ir_led/cam_ir_led_core.h create mode 100644 drivers/media/platform/msm/camera/cam_sensor_module/cam_ir_led/cam_ir_led_dev.c create mode 100644 drivers/media/platform/msm/camera/cam_sensor_module/cam_ir_led/cam_ir_led_dev.h create mode 100644 drivers/media/platform/msm/camera/cam_sensor_module/cam_ir_led/cam_ir_led_soc.c create mode 100644 drivers/media/platform/msm/camera/cam_sensor_module/cam_ir_led/cam_ir_led_soc.h diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/Makefile b/drivers/media/platform/msm/camera/cam_sensor_module/Makefile index 65c23274e5ae..dac985dc4a27 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/Makefile +++ b/drivers/media/platform/msm/camera/cam_sensor_module/Makefile @@ -8,3 +8,4 @@ obj-$(CONFIG_SPECTRA_CAMERA) += cam_sensor/ obj-$(CONFIG_SPECTRA_CAMERA) += cam_flash/ obj-$(CONFIG_SPECTRA_CAMERA) += cam_eeprom/ obj-$(CONFIG_SPECTRA_CAMERA) += cam_ois/ +obj-$(CONFIG_SPECTRA_CAMERA) += cam_ir_led/ diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_ir_led/Makefile b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ir_led/Makefile new file mode 100644 index 000000000000..2444a34c4dba --- /dev/null +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ir_led/Makefile @@ -0,0 +1,10 @@ +ccflags-y += -Idrivers/media/platform/msm/camera/cam_utils +ccflags-y += -Idrivers/media/platform/msm/camera/cam_sync +ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_res_mgr +ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils +ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io +ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_cci +ccflags-y += -Idrivers/media/platform/msm/camera/cam_req_mgr +ccflags-y += -Idrivers/media/platform/msm/camera/cam_smmu/ + +obj-$(CONFIG_SPECTRA_CAMERA) += cam_ir_led_dev.o cam_ir_led_soc.o cam_ir_led_core.o diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_ir_led/cam_ir_led_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ir_led/cam_ir_led_core.c new file mode 100644 index 000000000000..590e689bf72a --- /dev/null +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ir_led/cam_ir_led_core.c @@ -0,0 +1,54 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "cam_ir_led_core.h" + +int cam_ir_led_stop_dev(struct cam_ir_led_ctrl *ictrl) +{ + return ictrl->func_tbl->camera_ir_led_off(ictrl); +} + +int cam_ir_led_release_dev(struct cam_ir_led_ctrl *ictrl) +{ + int rc = 0; + + if (ictrl->device_hdl != -1) { + rc = cam_destroy_device_hdl(ictrl->device_hdl); + if (rc) + CAM_ERR(CAM_IR_LED, + "Failed in destroying device handle rc = %d", + rc); + ictrl->device_hdl = -1; + } + + return rc; +} + +void cam_ir_led_shutdown(struct cam_ir_led_ctrl *ictrl) +{ + int rc; + + if (ictrl->ir_led_state == CAM_IR_LED_STATE_INIT) + return; + + if (ictrl->ir_led_state == CAM_IR_LED_STATE_ON) { + rc = cam_ir_led_stop_dev(ictrl); + if (rc) + CAM_ERR(CAM_IR_LED, "Stop Failed rc: %d", rc); + } + + rc = cam_ir_led_release_dev(ictrl); + if (rc) + CAM_ERR(CAM_IR_LED, "Release failed rc: %d", rc); + else + ictrl->ir_led_state = CAM_IR_LED_STATE_INIT; +} diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_ir_led/cam_ir_led_core.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ir_led/cam_ir_led_core.h new file mode 100644 index 000000000000..b05aab2f2995 --- /dev/null +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ir_led/cam_ir_led_core.h @@ -0,0 +1,20 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _CAM_IR_LED_CORE_H_ +#define _CAM_IR_LED_CORE_H_ +#include "cam_ir_led_dev.h" + +void cam_ir_led_shutdown(struct cam_ir_led_ctrl *ir_led_ctrl); +int cam_ir_led_stop_dev(struct cam_ir_led_ctrl *ir_led_ctrl); +int cam_ir_led_release_dev(struct cam_ir_led_ctrl *fctrl); +#endif /*_CAM_IR_LED_CORE_H_*/ diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_ir_led/cam_ir_led_dev.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ir_led/cam_ir_led_dev.c new file mode 100644 index 000000000000..31dfb2c98fc8 --- /dev/null +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ir_led/cam_ir_led_dev.c @@ -0,0 +1,583 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include "cam_ir_led_dev.h" +#include "cam_ir_led_soc.h" +#include "cam_ir_led_core.h" + +static struct cam_ir_led_table cam_pmic_ir_led_table; + +static struct cam_ir_led_table *ir_led_table[] = { + &cam_pmic_ir_led_table, +}; + +static int32_t cam_pmic_ir_led_init( + struct cam_ir_led_ctrl *ictrl) +{ + return ictrl->func_tbl->camera_ir_led_off(ictrl); +} + +static int32_t cam_pmic_ir_led_release( + struct cam_ir_led_ctrl *ictrl) +{ + int32_t rc = 0; + + CAM_DBG(CAM_IR_LED, "Enter"); + rc = ictrl->func_tbl->camera_ir_led_off(ictrl); + if (rc < 0) { + CAM_ERR(CAM_IR_LED, "camera_ir_led_off failed (%d)", rc); + return rc; + } + return rc; +} + +static int32_t cam_pmic_ir_led_off(struct cam_ir_led_ctrl *ictrl) +{ + int32_t rc = 0; + + CAM_DBG(CAM_IR_LED, "Enter"); + if (ictrl->pwm_dev) { + pwm_disable(ictrl->pwm_dev); + } else { + CAM_ERR(CAM_IR_LED, "pwm device is null"); + return -EINVAL; + } + + rc = gpio_direction_input( + ictrl->soc_info.gpio_data->cam_gpio_common_tbl[0].gpio); + if (rc) + CAM_ERR(CAM_IR_LED, "gpio operation failed(%d)", rc); + + return rc; +} + +static int32_t cam_pmic_ir_led_on( + struct cam_ir_led_ctrl *ictrl, + struct cam_ir_led_set_on_off *ir_led_data) +{ + int rc; + + if (ictrl->pwm_dev) { + rc = pwm_config(ictrl->pwm_dev, + ir_led_data->pwm_duty_on_ns, + ir_led_data->pwm_period_ns); + if (rc) { + CAM_ERR(CAM_IR_LED, "PWM config failed (%d)", rc); + return rc; + } + + rc = pwm_enable(ictrl->pwm_dev); + CAM_DBG(CAM_IR_LED, "enabled=%d, period=%llu, duty_cycle=%llu", + ictrl->pwm_dev->state.enabled, + ictrl->pwm_dev->state.period, + ictrl->pwm_dev->state.duty_cycle); + if (rc) { + CAM_ERR(CAM_IR_LED, "PWM enable failed(%d)", rc); + return rc; + } + rc = gpio_direction_output( + ictrl->soc_info.gpio_data->cam_gpio_common_tbl[0].gpio, + 1); + if (rc) { + CAM_ERR(CAM_IR_LED, "gpio operation failed(%d)", rc); + return rc; + } + rc = gpio_direction_output( + ictrl->soc_info.gpio_data->cam_gpio_common_tbl[1].gpio, + 1); + if (rc) { + CAM_ERR(CAM_IR_LED, "gpio operation failed(%d)", rc); + return rc; + } + } else { + CAM_ERR(CAM_IR_LED, "pwm device is null"); + } + + return 0; +} + +static int32_t cam_ir_led_handle_init( + struct cam_ir_led_ctrl *ictrl) +{ + uint32_t i = 0; + int32_t rc = -EFAULT; + enum cam_ir_led_driver_type ir_led_driver_type = + ictrl->ir_led_driver_type; + + CAM_DBG(CAM_IR_LED, "IRLED HW type=%d", ir_led_driver_type); + for (i = 0; i < ARRAY_SIZE(ir_led_table); i++) { + if (ir_led_driver_type == ir_led_table[i]->ir_led_driver_type) { + ictrl->func_tbl = &ir_led_table[i]->func_tbl; + rc = 0; + break; + } + } + + if (rc < 0) { + CAM_ERR(CAM_IR_LED, "failed invalid ir_led_driver_type %d", + ir_led_driver_type); + return -EINVAL; + } + + rc = ictrl->func_tbl->camera_ir_led_init(ictrl); + if (rc < 0) + CAM_ERR(CAM_IR_LED, "camera_ir_led_init failed (%d)", rc); + + return rc; +} +static int32_t cam_ir_led_config(struct cam_ir_led_ctrl *ictrl, + void *arg) +{ + int rc = 0; + uint32_t *cmd_buf = NULL; + uintptr_t generic_ptr; + uint32_t *offset = NULL; + size_t len_of_buffer; + struct cam_control *ioctl_ctrl = NULL; + struct cam_packet *csl_packet = NULL; + struct cam_config_dev_cmd config; + struct cam_cmd_buf_desc *cmd_desc = NULL; + struct cam_ir_led_set_on_off *cam_ir_led_info = NULL; + + if (!ictrl || !arg) { + CAM_ERR(CAM_IR_LED, "ictrl/arg is NULL"); + return -EINVAL; + } + /* getting CSL Packet */ + ioctl_ctrl = (struct cam_control *)arg; + + if (copy_from_user((&config), u64_to_user_ptr(ioctl_ctrl->handle), + sizeof(config))) { + CAM_ERR(CAM_IR_LED, "Copy cmd handle from user failed"); + rc = -EFAULT; + return rc; + } + + rc = cam_mem_get_cpu_buf(config.packet_handle, + (uintptr_t *)&generic_ptr, &len_of_buffer); + if (rc) { + CAM_ERR(CAM_IR_LED, "Failed in getting the buffer : %d", rc); + return rc; + } + + if (config.offset > len_of_buffer) { + CAM_ERR(CAM_IR_LED, + "offset is out of bounds: offset: %lld len: %zu", + config.offset, len_of_buffer); + return -EINVAL; + } + + /* Add offset to the ir_led csl header */ + csl_packet = (struct cam_packet *)(uintptr_t)(generic_ptr + + config.offset); + + offset = (uint32_t *)((uint8_t *)&csl_packet->payload + + csl_packet->cmd_buf_offset); + cmd_desc = (struct cam_cmd_buf_desc *)(offset); + rc = cam_mem_get_cpu_buf(cmd_desc->mem_handle, + (uintptr_t *)&generic_ptr, &len_of_buffer); + if (rc < 0) { + CAM_ERR(CAM_IR_LED, "Failed to get the command Buffer"); + return -EINVAL; + } + + cmd_buf = (uint32_t *)((uint8_t *)generic_ptr + + cmd_desc->offset); + cam_ir_led_info = (struct cam_ir_led_set_on_off *)cmd_buf; + + switch (csl_packet->header.op_code & 0xFFFFFF) { + case CAM_IR_LED_PACKET_OPCODE_ON: + rc = ictrl->func_tbl->camera_ir_led_on( + ictrl, cam_ir_led_info); + if (rc < 0) { + CAM_ERR(CAM_IR_LED, "Fail to turn irled ON rc=%d", rc); + return rc; + } + ictrl->ir_led_state = CAM_IR_LED_STATE_ON; + break; + case CAM_IR_LED_PACKET_OPCODE_OFF: + if (ictrl->ir_led_state != CAM_IR_LED_STATE_ON) { + CAM_DBG(CAM_IR_LED, + "IRLED_OFF NA, Already OFF, state:%d", + ictrl->ir_led_state); + return 0; + } + rc = ictrl->func_tbl->camera_ir_led_off(ictrl); + if (rc < 0) { + CAM_ERR(CAM_IR_LED, "Fail to turn irled OFF rc=%d", rc); + return rc; + } + ictrl->ir_led_state = CAM_IR_LED_STATE_OFF; + break; + case CAM_PKT_NOP_OPCODE: + CAM_DBG(CAM_IR_LED, "CAM_PKT_NOP_OPCODE"); + break; + default: + CAM_ERR(CAM_IR_LED, "Invalid Opcode : %d", + (csl_packet->header.op_code & 0xFFFFFF)); + return -EINVAL; + } + + return rc; +} + +static int32_t cam_ir_led_driver_cmd(struct cam_ir_led_ctrl *ictrl, + void *arg, struct cam_ir_led_private_soc *soc_private) +{ + int rc = 0; + struct cam_control *cmd = (struct cam_control *)arg; + struct cam_sensor_acquire_dev ir_led_acq_dev; + struct cam_create_dev_hdl dev_hdl; + struct cam_ir_led_query_cap_info ir_led_cap = {0}; + + if (!ictrl || !arg) { + CAM_ERR(CAM_IR_LED, "ictrl/arg is NULL with arg:%pK ictrl%pK", + ictrl, arg); + return -EINVAL; + } + + if (cmd->handle_type != CAM_HANDLE_USER_POINTER) { + CAM_ERR(CAM_IR_LED, "Invalid handle type: %d", + cmd->handle_type); + return -EINVAL; + } + + mutex_lock(&(ictrl->ir_led_mutex)); + CAM_DBG(CAM_IR_LED, "cmd->op_code %d", cmd->op_code); + switch (cmd->op_code) { + case CAM_ACQUIRE_DEV: + if (ictrl->ir_led_state != CAM_IR_LED_STATE_INIT) { + CAM_ERR(CAM_IR_LED, + "Cannot apply Acquire dev: Prev state: %d", + ictrl->ir_led_state); + rc = -EINVAL; + goto release_mutex; + } + + rc = copy_from_user(&ir_led_acq_dev, + u64_to_user_ptr(cmd->handle), + sizeof(ir_led_acq_dev)); + if (rc) { + CAM_ERR(CAM_IR_LED, "Failed Copy from User rc=%d", rc); + goto release_mutex; + } + + dev_hdl.priv = ictrl; + + ir_led_acq_dev.device_handle = + cam_create_device_hdl(&dev_hdl); + ictrl->device_hdl = + ir_led_acq_dev.device_handle; + + rc = copy_to_user(u64_to_user_ptr(cmd->handle), &ir_led_acq_dev, + sizeof(struct cam_sensor_acquire_dev)); + if (rc) { + CAM_ERR(CAM_IR_LED, "Failed Copy to User rc=%d", rc); + rc = -EFAULT; + goto release_mutex; + } + rc = cam_ir_led_handle_init(ictrl); + ictrl->ir_led_state = CAM_IR_LED_STATE_ACQUIRE; + break; + case CAM_RELEASE_DEV: + if ((ictrl->ir_led_state == CAM_IR_LED_STATE_INIT) || + (ictrl->ir_led_state == CAM_IR_LED_STATE_START)) { + CAM_WARN(CAM_IR_LED, + " Cannot apply Release dev: Prev state:%d", + ictrl->ir_led_state); + } + + if (ictrl->device_hdl == -1 && + ictrl->ir_led_state == CAM_IR_LED_STATE_ACQUIRE) { + CAM_ERR(CAM_IR_LED, + " Invalid Handle: device hdl: %d", + ictrl->device_hdl); + rc = -EINVAL; + goto release_mutex; + } + rc = cam_ir_led_release_dev(ictrl); + if (rc) + CAM_ERR(CAM_IR_LED, + " Failed in destroying the device Handle rc= %d", + rc); + ictrl->ir_led_state = CAM_IR_LED_STATE_INIT; + break; + case CAM_QUERY_CAP: + ir_led_cap.slot_info = ictrl->soc_info.index; + + if (copy_to_user(u64_to_user_ptr(cmd->handle), &ir_led_cap, + sizeof(struct cam_ir_led_query_cap_info))) { + CAM_ERR(CAM_IR_LED, " Failed Copy to User"); + rc = -EFAULT; + goto release_mutex; + } + break; + case CAM_START_DEV: + if (ictrl->ir_led_state != CAM_IR_LED_STATE_ACQUIRE) { + CAM_ERR(CAM_IR_LED, + "Cannot apply Start Dev: Prev state: %d", + ictrl->ir_led_state); + rc = -EINVAL; + goto release_mutex; + } + ictrl->ir_led_state = CAM_IR_LED_STATE_START; + break; + case CAM_STOP_DEV: + rc = cam_ir_led_stop_dev(ictrl); + if (rc) { + CAM_ERR(CAM_IR_LED, "Failed STOP_DEV: rc=%d", rc); + goto release_mutex; + } + ictrl->ir_led_state = CAM_IR_LED_STATE_ACQUIRE; + break; + case CAM_CONFIG_DEV: + if ((ictrl->ir_led_state == CAM_IR_LED_STATE_INIT) || + (ictrl->ir_led_state == CAM_IR_LED_STATE_ACQUIRE)) { + CAM_ERR(CAM_IR_LED, + "Cannot apply Config Dev: Prev state: %d", + ictrl->ir_led_state); + rc = -EINVAL; + goto release_mutex; + } + rc = cam_ir_led_config(ictrl, arg); + if (rc) { + CAM_ERR(CAM_IR_LED, "Failed CONFIG_DEV: rc=%d", rc); + goto release_mutex; + } + break; + case CAM_FLUSH_REQ: + rc = cam_ir_led_stop_dev(ictrl); + if (rc) { + CAM_ERR(CAM_IR_LED, "Failed FLUSH_REQ: rc=%d", rc); + goto release_mutex; + } + ictrl->ir_led_state = CAM_IR_LED_STATE_ACQUIRE; + break; + default: + CAM_ERR(CAM_IR_LED, "Invalid Opcode:%d", cmd->op_code); + rc = -EINVAL; + } + +release_mutex: + mutex_unlock(&(ictrl->ir_led_mutex)); + return rc; +} + +static const struct of_device_id cam_ir_led_dt_match[] = { + {.compatible = "qcom,camera-ir-led", .data = NULL}, + {} +}; + +static long cam_ir_led_subdev_ioctl(struct v4l2_subdev *sd, + unsigned int cmd, void *arg) +{ + int rc = 0; + struct cam_ir_led_ctrl *ictrl = NULL; + struct cam_ir_led_private_soc *soc_private = NULL; + + CAM_DBG(CAM_IR_LED, "Enter"); + + ictrl = v4l2_get_subdevdata(sd); + soc_private = ictrl->soc_info.soc_private; + + switch (cmd) { + case VIDIOC_CAM_CONTROL: + rc = cam_ir_led_driver_cmd(ictrl, arg, + soc_private); + break; + default: + CAM_ERR(CAM_IR_LED, " Invalid ioctl cmd type"); + rc = -EINVAL; + break; + } + + CAM_DBG(CAM_IR_LED, "Exit"); + return rc; +} + +#ifdef CONFIG_COMPAT +static long cam_ir_led_subdev_do_ioctl(struct v4l2_subdev *sd, + unsigned int cmd, unsigned long arg) +{ + struct cam_control cmd_data; + int32_t rc = 0; + + if (copy_from_user(&cmd_data, (void __user *)arg, + sizeof(cmd_data))) { + CAM_ERR(CAM_IR_LED, + " Failed to copy from user_ptr=%pK size=%zu", + (void __user *)arg, sizeof(cmd_data)); + return -EFAULT; + } + + switch (cmd) { + case VIDIOC_CAM_CONTROL: + rc = cam_ir_led_subdev_ioctl(sd, cmd, &cmd_data); + if (rc) + CAM_ERR(CAM_IR_LED, "cam_ir_led_ioctl failed"); + break; + default: + CAM_ERR(CAM_IR_LED, " Invalid compat ioctl cmd_type:%d", + cmd); + rc = -EINVAL; + } + + if (!rc) { + if (copy_to_user((void __user *)arg, &cmd_data, + sizeof(cmd_data))) { + CAM_ERR(CAM_IR_LED, + " Failed to copy to user_ptr=%pK size=%zu", + (void __user *)arg, sizeof(cmd_data)); + rc = -EFAULT; + } + } + + return rc; +} +#endif + +static int cam_ir_led_platform_remove(struct platform_device *pdev) +{ + struct cam_ir_led_ctrl *ictrl; + + ictrl = platform_get_drvdata(pdev); + if (!ictrl) { + CAM_ERR(CAM_IR_LED, " Ir_led device is NULL"); + return 0; + } + + kfree(ictrl); + + return 0; +} + +static int cam_ir_led_subdev_close(struct v4l2_subdev *sd, + struct v4l2_subdev_fh *fh) +{ + struct cam_ir_led_ctrl *ictrl = + v4l2_get_subdevdata(sd); + + if (!ictrl) { + CAM_ERR(CAM_IR_LED, " Ir_led ctrl ptr is NULL"); + return -EINVAL; + } + + mutex_lock(&ictrl->ir_led_mutex); + cam_ir_led_shutdown(ictrl); + mutex_unlock(&ictrl->ir_led_mutex); + + return 0; +} + +static struct v4l2_subdev_core_ops cam_ir_led_subdev_core_ops = { + .ioctl = cam_ir_led_subdev_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl32 = cam_ir_led_subdev_do_ioctl +#endif +}; + +static struct v4l2_subdev_ops cam_ir_led_subdev_ops = { + .core = &cam_ir_led_subdev_core_ops, +}; + +static const struct v4l2_subdev_internal_ops cam_ir_led_internal_ops = { + .close = cam_ir_led_subdev_close, +}; + +static int32_t cam_ir_led_platform_probe(struct platform_device *pdev) +{ + int32_t rc = 0; + struct cam_ir_led_ctrl *ictrl = NULL; + + CAM_DBG(CAM_IR_LED, "Enter"); + if (!pdev->dev.of_node) { + CAM_ERR(CAM_IR_LED, "of_node NULL"); + return -EINVAL; + } + + ictrl = kzalloc(sizeof(struct cam_ir_led_ctrl), GFP_KERNEL); + if (!ictrl) { + CAM_ERR(CAM_IR_LED, "kzalloc failed!!"); + return -ENOMEM; + } + + ictrl->pdev = pdev; + ictrl->soc_info.pdev = pdev; + ictrl->soc_info.dev = &pdev->dev; + ictrl->soc_info.dev_name = pdev->name; + + rc = cam_ir_led_get_dt_data(ictrl, &ictrl->soc_info); + if (rc) { + CAM_ERR(CAM_IR_LED, "cam_ir_led_get_dt_data failed rc=%d", rc); + if (ictrl->soc_info.soc_private != NULL) { + kfree(ictrl->soc_info.soc_private); + ictrl->soc_info.soc_private = NULL; + } + kfree(ictrl); + ictrl = NULL; + return -EINVAL; + } + + ictrl->v4l2_dev_str.internal_ops = + &cam_ir_led_internal_ops; + ictrl->v4l2_dev_str.ops = &cam_ir_led_subdev_ops; + ictrl->v4l2_dev_str.name = CAMX_IR_LED_DEV_NAME; + ictrl->v4l2_dev_str.sd_flags = + V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS; + ictrl->v4l2_dev_str.ent_function = CAM_IRLED_DEVICE_TYPE; + ictrl->v4l2_dev_str.token = ictrl; + + rc = cam_register_subdev(&(ictrl->v4l2_dev_str)); + if (rc) { + CAM_ERR(CAM_IR_LED, "Fail to create subdev with %d", rc); + kfree(ictrl); + return rc; + } + + ictrl->device_hdl = -1; + platform_set_drvdata(pdev, ictrl); + v4l2_set_subdevdata(&ictrl->v4l2_dev_str.sd, ictrl); + mutex_init(&(ictrl->ir_led_mutex)); + ictrl->ir_led_state = CAM_IR_LED_STATE_INIT; + return rc; +} + +static struct cam_ir_led_table cam_pmic_ir_led_table = { + .ir_led_driver_type = IR_LED_DRIVER_PMIC, + .func_tbl = { + .camera_ir_led_init = &cam_pmic_ir_led_init, + .camera_ir_led_release = &cam_pmic_ir_led_release, + .camera_ir_led_off = &cam_pmic_ir_led_off, + .camera_ir_led_on = &cam_pmic_ir_led_on, + }, +}; + +MODULE_DEVICE_TABLE(of, cam_ir_led_dt_match); + +static struct platform_driver cam_ir_led_platform_driver = { + .probe = cam_ir_led_platform_probe, + .remove = cam_ir_led_platform_remove, + .driver = { + .name = "CAM-IR-LED-DRIVER", + .owner = THIS_MODULE, + .of_match_table = cam_ir_led_dt_match, + .suppress_bind_attrs = true, + }, +}; + +module_platform_driver(cam_ir_led_platform_driver); + +MODULE_DESCRIPTION("CAM IR_LED"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_ir_led/cam_ir_led_dev.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ir_led/cam_ir_led_dev.h new file mode 100644 index 000000000000..7549435ae92b --- /dev/null +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ir_led/cam_ir_led_dev.h @@ -0,0 +1,164 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _CAM_IR_LED_DEV_H_ +#define _CAM_IR_LED_DEV_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "cam_req_mgr_util.h" +#include "cam_req_mgr_interface.h" +#include "cam_subdev.h" +#include "cam_mem_mgr.h" +#include "cam_sensor_cmn_header.h" +#include "cam_soc_util.h" +#include "cam_debug_util.h" + +#define CAMX_IR_LED_DEV_NAME "cam-ir-led-dev" +#define CAM_IR_LED_PIPELINE_DELAY 1 +#define CAM_IR_LED_PACKET_OPCODE_OFF 0 +#define CAM_IR_LED_PACKET_OPCODE_ON 1 + +enum cam_ir_led_switch_trigger_ops { + LED_SWITCH_OFF = 0, + LED_SWITCH_ON, +}; + +enum cam_ir_led_driver_type { + IR_LED_DRIVER_GPIO, + IR_LED_DRIVER_PMIC, + IR_LED_DRIVER_DEFAULT, +}; + +enum cam_ir_led_state { + CAM_IR_LED_STATE_INIT = 0, + CAM_IR_LED_STATE_ACQUIRE, + CAM_IR_LED_STATE_START, + CAM_IR_LED_STATE_ON, + CAM_IR_LED_STATE_OFF, +}; + +/** + * struct cam_ir_led_intf_params + * @device_hdl : Device Handle + * @session_hdl : Session Handle + * @link_hdl : Link Handle + * @ops : KMD operations + * @crm_cb : Callback API pointers + */ +struct cam_ir_led_intf_params { + int32_t device_hdl; + int32_t session_hdl; + int32_t link_hdl; + struct cam_req_mgr_kmd_ops ops; + struct cam_req_mgr_crm_cb *crm_cb; +}; + +/** + * struct cam_ir_led_common_attr + * @is_settings_valid : Notify the valid settings + * @request_id : Request id provided by umd + * @count : Number of led count + * @cmd_type : Command buffer type + */ +struct cam_ir_led_common_attr { + bool is_settings_valid; + uint64_t request_id; + uint16_t count; + uint8_t cmd_type; +}; + +/** + * struct ir_led_init_packet + * @cmn_attr : Provides common attributes + * @ir_led_type : Ir_led type(PMIC/I2C/GPIO) + */ +struct cam_ir_led_init_packet { + struct cam_ir_led_common_attr cmn_attr; + uint8_t ir_led_type; +}; + +/** + * struct cam_ir_led_private_soc + * @switch_trigger_name : Switch trigger name + * @ir_led_trigger_name : Ir_led trigger name array + * @ir_led_op_current : Ir_led operational current + * @ir_led_max_current : Max supported current for LED in ir_led mode + * @ir_led_max_duration : Max turn on duration for LED in Ir_led mode + * @torch_trigger_name : Torch trigger name array + * @torch_op_current : Torch operational current + * @torch_max_current : Max supported current for LED in torch mode + */ + +struct cam_ir_led_private_soc { + const char *switch_trigger_name; + const char *ir_led_trigger_name; + uint32_t ir_led_op_current; + uint32_t ir_led_max_current; + uint32_t ir_led_max_duration; + const char *torch_trigger_name; + uint32_t torch_op_current; + uint32_t torch_max_current; +}; + +/** + * struct cam_ir_led_ctrl + * @soc_info : Soc related information + * @pdev : Platform device + * @pwm_dev : PWM device handle + * @func_tbl : structure of h/w specific function pointers + * @of_node : Of Node ptr + * @v4l2_dev_str : V4L2 device structure + * @ir_led_mutex : Mutex for ir_led operations + * @ir_led_state : Current ir_led state (INIT/ACQUIRE/START/ON/OFF) + * @device_hdl : Device Handle + * @ir_led_driver_type : ir_led driver type (GPIO/PWM) + */ +struct cam_ir_led_ctrl { + struct cam_hw_soc_info soc_info; + struct platform_device *pdev; + struct pwm_device *pwm_dev; + struct cam_ir_led_func *func_tbl; + struct device_node *of_node; + struct cam_subdev v4l2_dev_str; + struct mutex ir_led_mutex; + enum cam_ir_led_state ir_led_state; + int32_t device_hdl; + enum cam_ir_led_driver_type ir_led_driver_type; +}; + +struct cam_ir_led_func { + int32_t (*camera_ir_led_init)(struct cam_ir_led_ctrl *); + int32_t (*camera_ir_led_release)(struct cam_ir_led_ctrl *); + int32_t (*camera_ir_led_off)(struct cam_ir_led_ctrl *); + int32_t (*camera_ir_led_on)(struct cam_ir_led_ctrl *, + struct cam_ir_led_set_on_off *); +}; + +struct cam_ir_led_table { + enum cam_ir_led_driver_type ir_led_driver_type; + struct cam_ir_led_func func_tbl; +}; + +#endif /*_CAM_IR_LED_DEV_H_*/ diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_ir_led/cam_ir_led_soc.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ir_led/cam_ir_led_soc.c new file mode 100644 index 000000000000..cb0262fe2767 --- /dev/null +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ir_led/cam_ir_led_soc.c @@ -0,0 +1,57 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include "cam_ir_led_soc.h" +#include "cam_res_mgr_api.h" + +int cam_ir_led_get_dt_data(struct cam_ir_led_ctrl *ictrl, + struct cam_hw_soc_info *soc_info) +{ + int32_t rc = 0; + + if (!ictrl) { + CAM_ERR(CAM_IR_LED, "NULL ir_led control structure"); + return -EINVAL; + } + + rc = cam_soc_util_get_dt_properties(soc_info); + if (rc < 0) { + CAM_ERR(CAM_IR_LED, "get_dt_properties failed rc %d", rc); + return rc; + } + + soc_info->soc_private = + kzalloc(sizeof(struct cam_ir_led_private_soc), GFP_KERNEL); + if (!soc_info->soc_private) { + CAM_ERR(CAM_IR_LED, "soc_info->soc_private is NULL"); + rc = -ENOMEM; + goto release_soc_res; + } + + if (of_property_read_bool(soc_info->dev->of_node, "pwms")) { + ictrl->pwm_dev = of_pwm_get(ictrl->pdev->dev.of_node, NULL); + if (ictrl->pwm_dev == NULL) + CAM_ERR(CAM_IR_LED, "Cannot get PWM device"); + ictrl->ir_led_driver_type = IR_LED_DRIVER_PMIC; + } else { + ictrl->ir_led_driver_type = IR_LED_DRIVER_GPIO; + } + + return rc; + +release_soc_res: + cam_soc_util_release_platform_resource(soc_info); + return rc; +} diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_ir_led/cam_ir_led_soc.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ir_led/cam_ir_led_soc.h new file mode 100644 index 000000000000..3a9139ae2cc1 --- /dev/null +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ir_led/cam_ir_led_soc.h @@ -0,0 +1,21 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _CAM_IR_LED_SOC_H_ +#define _CAM_IR_LED_SOC_H_ + +#include "cam_ir_led_dev.h" + +int cam_ir_led_get_dt_data(struct cam_ir_led_ctrl *fctrl, + struct cam_hw_soc_info *soc_info); + +#endif /*_CAM_IR_LED_SOC_H_*/ diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c index 7c44aaa4ccec..69161aaf2a0b 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c @@ -556,6 +556,8 @@ void cam_sensor_query_cap(struct cam_sensor_ctrl_t *s_ctrl, s_ctrl->sensordata->subdev_id[SUB_MODULE_LED_FLASH]; query_cap->ois_slot_id = s_ctrl->sensordata->subdev_id[SUB_MODULE_OIS]; + query_cap->ir_led_slot_id = + s_ctrl->sensordata->subdev_id[SUB_MODULE_IR_LED]; query_cap->slot_info = s_ctrl->soc_info.index; } diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_soc.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_soc.c index 6d7d07cb4ff3..0e19f4b3aa66 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_soc.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_soc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -98,6 +98,21 @@ int32_t cam_sensor_get_sub_module_index(struct device_node *of_node, else sensor_info->subdev_id[SUB_MODULE_CSIPHY] = val; + src_node = of_parse_phandle(of_node, "ir-led-src", 0); + if (!src_node) { + CAM_DBG(CAM_SENSOR, "ir led src_node NULL"); + } else { + rc = of_property_read_u32(src_node, "cell-index", &val); + CAM_DBG(CAM_SENSOR, "ir led cell index %d, rc %d", val, rc); + if (rc < 0) { + CAM_ERR(CAM_SENSOR, "failed %d", rc); + of_node_put(src_node); + return rc; + } + sensor_info->subdev_id[SUB_MODULE_IR_LED] = val; + of_node_put(src_node); + } + return rc; } diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_cmn_header.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_cmn_header.h index 5c5310987f62..955dc0cf36cf 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_cmn_header.h +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_cmn_header.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -132,6 +132,7 @@ enum sensor_sub_module { SUB_MODULE_CSID, SUB_MODULE_CSIPHY, SUB_MODULE_OIS, + SUB_MODULE_IR_LED, SUB_MODULE_EXT, SUB_MODULE_MAX, }; diff --git a/drivers/media/platform/msm/camera/cam_utils/cam_debug_util.c b/drivers/media/platform/msm/camera/cam_utils/cam_debug_util.c index 4f326342e3a7..8ad985898702 100644 --- a/drivers/media/platform/msm/camera/cam_utils/cam_debug_util.c +++ b/drivers/media/platform/msm/camera/cam_utils/cam_debug_util.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundataion. All rights reserved. +/* Copyright (c) 2017-2019, The Linux Foundataion. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -98,6 +98,9 @@ const char *cam_get_module_name(unsigned int module_id) case CAM_REQ: name = "CAM-REQ"; break; + case CAM_IR_LED: + name = "CAM-IR-LED"; + break; default: name = "CAM"; break; diff --git a/drivers/media/platform/msm/camera/cam_utils/cam_debug_util.h b/drivers/media/platform/msm/camera/cam_utils/cam_debug_util.h index 3fa92df65a3a..52c334201478 100644 --- a/drivers/media/platform/msm/camera/cam_utils/cam_debug_util.h +++ b/drivers/media/platform/msm/camera/cam_utils/cam_debug_util.h @@ -47,6 +47,7 @@ #define CAM_PERF (1 << 25) #define CAM_HYP (1 << 26) +#define CAM_IR_LED (1 << 27) #define STR_BUFFER_MAX_LENGTH 1024 /* diff --git a/include/uapi/media/cam_req_mgr.h b/include/uapi/media/cam_req_mgr.h index b903078dccbd..5341d626e017 100644 --- a/include/uapi/media/cam_req_mgr.h +++ b/include/uapi/media/cam_req_mgr.h @@ -24,6 +24,7 @@ #define CAM_FLASH_DEVICE_TYPE (CAM_DEVICE_TYPE_BASE + 11) #define CAM_EEPROM_DEVICE_TYPE (CAM_DEVICE_TYPE_BASE + 12) #define CAM_OIS_DEVICE_TYPE (CAM_DEVICE_TYPE_BASE + 13) +#define CAM_IRLED_DEVICE_TYPE (CAM_DEVICE_TYPE_BASE + 14) /* cam_req_mgr hdl info */ #define CAM_REQ_MGR_HDL_IDX_POS 8 diff --git a/include/uapi/media/cam_sensor.h b/include/uapi/media/cam_sensor.h index f5af6047f5ac..8fc180b7b632 100644 --- a/include/uapi/media/cam_sensor.h +++ b/include/uapi/media/cam_sensor.h @@ -9,6 +9,7 @@ #define CAM_FLASH_MAX_LED_TRIGGERS 3 #define MAX_OIS_NAME_SIZE 32 #define CAM_CSIPHY_SECURE_MODE_ENABLED 1 +#define CAM_IR_LED_SUPPORTED /** * struct cam_sensor_query_cap - capabilities info for sensor * @@ -22,6 +23,7 @@ * @ois_slot_id : OIS slot id which connected to sensor * @flash_slot_id : Flash slot id which connected to sensor * @csiphy_slot_id : CSIphy slot id which connected to sensor + * @irled_slot_id : IRLED slot id which connected to sensor * */ struct cam_sensor_query_cap { @@ -35,6 +37,7 @@ struct cam_sensor_query_cap { uint32_t ois_slot_id; uint32_t flash_slot_id; uint32_t csiphy_slot_id; + uint32_t ir_led_slot_id; } __attribute__((packed)); /** @@ -474,4 +477,32 @@ struct cam_flash_query_cap_info { uint32_t max_current_torch[CAM_FLASH_MAX_LED_TRIGGERS]; } __attribute__ ((packed)); +/** + * struct cam_ir_led_query_cap : capabilities info for ir_led + * + * @slot_info : Indicates about the slotId or cell Index + * + */ +struct cam_ir_led_query_cap_info { + uint32_t slot_info; +} __attribute__ ((packed)); + +/** + * struct cam_ir_ledset_on_off : led turn on/off command buffer + * + * @opcode : command buffer opcodes + * @cmd_type : command buffer operation type + * @ir_led_intensity : ir led intensity level + * @pwm_duty_on_ns : PWM duty cycle in ns for IRLED intensity + * @pwm_period_ns : PWM period in ns + * + */ +struct cam_ir_led_set_on_off { + uint16_t reserved; + uint8_t opcode; + uint8_t cmd_type; + uint32_t ir_led_intensity; + uint32_t pwm_duty_on_ns; + uint32_t pwm_period_ns; +} __attribute__((packed)); #endif -- GitLab From a7a7037b04db0511ea3bc0fddec23b37b6798ad3 Mon Sep 17 00:00:00 2001 From: Chandana Kishori Chiluveru Date: Tue, 11 Jun 2019 12:38:42 +0530 Subject: [PATCH 0604/1121] USB: configfs: Send DISCONNECT uevent during UDC bind commit ("USB: configfs: Don't send DISCONNECT uevent during unbind") removed sending disconnect uevent from unbind path. In normal disconnect path kernel will notify the disconnect event from dwc3_disconnect_gadget() function. If their is a race between composition switch and cable disconnect dwc gadget pointers may become null from composition unbind rules and then we end up not sending any disconnect notification to usespace and status remains in usb connected state in usb preferences screen. Hence fix this issue by scheduling android work from bind path which will send disconnect event to userspace. Change-Id: Ic53d8d9f6e5ae19d28bb1c23722a62a38f80ec08 Signed-off-by: Chandana Kishori Chiluveru --- drivers/usb/gadget/configfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index 1c51407ae16e..457e2b181f1c 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -329,6 +329,7 @@ static ssize_t gadget_dev_desc_UDC_store(struct config_item *item, gi->composite.gadget_driver.udc_name = NULL; goto err; } + schedule_work(&gi->work); } mutex_unlock(&gi->lock); return len; -- GitLab From 64919e5bb6d66827ed621a939ac5a7d723c7af15 Mon Sep 17 00:00:00 2001 From: vagdhan kumar kanukurthi Date: Tue, 18 Jun 2019 14:45:53 +0530 Subject: [PATCH 0605/1121] clk: qcom: Add sa6155 sdhci support for virtual clock Add sa6155 sdhci clocks in virtual clock driver. Change-Id: I3eb7c091560651b065f11a27baaf37b8e129b83f Signed-off-by: Vagdhan Kanukurthi --- drivers/clk/qcom/clk-virt-sm6150.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/clk/qcom/clk-virt-sm6150.c b/drivers/clk/qcom/clk-virt-sm6150.c index cb747efec1b1..bcfcf42c3ad3 100644 --- a/drivers/clk/qcom/clk-virt-sm6150.c +++ b/drivers/clk/qcom/clk-virt-sm6150.c @@ -281,6 +281,20 @@ static struct clk_virt gcc_pcie_phy_aux_clk = { }, }; +static struct clk_virt gcc_sdcc2_ahb_clk = { + .hw.init = &(struct clk_init_data) { + .ops = &clk_virt_ops, + .name = "gcc_sdcc2_ahb_clk", + }, +}; + +static struct clk_virt gcc_sdcc2_apps_clk = { + .hw.init = &(struct clk_init_data) { + .ops = &clk_virt_ops, + .name = "gcc_sdcc2_apps_clk", + }, +}; + static struct clk_hw *sm6150_gcc_virt_clocks[] = { [GCC_QUPV3_WRAP0_S0_CLK] = &gcc_qupv3_wrap0_s0_clk.hw, [GCC_QUPV3_WRAP0_S1_CLK] = &gcc_qupv3_wrap0_s1_clk.hw, @@ -318,6 +332,8 @@ static struct clk_hw *sm6150_gcc_virt_clocks[] = { [GCC_PCIE_0_SLV_Q2A_AXI_CLK] = &gcc_pcie_0_slv_q2a_axi_clk.hw, [GCC_PCIE0_PHY_REFGEN_CLK] = &gcc_pcie0_phy_refgen_clk.hw, [GCC_PCIE_PHY_AUX_CLK] = &gcc_pcie_phy_aux_clk.hw, + [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.hw, + [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.hw, }; const struct clk_virt_desc clk_virt_sm6150_gcc = { -- GitLab From 57254179bed9c75571e9e31b7a80004ccfc48e62 Mon Sep 17 00:00:00 2001 From: Manu Gautam Date: Tue, 18 Jun 2019 15:41:50 +0530 Subject: [PATCH 0606/1121] usb: dwc3-msm: Program MSB of doorbell register when using dummy_addr Driver currently assumes that dma mapped address for doorbell register would be 32 bit only. This assumption works fine for real doorbell register. However, if memory address is used as dummy doorbell register then we must program MSB register as well as buffer address could be more than 32 bits if IOMMU is not enabled with USB. If IOMMU is enabled then dma-mapped address would always be of 32 bits and this issue won't be seen. Change-Id: Id33117830dfebe60216bdf035d2530d584dc6b6b Signed-off-by: Manu Gautam --- drivers/usb/dwc3/dwc3-msm.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index 487d3d231071..a3116cc2b627 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -1009,6 +1009,10 @@ static void gsi_store_ringbase_dbl_info(struct usb_ep *ep, * Replace dummy doorbell address with real one as IPA connection * is setup now and GSI must be ready to handle doorbell updates. */ + dwc3_msm_write_reg_field(mdwc->base, + GSI_DBL_ADDR_H(mdwc->gsi_reg[DBL_ADDR_H], (n)), + ~0x0, 0x0); + dwc3_msm_write_reg(mdwc->base, GSI_DBL_ADDR_L(mdwc->gsi_reg[DBL_ADDR_L], (n)), (u32)request->mapped_db_reg_phs_addr_lsb); @@ -1290,6 +1294,10 @@ static void gsi_configure_ep(struct usb_ep *ep, struct usb_gsi_request *request) int ret; /* setup dummy doorbell as IPA connection isn't setup yet */ + dwc3_msm_write_reg_field(mdwc->base, + GSI_DBL_ADDR_H(mdwc->gsi_reg[DBL_ADDR_H], (n)), + ~0x0, (u32)((u64)mdwc->dummy_gsi_db_dma >> 32)); + dwc3_msm_write_reg_field(mdwc->base, GSI_DBL_ADDR_L(mdwc->gsi_reg[DBL_ADDR_L], (n)), ~0x0, (u32)mdwc->dummy_gsi_db_dma); -- GitLab From e965eef4c370419d8158652cc1e3d2f10827884e Mon Sep 17 00:00:00 2001 From: Hardik Arya Date: Mon, 17 Jun 2019 17:45:16 +0530 Subject: [PATCH 0607/1121] diag: Update diag get log request structure Currently diag get log mask is using structure with num_items which is not being used. The patch updates structure for diag get log mask request. Change-Id: I1d4d110ca1793e1c8bedcab33e2626f02af37926 Signed-off-by: Hardik Arya --- drivers/char/diag/diag_masks.c | 6 +++--- drivers/char/diag/diag_masks.h | 9 ++++++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c index eca580ae337a..e2b022affbee 100644 --- a/drivers/char/diag/diag_masks.c +++ b/drivers/char/diag/diag_masks.c @@ -1206,7 +1206,7 @@ static int diag_cmd_get_log_mask(unsigned char *src_buf, int src_len, int rsp_header_len = sizeof(struct diag_log_config_rsp_t); uint32_t mask_size = 0; struct diag_log_mask_t *log_item = NULL; - struct diag_log_config_req_t *req; + struct diag_log_config_get_req_t *req; struct diag_log_config_rsp_t rsp; struct diag_mask_info *mask_info = NULL; struct diag_md_session_t *info = NULL; @@ -1216,7 +1216,7 @@ static int diag_cmd_get_log_mask(unsigned char *src_buf, int src_len, mask_info = (!info) ? &log_mask : info->log_mask; if (!src_buf || !dest_buf || dest_len <= 0 || !mask_info || - src_len < sizeof(struct diag_log_config_req_t)) { + src_len < sizeof(struct diag_log_config_get_req_t)) { pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d, mask_info: %pK\n", __func__, src_buf, src_len, dest_buf, dest_len, mask_info); @@ -1235,7 +1235,7 @@ static int diag_cmd_get_log_mask(unsigned char *src_buf, int src_len, return 0; } - req = (struct diag_log_config_req_t *)src_buf; + req = (struct diag_log_config_get_req_t *)src_buf; read_len += req_header_len; rsp.cmd_code = DIAG_CMD_LOG_CONFIG; diff --git a/drivers/char/diag/diag_masks.h b/drivers/char/diag/diag_masks.h index 0ccadf30f092..53966e58284c 100644 --- a/drivers/char/diag/diag_masks.h +++ b/drivers/char/diag/diag_masks.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2015, 2017-2018 The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2015, 2017-2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -40,6 +40,13 @@ struct diag_msg_mask_t { uint32_t *ptr; }; +struct diag_log_config_get_req_t { + uint8_t cmd_code; + uint8_t padding[3]; + uint32_t sub_cmd; + uint32_t equip_id; +} __packed; + struct diag_log_config_req_t { uint8_t cmd_code; uint8_t padding[3]; -- GitLab From 601c3460d143f5182fa2a3391b5e72dbbb38e8ce Mon Sep 17 00:00:00 2001 From: vagdhan kumar kanukurthi Date: Tue, 18 Jun 2019 17:51:44 +0530 Subject: [PATCH 0608/1121] defconfig: msm: Enable support for sdhci in qti-quin-gvm Enable sdcard support for qti-quin-gvm. Change-Id: Ied480b3e98ce5c34eb9125dfac2cd8c5b7d61c9d Signed-off-by: Vagdhan Kanukurthi --- .../configs/vendor/qti-quin-gvm-perf_defconfig | 13 +++++++++++++ arch/arm64/configs/vendor/qti-quin-gvm_defconfig | 14 ++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/arch/arm64/configs/vendor/qti-quin-gvm-perf_defconfig b/arch/arm64/configs/vendor/qti-quin-gvm-perf_defconfig index d9989c6dd3f5..1c21491ae274 100644 --- a/arch/arm64/configs/vendor/qti-quin-gvm-perf_defconfig +++ b/arch/arm64/configs/vendor/qti-quin-gvm-perf_defconfig @@ -390,6 +390,17 @@ CONFIG_USB_CONFIGFS_F_GSI=y CONFIG_USB_CONFIGFS_F_QDSS=y CONFIG_USB_PD_POLICY=y CONFIG_QPNP_USB_PDPHY=y +CONFIG_MMC=y +CONFIG_MMC_PERF_PROFILING=y +CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_BLOCK_DEFERRED_RESUME=y +CONFIG_MMC_TEST=m +CONFIG_MMC_PARANOID_SD_INIT=y +CONFIG_MMC_CLKGATE=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_MSM=y +CONFIG_MMC_CQ_HCI=y CONFIG_RTC_CLASS=y CONFIG_DMADEVICES=y CONFIG_UIO=y @@ -422,6 +433,8 @@ CONFIG_MSM_SUBSYSTEM_RESTART=y CONFIG_MSM_PIL=y CONFIG_MEM_SHARE_QMI_SERVICE=y CONFIG_MSM_HAB=y +CONFIG_PM_DEVFREQ=y +CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y CONFIG_EXTCON_USB_GPIO=y CONFIG_ANDROID=y CONFIG_ANDROID_BINDER_IPC=y diff --git a/arch/arm64/configs/vendor/qti-quin-gvm_defconfig b/arch/arm64/configs/vendor/qti-quin-gvm_defconfig index 7eed8e1c416a..0ab5f39e47ad 100644 --- a/arch/arm64/configs/vendor/qti-quin-gvm_defconfig +++ b/arch/arm64/configs/vendor/qti-quin-gvm_defconfig @@ -403,6 +403,18 @@ CONFIG_USB_CONFIGFS_F_GSI=y CONFIG_USB_CONFIGFS_F_QDSS=y CONFIG_USB_PD_POLICY=y CONFIG_QPNP_USB_PDPHY=y +CONFIG_MMC=y +CONFIG_MMC_PERF_PROFILING=y +CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_BLOCK_DEFERRED_RESUME=y +CONFIG_MMC_TEST=m +CONFIG_MMC_RING_BUFFER=y +CONFIG_MMC_PARANOID_SD_INIT=y +CONFIG_MMC_CLKGATE=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_MSM=y +CONFIG_MMC_CQ_HCI=y CONFIG_RTC_CLASS=y CONFIG_DMADEVICES=y CONFIG_UIO=y @@ -435,6 +447,8 @@ CONFIG_MSM_SUBSYSTEM_RESTART=y CONFIG_MSM_PIL=y CONFIG_MEM_SHARE_QMI_SERVICE=y CONFIG_MSM_HAB=y +CONFIG_PM_DEVFREQ=y +CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y CONFIG_EXTCON_USB_GPIO=y CONFIG_ANDROID=y CONFIG_ANDROID_BINDER_IPC=y -- GitLab From e820d6f61c59b807384264d73a57a7938c82c109 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Wed, 22 May 2019 13:01:02 +0530 Subject: [PATCH 0609/1121] msm: vidc: add additional check to avoid out of bound access pkt->msg_size can be corrupted, that leads to OOB access. So added additional conditional check to avoid OOB access in debug queue packet handling. Change-Id: I360812c40369ecef2dd99464d400661bc785074b Signed-off-by: Govindaraj Rajagopal --- drivers/media/platform/msm/vidc/venus_hfi.c | 37 +++++++++++++++++-- .../media/platform/msm/vidc/vidc_hfi_helper.h | 5 +++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c index 3b1b3398f796..b22f228e2017 100644 --- a/drivers/media/platform/msm/vidc/venus_hfi.c +++ b/drivers/media/platform/msm/vidc/venus_hfi.c @@ -45,6 +45,7 @@ #define FIRMWARE_SIZE 0X00A00000 #define REG_ADDR_OFFSET_BITMASK 0x000FFFFF #define QDSS_IOVA_START 0x80001000 +#define MIN_PAYLOAD_SIZE 3 #define VERSION_HANA (0x5 << 28 | 0x10 << 16) @@ -3443,22 +3444,50 @@ static void __flush_debug_queue(struct venus_hfi_device *device, u8 *packet) log_level = VIDC_ERR; } +#define SKIP_INVALID_PKT(pkt_size, payload_size, pkt_hdr_size) ({ \ + if (pkt_size < pkt_hdr_size || \ + payload_size < MIN_PAYLOAD_SIZE || \ + payload_size > \ + (pkt_size - pkt_hdr_size + sizeof(u8))) { \ + dprintk(VIDC_ERR, \ + "%s: invalid msg size - %d\n", \ + __func__, pkt->msg_size); \ + continue; \ + } \ + }) + while (!__iface_dbgq_read(device, packet)) { - struct hfi_msg_sys_coverage_packet *pkt = - (struct hfi_msg_sys_coverage_packet *) packet; + struct hfi_packet_header *pkt = + (struct hfi_packet_header *) packet; + + if (pkt->size < sizeof(struct hfi_packet_header)) { + dprintk(VIDC_ERR, "Invalid pkt size - %s\n", + __func__); + continue; + } if (pkt->packet_type == HFI_MSG_SYS_COV) { + struct hfi_msg_sys_coverage_packet *pkt = + (struct hfi_msg_sys_coverage_packet *) packet; int stm_size = 0; + SKIP_INVALID_PKT(pkt->size, + pkt->msg_size, sizeof(*pkt)); + stm_size = stm_log_inv_ts(0, 0, pkt->rg_msg_data, pkt->msg_size); if (stm_size == 0) dprintk(VIDC_ERR, "In %s, stm_log returned size of 0\n", __func__); - } else { + + } else if (pkt->packet_type == HFI_MSG_SYS_DEBUG) { struct hfi_msg_sys_debug_packet *pkt = (struct hfi_msg_sys_debug_packet *) packet; + + SKIP_INVALID_PKT(pkt->size, + pkt->msg_size, sizeof(*pkt)); + /* * All fw messages starts with new line character. This * causes dprintk to print this message in two lines @@ -3466,9 +3495,11 @@ static void __flush_debug_queue(struct venus_hfi_device *device, u8 *packet) * from the message fixes this to print it in a single * line. */ + pkt->rg_msg_data[pkt->msg_size-1] = '\0'; dprintk(log_level, "%s", &pkt->rg_msg_data[1]); } } +#undef SKIP_INVALID_PKT if (local_packet) kfree(packet); diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h index 424c663e8a5d..a49e8fd7f9f5 100644 --- a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h +++ b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h @@ -917,6 +917,11 @@ struct vidc_hal_session_cmd_pkt { u32 session_id; }; +struct hfi_packet_header { + u32 size; + u32 packet_type; +}; + struct hfi_cmd_sys_init_packet { u32 size; u32 packet_type; -- GitLab From 53547d502a4ae68a5f9725d06afc1c86ea012a19 Mon Sep 17 00:00:00 2001 From: Conner Huff Date: Tue, 11 Jun 2019 15:27:55 -0700 Subject: [PATCH 0610/1121] net: qualcomm: rmnet: DL marker v2 for frags With the paged data memory scheme recently implemented in rmnet driver, we had a couple issues. Fixes stats which ethtool pulls from, changes type of struct our command packet is pointed to by so as not to overshoot, and points to the proper v2 dl marker callback Change-Id: I4188b8b1f06bace2f98f4def314b72c8552eda52 Signed-off-by: Conner Huff --- .../qualcomm/rmnet/rmnet_descriptor.c | 49 ++++++++++++++----- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c index a644809106fa..d5728edc5d2b 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c @@ -197,17 +197,25 @@ static void rmnet_frag_send_ack(struct rmnet_map_header *qmap, netif_tx_unlock(dev); } -static void rmnet_frag_process_flow_start(struct rmnet_map_control_command *cmd, - struct rmnet_port *port, - u16 cmd_len) +static void +rmnet_frag_process_flow_start(struct rmnet_map_control_command_header *cmd, + struct rmnet_port *port, + u16 cmd_len) { struct rmnet_map_dl_ind_hdr *dlhdr; + u32 data_format; + bool is_dl_mark_v2; - if (cmd_len < RMNET_DL_IND_HDR_SIZE) + if (cmd_len + sizeof(struct rmnet_map_header) < RMNET_DL_IND_HDR_SIZE) return; + data_format = port->data_format; + is_dl_mark_v2 = data_format & RMNET_INGRESS_FORMAT_DL_MARKER_V2; dlhdr = (struct rmnet_map_dl_ind_hdr *)((char *)cmd + sizeof(*cmd)); + port->stats.dl_hdr_last_ep_id = cmd->source_id; + port->stats.dl_hdr_last_qmap_vers = cmd->reserved; + port->stats.dl_hdr_last_trans_id = cmd->transaction_id; port->stats.dl_hdr_last_seq = dlhdr->le.seq; port->stats.dl_hdr_last_bytes = dlhdr->le.bytes; port->stats.dl_hdr_last_pkts = dlhdr->le.pkts; @@ -216,24 +224,41 @@ static void rmnet_frag_process_flow_start(struct rmnet_map_control_command *cmd, port->stats.dl_hdr_total_pkts += port->stats.dl_hdr_last_pkts; port->stats.dl_hdr_count++; - rmnet_map_dl_hdr_notify(port, dlhdr); + /* If a target is taking frag path, we can assume DL marker v2 is in + * play + */ + if (is_dl_mark_v2) + rmnet_map_dl_hdr_notify_v2(port, dlhdr, cmd); + else + rmnet_map_dl_hdr_notify(port, dlhdr); } -static void rmnet_frag_process_flow_end(struct rmnet_map_control_command *cmd, - struct rmnet_port *port, - u16 cmd_len) +static void +rmnet_frag_process_flow_end(struct rmnet_map_control_command_header *cmd, + struct rmnet_port *port, u16 cmd_len) { struct rmnet_map_dl_ind_trl *dltrl; + u32 data_format; + bool is_dl_mark_v2; + - if (cmd_len < RMNET_DL_IND_TRL_SIZE) + if (cmd_len + sizeof(struct rmnet_map_header) < RMNET_DL_IND_TRL_SIZE) return; + data_format = port->data_format; + is_dl_mark_v2 = data_format & RMNET_INGRESS_FORMAT_DL_MARKER_V2; dltrl = (struct rmnet_map_dl_ind_trl *)((char *)cmd + sizeof(*cmd)); port->stats.dl_trl_last_seq = dltrl->seq_le; port->stats.dl_trl_count++; - rmnet_map_dl_trl_notify(port, dltrl); + /* If a target is taking frag path, we can assume DL marker v2 is in + * play + */ + if (is_dl_mark_v2) + rmnet_map_dl_trl_notify_v2(port, dltrl, cmd); + else + rmnet_map_dl_trl_notify(port, dltrl); } /* Process MAP command frame and send N/ACK message as appropriate. Message cmd @@ -269,10 +294,10 @@ void rmnet_frag_command(struct rmnet_map_header *qmap, struct rmnet_port *port) int rmnet_frag_flow_command(struct rmnet_map_header *qmap, struct rmnet_port *port, u16 pkt_len) { - struct rmnet_map_control_command *cmd; + struct rmnet_map_control_command_header *cmd; unsigned char command_name; - cmd = (struct rmnet_map_control_command *) + cmd = (struct rmnet_map_control_command_header *) ((char *)qmap + sizeof(*qmap)); command_name = cmd->command_name; -- GitLab From e06ef8ea48e5fd56e2241eba00d67b432bedd045 Mon Sep 17 00:00:00 2001 From: Rishabh Bhatnagar Date: Wed, 29 May 2019 16:36:55 -0700 Subject: [PATCH 0611/1121] esoc: Add mdm error-fatal notifier hook Add an error-fatal notifier hook to the list of other client hooks, which would notify the clients about modem's unexpected reset or error-fatal. Change-Id: I185c4b05795b7ffb0768c240f25cc487f3d67b63 Signed-off-by: Rishabh Bhatnagar --- drivers/esoc/esoc-mdm-drv.c | 19 ++++++++++++++++++- include/linux/esoc_client.h | 1 + 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/esoc/esoc-mdm-drv.c b/drivers/esoc/esoc-mdm-drv.c index 353bcfe2114f..9fe5a8c23de8 100644 --- a/drivers/esoc/esoc-mdm-drv.c +++ b/drivers/esoc/esoc-mdm-drv.c @@ -65,6 +65,7 @@ struct mdm_drv { static void esoc_client_link_power_off(struct esoc_clink *esoc_clink, unsigned int flags); +static void esoc_client_link_mdm_crash(struct esoc_clink *esoc_clink); int esoc_set_boot_fail_action(struct esoc_clink *esoc_clink, u32 action) { @@ -201,10 +202,11 @@ static void mdm_ssr_fn(struct work_struct *work) struct mdm_drv *mdm_drv = container_of(work, struct mdm_drv, ssr_work); struct mdm_ctrl *mdm = get_esoc_clink_data(mdm_drv->esoc_clink); + esoc_client_link_mdm_crash(mdm_drv->esoc_clink); + mdm_wait_for_status_low(mdm, false); esoc_mdm_log("Starting SSR work\n"); - /* * If restarting esoc fails, the SSR framework triggers a kernel panic */ @@ -248,6 +250,21 @@ static void esoc_client_link_power_off(struct esoc_clink *esoc_clink, } } +static void esoc_client_link_mdm_crash(struct esoc_clink *esoc_clink) +{ + int i; + struct esoc_client_hook *client_hook; + + dev_dbg(&esoc_clink->dev, "Calling mdm_crash hooks\n"); + esoc_mdm_log("Calling mdm_crash hooks\n"); + + for (i = 0; i < ESOC_MAX_HOOKS; i++) { + client_hook = esoc_clink->client_hook[i]; + if (client_hook && client_hook->esoc_link_mdm_crash) + client_hook->esoc_link_mdm_crash(client_hook->priv); + } +} + static void mdm_crash_shutdown(const struct subsys_desc *mdm_subsys) { struct esoc_clink *esoc_clink = diff --git a/include/linux/esoc_client.h b/include/linux/esoc_client.h index 9a4167a18c82..7540fe72bcd6 100644 --- a/include/linux/esoc_client.h +++ b/include/linux/esoc_client.h @@ -38,6 +38,7 @@ struct esoc_client_hook { int (*esoc_link_power_on)(void *priv, unsigned int flags); void (*esoc_link_power_off)(void *priv, unsigned int flags); u64 (*esoc_link_get_id)(void *priv); + void (*esoc_link_mdm_crash)(void *priv); }; /* -- GitLab From 51c4d9f6442e24f87ecc107d7d421d1b387bf42c Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Fri, 26 Apr 2019 10:09:06 -0700 Subject: [PATCH 0612/1121] ARM: dts: msm: Add TSPP pin definitions for sdmshrike Provide device tree entries for TSPP pin definitions needed by sdmshrike. Change-Id: I61b77f63fe96eab5c5a19d2b79215b6d7507c1d2 Signed-off-by: Anant Goel --- .../boot/dts/qcom/sdmshrike-pinctrl.dtsi | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdmshrike-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sdmshrike-pinctrl.dtsi index 28d312ae4122..d469d38a23e3 100644 --- a/arch/arm64/boot/dts/qcom/sdmshrike-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/sdmshrike-pinctrl.dtsi @@ -2782,6 +2782,66 @@ }; }; + tsif0_signals_active: tsif0_signals_active { + tsif1_clk { + pins = "gpio88"; /* TSIF0 CLK */ + function = "tsif1_clk"; + }; + tsif1_en { + pins = "gpio89"; /* TSIF0 Enable */ + function = "tsif1_en"; + }; + tsif1_data { + pins = "gpio90"; /* TSIF0 DATA */ + function = "tsif1_data"; + }; + signals_cfg { + pins = "gpio88", "gpio89", "gpio90"; + drive_strength = <2>; /* 2 mA */ + bias-pull-down; /* pull down */ + }; + }; + + /* sync signal is only used if configured to mode-2 */ + tsif0_sync_active: tsif0_sync_active { + tsif1_sync { + pins = "gpio91"; /* TSIF0 SYNC */ + function = "tsif1_sync"; + drive_strength = <2>; /* 2 mA */ + bias-pull-down; /* pull down */ + }; + }; + + tsif1_signals_active: tsif1_signals_active { + tsif2_clk { + pins = "gpio92"; /* TSIF1 CLK */ + function = "tsif2_clk"; + }; + tsif2_en { + pins = "gpio93"; /* TSIF1 Enable */ + function = "tsif2_en"; + }; + tsif2_data { + pins = "gpio94"; /* TSIF1 DATA */ + function = "tsif2_data"; + }; + signals_cfg { + pins = "gpio92", "gpio93", "gpio94"; + drive_strength = <2>; /* 2 mA */ + bias-pull-down; /* pull down */ + }; + }; + + /* sync signal is only used if configured to mode-2 */ + tsif1_sync_active: tsif1_sync_active { + tsif2_sync { + pins = "gpio95"; /* TSIF1 SYNC */ + function = "tsif2_sync"; + drive_strength = <2>; /* 2 mA */ + bias-pull-down; /* pull down */ + }; + }; + /* SE0 pin mappings */ qupv3_se0_i2c_pins: qupv3_se0_i2c_pins { qupv3_se0_i2c_active: qupv3_se0_i2c_active { -- GitLab From 1e97cd17037296c96cfae6608b7e25b03d7e3925 Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Tue, 18 Jun 2019 00:57:46 -0700 Subject: [PATCH 0613/1121] ARM: dts: add pinctrl handle in snd card on 8155 platform Add pinctrl handle information in snd card node on automotive 8155 platform. Change-Id: Ieaf4074f6d4e96dbdc7cd155d462d1618682c728 Signed-off-by: Derek Chen --- arch/arm64/boot/dts/qcom/sa8155-audio.dtsi | 61 +++++++++++----------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sa8155-audio.dtsi b/arch/arm64/boot/dts/qcom/sa8155-audio.dtsi index b18164fa69df..72dbd6a6d2b5 100644 --- a/arch/arm64/boot/dts/qcom/sa8155-audio.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8155-audio.dtsi @@ -12,7 +12,7 @@ */ &soc { - qcom,msm-dai-tdm-pri-rx { + tdm_pri_rx: qcom,msm-dai-tdm-pri-rx { compatible = "qcom,msm-dai-tdm"; qcom,msm-cpudai-tdm-group-id = <37120>; qcom,msm-cpudai-tdm-group-num-ports = <4>; @@ -50,7 +50,7 @@ }; }; - qcom,msm-dai-tdm-pri-tx { + tdm_pri_tx: qcom,msm-dai-tdm-pri-tx { compatible = "qcom,msm-dai-tdm"; qcom,msm-cpudai-tdm-group-id = <37121>; qcom,msm-cpudai-tdm-group-num-ports = <4>; @@ -88,7 +88,7 @@ }; }; - qcom,msm-dai-tdm-sec-rx { + tdm_sec_rx: qcom,msm-dai-tdm-sec-rx { compatible = "qcom,msm-dai-tdm"; qcom,msm-cpudai-tdm-group-id = <37136>; qcom,msm-cpudai-tdm-group-num-ports = <5>; @@ -102,8 +102,10 @@ qcom,msm-cpudai-tdm-invert-sync = <0>; qcom,msm-cpudai-tdm-data-delay = <0>; pinctrl-names = "default", "sleep"; - pinctrl-0 = <&sec_tdm_active &sec_tdm_dout_active>; - pinctrl-1 = <&sec_tdm_sleep &sec_tdm_dout_sleep>; + pinctrl-0 = <&sec_tdm_active &sec_tdm_din_active + &sec_tdm_dout_active>; + pinctrl-1 = <&sec_tdm_sleep &sec_tdm_din_sleep + &sec_tdm_dout_sleep>; dai_sec_tdm_rx_0: qcom,msm-dai-q6-tdm-sec-rx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36880>; @@ -135,7 +137,7 @@ }; }; - qcom,msm-dai-tdm-sec-tx { + tdm_sec_tx: qcom,msm-dai-tdm-sec-tx { compatible = "qcom,msm-dai-tdm"; qcom,msm-cpudai-tdm-group-id = <37137>; qcom,msm-cpudai-tdm-group-num-ports = <4>; @@ -147,9 +149,6 @@ qcom,msm-cpudai-tdm-data-out = <0>; qcom,msm-cpudai-tdm-invert-sync = <0>; qcom,msm-cpudai-tdm-data-delay = <0>; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&sec_tdm_din_active>; - pinctrl-1 = <&sec_tdm_din_sleep>; dai_sec_tdm_tx_0: qcom,msm-dai-q6-tdm-sec-tx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36881>; @@ -175,7 +174,7 @@ }; }; - qcom,msm-dai-tdm-tert-rx { + tdm_tert_rx: qcom,msm-dai-tdm-tert-rx { compatible = "qcom,msm-dai-tdm"; qcom,msm-cpudai-tdm-group-id = <37152>; qcom,msm-cpudai-tdm-group-num-ports = <5>; @@ -189,8 +188,10 @@ qcom,msm-cpudai-tdm-invert-sync = <0>; qcom,msm-cpudai-tdm-data-delay = <0>; pinctrl-names = "default", "sleep"; - pinctrl-0 = <&tert_tdm_active &tert_tdm_dout_active>; - pinctrl-1 = <&tert_tdm_sleep &tert_tdm_dout_sleep>; + pinctrl-0 = <&tert_tdm_active &tert_tdm_din_active + &tert_tdm_dout_active>; + pinctrl-1 = <&tert_tdm_sleep &tert_tdm_din_sleep + &tert_tdm_dout_sleep>; dai_tert_tdm_rx_0: qcom,msm-dai-q6-tdm-tert-rx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36896>; @@ -222,7 +223,7 @@ }; }; - qcom,msm-dai-tdm-tert-tx { + tdm_tert_tx: qcom,msm-dai-tdm-tert-tx { compatible = "qcom,msm-dai-tdm"; qcom,msm-cpudai-tdm-group-id = <37153>; qcom,msm-cpudai-tdm-group-num-ports = <5>; @@ -235,9 +236,6 @@ qcom,msm-cpudai-tdm-data-out = <0>; qcom,msm-cpudai-tdm-invert-sync = <0>; qcom,msm-cpudai-tdm-data-delay = <0>; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&tert_tdm_din_active>; - pinctrl-1 = <&tert_tdm_din_sleep>; dai_tert_tdm_tx_0: qcom,msm-dai-q6-tdm-tert-tx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36897>; @@ -269,7 +267,7 @@ }; }; - qcom,msm-dai-tdm-quat-rx { + tdm_quat_rx: qcom,msm-dai-tdm-quat-rx { compatible = "qcom,msm-dai-tdm"; qcom,msm-cpudai-tdm-group-id = <37168>; qcom,msm-cpudai-tdm-group-num-ports = <5>; @@ -284,8 +282,10 @@ qcom,msm-cpudai-tdm-invert-sync = <0>; qcom,msm-cpudai-tdm-data-delay = <0>; pinctrl-names = "default", "sleep"; - pinctrl-0 = <&quat_tdm_active &quat_tdm_dout_active>; - pinctrl-1 = <&quat_tdm_sleep &quat_tdm_dout_sleep>; + pinctrl-0 = <&quat_tdm_active &quat_tdm_din_active + &quat_tdm_dout_active>; + pinctrl-1 = <&quat_tdm_sleep &quat_tdm_din_sleep + &quat_tdm_dout_sleep>; dai_quat_tdm_rx_0: qcom,msm-dai-q6-tdm-quat-rx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36912>; @@ -316,7 +316,7 @@ }; }; - qcom,msm-dai-tdm-quat-tx { + tdm_quat_tx: qcom,msm-dai-tdm-quat-tx { compatible = "qcom,msm-dai-tdm"; qcom,msm-cpudai-tdm-group-id = <37169>; qcom,msm-cpudai-tdm-group-num-ports = <5>; @@ -330,9 +330,6 @@ qcom,msm-cpudai-tdm-data-out = <0>; qcom,msm-cpudai-tdm-invert-sync = <0>; qcom,msm-cpudai-tdm-data-delay = <0>; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&quat_tdm_din_active>; - pinctrl-1 = <&quat_tdm_din_sleep>; dai_quat_tdm_tx_0: qcom,msm-dai-q6-tdm-quat-tx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36913>; @@ -364,7 +361,7 @@ }; }; - qcom,msm-dai-tdm-quin-rx { + tdm_quin_rx: qcom,msm-dai-tdm-quin-rx { compatible = "qcom,msm-dai-tdm"; qcom,msm-cpudai-tdm-group-id = <37184>; qcom,msm-cpudai-tdm-group-num-ports = <4>; @@ -377,8 +374,10 @@ qcom,msm-cpudai-tdm-invert-sync = <0>; qcom,msm-cpudai-tdm-data-delay = <0>; pinctrl-names = "default", "sleep"; - pinctrl-0 = <&quin_tdm_active &quin_tdm_dout_active>; - pinctrl-1 = <&quin_tdm_sleep &quin_tdm_dout_sleep>; + pinctrl-0 = <&quin_tdm_active &quin_tdm_din_active + &quin_tdm_dout_active>; + pinctrl-1 = <&quin_tdm_sleep &quin_tdm_din_sleep + &quin_tdm_dout_sleep>; dai_quin_tdm_rx_0: qcom,msm-dai-q6-tdm-quin-rx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36928>; @@ -404,7 +403,7 @@ }; }; - qcom,msm-dai-tdm-quin-tx { + tdm_quin_tx: qcom,msm-dai-tdm-quin-tx { compatible = "qcom,msm-dai-tdm"; qcom,msm-cpudai-tdm-group-id = <37185>; qcom,msm-cpudai-tdm-group-num-ports = <4>; @@ -416,9 +415,6 @@ qcom,msm-cpudai-tdm-data-out = <0>; qcom,msm-cpudai-tdm-invert-sync = <0>; qcom,msm-cpudai-tdm-data-delay = <0>; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&quin_tdm_din_active>; - pinctrl-1 = <&quin_tdm_din_sleep>; dai_quin_tdm_tx_0: qcom,msm-dai-q6-tdm-quin-tx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36929>; @@ -475,6 +471,11 @@ qcom,auxpcm-audio-intf; qcom,msm-mi2s-master = <1>, <1>, <1>, <1>, <1>; + qcom,sec-tdm-gpios = <&tdm_sec_rx>; + qcom,tert-tdm-gpios = <&tdm_tert_rx>; + qcom,quat-tdm-gpios = <&tdm_quat_rx>; + qcom,quin-tdm-gpios = <&tdm_quin_rx>; + asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>, <&loopback>, <&compress>, <&hostless>, <&afe>, <&lsm>, <&routing>, <&compr>, -- GitLab From c1bbcf80a1baf96bd73d35080a28d7b64620c270 Mon Sep 17 00:00:00 2001 From: Nagarjuna Paladugu Date: Mon, 27 May 2019 18:15:05 +0530 Subject: [PATCH 0614/1121] ARM: dts: msm: update audio node and pinctrl on 615x platform Add 6155 device tree node and pinctrl info for audio to maintain parity with 8155 for automotive platform. Change-Id: I2dd027953c6b75d6c07f5574b050e147303eba52 Signed-off-by: Nagarjuna Paladugu --- arch/arm64/boot/dts/qcom/sa6155-audio.dtsi | 125 ++++++++++++------ arch/arm64/boot/dts/qcom/sm6150-pinctrl.dtsi | 8 +- .../boot/dts/qcom/sm6150-slpi-pinctrl.dtsi | 40 +++--- 3 files changed, 108 insertions(+), 65 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sa6155-audio.dtsi b/arch/arm64/boot/dts/qcom/sa6155-audio.dtsi index 096142eabf92..6b8316ad66b9 100644 --- a/arch/arm64/boot/dts/qcom/sa6155-audio.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155-audio.dtsi @@ -92,8 +92,9 @@ qcom,msm-dai-tdm-sec-rx { compatible = "qcom,msm-dai-tdm"; qcom,msm-cpudai-tdm-group-id = <37136>; - qcom,msm-cpudai-tdm-group-num-ports = <4>; - qcom,msm-cpudai-tdm-group-port-id = <36880 36882 36884 36886>; + qcom,msm-cpudai-tdm-group-num-ports = <5>; + qcom,msm-cpudai-tdm-group-port-id = <36880 36882 36884 + 36886 36894>; qcom,msm-cpudai-tdm-clk-rate = <12288000>; qcom,msm-cpudai-tdm-clk-internal = <1>; qcom,msm-cpudai-tdm-sync-mode = <1>; @@ -124,6 +125,12 @@ qcom,msm-cpudai-tdm-dev-id = <36886>; qcom,msm-cpudai-tdm-data-align = <0>; }; + + dai_sec_tdm_rx_7: qcom,msm-dai-q6-tdm-sec-rx-7 { + compatible = "qcom,msm-dai-q6-tdm"; + qcom,msm-cpudai-tdm-dev-id = <36894>; + qcom,msm-cpudai-tdm-data-align = <0>; + }; }; qcom,msm-dai-tdm-sec-tx { @@ -177,8 +184,8 @@ qcom,msm-cpudai-tdm-invert-sync = <0>; qcom,msm-cpudai-tdm-data-delay = <0>; pinctrl-names = "default", "sleep"; - pinctrl-0 = <&ter_i2s_sck_active &ter_i2s_data0_active>; - pinctrl-1 = <&ter_i2s_sck_sleep &ter_i2s_data0_sleep>; + pinctrl-0 = <&ter_i2s_sck_active &ter_i2s_data1_active>; + pinctrl-1 = <&ter_i2s_sck_sleep &ter_i2s_data1_sleep>; dai_tert_tdm_rx_0: qcom,msm-dai-q6-tdm-tert-rx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36896>; @@ -213,8 +220,9 @@ qcom,msm-dai-tdm-tert-tx { compatible = "qcom,msm-dai-tdm"; qcom,msm-cpudai-tdm-group-id = <37153>; - qcom,msm-cpudai-tdm-group-num-ports = <4>; - qcom,msm-cpudai-tdm-group-port-id = <36897 36899 36901 36903>; + qcom,msm-cpudai-tdm-group-num-ports = <5>; + qcom,msm-cpudai-tdm-group-port-id = <36897 36899 36901 + 36903 36911>; qcom,msm-cpudai-tdm-clk-rate = <12288000>; qcom,msm-cpudai-tdm-clk-internal = <1>; qcom,msm-cpudai-tdm-sync-mode = <1>; @@ -223,8 +231,8 @@ qcom,msm-cpudai-tdm-invert-sync = <0>; qcom,msm-cpudai-tdm-data-delay = <0>; pinctrl-names = "default", "sleep"; - pinctrl-0 = <&ter_i2s_data1_active>; - pinctrl-1 = <&ter_i2s_data1_sleep>; + pinctrl-0 = <&ter_i2s_data0_active>; + pinctrl-1 = <&ter_i2s_data0_sleep>; dai_tert_tdm_tx_0: qcom,msm-dai-q6-tdm-tert-tx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36897>; @@ -248,13 +256,21 @@ qcom,msm-cpudai-tdm-dev-id = <36903>; qcom,msm-cpudai-tdm-data-align = <0>; }; + + dai_tert_tdm_tx_7: qcom,msm-dai-q6-tdm-tert-tx-7 { + compatible = "qcom,msm-dai-q6-tdm"; + qcom,msm-cpudai-tdm-dev-id = <36911>; + qcom,msm-cpudai-tdm-data-align = <0>; + }; }; qcom,msm-dai-tdm-quat-rx { compatible = "qcom,msm-dai-tdm"; qcom,msm-cpudai-tdm-group-id = <37168>; - qcom,msm-cpudai-tdm-group-num-ports = <4>; - qcom,msm-cpudai-tdm-group-port-id = <36912 36914 36916 36918>; + qcom,msm-cpudai-tdm-group-num-ports = <5>; + qcom,msm-cpudai-tdm-group-port-id = <36912 36914 36916 + 36918 36926>; + qcom,msm-cpudai-tdm-lane-mask = /bits/ 16 <3>; qcom,msm-cpudai-tdm-clk-rate = <24576000>; qcom,msm-cpudai-tdm-clk-internal = <1>; qcom,msm-cpudai-tdm-sync-mode = <1>; @@ -262,10 +278,11 @@ qcom,msm-cpudai-tdm-data-out = <0>; qcom,msm-cpudai-tdm-invert-sync = <0>; qcom,msm-cpudai-tdm-data-delay = <0>; + pinctrl-names = "default", "sleep"; pinctrl-0 = <&quat_tdm_sclk_active &quat_tdm_ws_active - &quat_tdm_data0_active>; + &quat_tdm_data1_active>; pinctrl-1 = <&quat_tdm_sclk_sleep &quat_tdm_ws_sleep - &quat_tdm_data0_sleep>; + &quat_tdm_data1_sleep>; dai_quat_tdm_rx_0: qcom,msm-dai-q6-tdm-quat-rx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36912>; @@ -289,13 +306,20 @@ qcom,msm-cpudai-tdm-dev-id = <36918>; qcom,msm-cpudai-tdm-data-align = <0>; }; + dai_quat_tdm_rx_7: qcom,msm-dai-q6-tdm-quat-rx-7 { + compatible = "qcom,msm-dai-q6-tdm"; + qcom,msm-cpudai-tdm-dev-id = <36926>; + qcom,msm-cpudai-tdm-data-align = <0>; + }; }; qcom,msm-dai-tdm-quat-tx { compatible = "qcom,msm-dai-tdm"; qcom,msm-cpudai-tdm-group-id = <37169>; - qcom,msm-cpudai-tdm-group-num-ports = <4>; - qcom,msm-cpudai-tdm-group-port-id = <36913 36915 36917 36919>; + qcom,msm-cpudai-tdm-group-num-ports = <5>; + qcom,msm-cpudai-tdm-group-port-id = <36913 36915 36917 + 36919 36927>; + qcom,msm-cpudai-tdm-lane-mask = /bits/ 16 <12>; qcom,msm-cpudai-tdm-clk-rate = <24576000>; qcom,msm-cpudai-tdm-clk-internal = <1>; qcom,msm-cpudai-tdm-sync-mode = <1>; @@ -303,8 +327,9 @@ qcom,msm-cpudai-tdm-data-out = <0>; qcom,msm-cpudai-tdm-invert-sync = <0>; qcom,msm-cpudai-tdm-data-delay = <0>; - pinctrl-0 = <&quat_tdm_data1_active>; - pinctrl-1 = <&quat_tdm_data1_sleep>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&quat_tdm_data0_active>; + pinctrl-1 = <&quat_tdm_data0_sleep>; dai_quat_tdm_tx_0: qcom,msm-dai-q6-tdm-quat-tx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36913>; @@ -328,6 +353,12 @@ qcom,msm-cpudai-tdm-dev-id = <36919>; qcom,msm-cpudai-tdm-data-align = <0>; }; + + dai_quat_tdm_tx_7: qcom,msm-dai-q6-tdm-quat-tx-7 { + compatible = "qcom,msm-dai-q6-tdm"; + qcom,msm-cpudai-tdm-dev-id = <36927>; + qcom,msm-cpudai-tdm-data-align = <0>; + }; }; qcom,msm-dai-tdm-quin-rx { @@ -336,16 +367,17 @@ qcom,msm-cpudai-tdm-group-num-ports = <4>; qcom,msm-cpudai-tdm-group-port-id = <36928 36930 36932 36934>; qcom,msm-cpudai-tdm-clk-rate = <12288000>; - qcom,msm-cpudai-tdm-clk-internal = <1>; + qcom,msm-cpudai-tdm-clk-internal = <0>; qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <1>; + qcom,msm-cpudai-tdm-sync-src = <0>; qcom,msm-cpudai-tdm-data-out = <0>; qcom,msm-cpudai-tdm-invert-sync = <0>; qcom,msm-cpudai-tdm-data-delay = <0>; + pinctrl-names = "default", "sleep"; pinctrl-0 = <&quin_tdm_sclk_active &quin_tdm_ws_active - &quin_tdm_data0_active>; + &quin_tdm_data1_active>; pinctrl-1 = <&quin_tdm_sclk_sleep &quin_tdm_ws_sleep - &quin_tdm_data0_sleep>; + &quin_tdm_data1_sleep>; dai_quin_tdm_rx_0: qcom,msm-dai-q6-tdm-quin-rx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36928>; @@ -377,14 +409,15 @@ qcom,msm-cpudai-tdm-group-num-ports = <4>; qcom,msm-cpudai-tdm-group-port-id = <36929 36931 36933 36935>; qcom,msm-cpudai-tdm-clk-rate = <12288000>; - qcom,msm-cpudai-tdm-clk-internal = <1>; + qcom,msm-cpudai-tdm-clk-internal = <0>; qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <1>; + qcom,msm-cpudai-tdm-sync-src = <0>; qcom,msm-cpudai-tdm-data-out = <0>; qcom,msm-cpudai-tdm-invert-sync = <0>; qcom,msm-cpudai-tdm-data-delay = <0>; - pinctrl-0 = <&quin_tdm_data1_active>; - pinctrl-1 = <&quin_tdm_data1_sleep>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&quin_tdm_data0_active>; + pinctrl-1 = <&quin_tdm_data0_sleep>; dai_quin_tdm_tx_0: qcom,msm-dai-q6-tdm-quin-tx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36929>; @@ -471,17 +504,19 @@ <&dai_pri_tdm_tx_2>, <&dai_pri_tdm_tx_3>, <&dai_sec_tdm_rx_0>, <&dai_sec_tdm_rx_1>, <&dai_sec_tdm_rx_2>, <&dai_sec_tdm_rx_3>, - <&dai_sec_tdm_tx_0>, <&dai_sec_tdm_tx_1>, - <&dai_sec_tdm_tx_2>, <&dai_sec_tdm_tx_3>, - <&dai_tert_tdm_rx_0>, <&dai_tert_tdm_rx_1>, - <&dai_tert_tdm_rx_2>, <&dai_tert_tdm_rx_3>, - <&dai_tert_tdm_rx_4>, <&dai_tert_tdm_tx_0>, - <&dai_tert_tdm_tx_1>, <&dai_tert_tdm_tx_2>, - <&dai_tert_tdm_tx_3>, <&dai_quat_tdm_rx_0>, + <&dai_sec_tdm_rx_7>, <&dai_sec_tdm_tx_0>, + <&dai_sec_tdm_tx_1>, <&dai_sec_tdm_tx_2>, + <&dai_sec_tdm_tx_3>, <&dai_tert_tdm_rx_0>, + <&dai_tert_tdm_rx_1>, <&dai_tert_tdm_rx_2>, + <&dai_tert_tdm_rx_3>, <&dai_tert_tdm_rx_4>, + <&dai_tert_tdm_tx_0>, <&dai_tert_tdm_tx_1>, + <&dai_tert_tdm_tx_2>, <&dai_tert_tdm_tx_3>, + <&dai_tert_tdm_tx_7>, <&dai_quat_tdm_rx_0>, <&dai_quat_tdm_rx_1>, <&dai_quat_tdm_rx_2>, - <&dai_quat_tdm_rx_3>, <&dai_quat_tdm_tx_0>, - <&dai_quat_tdm_tx_1>, <&dai_quat_tdm_tx_2>, - <&dai_quat_tdm_tx_3>, <&dai_quin_tdm_rx_0>, + <&dai_quat_tdm_rx_3>, <&dai_quat_tdm_rx_7>, + <&dai_quat_tdm_tx_0>, <&dai_quat_tdm_tx_1>, + <&dai_quat_tdm_tx_2>, <&dai_quat_tdm_tx_3>, + <&dai_quat_tdm_tx_7>, <&dai_quin_tdm_rx_0>, <&dai_quin_tdm_rx_1>, <&dai_quin_tdm_rx_2>, <&dai_quin_tdm_rx_3>, <&dai_quin_tdm_tx_0>, <&dai_quin_tdm_tx_1>, <&dai_quin_tdm_tx_2>, @@ -503,17 +538,19 @@ "msm-dai-q6-tdm.36869", "msm-dai-q6-tdm.36871", "msm-dai-q6-tdm.36880", "msm-dai-q6-tdm.36882", "msm-dai-q6-tdm.36884", "msm-dai-q6-tdm.36886", - "msm-dai-q6-tdm.36881", "msm-dai-q6-tdm.36883", - "msm-dai-q6-tdm.36885", "msm-dai-q6-tdm.36887", - "msm-dai-q6-tdm.36896", "msm-dai-q6-tdm.36898", - "msm-dai-q6-tdm.36900", "msm-dai-q6-tdm.36902", - "msm-dai-q6-tdm.36904", "msm-dai-q6-tdm.36897", - "msm-dai-q6-tdm.36899", "msm-dai-q6-tdm.36901", - "msm-dai-q6-tdm.36903", "msm-dai-q6-tdm.36912", + "msm-dai-q6-tdm.36894", "msm-dai-q6-tdm.36881", + "msm-dai-q6-tdm.36883", "msm-dai-q6-tdm.36885", + "msm-dai-q6-tdm.36887", "msm-dai-q6-tdm.36896", + "msm-dai-q6-tdm.36898", "msm-dai-q6-tdm.36900", + "msm-dai-q6-tdm.36902", "msm-dai-q6-tdm.36904", + "msm-dai-q6-tdm.36897", "msm-dai-q6-tdm.36899", + "msm-dai-q6-tdm.36901", "msm-dai-q6-tdm.36903", + "msm-dai-q6-tdm.36911", "msm-dai-q6-tdm.36912", "msm-dai-q6-tdm.36914", "msm-dai-q6-tdm.36916", - "msm-dai-q6-tdm.36918", "msm-dai-q6-tdm.36913", - "msm-dai-q6-tdm.36915", "msm-dai-q6-tdm.36917", - "msm-dai-q6-tdm.36919", "msm-dai-q6-tdm.36928", + "msm-dai-q6-tdm.36918", "msm-dai-q6-tdm.36926", + "msm-dai-q6-tdm.36913", "msm-dai-q6-tdm.36915", + "msm-dai-q6-tdm.36917", "msm-dai-q6-tdm.36919", + "msm-dai-q6-tdm.36927", "msm-dai-q6-tdm.36928", "msm-dai-q6-tdm.36930", "msm-dai-q6-tdm.36932", "msm-dai-q6-tdm.36934", "msm-dai-q6-tdm.36929", "msm-dai-q6-tdm.36931", "msm-dai-q6-tdm.36933", diff --git a/arch/arm64/boot/dts/qcom/sm6150-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sm6150-pinctrl.dtsi index 08f833f2731c..296ceb69f8f4 100644 --- a/arch/arm64/boot/dts/qcom/sm6150-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/sm6150-pinctrl.dtsi @@ -1099,6 +1099,7 @@ config { pins = "gpio115", "gpio116"; drive-strength = <2>; /* 2 mA */ + bias-disable; }; }; @@ -1112,6 +1113,7 @@ pins = "gpio115", "gpio116"; drive-strength = <8>; /* 8 mA */ input-enable; + bias-disable; }; }; }; @@ -1126,6 +1128,7 @@ config { pins = "gpio117"; drive-strength = <2>; /* 2 mA */ + bias-pull-up; }; }; @@ -1137,8 +1140,9 @@ config { pins = "gpio117"; - drive-strength = <8>; /* 8 mA */ + drive-strength = <2>; /* 8 mA */ input-enable; + bias-disable; }; }; }; @@ -1153,6 +1157,7 @@ config { pins = "gpio118"; drive-strength = <2>; /* 2 mA */ + bias-disable; }; }; @@ -1166,6 +1171,7 @@ pins = "gpio118"; drive-strength = <8>; /* 8 mA */ output-high; + bias-disable; }; }; }; diff --git a/arch/arm64/boot/dts/qcom/sm6150-slpi-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sm6150-slpi-pinctrl.dtsi index f00b107a6e5f..a5bac24136b7 100644 --- a/arch/arm64/boot/dts/qcom/sm6150-slpi-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/sm6150-slpi-pinctrl.dtsi @@ -258,7 +258,7 @@ config { pins = "gpio23"; drive-strength = <8>; - bias-bus-hold; + bias-disable; }; }; @@ -271,7 +271,7 @@ config { pins = "gpio23"; drive-strength = <2>; - bias-bus-hold; + bias-disable; }; }; @@ -284,7 +284,7 @@ config { pins = "gpio24"; drive-strength = <8>; - bias-bus-hold; + bias-disable; }; }; @@ -297,7 +297,7 @@ config { pins = "gpio24"; drive-strength = <2>; - bias-bus-hold; + bias-disable; }; }; @@ -310,7 +310,7 @@ config { pins = "gpio26"; drive-strength = <8>; - bias-bus-hold; + bias-disable; }; }; @@ -323,7 +323,7 @@ config { pins = "gpio26"; drive-strength = <2>; - bias-bus-hold; + bias-disable; }; }; @@ -335,8 +335,8 @@ config { pins = "gpio25"; - drive-strength = <8>; - bias-bus-hold; + drive-strength = <2>; + bias-disable; }; }; @@ -349,7 +349,7 @@ config { pins = "gpio25"; drive-strength = <2>; - bias-bus-hold; + bias-pull-up; }; }; @@ -361,8 +361,8 @@ config { pins = "gpio18"; - drive-strength = <8>; - bias-bus-hold; + drive-strength = <2>; + bias-disable; }; }; @@ -375,7 +375,7 @@ config { pins = "gpio18"; drive-strength = <2>; - bias-bus-hold; + bias-pull-down; }; }; @@ -387,8 +387,8 @@ config { pins = "gpio20"; - drive-strength = <8>; - bias-bus-hold; + drive-strength = <2>; + bias-disable; }; }; @@ -401,7 +401,7 @@ config { pins = "gpio20"; drive-strength = <2>; - bias-bus-hold; + bias-pull-up; }; }; @@ -413,8 +413,8 @@ config { pins = "gpio21"; - drive-strength = <8>; - bias-bus-hold; + drive-strength = <2>; + bias-disable; }; }; @@ -427,7 +427,7 @@ config { pins = "gpio21"; drive-strength = <2>; - bias-bus-hold; + bias-pull-down; }; }; @@ -440,7 +440,7 @@ config { pins = "gpio22"; drive-strength = <8>; - bias-bus-hold; + bias-disable; }; }; @@ -453,7 +453,7 @@ config { pins = "gpio22"; drive-strength = <2>; - bias-bus-hold; + bias-disable; }; }; -- GitLab From f561a0ebfb3fddc9e748ed411bbdf43ce33fe1e2 Mon Sep 17 00:00:00 2001 From: Bojun Pan Date: Thu, 16 May 2019 19:00:10 -0700 Subject: [PATCH 0615/1121] msm: ipa3: Drop WAN TX packets when pipe is down in ssr When ssr happens and pipe teardown, if rmnet_data still send TX packet, we should drop those instead of sending NETDEV_TX_BUSY to let it retry. Change-Id: I3558d2d32517d609ca45ee09f83785b9ecb5542f Signed-off-by: Bojun Pan --- drivers/platform/msm/ipa/ipa_v3/ipa_dp.c | 6 ++++-- drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c | 11 ++++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c index f72dd6c41e97..d6c80ef0a4d0 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c @@ -1640,8 +1640,8 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb, sys = ipa3_ctx->ep[src_ep_idx].sys; if (!sys || !sys->ep->valid) { - IPAERR_RL("pipe not valid\n"); - goto fail_gen; + IPAERR_RL("pipe %d not valid\n", src_ep_idx); + goto fail_pipe_not_valid; } num_frags = skb_shinfo(skb)->nr_frags; @@ -1809,6 +1809,8 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb, kfree(desc); fail_gen: return -EFAULT; +fail_pipe_not_valid: + return -EPIPE; } static void ipa3_wq_handle_rx(struct work_struct *work) diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c index d21f58558ce5..ab50dd06f9dd 100644 --- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c @@ -1284,7 +1284,7 @@ static int ipa3_wwan_xmit(struct sk_buff *skb, struct net_device *dev) dev_kfree_skb_any(skb); dev->stats.tx_dropped++; spin_unlock_irqrestore(&wwan_ptr->lock, flags); - return -EFAULT; + return NETDEV_TX_OK; } /* IPA_RM checking end */ @@ -1294,6 +1294,14 @@ static int ipa3_wwan_xmit(struct sk_buff *skb, struct net_device *dev) */ ret = ipa3_tx_dp(IPA_CLIENT_APPS_WAN_PROD, skb, NULL); if (ret) { + if (ret == -EPIPE) { + IPAWANERR_RL("[%s] fatal: pipe is not valid\n", + dev->name); + dev_kfree_skb_any(skb); + dev->stats.tx_dropped++; + spin_unlock_irqrestore(&wwan_ptr->lock, flags); + return NETDEV_TX_OK; + } ret = NETDEV_TX_BUSY; goto out; } @@ -2803,6 +2811,7 @@ static int ipa3_wwan_remove(struct platform_device *pdev) if (ipa3_rmnet_res.ipa_napi_enable) netif_napi_del(&(rmnet_ipa3_ctx->wwan_priv->napi)); mutex_unlock(&rmnet_ipa3_ctx->pipe_handle_guard); + IPAWANINFO("rmnet_ipa unregister_netdev\n"); unregister_netdev(IPA_NETDEV()); if (ipa3_ctx->use_ipa_pm) ipa3_wwan_deregister_netdev_pm_client(); -- GitLab From ccc1aa6aa06106dbcb0f8d2ada5b8ee34d7e248b Mon Sep 17 00:00:00 2001 From: Marco Zhang Date: Tue, 28 May 2019 12:49:15 +0800 Subject: [PATCH 0616/1121] ARM: dts: msm: Add early mount partition details for atoll Add details of vendor partition to support early mount on atoll. Change-Id: I30a284f631c1a251ebb678f80e13328a925f0ee3 Signed-off-by: Marco Zhang --- arch/arm64/boot/dts/qcom/atoll.dtsi | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index 08599320e9d0..a56e0141ec11 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -450,6 +450,23 @@ method = "smc"; }; + firmware: firmware { + android { + compatible = "android,firmware"; + fstab { + compatible = "android,fstab"; + vendor { + compatible = "android,vendor"; + dev = "/dev/block/platform/soc/7c4000.sdhci/by-name/vendor"; + type = "ext4"; + mnt_flags = "ro,barrier=1,discard"; + fsmgr_flags = "wait,slotselect"; + status = "ok"; + }; + }; + }; + }; + reserved_memory: reserved-memory { #address-cells = <2>; #size-cells = <2>; -- GitLab From 0e9a5f5982165404682c75783b2a89a536faa7f1 Mon Sep 17 00:00:00 2001 From: Michael Adisumarta Date: Tue, 18 Jun 2019 17:37:59 -0700 Subject: [PATCH 0617/1121] msm: IPA : Tethering offload clean up on MHI PRIME This change does code clean up for tethering use cases such as Rndis and WiFi on MHI Prime IPA offload path. Change-Id: Iba9191ae8dcfdda79711327902d9df33550e7c69 Acked-by: Jyothij Signed-off-by: Michael Adisumarta --- .../platform/msm/ipa/ipa_clients/ipa_usb.c | 42 +--- drivers/platform/msm/ipa/ipa_v3/ipa_i.h | 20 +- drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c | 184 +++++++++--------- .../msm/ipa/ipa_v3/rmnet_ipa_fd_ioctl.c | 3 +- 4 files changed, 98 insertions(+), 151 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_clients/ipa_usb.c b/drivers/platform/msm/ipa/ipa_clients/ipa_usb.c index ee7c1ad72883..453941d7d3c7 100644 --- a/drivers/platform/msm/ipa/ipa_clients/ipa_usb.c +++ b/drivers/platform/msm/ipa/ipa_clients/ipa_usb.c @@ -2530,17 +2530,6 @@ int ipa_usb_xdci_disconnect(u32 ul_clnt_hdl, u32 dl_clnt_hdl, if (orig_state != IPA_USB_SUSPENDED) { spin_unlock_irqrestore(&ipa3_usb_ctx->state_lock, flags); - - /* Stop UL MHIP channel */ - if (ipa3_is_mhip_offload_enabled()) { - result = ipa_mpm_mhip_ul_start_stop_data( - MPM_MHIP_STOP, teth_prot); - if (result) { - IPA_USB_ERR("fail UL MHIP Data stop\n"); - goto bad_params; - } - } - /* Stop UL channel */ result = ipa3_xdci_disconnect(ul_clnt_hdl, true, @@ -2745,21 +2734,12 @@ static int ipa3_usb_suspend_no_remote_wakeup(u32 ul_clnt_hdl, u32 dl_clnt_hdl, } if (!IPA3_USB_IS_TTYPE_DPL(ttype)) { - /* Stop UL MHIP channel - enable HOLB */ - if (ipa3_is_mhip_offload_enabled()) { - result = ipa_mpm_mhip_ul_start_stop_data(MPM_MHIP_STOP, - teth_prot); - if (result) { - IPA_USB_ERR("fail UL MHIP Data stop\n"); - goto start_dl; - } - } /* Stop UL channel */ result = ipa3_xdci_disconnect(ul_clnt_hdl, true, ipa3_usb_ctx->qmi_req_id); if (result) { IPA_USB_ERR("failed disconnect UL channel\n"); - goto start_mhip; + goto start_dl; } ipa3_usb_ctx->qmi_req_id++; } @@ -2803,10 +2783,6 @@ static int ipa3_usb_suspend_no_remote_wakeup(u32 ul_clnt_hdl, u32 dl_clnt_hdl, start_ul: if (!IPA3_USB_IS_TTYPE_DPL(ttype)) (void)ipa3_xdci_connect(ul_clnt_hdl); -start_mhip: - if (ipa3_is_mhip_offload_enabled() && !IPA3_USB_IS_TTYPE_DPL(ttype)) - (void)ipa_mpm_mhip_ul_start_stop_data(MPM_MHIP_START, - teth_prot); start_dl: (void)ipa3_xdci_connect(dl_clnt_hdl); fail_exit: @@ -2969,19 +2945,10 @@ static int ipa3_usb_resume_no_remote_wakeup(u32 ul_clnt_hdl, u32 dl_clnt_hdl, /* Start MHIP channel */ if (ipa3_is_mhip_offload_enabled()) { - if (!IPA3_USB_IS_TTYPE_DPL(ttype)) { - /* Start UL MHIP channel */ - result = ipa_mpm_mhip_ul_start_stop_data(MPM_MHIP_START, - teth_prot); - if (result) { - IPA_USB_ERR("fail UL MHIP Data Start\n"); - goto stop_dl; - } - } result = ipa_mpm_mhip_xdci_pipe_enable(teth_prot); if (result) { IPA_USB_ERR("failed to enable MHIP pipe\n"); - goto stop_mhip_data; + goto stop_dl; } } /* Change state to CONNECTED */ @@ -2995,11 +2962,6 @@ static int ipa3_usb_resume_no_remote_wakeup(u32 ul_clnt_hdl, u32 dl_clnt_hdl, stop_mhip: if (ipa3_is_mhip_offload_enabled()) (void)ipa_mpm_mhip_xdci_pipe_disable(teth_prot); -stop_mhip_data: - /* Stop UL MHIP data */ - if (ipa3_is_mhip_offload_enabled() && !IPA3_USB_IS_TTYPE_DPL(ttype)) - (void)ipa_mpm_mhip_ul_start_stop_data(MPM_MHIP_STOP, - teth_prot); stop_dl: (void)ipa3_xdci_disconnect(dl_clnt_hdl, false, -1); stop_ul: diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index d8caa5fa835c..b5aa2715d59a 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -41,6 +41,7 @@ #include "ipa_defs.h" #include #include +#include #define IPA_DEV_NAME_MAX_LEN 15 #define DRV_NAME "ipa" @@ -225,11 +226,6 @@ enum { NUM_SMEM_SUBSYSTEMS, }; -enum ipa_mpm_start_stop_type { - MPM_MHIP_STOP, - MPM_MHIP_START, -}; - #define IPA_WDI_RX_RING_RES 0 #define IPA_WDI_RX_RING_RP_RES 1 #define IPA_WDI_RX_COMP_RING_RES 2 @@ -3004,10 +3000,7 @@ int ipa3_get_gsi_chan_info(struct gsi_chan_info *gsi_chan_info, #ifdef CONFIG_IPA3_MHI_PRIME_MANAGER int ipa_mpm_mhip_xdci_pipe_enable(enum ipa_usb_teth_prot prot); int ipa_mpm_mhip_xdci_pipe_disable(enum ipa_usb_teth_prot xdci_teth_prot); -int ipa_mpm_notify_wan_state(void); -int ipa_mpm_mhip_ul_start_stop_data( - enum ipa_mpm_start_stop_type start_stop, - enum ipa_usb_teth_prot xdci_teth_prot); +int ipa_mpm_notify_wan_state(struct wan_ioctl_notify_wan_state *state); int ipa3_is_mhip_offload_enabled(void); int ipa_mpm_reset_dma_mode(enum ipa_client_type src_pipe, enum ipa_client_type dst_pipe); @@ -3024,13 +3017,8 @@ static inline int ipa_mpm_mhip_xdci_pipe_disable( { return 0; } -static inline int ipa_mpm_notify_wan_state(void) -{ - return 0; -} -static inline int ipa_mpm_mhip_ul_start_stop_data( - enum ipa_mpm_start_stop_type start_stop, - enum ipa_usb_teth_prot xdci_teth_prot) +static inline int ipa_mpm_notify_wan_state( + struct wan_ioctl_notify_wan_state *state) { return 0; } diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c b/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c index 1e64df86b403..410efc789bd5 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c @@ -133,6 +133,10 @@ enum mhip_smmu_domain_type { MHIP_SMMU_DOMAIN_NONE, }; +enum ipa_mpm_start_stop_type { + MPM_MHIP_STOP, + MPM_MHIP_START, +}; /* each pair of UL/DL channels are defined below */ static const struct mhi_device_id mhi_driver_match_table[] = { { .chan = "IP_HW_MHIP_0" }, /* for rndis/Wifi teth pipes */ @@ -1539,15 +1543,17 @@ static enum mhip_status_type ipa_mpm_start_stop_mhip_chan( return MHIP_STATUS_FAIL; } -int ipa_mpm_notify_wan_state(void) +int ipa_mpm_notify_wan_state(struct wan_ioctl_notify_wan_state *state) { int probe_id = IPA_MPM_MHIP_CH_ID_MAX; int i; static enum mhip_status_type status; int ret = 0; - enum ipa_client_type ul_chan, dl_chan; enum ipa_mpm_mhip_client_type mhip_client = IPA_MPM_MHIP_TETH; + if (!state) + return -EPERM; + if (!ipa3_is_mhip_offload_enabled()) return -EPERM; @@ -1564,53 +1570,85 @@ int ipa_mpm_notify_wan_state(void) } IPA_MPM_DBG("WAN backhaul available for probe_id = %d\n", probe_id); - get_ipa3_client(probe_id, &ul_chan, &dl_chan); - - /* Start UL MHIP channel for offloading the tethering connection */ - ret = ipa_mpm_vote_unvote_pcie_clk(CLK_ON, probe_id); - if (ret) { - IPA_MPM_ERR("Error cloking on PCIe clk, err = %d\n", ret); - return ret; - } - - status = ipa_mpm_start_stop_mhip_chan( - IPA_MPM_MHIP_CHAN_UL, probe_id, MPM_MHIP_START); - switch (status) { - case MHIP_STATUS_SUCCESS: - case MHIP_STATUS_NO_OP: - ipa_mpm_change_teth_state(probe_id, IPA_MPM_TETH_CONNECTED); - ret = ipa_mpm_start_stop_ul_mhip_data_path(probe_id, - MPM_MHIP_START); + if (state->up) { + /* Start UL MHIP channel for offloading tethering connection */ + ret = ipa_mpm_vote_unvote_pcie_clk(CLK_ON, probe_id); if (ret) { - IPA_MPM_ERR("Couldnt start UL GSI channel"); - ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); + IPA_MPM_ERR("Error cloking on PCIe clk, err = %d\n", + ret); return ret; } - - if (status == MHIP_STATUS_NO_OP) { - /* Channels already have been started, - * we can devote for pcie clocks - */ + status = ipa_mpm_start_stop_mhip_chan( + IPA_MPM_MHIP_CHAN_UL, probe_id, MPM_MHIP_START); + switch (status) { + case MHIP_STATUS_SUCCESS: + ipa_mpm_ctx->md[probe_id].teth_state = + IPA_MPM_TETH_CONNECTED; + ret = ipa_mpm_start_stop_ul_mhip_data_path( + probe_id, MPM_MHIP_START); + if (ret) { + IPA_MPM_ERR("err UL chan start\n"); + ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); + return ret; + } + break; + case MHIP_STATUS_EP_NOT_READY: + case MHIP_STATUS_NO_OP: + IPA_MPM_DBG("UL chan already start, status = %d\n", + status); + ret = ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); + return ret; + case MHIP_STATUS_FAIL: + case MHIP_STATUS_BAD_STATE: + case MHIP_STATUS_EP_NOT_FOUND: + IPA_MPM_ERR("UL chan start err =%d\n", status); + ret = ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); + ipa_assert(); + return -EFAULT; + default: + IPA_MPM_ERR("Err not found\n"); ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); + ret = -EFAULT; + break; } - break; - case MHIP_STATUS_EP_NOT_READY: - ipa_mpm_change_teth_state(probe_id, IPA_MPM_TETH_INPROGRESS); - break; - case MHIP_STATUS_FAIL: - case MHIP_STATUS_BAD_STATE: - case MHIP_STATUS_EP_NOT_FOUND: - IPA_MPM_ERR("UL chan cant be started err =%d\n", status); + ipa_mpm_ctx->md[probe_id].mhip_client = mhip_client; + } else { + status = ipa_mpm_start_stop_mhip_chan( + IPA_MPM_MHIP_CHAN_UL, probe_id, + MPM_MHIP_STOP); + switch (status) { + case MHIP_STATUS_SUCCESS: + ipa_mpm_change_teth_state(probe_id, IPA_MPM_TETH_INIT); + ipa_mpm_start_stop_ul_mhip_data_path(probe_id, + MPM_MHIP_STOP); + break; + case MHIP_STATUS_NO_OP: + case MHIP_STATUS_EP_NOT_READY: + IPA_MPM_DBG("UL chan already stop, status = %d\n", + status); + break; + case MHIP_STATUS_FAIL: + case MHIP_STATUS_BAD_STATE: + case MHIP_STATUS_EP_NOT_FOUND: + IPA_MPM_ERR("UL chan cant be stopped err =%d\n", + status); + ipa_assert(); + return -EFAULT; + default: + IPA_MPM_ERR("Err not found\n"); + return -EFAULT; + } + /* Stop UL MHIP channel for offloading tethering connection */ ret = ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); - return -EFAULT; - default: - IPA_MPM_ERR("Err not found\n"); - ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); - ret = -EFAULT; - break; - } + if (ret) { + IPA_MPM_ERR("Error cloking on PCIe clk, err = %d\n", + ret); + return ret; + } + ipa_mpm_ctx->md[probe_id].mhip_client = IPA_MPM_MHIP_NONE; + } return ret; } @@ -2358,7 +2396,7 @@ int ipa_mpm_mhip_xdci_pipe_enable(enum ipa_usb_teth_prot xdci_teth_prot) } IPA_MPM_DBG("Connect xdci prot %d -> mhip_client = %d probe_id = %d\n", - xdci_teth_prot, mhip_client, probe_id); + xdci_teth_prot, mhip_client, probe_id); ipa_mpm_ctx->md[probe_id].mhip_client = mhip_client; @@ -2373,16 +2411,19 @@ int ipa_mpm_mhip_xdci_pipe_enable(enum ipa_usb_teth_prot xdci_teth_prot) ipa_mpm_set_dma_mode(IPA_CLIENT_USB_PROD, IPA_CLIENT_MHI_PRIME_RMNET_CONS); break; - case IPA_MPM_MHIP_TETH: - IPA_MPM_DBG("Teth for prot %d\n", mhip_client); - return 0; case IPA_MPM_MHIP_USB_DPL: IPA_MPM_DBG("connecting DPL prot %d\n", mhip_client); ipa_mpm_change_teth_state(probe_id, IPA_MPM_TETH_CONNECTED); return 0; default: - IPA_MPM_ERR("mhip_client = %d not supported\n", mhip_client); - break; + IPA_MPM_DBG("mhip_client = %d not processed\n", mhip_client); + ret = ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); + if (ret) { + IPA_MPM_ERR("Error unvoting on PCIe clk, err = %d\n", + ret); + return ret; + } + return 0; } if (mhip_client != IPA_MPM_MHIP_USB_DPL) @@ -2427,51 +2468,6 @@ int ipa_mpm_mhip_xdci_pipe_enable(enum ipa_usb_teth_prot xdci_teth_prot) return ret; } -int ipa_mpm_mhip_ul_start_stop_data(enum ipa_mpm_start_stop_type start_stop, - enum ipa_usb_teth_prot xdci_teth_prot) -{ - int probe_id = IPA_MPM_MHIP_CH_ID_MAX; - int i; - enum ipa_mpm_mhip_client_type mhip_client; - int ret = 0; - - if (ipa_mpm_ctx == NULL) { - IPA_MPM_ERR("MPM not platform probed, returning ..\n"); - return 0; - } - - ipa_mpm_mhip_map_prot(xdci_teth_prot, &mhip_client); - - for (i = 0; i < IPA_MPM_MHIP_CH_ID_MAX; i++) { - if (ipa_mpm_pipes[i].mhip_client == mhip_client) { - probe_id = i; - break; - } - } - - if (probe_id == IPA_MPM_MHIP_CH_ID_MAX) { - IPA_MPM_ERR("Invalid probe_id\n"); - return 0; - } - - IPA_MPM_DBG("Map xdci prot %d to mhip_client = %d probe_id = %d\n", - xdci_teth_prot, mhip_client, probe_id); - - if (start_stop == MPM_MHIP_STOP) { - ret = ipa_mpm_start_stop_ul_mhip_data_path(probe_id, - MPM_MHIP_STOP); - if (ret) - IPA_MPM_ERR("Error stopping UL path, err = %d\n", ret); - } else if (start_stop == MPM_MHIP_START) { - ret = ipa_mpm_start_stop_ul_mhip_data_path(probe_id, - MPM_MHIP_START); - if (ret) - IPA_MPM_ERR("Error starting UL path, err = %d\n", ret); - } - - return ret; -} - int ipa_mpm_mhip_xdci_pipe_disable(enum ipa_usb_teth_prot xdci_teth_prot) { int probe_id = IPA_MPM_MHIP_CH_ID_MAX; @@ -2512,8 +2508,8 @@ int ipa_mpm_mhip_xdci_pipe_disable(enum ipa_usb_teth_prot xdci_teth_prot) } break; case IPA_MPM_MHIP_TETH: - IPA_MPM_DBG("Teth Disconnecting for prot %d\n", mhip_client); - break; + IPA_MPM_DBG("Rndis Disconnect, wait for wan_state ioctl\n"); + return 0; case IPA_MPM_MHIP_USB_DPL: IPA_MPM_DBG("Teth Disconnecting for DPL\n"); ipa_mpm_change_teth_state(probe_id, IPA_MPM_TETH_INIT); diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa_fd_ioctl.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa_fd_ioctl.c index d43913026090..8c53d5df1e6f 100644 --- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa_fd_ioctl.c +++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa_fd_ioctl.c @@ -445,7 +445,8 @@ static long ipa3_wan_ioctl(struct file *filp, break; } - if (ipa_mpm_notify_wan_state()) { + if (ipa_mpm_notify_wan_state( + (struct wan_ioctl_notify_wan_state *)param)) { IPAWANERR("WAN_IOC_NOTIFY_WAN_STATE failed\n"); retval = -EPERM; } -- GitLab From 63d9b00c526502af0b4b6b630bdfcb18329656a1 Mon Sep 17 00:00:00 2001 From: Xianbin Zhu Date: Wed, 12 Jun 2019 19:03:20 +0800 Subject: [PATCH 0618/1121] i2c: virtio:refine the driver of i2c virtualization - there's no need to allocate buffer for virtio_i2c_req every time when it comes to data transmission, we can prepare this buffer at probe stage. - we need to add some input parameter checking for avoiding security risks. - refine the code to reduce the number of judgement statements. Change-Id: Idb6ae8bb632c1a3032c6ba04de6ebb460f1e1a5c Signed-off-by: Xianbin Zhu --- drivers/i2c/busses/virtio-i2c.c | 103 ++++++++++++++------------------ 1 file changed, 44 insertions(+), 59 deletions(-) diff --git a/drivers/i2c/busses/virtio-i2c.c b/drivers/i2c/busses/virtio-i2c.c index f26551886f47..4607cf48f842 100644 --- a/drivers/i2c/busses/virtio-i2c.c +++ b/drivers/i2c/busses/virtio-i2c.c @@ -34,19 +34,6 @@ #define I2C_VIRTIO_WR 0x02 #define I2C_VIRTIO_RDWR 0x03 -/** - * struct virtio_i2c - virtio i2c device - * @adapter: i2c adapter - * @vdev: the virtio device - * @vq: i2c virtqueue - */ -struct virtio_i2c { - struct i2c_adapter adapter; - struct virtio_device *vdev; - struct virtqueue *vq; - wait_queue_head_t inq; -}; - struct i2c_transfer_head { u32 type; /* read or write from or to slave */ u32 addr; /* slave addr */ @@ -64,6 +51,21 @@ struct virtio_i2c_req { struct i2c_transfer_end end; }; +/** + * struct virtio_i2c - virtio i2c device + * @adapter: i2c adapter + * @vdev: the virtio device + * @i2c_req: description of the fromat of transfer data + * @vq: i2c virtqueue + */ +struct virtio_i2c { + struct i2c_adapter adapter; + struct virtio_device *vdev; + struct virtio_i2c_req i2c_req; + struct virtqueue *vq; + wait_queue_head_t inq; +}; + static int virti2c_transfer(struct virtio_i2c *vi2c, struct virtio_i2c_req *i2c_req) { @@ -117,49 +119,35 @@ static int virti2c_transfer(struct virtio_i2c *vi2c, } /* prepare the transfer req */ -static struct virtio_i2c_req *virti2c_transfer_prepare(struct i2c_msg *msg_1, - struct i2c_msg *msg_2) +static int virti2c_transfer_prepare(struct i2c_msg *msg_1, + struct i2c_msg *msg_2, struct virtio_i2c_req *i2c_req) { - char *ptr = NULL; - int merge = 0; - struct virtio_i2c_req *i2c_req; - - if (msg_1 == NULL) - return NULL; - - if (msg_2) - merge = 1; - - i2c_req = kzalloc(sizeof(struct virtio_i2c_req), GFP_KERNEL); - if (i2c_req == NULL) - return NULL; + if (IS_ERR_OR_NULL(msg_1) || !msg_1->len || + IS_ERR_OR_NULL(msg_1->buf)) + return -EINVAL; - if (merge) - ptr = kzalloc((msg_1->len + msg_2->len), GFP_KERNEL); - else - ptr = msg_1->buf; - if (ptr == NULL) - goto err_mem; - - /* prepare the head */ - i2c_req->head.type = merge ? - I2C_VIRTIO_RDWR : ((msg_1->flags & I2C_M_RD) ? - I2C_VIRTIO_RD : I2C_VIRTIO_WR); i2c_req->head.addr = msg_1->addr; i2c_req->head.length = msg_1->len; - if (merge) + + if (IS_ERR_OR_NULL(msg_2)) { + i2c_req->head.type = (msg_1->flags & I2C_M_RD) ? + I2C_VIRTIO_RD : I2C_VIRTIO_WR; + i2c_req->buf = msg_1->buf; + } else { + if (!msg_2->len || IS_ERR_OR_NULL(msg_2->buf)) + return -EINVAL; + + i2c_req->head.type = I2C_VIRTIO_RDWR; i2c_req->head.total_length = msg_1->len + msg_2->len; - /* prepare the buf */ - if (merge) - memcpy(ptr, msg_1->buf, msg_1->len); - i2c_req->buf = ptr; + i2c_req->buf = kzalloc((msg_1->len + msg_2->len), GFP_KERNEL); + if (IS_ERR_OR_NULL(i2c_req->buf)) + return -ENOMEM; - return i2c_req; -err_mem: - kfree(i2c_req); - i2c_req = NULL; - return NULL; + memcpy(i2c_req->buf, msg_1->buf, msg_1->len); + } + + return 0; } static void virti2c_transfer_end(struct virtio_i2c_req *req, @@ -171,16 +159,15 @@ static void virti2c_transfer_end(struct virtio_i2c_req *req, req->buf = NULL; } - kfree(req); - req = NULL; + memset(req, 0, sizeof(struct virtio_i2c_req)); } static int virtio_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) { int i, ret; - struct virtio_i2c_req *i2c_req; struct virtio_i2c *vi2c = i2c_get_adapdata(adap); + struct virtio_i2c_req *i2c_req = &vi2c->i2c_req; if (num < 1) { dev_err(&vi2c->vdev->dev, @@ -197,24 +184,22 @@ static int virtio_i2c_master_xfer(struct i2c_adapter *adap, if (msgs[i].flags & I2C_M_RD) { /* read the data from slave to master*/ - i2c_req = virti2c_transfer_prepare(&msgs[i], NULL); + ret = virti2c_transfer_prepare(&msgs[i], NULL, i2c_req); } else if ((i + 1 < num) && (msgs[i + 1].flags & I2C_M_RD) && (msgs[i].addr == msgs[i + 1].addr)) { /* write then read from same address*/ - i2c_req = virti2c_transfer_prepare(&msgs[i], - &msgs[i+1]); + ret = virti2c_transfer_prepare(&msgs[i], + &msgs[i+1], i2c_req); i += 1; } else { /* write the data to slave */ - i2c_req = virti2c_transfer_prepare(&msgs[i], NULL); + ret = virti2c_transfer_prepare(&msgs[i], NULL, i2c_req); } - if (i2c_req == NULL) { - ret = -ENOMEM; + if (ret) goto err; - } ret = virti2c_transfer(vi2c, i2c_req); virti2c_transfer_end(i2c_req, &msgs[i]); if (ret) -- GitLab From 5fc964ccb35a4a85070fc6aa796e1086908138b0 Mon Sep 17 00:00:00 2001 From: Rishabh Jain Date: Wed, 19 Jun 2019 11:13:21 +0530 Subject: [PATCH 0619/1121] msm: camera: isp: Enabling critical logs to improve debugging Enables logs to improve debugging. These logs need to be default logs. Change-Id: I7686fedcad50f0172308579012a72fb26b603da9 Signed-off-by: Rishabh Jain --- drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c index c0ab5e6f2e4e..3f6fa82adbbb 100644 --- a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c +++ b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c @@ -440,7 +440,7 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state( struct cam_context *ctx = ctx_isp->base; if (list_empty(&ctx->active_req_list)) { - CAM_DBG(CAM_ISP, "Buf done with no active request!"); + CAM_WARN(CAM_ISP, "Buf done with no active request!"); goto end; } -- GitLab From 158372aa9c339e590130eaeae2559704c5955662 Mon Sep 17 00:00:00 2001 From: Venkata Rao Kakani Date: Wed, 19 Jun 2019 11:41:27 +0530 Subject: [PATCH 0620/1121] defconfig: sa6155: Enable CONFIG_DEVTMPFS Enable CONFIG_DEVTMPFS for supporting dev mounting in early userspace. Change-Id: I5a663fd5a053afb8e4462157ff4837e35fa8f285 Signed-off-by: Venkata Rao Kakani --- arch/arm64/configs/vendor/sdmsteppe-auto-perf_defconfig | 2 ++ arch/arm64/configs/vendor/sdmsteppe-auto_defconfig | 2 ++ 2 files changed, 4 insertions(+) diff --git a/arch/arm64/configs/vendor/sdmsteppe-auto-perf_defconfig b/arch/arm64/configs/vendor/sdmsteppe-auto-perf_defconfig index e3bb3ea71df9..ec0ea0708667 100644 --- a/arch/arm64/configs/vendor/sdmsteppe-auto-perf_defconfig +++ b/arch/arm64/configs/vendor/sdmsteppe-auto-perf_defconfig @@ -250,6 +250,8 @@ CONFIG_CFG80211_REG_CELLULAR_HINTS=y CONFIG_CFG80211_INTERNAL_REGDB=y CONFIG_RFKILL=y CONFIG_NFC_NQ=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y CONFIG_REGMAP_WCD_IRQ=y CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y diff --git a/arch/arm64/configs/vendor/sdmsteppe-auto_defconfig b/arch/arm64/configs/vendor/sdmsteppe-auto_defconfig index 90207531f7d2..cc453bb6e587 100644 --- a/arch/arm64/configs/vendor/sdmsteppe-auto_defconfig +++ b/arch/arm64/configs/vendor/sdmsteppe-auto_defconfig @@ -259,6 +259,8 @@ CONFIG_CFG80211_INTERNAL_REGDB=y # CONFIG_CFG80211_CRDA_SUPPORT is not set CONFIG_RFKILL=y CONFIG_NFC_NQ=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y CONFIG_REGMAP_WCD_IRQ=y CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y -- GitLab From 51a402fdb208945de2fc4f04d5eb037391d064aa Mon Sep 17 00:00:00 2001 From: Yong Ding Date: Fri, 14 Jun 2019 18:11:24 +0800 Subject: [PATCH 0621/1121] soc: qcom: hab: use spin_lock/unlock() when local irqs are disabled In habmm_socket_read/write(), spin_lock/unlock_bh() are naturally used to handle the race between the tasklet, as bottom half, and process context. Sometimes and rarely, some kernel-space drivers(e.g., scm_qcpe.c, apr_vm.c) could call habmm_socket_read/write() from the process context where local irqs are disabled(e.g., spin_lock_irqsave is called). In such case, spin_unlock_bh() will trigger such below warning log, warning: kernel/softirq.c:157 WARN_ON_ONCE(in_irq() || irqs_disabled()). Actually in such case, no need for HAB to disable and enable bottom half considering the fact that local irqs are already disabled from the caller. Change-Id: I20c37b12b3ce7ad1ebd6f8245f9e55aa2fa215b6 Signed-off-by: Yong Ding --- drivers/soc/qcom/hab/ghs_comm.c | 16 ++++++++------- drivers/soc/qcom/hab/hab.h | 34 +++++++++++++++++++++++++++++++- drivers/soc/qcom/hab/hab_msg.c | 29 ++++++++++++++++----------- drivers/soc/qcom/hab/hab_open.c | 17 +++++++++------- drivers/soc/qcom/hab/hab_vchan.c | 20 ++++++++++--------- drivers/soc/qcom/hab/qvm_comm.c | 21 +++++++++++--------- 6 files changed, 93 insertions(+), 44 deletions(-) diff --git a/drivers/soc/qcom/hab/ghs_comm.c b/drivers/soc/qcom/hab/ghs_comm.c index 825f33a23858..b426cb1972aa 100644 --- a/drivers/soc/qcom/hab/ghs_comm.c +++ b/drivers/soc/qcom/hab/ghs_comm.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -43,19 +43,20 @@ int physical_channel_send(struct physical_channel *pchan, struct ghs_vdev *dev = (struct ghs_vdev *)pchan->hyp_data; GIPC_Result result; uint8_t *msg; + int irqs_disabled = irqs_disabled(); - spin_lock_bh(&dev->io_lock); + hab_spin_lock(&dev->io_lock, irqs_disabled); result = GIPC_PrepareMessage(dev->endpoint, sizebytes+sizeof(*header), (void **)&msg); if (result == GIPC_Full) { - spin_unlock_bh(&dev->io_lock); + hab_spin_unlock(&dev->io_lock, irqs_disabled); /* need to wait for space! */ pr_err("failed to reserve send msg for %zd bytes\n", sizebytes+sizeof(*header)); return -EBUSY; } else if (result != GIPC_Success) { - spin_unlock_bh(&dev->io_lock); + hab_spin_unlock(&dev->io_lock, irqs_disabled); pr_err("failed to send due to error %d\n", result); return -ENOMEM; } @@ -77,7 +78,7 @@ int physical_channel_send(struct physical_channel *pchan, result = GIPC_IssueMessage(dev->endpoint, sizebytes+sizeof(*header), header->id_type_size); - spin_unlock_bh(&dev->io_lock); + hab_spin_unlock(&dev->io_lock, irqs_disabled); if (result != GIPC_Success) { pr_err("send error %d, sz %zd, prot %x\n", result, sizebytes+sizeof(*header), @@ -98,6 +99,7 @@ void physical_channel_rx_dispatch(unsigned long physical_channel) uint32_t events; unsigned long flags; + int irqs_disabled = irqs_disabled(); spin_lock_irqsave(&pchan->rxbuf_lock, flags); events = kgipc_dequeue_events(dev->endpoint); @@ -111,7 +113,7 @@ void physical_channel_rx_dispatch(unsigned long physical_channel) dev->name, pchan->vmid_remote); if (events & (GIPC_EVENT_RECEIVEREADY)) { - spin_lock_bh(&pchan->rxbuf_lock); + hab_spin_lock(&pchan->rxbuf_lock, irqs_disabled); while (1) { dev->read_size = 0; dev->read_offset = 0; @@ -133,7 +135,7 @@ void physical_channel_rx_dispatch(unsigned long physical_channel) result, dev->read_size); break; } - spin_unlock_bh(&pchan->rxbuf_lock); + hab_spin_unlock(&pchan->rxbuf_lock, irqs_disabled); } if (events & (GIPC_EVENT_SENDREADY)) diff --git a/drivers/soc/qcom/hab/hab.h b/drivers/soc/qcom/hab/hab.h index ce7e83a2ba84..1ba38599532f 100644 --- a/drivers/soc/qcom/hab/hab.h +++ b/drivers/soc/qcom/hab/hab.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -577,6 +577,38 @@ int hab_stat_show_expimp(struct hab_driver *drv, int pid, char *buf, int sz); int hab_stat_init_sub(struct hab_driver *drv); int hab_stat_deinit_sub(struct hab_driver *drv); +static inline void hab_spin_lock(spinlock_t *lock, int irqs_disabled) +{ + if (irqs_disabled) + spin_lock(lock); + else + spin_lock_bh(lock); +} + +static inline void hab_spin_unlock(spinlock_t *lock, int irqs_disabled) +{ + if (irqs_disabled) + spin_unlock(lock); + else + spin_unlock_bh(lock); +} + +static inline void hab_write_lock(rwlock_t *lock, int irqs_disabled) +{ + if (irqs_disabled) + write_lock(lock); + else + write_lock_bh(lock); +} + +static inline void hab_write_unlock(rwlock_t *lock, int irqs_disabled) +{ + if (irqs_disabled) + write_unlock(lock); + else + write_unlock_bh(lock); +} + /* Global singleton HAB instance */ extern struct hab_driver hab_driver; diff --git a/drivers/soc/qcom/hab/hab_msg.c b/drivers/soc/qcom/hab/hab_msg.c index 40ff1a9d6415..f55628b29912 100644 --- a/drivers/soc/qcom/hab/hab_msg.c +++ b/drivers/soc/qcom/hab/hab_msg.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -15,10 +15,12 @@ static int hab_rx_queue_empty(struct virtual_channel *vchan) { int ret; + int irqs_disabled = irqs_disabled(); - spin_lock_bh(&vchan->rx_lock); + hab_spin_lock(&vchan->rx_lock, irqs_disabled); ret = list_empty(&vchan->rx_list); - spin_unlock_bh(&vchan->rx_lock); + hab_spin_unlock(&vchan->rx_lock, irqs_disabled); + return ret; } @@ -56,6 +58,7 @@ hab_msg_dequeue(struct virtual_channel *vchan, struct hab_message **msg, int ret = 0; int wait = !(flags & HABMM_SOCKET_RECV_FLAGS_NON_BLOCKING); int interruptible = !(flags & HABMM_SOCKET_RECV_FLAGS_UNINTERRUPTIBLE); + int irqs_disabled = irqs_disabled(); if (wait) { if (hab_rx_queue_empty(vchan)) { @@ -75,7 +78,7 @@ hab_msg_dequeue(struct virtual_channel *vchan, struct hab_message **msg, * and need empty check again in case the list is empty now due to * dequeue by other threads */ - spin_lock_bh(&vchan->rx_lock); + hab_spin_lock(&vchan->rx_lock, irqs_disabled); if ((!ret || (ret == -ERESTARTSYS)) && !list_empty(&vchan->rx_list)) { message = list_first_entry(&vchan->rx_list, @@ -99,7 +102,7 @@ hab_msg_dequeue(struct virtual_channel *vchan, struct hab_message **msg, /* no message received, retain the original status */ *rsize = 0; - spin_unlock_bh(&vchan->rx_lock); + hab_spin_unlock(&vchan->rx_lock, irqs_disabled); *msg = message; return ret; @@ -108,9 +111,11 @@ hab_msg_dequeue(struct virtual_channel *vchan, struct hab_message **msg, static void hab_msg_queue(struct virtual_channel *vchan, struct hab_message *message) { - spin_lock_bh(&vchan->rx_lock); + int irqs_disabled = irqs_disabled(); + + hab_spin_lock(&vchan->rx_lock, irqs_disabled); list_add_tail(&message->node, &vchan->rx_list); - spin_unlock_bh(&vchan->rx_lock); + hab_spin_unlock(&vchan->rx_lock, irqs_disabled); wake_up(&vchan->rx_queue); } @@ -119,11 +124,12 @@ static int hab_export_enqueue(struct virtual_channel *vchan, struct export_desc *exp) { struct uhab_context *ctx = vchan->ctx; + int irqs_disabled = irqs_disabled(); - spin_lock_bh(&ctx->imp_lock); + hab_spin_lock(&ctx->imp_lock, irqs_disabled); list_add_tail(&exp->node, &ctx->imp_whse); ctx->import_total++; - spin_unlock_bh(&ctx->imp_lock); + hab_spin_unlock(&ctx->imp_lock, irqs_disabled); return 0; } @@ -151,6 +157,7 @@ static int hab_receive_create_export_ack(struct physical_channel *pchan, { struct hab_export_ack_recvd *ack_recvd = kzalloc(sizeof(*ack_recvd), GFP_ATOMIC); + int irqs_disabled = irqs_disabled(); if (!ack_recvd) return -ENOMEM; @@ -170,9 +177,9 @@ static int hab_receive_create_export_ack(struct physical_channel *pchan, sizebytes) != sizebytes) return -EIO; - spin_lock_bh(&ctx->expq_lock); + hab_spin_lock(&ctx->expq_lock, irqs_disabled); list_add_tail(&ack_recvd->node, &ctx->exp_rxq); - spin_unlock_bh(&ctx->expq_lock); + hab_spin_unlock(&ctx->expq_lock, irqs_disabled); return 0; } diff --git a/drivers/soc/qcom/hab/hab_open.c b/drivers/soc/qcom/hab/hab_open.c index bc2b774883f4..a90460a1295e 100644 --- a/drivers/soc/qcom/hab/hab_open.c +++ b/drivers/soc/qcom/hab/hab_open.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -46,6 +46,7 @@ int hab_open_request_add(struct physical_channel *pchan, struct hab_device *dev = pchan->habdev; struct hab_open_request *request; struct timeval tv; + int irqs_disabled = irqs_disabled(); if (sizebytes > HAB_HEADER_SIZE_MASK) { pr_err("pchan %s request size too large %zd\n", @@ -70,10 +71,11 @@ int hab_open_request_add(struct physical_channel *pchan, tv.tv_usec/1000000; hab_pchan_get(pchan); - spin_lock_bh(&dev->openlock); + hab_spin_lock(&dev->openlock, irqs_disabled); list_add_tail(&node->node, &dev->openq_list); dev->openq_cnt++; - spin_unlock_bh(&dev->openlock); + hab_spin_unlock(&dev->openlock, irqs_disabled); + return 0; } @@ -192,6 +194,7 @@ int hab_open_receive_cancel(struct physical_channel *pchan, struct hab_open_node *node, *tmp; int bfound = 0; struct timeval tv; + int irqs_disabled = irqs_disabled(); if (sizebytes > HAB_HEADER_SIZE_MASK) { pr_err("pchan %s cancel size too large %zd\n", @@ -202,7 +205,7 @@ int hab_open_receive_cancel(struct physical_channel *pchan, if (physical_channel_read(pchan, &data, sizebytes) != sizebytes) return -EIO; - spin_lock_bh(&dev->openlock); + hab_spin_lock(&dev->openlock, irqs_disabled); list_for_each_entry_safe(node, tmp, &dev->openq_list, node) { request = &node->request; /* check if open request has been serviced or not */ @@ -221,7 +224,7 @@ int hab_open_receive_cancel(struct physical_channel *pchan, break; } } - spin_unlock_bh(&dev->openlock); + hab_spin_unlock(&dev->openlock, irqs_disabled); if (!bfound) { pr_info("init waiting is in-flight. vcid %x sub %d open %d\n", @@ -244,10 +247,10 @@ int hab_open_receive_cancel(struct physical_channel *pchan, /* put when this node is handled in open path */ hab_pchan_get(pchan); - spin_lock_bh(&dev->openlock); + hab_spin_lock(&dev->openlock, irqs_disabled); list_add_tail(&node->node, &dev->openq_list); dev->openq_cnt++; - spin_unlock_bh(&dev->openlock); + hab_spin_unlock(&dev->openlock, irqs_disabled); wake_up_interruptible(&dev->openq); } diff --git a/drivers/soc/qcom/hab/hab_vchan.c b/drivers/soc/qcom/hab/hab_vchan.c index a95d6c7451c9..0ed957589ecc 100644 --- a/drivers/soc/qcom/hab/hab_vchan.c +++ b/drivers/soc/qcom/hab/hab_vchan.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -77,16 +77,17 @@ hab_vchan_free(struct kref *ref) struct physical_channel *pchan = vchan->pchan; struct uhab_context *ctx = vchan->ctx; struct virtual_channel *vc, *vc_tmp; + int irqs_disabled = irqs_disabled(); - spin_lock_bh(&vchan->rx_lock); + hab_spin_lock(&vchan->rx_lock, irqs_disabled); list_for_each_entry_safe(message, msg_tmp, &vchan->rx_list, node) { list_del(&message->node); hab_msg_free(message); } - spin_unlock_bh(&vchan->rx_lock); + hab_spin_unlock(&vchan->rx_lock, irqs_disabled); /* release vchan from pchan. no more msg for this vchan */ - write_lock_bh(&pchan->vchans_lock); + hab_write_lock(&pchan->vchans_lock, irqs_disabled); list_for_each_entry_safe(vc, vc_tmp, &pchan->vchannels, pnode) { if (vchan == vc) { list_del(&vc->pnode); @@ -95,15 +96,15 @@ hab_vchan_free(struct kref *ref) break; } } - write_unlock_bh(&pchan->vchans_lock); + hab_write_unlock(&pchan->vchans_lock, irqs_disabled); /* the release vchan from ctx was done earlier in vchan close() */ hab_ctx_put(ctx); /* now ctx is not needed from this vchan's view */ /* release idr at the last so same idr will not be used early */ - spin_lock_bh(&pchan->vid_lock); + hab_spin_lock(&pchan->vid_lock, irqs_disabled); idr_remove(&pchan->vchan_idr, HAB_VCID_GET_ID(vchan->id)); - spin_unlock_bh(&pchan->vid_lock); + hab_spin_unlock(&pchan->vid_lock, irqs_disabled); hab_pchan_put(pchan); /* no more need for pchan from this vchan */ @@ -122,8 +123,9 @@ hab_vchan_get(struct physical_channel *pchan, struct hab_header *header) uint32_t session_id = HAB_HEADER_GET_SESSION_ID(*header); size_t sizebytes = HAB_HEADER_GET_SIZE(*header); uint32_t payload_type = HAB_HEADER_GET_TYPE(*header); + int irqs_disabled = irqs_disabled(); - spin_lock_bh(&pchan->vid_lock); + hab_spin_lock(&pchan->vid_lock, irqs_disabled); vchan = idr_find(&pchan->vchan_idr, HAB_VCID_GET_ID(vchan_id)); if (vchan) { if (vchan->session_id != session_id) @@ -162,7 +164,7 @@ hab_vchan_get(struct physical_channel *pchan, struct hab_header *header) vchan = NULL; } } - spin_unlock_bh(&pchan->vid_lock); + hab_spin_unlock(&pchan->vid_lock, irqs_disabled); return vchan; } diff --git a/drivers/soc/qcom/hab/qvm_comm.c b/drivers/soc/qcom/hab/qvm_comm.c index ab57f2758aed..985f6b646875 100644 --- a/drivers/soc/qcom/hab/qvm_comm.c +++ b/drivers/soc/qcom/hab/qvm_comm.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -43,16 +43,17 @@ int physical_channel_send(struct physical_channel *pchan, int sizebytes = HAB_HEADER_GET_SIZE(*header); struct qvm_channel *dev = (struct qvm_channel *)pchan->hyp_data; int total_size = sizeof(*header) + sizebytes; + int irqs_disabled = irqs_disabled(); if (total_size > dev->pipe_ep->tx_info.sh_buf->size) return -EINVAL; /* too much data for ring */ - spin_lock_bh(&dev->io_lock); + hab_spin_lock(&dev->io_lock, irqs_disabled); if ((dev->pipe_ep->tx_info.sh_buf->size - (dev->pipe_ep->tx_info.wr_count - dev->pipe_ep->tx_info.sh_buf->rd_count)) < total_size) { - spin_unlock_bh(&dev->io_lock); + hab_spin_unlock(&dev->io_lock, irqs_disabled); return -EAGAIN; /* not enough free space */ } @@ -62,7 +63,7 @@ int physical_channel_send(struct physical_channel *pchan, if (hab_pipe_write(dev->pipe_ep, (unsigned char *)header, sizeof(*header)) != sizeof(*header)) { - spin_unlock_bh(&dev->io_lock); + hab_spin_unlock(&dev->io_lock, irqs_disabled); return -EIO; } @@ -76,7 +77,7 @@ int physical_channel_send(struct physical_channel *pchan, pstat->tx_sec = tv.tv_sec; pstat->tx_usec = tv.tv_usec; } else { - spin_unlock_bh(&dev->io_lock); + hab_spin_unlock(&dev->io_lock, irqs_disabled); return -EINVAL; } } @@ -85,13 +86,14 @@ int physical_channel_send(struct physical_channel *pchan, if (hab_pipe_write(dev->pipe_ep, (unsigned char *)payload, sizebytes) != sizebytes) { - spin_unlock_bh(&dev->io_lock); + hab_spin_unlock(&dev->io_lock, irqs_disabled); return -EIO; } } hab_pipe_write_commit(dev->pipe_ep); - spin_unlock_bh(&dev->io_lock); + hab_spin_unlock(&dev->io_lock, irqs_disabled); + habhyp_notify(dev); ++pchan->sequence_tx; return 0; @@ -102,8 +104,9 @@ void physical_channel_rx_dispatch(unsigned long data) struct hab_header header; struct physical_channel *pchan = (struct physical_channel *)data; struct qvm_channel *dev = (struct qvm_channel *)pchan->hyp_data; + int irqs_disabled = irqs_disabled(); - spin_lock_bh(&pchan->rxbuf_lock); + hab_spin_lock(&pchan->rxbuf_lock, irqs_disabled); while (1) { if (hab_pipe_read(dev->pipe_ep, (unsigned char *)&header, @@ -122,5 +125,5 @@ void physical_channel_rx_dispatch(unsigned long data) hab_msg_recv(pchan, &header); } - spin_unlock_bh(&pchan->rxbuf_lock); + hab_spin_unlock(&pchan->rxbuf_lock, irqs_disabled); } -- GitLab From 4f5d9fa7cf917670983b73278e475e9975eecafb Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Tue, 18 Jun 2019 11:08:13 +0530 Subject: [PATCH 0622/1121] msm: vidc: Add checks to avoid OOB access validate structures and payload sizes in the packet against packet size to avoid OOB access. Change-Id: Id44e5c6be4dde3e6545d453f5edd3219776a4e58 Signed-off-by: Manikanta Kanamarlapudi --- .../platform/msm/vidc/hfi_response_handler.c | 93 +++++++++++++++---- 1 file changed, 77 insertions(+), 16 deletions(-) diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c index bb5661bd00ad..eca5d9b02184 100644 --- a/drivers/media/platform/msm/vidc/hfi_response_handler.c +++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c @@ -942,6 +942,21 @@ static enum vidc_status hfi_parse_init_done_properties( u32 prop_id, next_offset; u32 codecs = 0, domain = 0; +#define VALIDATE_PROPERTY_STRUCTURE_SIZE(pkt_size, property_size) ({\ + if (pkt_size < property_size) { \ + status = VIDC_ERR_BAD_PARAM; \ + break; \ + } \ +}) + +#define VALIDATE_PROPERTY_PAYLOAD_SIZE(pkt_size, payload_size, \ + property_count) ({\ + if (pkt_size/payload_size < property_count) { \ + status = VIDC_ERR_BAD_PARAM; \ + break; \ + } \ +}) + while (status == VIDC_ERR_NONE && num_properties && rem_bytes >= sizeof(u32)) { @@ -955,6 +970,10 @@ static enum vidc_status hfi_parse_init_done_properties( (struct hfi_codec_mask_supported *) (data_ptr + next_offset); + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(*prop)); + codecs = prop->codecs; domain = prop->video_domains; next_offset += sizeof(struct hfi_codec_mask_supported); @@ -967,11 +986,14 @@ static enum vidc_status hfi_parse_init_done_properties( (struct hfi_capability_supported_info *) (data_ptr + next_offset); - if ((rem_bytes - next_offset) < prop->num_capabilities * - sizeof(struct hfi_capability_supported)) { - status = VIDC_ERR_BAD_PARAM; - break; - } + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(*prop)); + VALIDATE_PROPERTY_PAYLOAD_SIZE(rem_bytes - + next_offset - sizeof(u32), + sizeof(struct hfi_capability_supported), + prop->num_capabilities); + next_offset += sizeof(u32) + prop->num_capabilities * sizeof(struct hfi_capability_supported); @@ -992,10 +1014,10 @@ static enum vidc_status hfi_parse_init_done_properties( char *fmt_ptr; struct hfi_uncompressed_plane_info *plane_info; - if ((rem_bytes - next_offset) < sizeof(*prop)) { - status = VIDC_ERR_BAD_PARAM; - break; - } + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(*prop)); + num_format_entries = prop->format_entries; next_offset = sizeof(*prop); fmt_ptr = (char *)&prop->rg_format_info[0]; @@ -1006,11 +1028,10 @@ static enum vidc_status hfi_parse_init_done_properties( plane_info = (struct hfi_uncompressed_plane_info *) fmt_ptr; - if ((rem_bytes - next_offset) < - sizeof(*plane_info)) { - status = VIDC_ERR_BAD_PARAM; - break; - } + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(*plane_info)); + bytes_to_skip = sizeof(*plane_info) - sizeof(struct hfi_uncompressed_plane_constraints) + @@ -1018,6 +1039,10 @@ static enum vidc_status hfi_parse_init_done_properties( sizeof(struct hfi_uncompressed_plane_constraints); + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + bytes_to_skip); + fmt_ptr += bytes_to_skip; next_offset += bytes_to_skip; num_format_entries--; @@ -1030,6 +1055,15 @@ static enum vidc_status hfi_parse_init_done_properties( struct hfi_properties_supported *prop = (struct hfi_properties_supported *) (data_ptr + next_offset); + + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(*prop)); + VALIDATE_PROPERTY_PAYLOAD_SIZE(rem_bytes - + next_offset - sizeof(*prop) + + sizeof(u32), sizeof(u32), + prop->num_properties); + next_offset += sizeof(*prop) - sizeof(u32) + prop->num_properties * sizeof(u32); num_properties--; @@ -1041,6 +1075,15 @@ static enum vidc_status hfi_parse_init_done_properties( (struct hfi_profile_level_supported *) (data_ptr + next_offset); + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(*prop)); + VALIDATE_PROPERTY_PAYLOAD_SIZE(rem_bytes - + next_offset - + sizeof(u32), + sizeof(struct hfi_profile_level), + prop->profile_count); + next_offset += sizeof(u32) + prop->profile_count * sizeof(struct hfi_profile_level); @@ -1065,6 +1108,10 @@ static enum vidc_status hfi_parse_init_done_properties( (struct hfi_nal_stream_format_supported *) (data_ptr + next_offset); + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(*prop)); + copy_nal_stream_format_caps_to_sessions( prop->nal_stream_format_supported, capabilities, num_sessions, @@ -1077,12 +1124,18 @@ static enum vidc_status hfi_parse_init_done_properties( } case HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SELECT: { + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(u32)); next_offset += sizeof(u32); num_properties--; break; } case HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH: { + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(struct hfi_intra_refresh)); next_offset += sizeof(struct hfi_intra_refresh); num_properties--; @@ -1090,6 +1143,9 @@ static enum vidc_status hfi_parse_init_done_properties( } case HFI_PROPERTY_TME_VERSION_SUPPORTED: { + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(u32)); capabilities->tme_version = *((u32 *)(data_ptr + next_offset)); next_offset += @@ -1103,8 +1159,13 @@ static enum vidc_status hfi_parse_init_done_properties( __func__, data_ptr, prop_id); break; } - rem_bytes -= next_offset; - data_ptr += next_offset; + + if (rem_bytes > next_offset) { + rem_bytes -= next_offset; + data_ptr += next_offset; + } else { + rem_bytes = 0; + } } return status; -- GitLab From ffd32d2bafa689620751319a79c2e5513bd33c59 Mon Sep 17 00:00:00 2001 From: Vivek Kumar Date: Tue, 18 Jun 2019 12:20:37 +0530 Subject: [PATCH 0623/1121] PM: Hibernate: Add option to disable disk offset randomization Add a kernel parameter to disable the disk offset randomization for SSD devices in which such feature is available at the firmware level. This is helpful in improving hibernation resume time. Change-Id: Ic1739bf63ad8cf3e71500e12552d4382da617341 Signed-off-by: Vivek Kumar --- Documentation/admin-guide/kernel-parameters.txt | 11 +++++++++++ kernel/power/swap.c | 9 +++++++++ 2 files changed, 20 insertions(+) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index a73f7b1765b2..9cebc1c205c2 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -3800,6 +3800,17 @@ (that will set all pages holding image data during restoration read-only). + noswap_randomize + Kernel uses random disk offsets to help with wear-levelling + of SSD devices, while saving the hibernation snapshot image to + disk. Use this parameter to disable this feature for SSD + devices in scenarios when, such randomization is addressed at + the firmware level and hibenration image is not re-generated + frequently. + (Useful for improving hibernation resume time as snapshot pages + are available in disk serially and can be read in bigger chunks + without seeking) + retain_initrd [RAM] Keep initrd memory after extraction rfkill.default_state= diff --git a/kernel/power/swap.c b/kernel/power/swap.c index 52623f04f18f..117c172223a9 100644 --- a/kernel/power/swap.c +++ b/kernel/power/swap.c @@ -43,6 +43,7 @@ */ static bool clean_pages_on_read; static bool clean_pages_on_decompress; +static bool noswap_randomize; /* * The swap map is a data structure used for keeping track of each page @@ -1620,3 +1621,11 @@ static int swsusp_header_init(void) } core_initcall(swsusp_header_init); + +static int __init noswap_randomize_setup(char *str) +{ + noswap_randomize = true; + return 1; +} + +__setup("noswap_randomize", noswap_randomize_setup); -- GitLab From 696fe91745ad73e9601f2b63ddd1cb7bc55ca9e8 Mon Sep 17 00:00:00 2001 From: Vivek Kumar Date: Tue, 18 Jun 2019 12:29:09 +0530 Subject: [PATCH 0624/1121] block: gendisk: Add a new flag in gendisk structure Add a new flag in gendisk structure to serialize offsets for swap partition. This flag is enabled for the gendisk of the block device which will be used for saving the snapshot of the hibernation image, based on a kernel parameter "noswap_randomize". Serializing offset in swap partition helps in improving hibernation resume time from bootloader. Change-Id: I52ecd078fd47ff6f47b7eff27ee8333a3aac85f8 Signed-off-by: Vivek Kumar --- include/linux/genhd.h | 1 + kernel/power/swap.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 550fa358893a..19687c9bc4d2 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -141,6 +141,7 @@ struct hd_struct { #define GENHD_FL_NATIVE_CAPACITY 128 #define GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE 256 #define GENHD_FL_NO_PART_SCAN 512 +#define GENHD_FL_NO_RANDOMIZE 1024 enum { DISK_EVENT_MEDIA_CHANGE = 1 << 0, /* media changed */ diff --git a/kernel/power/swap.c b/kernel/power/swap.c index 117c172223a9..75164e041b8e 100644 --- a/kernel/power/swap.c +++ b/kernel/power/swap.c @@ -1534,6 +1534,9 @@ int swsusp_check(void) FMODE_READ, NULL); if (!IS_ERR(hib_resume_bdev)) { set_blocksize(hib_resume_bdev, PAGE_SIZE); + if (noswap_randomize) + hib_resume_bdev->bd_disk->flags |= + GENHD_FL_NO_RANDOMIZE; clear_page(swsusp_header); error = hib_submit_io(REQ_OP_READ, 0, swsusp_resume_block, -- GitLab From 9ac5f3cf60dfd084da976be3682ef2ad69095e6b Mon Sep 17 00:00:00 2001 From: Vivek Kumar Date: Tue, 18 Jun 2019 12:39:37 +0530 Subject: [PATCH 0625/1121] mm: swap: Add randomization check for swapon/off calls Add addtional check on swapon/swapoff sycalls to disable randomization of swap offsets if GENHD_FL_NO_RANDOMIZE flag is passed. Change-Id: I6f5ce7275f09b812a8954328331545eee0aa77ef Signed-off-by: Vivek Kumar --- mm/swapfile.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mm/swapfile.c b/mm/swapfile.c index f1f8dcc4453a..4c7fa1c02005 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -2645,7 +2645,8 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) if (p->flags & SWP_CONTINUED) free_swap_count_continuations(p); - if (!p->bdev || !blk_queue_nonrot(bdev_get_queue(p->bdev))) + if (!p->bdev || (p->bdev->bd_disk->flags & GENHD_FL_NO_RANDOMIZE) || + !blk_queue_nonrot(bdev_get_queue(p->bdev))) atomic_dec(&nr_rotate_swap); mutex_lock(&swapon_mutex); @@ -3220,7 +3221,8 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) if (bdi_cap_synchronous_io(inode_to_bdi(inode))) p->flags |= SWP_SYNCHRONOUS_IO; - if (p->bdev && blk_queue_nonrot(bdev_get_queue(p->bdev))) { + if (p->bdev && !(p->bdev->bd_disk->flags & GENHD_FL_NO_RANDOMIZE) && + blk_queue_nonrot(bdev_get_queue(p->bdev))) { int cpu; unsigned long ci, nr_cluster; -- GitLab From 8b575a30ff778f8861a2d66bede6c75bb479e787 Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Tue, 18 Jun 2019 01:12:17 -0700 Subject: [PATCH 0626/1121] ARM: dts: add pinctrl handle in snd card on 6155 platform Add pinctrl handle information in snd card node on automotive 6155 platform. Change-Id: I8ac3f59e051f09e8978123364db41461b85e26ad Signed-off-by: Derek Chen --- arch/arm64/boot/dts/qcom/sa6155-audio.dtsi | 48 ++++++++++------------ 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sa6155-audio.dtsi b/arch/arm64/boot/dts/qcom/sa6155-audio.dtsi index 6b8316ad66b9..e67566916662 100644 --- a/arch/arm64/boot/dts/qcom/sa6155-audio.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155-audio.dtsi @@ -13,7 +13,7 @@ #include "sm6150-lpi.dtsi" &soc { - qcom,msm-dai-tdm-pri-rx { + tdm_pri_rx: qcom,msm-dai-tdm-pri-rx { compatible = "qcom,msm-dai-tdm"; qcom,msm-cpudai-tdm-group-id = <37120>; qcom,msm-cpudai-tdm-group-num-ports = <4>; @@ -51,7 +51,7 @@ }; }; - qcom,msm-dai-tdm-pri-tx { + tdm_pri_tx: qcom,msm-dai-tdm-pri-tx { compatible = "qcom,msm-dai-tdm"; qcom,msm-cpudai-tdm-group-id = <37121>; qcom,msm-cpudai-tdm-group-num-ports = <4>; @@ -89,7 +89,7 @@ }; }; - qcom,msm-dai-tdm-sec-rx { + tdm_sec_rx: qcom,msm-dai-tdm-sec-rx { compatible = "qcom,msm-dai-tdm"; qcom,msm-cpudai-tdm-group-id = <37136>; qcom,msm-cpudai-tdm-group-num-ports = <5>; @@ -133,7 +133,7 @@ }; }; - qcom,msm-dai-tdm-sec-tx { + tdm_sec_tx: qcom,msm-dai-tdm-sec-tx { compatible = "qcom,msm-dai-tdm"; qcom,msm-cpudai-tdm-group-id = <37137>; qcom,msm-cpudai-tdm-group-num-ports = <4>; @@ -170,7 +170,7 @@ }; }; - qcom,msm-dai-tdm-tert-rx { + tdm_tert_rx: qcom,msm-dai-tdm-tert-rx { compatible = "qcom,msm-dai-tdm"; qcom,msm-cpudai-tdm-group-id = <37152>; qcom,msm-cpudai-tdm-group-num-ports = <5>; @@ -184,8 +184,10 @@ qcom,msm-cpudai-tdm-invert-sync = <0>; qcom,msm-cpudai-tdm-data-delay = <0>; pinctrl-names = "default", "sleep"; - pinctrl-0 = <&ter_i2s_sck_active &ter_i2s_data1_active>; - pinctrl-1 = <&ter_i2s_sck_sleep &ter_i2s_data1_sleep>; + pinctrl-0 = <&ter_i2s_sck_active &ter_i2s_data0_active + &ter_i2s_data1_active>; + pinctrl-1 = <&ter_i2s_sck_sleep &ter_i2s_data0_sleep + &ter_i2s_data1_sleep>; dai_tert_tdm_rx_0: qcom,msm-dai-q6-tdm-tert-rx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36896>; @@ -217,7 +219,7 @@ }; }; - qcom,msm-dai-tdm-tert-tx { + tdm_tert_tx: qcom,msm-dai-tdm-tert-tx { compatible = "qcom,msm-dai-tdm"; qcom,msm-cpudai-tdm-group-id = <37153>; qcom,msm-cpudai-tdm-group-num-ports = <5>; @@ -230,9 +232,6 @@ qcom,msm-cpudai-tdm-data-out = <0>; qcom,msm-cpudai-tdm-invert-sync = <0>; qcom,msm-cpudai-tdm-data-delay = <0>; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&ter_i2s_data0_active>; - pinctrl-1 = <&ter_i2s_data0_sleep>; dai_tert_tdm_tx_0: qcom,msm-dai-q6-tdm-tert-tx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36897>; @@ -264,7 +263,7 @@ }; }; - qcom,msm-dai-tdm-quat-rx { + tdm_quat_rx: qcom,msm-dai-tdm-quat-rx { compatible = "qcom,msm-dai-tdm"; qcom,msm-cpudai-tdm-group-id = <37168>; qcom,msm-cpudai-tdm-group-num-ports = <5>; @@ -280,9 +279,9 @@ qcom,msm-cpudai-tdm-data-delay = <0>; pinctrl-names = "default", "sleep"; pinctrl-0 = <&quat_tdm_sclk_active &quat_tdm_ws_active - &quat_tdm_data1_active>; + &quat_tdm_data0_active &quat_tdm_data1_active>; pinctrl-1 = <&quat_tdm_sclk_sleep &quat_tdm_ws_sleep - &quat_tdm_data1_sleep>; + &quat_tdm_data0_sleep &quat_tdm_data1_sleep>; dai_quat_tdm_rx_0: qcom,msm-dai-q6-tdm-quat-rx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36912>; @@ -313,7 +312,7 @@ }; }; - qcom,msm-dai-tdm-quat-tx { + tdm_quat_tx: qcom,msm-dai-tdm-quat-tx { compatible = "qcom,msm-dai-tdm"; qcom,msm-cpudai-tdm-group-id = <37169>; qcom,msm-cpudai-tdm-group-num-ports = <5>; @@ -327,9 +326,6 @@ qcom,msm-cpudai-tdm-data-out = <0>; qcom,msm-cpudai-tdm-invert-sync = <0>; qcom,msm-cpudai-tdm-data-delay = <0>; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&quat_tdm_data0_active>; - pinctrl-1 = <&quat_tdm_data0_sleep>; dai_quat_tdm_tx_0: qcom,msm-dai-q6-tdm-quat-tx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36913>; @@ -361,7 +357,7 @@ }; }; - qcom,msm-dai-tdm-quin-rx { + tdm_quin_rx: qcom,msm-dai-tdm-quin-rx { compatible = "qcom,msm-dai-tdm"; qcom,msm-cpudai-tdm-group-id = <37184>; qcom,msm-cpudai-tdm-group-num-ports = <4>; @@ -375,9 +371,9 @@ qcom,msm-cpudai-tdm-data-delay = <0>; pinctrl-names = "default", "sleep"; pinctrl-0 = <&quin_tdm_sclk_active &quin_tdm_ws_active - &quin_tdm_data1_active>; + &quin_tdm_data0_active &quin_tdm_data1_active>; pinctrl-1 = <&quin_tdm_sclk_sleep &quin_tdm_ws_sleep - &quin_tdm_data1_sleep>; + &quin_tdm_data0_sleep &quin_tdm_data1_sleep>; dai_quin_tdm_rx_0: qcom,msm-dai-q6-tdm-quin-rx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36928>; @@ -403,7 +399,7 @@ }; }; - qcom,msm-dai-tdm-quin-tx { + tdm_quin_tx: qcom,msm-dai-tdm-quin-tx { compatible = "qcom,msm-dai-tdm"; qcom,msm-cpudai-tdm-group-id = <37185>; qcom,msm-cpudai-tdm-group-num-ports = <4>; @@ -415,9 +411,6 @@ qcom,msm-cpudai-tdm-data-out = <0>; qcom,msm-cpudai-tdm-invert-sync = <0>; qcom,msm-cpudai-tdm-data-delay = <0>; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&quin_tdm_data0_active>; - pinctrl-1 = <&quin_tdm_data0_sleep>; dai_quin_tdm_tx_0: qcom,msm-dai-q6-tdm-quin-tx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36929>; @@ -468,13 +461,16 @@ &q6core { sound-adp-star { - status = "ok"; compatible = "qcom,sa6155-asoc-snd-adp-star"; qcom,model = "sa6155-adp-star-snd-card"; qcom,mi2s-audio-intf; qcom,auxpcm-audio-intf; qcom,msm-mi2s-master = <1>, <1>, <1>, <1>, <1>; + qcom,tert-tdm-gpios = <&tdm_tert_rx>; + qcom,quat-tdm-gpios = <&tdm_quat_rx>; + qcom,quin-tdm-gpios = <&tdm_quin_rx>; + asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>, <&loopback>, <&compress>, <&hostless>, <&afe>, <&lsm>, <&routing>, <&compr>, -- GitLab From 7167b0db46a446eb5bc5b01b2d6f0a736e171b22 Mon Sep 17 00:00:00 2001 From: Sanjay Dwivedi Date: Tue, 18 Jun 2019 17:48:30 +0530 Subject: [PATCH 0627/1121] ARM: dts: msm: delete pm8150b nodes from mtp cpe dts file CPE design operates with 12V input and has an external regulator to provide VPH_PWR. Battery is used here only as back up. USB_VBUS is connected to PMX55 and is not connected PM8150B, so deleted nodes of PM8150M Change-Id: Ie72bb758cf7a274bce1eb99a0809811b12212d97 Signed-off-by: Sanjay Dwivedi --- .../boot/dts/qcom/sdxprairie-mtp-cpe.dts | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdxprairie-mtp-cpe.dts b/arch/arm64/boot/dts/qcom/sdxprairie-mtp-cpe.dts index 1c15d85d8afa..94f1729753eb 100644 --- a/arch/arm64/boot/dts/qcom/sdxprairie-mtp-cpe.dts +++ b/arch/arm64/boot/dts/qcom/sdxprairie-mtp-cpe.dts @@ -21,4 +21,35 @@ qcom,board-id = <0x7010008 0x0>; }; +/* delete pm8150b nodes */ +&soc { + /delete-node/ thermal-zones; +}; + +&usb { + extcon = <&vbus_detect>; +}; + +&spmi_bus { + /delete-node/ qpnp,fg; + /delete-node/ bcl@1d00; + /delete-node/ qcom,usb-pdphy@1700; + /delete-node/ qcom,qpnp-smb5; + /delete-node/ adc_tm@3500; + /delete-node/ vadc@3100; + /delete-node/ qcom,pm8150b@2; + /delete-node/ qcom,pm8150b@3; +}; + +&qnand_1 { + status = "ok"; +}; + +&blsp1_uart2b_hs { + status = "okay"; +}; + +&vbus_detect { + status = "okay"; +}; -- GitLab From 19406ab126bd517891e9e770695d34797ce60097 Mon Sep 17 00:00:00 2001 From: Ghanim Fodi Date: Tue, 18 Jun 2019 18:18:39 +0300 Subject: [PATCH 0628/1121] msm: ipa: Update IPA SRAM mapping Update IPA SRAM mapping allocating more space for modem header proc contexts to support more UL NLO bearers. Change-Id: I9435445491cddde8a13c16b7704ced37b1b74bf6 Signed-off-by: Ghanim Fodi --- drivers/platform/msm/ipa/ipa_v3/ipa_utils.c | 26 ++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c index d9e33fc3a23e..4e689348c0b6 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c @@ -2825,21 +2825,19 @@ static struct ipa3_mem_partition ipa_4_5_mem_part = { .apps_hdr_size = 0x200, .apps_hdr_size_ddr = 0x800, .modem_hdr_proc_ctx_ofst = 0xad0, - .modem_hdr_proc_ctx_size = 0xac0, - .apps_hdr_proc_ctx_ofst = 0x1590, + .modem_hdr_proc_ctx_size = 0xb20, + .apps_hdr_proc_ctx_ofst = 0x15f0, .apps_hdr_proc_ctx_size = 0x200, .apps_hdr_proc_ctx_size_ddr = 0x0, - .nat_tbl_ofst = 0x17a0, + .nat_tbl_ofst = 0x1800, .nat_tbl_size = 0x800, - .nat_index_tbl_ofst = 0x1fa0, + .nat_index_tbl_ofst = 0x2000, .nat_index_tbl_size = 0x100, - .nat_exp_tbl_ofst = 0x20a0, + .nat_exp_tbl_ofst = 0x2100, .nat_exp_tbl_size = 0x400, - .pdn_config_ofst = 0x24a8, - .pdn_config_size = 0x50, - .stats_quota_ofst = 0x2500, + .stats_quota_ofst = 0x2510, .stats_quota_size = 0x78, - .stats_tethering_ofst = 0x2578, + .stats_tethering_ofst = 0x2588, .stats_tethering_size = 0x238, .stats_flt_v4_ofst = 0, .stats_flt_v4_size = 0, @@ -2849,13 +2847,13 @@ static struct ipa3_mem_partition ipa_4_5_mem_part = { .stats_rt_v4_size = 0, .stats_rt_v6_ofst = 0, .stats_rt_v6_size = 0, - .stats_fnr_ofst = 0x27b0, + .stats_fnr_ofst = 0x27c0, .stats_fnr_size = 0x800, - .stats_drop_ofst = 0x2fb0, + .stats_drop_ofst = 0x2fc0, .stats_drop_size = 0x20, .modem_comp_decomp_ofst = 0x0, .modem_comp_decomp_size = 0x0, - .modem_ofst = 0x2fd8, + .modem_ofst = 0x2fe8, .modem_size = 0x800, .apps_v4_flt_hash_ofst = 0x2718, .apps_v4_flt_hash_size = 0x0, @@ -2875,7 +2873,9 @@ static struct ipa3_mem_partition ipa_4_5_mem_part = { .apps_v6_rt_nhash_size = 0x0, .uc_descriptor_ram_ofst = 0x3800, .uc_descriptor_ram_size = 0x1000, - .end_ofst = 0x4800, + .pdn_config_ofst = 0x4800, + .pdn_config_size = 0x50, + .end_ofst = 0x4850, }; -- GitLab From 6c2d12efae48ead1222ac68e0391a6ec8a0f9e29 Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Wed, 19 Jun 2019 11:08:11 -0700 Subject: [PATCH 0629/1121] ARM: dts: msm: Add calypso CAN controller support for the SA8195 target This change enables support for the CAN controller on the SA8195 target. Change-Id: Ied6dba75ae3e48a5e2e1689884db54a6f48e7adc Signed-off-by: Anant Goel --- .../arm64/boot/dts/qcom/sa8195p-adp-star.dtsi | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sa8195p-adp-star.dtsi b/arch/arm64/boot/dts/qcom/sa8195p-adp-star.dtsi index 1232f4bc40d2..f35258968995 100644 --- a/arch/arm64/boot/dts/qcom/sa8195p-adp-star.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8195p-adp-star.dtsi @@ -12,6 +12,25 @@ #include "sdmshrike-v2.dtsi" +&qupv3_se0_spi { + status = "ok"; + + #address-cells = <1>; + #size-cells = <0>; + + can-controller@0 { + compatible = "qcom,nxp,mpc5746c"; + reg = <0>; + interrupt-parent = <&tlmm>; + interrupts = <38 0>; + spi-max-frequency = <5000000>; + qcom,clk-freq-mhz = <40000000>; + qcom,max-can-channels = <1>; + qcom,bits-per-word = <8>; + qcom,support-can-fd; + }; +}; + &qupv3_se12_2uart { status = "ok"; }; -- GitLab From d0ecb4b79e8d57313047a3a18ce2cdf0c521b934 Mon Sep 17 00:00:00 2001 From: Sushmita Susheelendra Date: Mon, 17 Jun 2019 17:19:32 -0600 Subject: [PATCH 0630/1121] msm: kgsl: Change throttling counter weight from 15% to 5% Change weights for throttling counters from (15%, 50%, 90%) to (5%, 50%, 90%) for GMU FW step version > 0x104. Change-Id: Ia98303dc894ac07e285e8145923d6ad1c152b3cf Signed-off-by: Sushmita Susheelendra --- drivers/gpu/msm/adreno_a6xx.c | 13 +++++++++++-- drivers/gpu/msm/adreno_a6xx_gmu.c | 6 +++++- drivers/gpu/msm/kgsl_gmu_core.h | 8 +++++++- drivers/gpu/msm/kgsl_hfi.c | 7 +------ 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/msm/adreno_a6xx.c b/drivers/gpu/msm/adreno_a6xx.c index 0ec46c177efb..81a93c5dbfa8 100644 --- a/drivers/gpu/msm/adreno_a6xx.c +++ b/drivers/gpu/msm/adreno_a6xx.c @@ -30,6 +30,7 @@ #include "kgsl.h" #include "kgsl_hfi.h" #include "kgsl_trace.h" +#include "kgsl_gmu.h" #define MIN_HBB 13 @@ -1445,6 +1446,8 @@ static int64_t a6xx_read_throttling_counters(struct adreno_device *adreno_dev) int64_t adj = -1; uint32_t counts[ADRENO_GPMU_THROTTLE_COUNTERS]; struct adreno_busy_data *busy = &adreno_dev->busy_data; + struct kgsl_device *device = KGSL_DEVICE(adreno_dev); + struct gmu_device *gmu = KGSL_GMU_DEVICE(device); for (i = 0; i < ARRAY_SIZE(counts); i++) { if (!adreno_dev->gpmu_throttle_counters[i]) @@ -1458,12 +1461,18 @@ static int64_t a6xx_read_throttling_counters(struct adreno_device *adreno_dev) /* * The adjustment is the number of cycles lost to throttling, which * is calculated as a weighted average of the cycles throttled - * at 15%, 50%, and 90%. The adjustment is negative because in A6XX, + * at 5% or 15% based on GMU FW version, 50%, and 90%. + * The adjustment is negative because in A6XX, * the busy count includes the throttled cycles. Therefore, we want * to remove them to prevent appearing to be busier than * we actually are. */ - adj *= ((counts[0] * 15) + (counts[1] * 50) + (counts[2] * 90)) / 100; + if (GMU_VER_STEP(gmu->ver) > 0x104) + adj *= ((counts[0] * 5) + (counts[1] * 50) + (counts[2] * 90)) + / 100; + else + adj *= ((counts[0] * 15) + (counts[1] * 50) + (counts[2] * 90)) + / 100; trace_kgsl_clock_throttling(0, counts[1], counts[2], counts[0], adj); diff --git a/drivers/gpu/msm/adreno_a6xx_gmu.c b/drivers/gpu/msm/adreno_a6xx_gmu.c index 315eea3a3a85..eab598e8ea86 100644 --- a/drivers/gpu/msm/adreno_a6xx_gmu.c +++ b/drivers/gpu/msm/adreno_a6xx_gmu.c @@ -1316,7 +1316,7 @@ static uint32_t lm_limit(struct adreno_device *adreno_dev) } static int a640_throttling_counters[ADRENO_GPMU_THROTTLE_COUNTERS] = { - 0x11, 0x15, 0x19 + 0x11, 0x15, 0x19, }; static void _setup_throttling_counters(struct adreno_device *adreno_dev) @@ -1325,6 +1325,10 @@ static void _setup_throttling_counters(struct adreno_device *adreno_dev) struct gmu_device *gmu = KGSL_GMU_DEVICE(device); int i, ret; + /* Select counter for 5% throttling instead of 15% */ + if (GMU_VER_STEP(gmu->ver) > 0x104) + a640_throttling_counters[0] = 0x10; + for (i = 0; i < ARRAY_SIZE(a640_throttling_counters); i++) { adreno_dev->busy_data.throttle_cycles[i] = 0; diff --git a/drivers/gpu/msm/kgsl_gmu_core.h b/drivers/gpu/msm/kgsl_gmu_core.h index 52395b76b995..0bb6c55ea0d5 100644 --- a/drivers/gpu/msm/kgsl_gmu_core.h +++ b/drivers/gpu/msm/kgsl_gmu_core.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -21,6 +21,12 @@ (((_devops) != NULL) && \ ((_devops)->_field != NULL)) +#define GMU_VER_MAJOR(ver) (((ver) >> 28) & 0xF) +#define GMU_VER_MINOR(ver) (((ver) >> 16) & 0xFFF) +#define GMU_VER_STEP(ver) (((ver) >> 0) & 0xFFFF) +#define GMU_VERSION(major, minor) \ + ((((major) & 0xF) << 28) | (((minor) & 0xFFF) << 16)) + #define NUM_BW_LEVELS 100 #define MAX_GX_LEVELS 16 #define MAX_CX_LEVELS 4 diff --git a/drivers/gpu/msm/kgsl_hfi.c b/drivers/gpu/msm/kgsl_hfi.c index aa0c9cc8d1bb..2810644a592b 100644 --- a/drivers/gpu/msm/kgsl_hfi.c +++ b/drivers/gpu/msm/kgsl_hfi.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -628,11 +628,6 @@ void hfi_receiver(unsigned long data) hfi_process_queue((struct gmu_device *) data, HFI_DBG_ID, NULL); } -#define GMU_VER_MAJOR(ver) (((ver) >> 28) & 0xF) -#define GMU_VER_MINOR(ver) (((ver) >> 16) & 0xFFF) -#define GMU_VERSION(major, minor) \ - ((((major) & 0xF) << 28) | (((minor) & 0xFFF) << 16)) - static int hfi_verify_fw_version(struct kgsl_device *device, struct gmu_device *gmu) { -- GitLab From 6c254244628c0c71fd23d2d058d5d0c515572827 Mon Sep 17 00:00:00 2001 From: Sean Tranchetti Date: Wed, 19 Jun 2019 14:39:15 -0600 Subject: [PATCH 0631/1121] net: qualcomm: rmnet: Use header lengths in descriptor segmentation When segmenting RSB/RSC frames, account for the L3 and L4 header lengths at the start of the coalescing descriptor's page. This allows the newly filled descriptor to have the proper length and data pointer. Change-Id: If4ae73636f89d41f501c30cd1400a9c7e94c4dcb CRs-Fixed: 2474307 Signed-off-by: Sean Tranchetti --- drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c index e4f073422db6..00516925c8a6 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c @@ -577,17 +577,21 @@ static void __rmnet_frag_segment_data(struct rmnet_frag_descriptor *coal_desc, struct rmnet_priv *priv = netdev_priv(coal_desc->dev); struct rmnet_frag_descriptor *new_frag; u8 *hdr_start = rmnet_frag_data_ptr(coal_desc); + u32 offset; new_frag = rmnet_get_frag_descriptor(port); if (!new_frag) return; + /* Account for header lengths to access the data start */ + offset = coal_desc->frag.page_offset + coal_desc->ip_len + + coal_desc->trans_len + coal_desc->data_offset; + /* Header information and most metadata is the same as the original */ memcpy(new_frag, coal_desc, sizeof(*coal_desc)); INIT_LIST_HEAD(&new_frag->list); INIT_LIST_HEAD(&new_frag->sub_frags); - rmnet_frag_fill(new_frag, skb_frag_page(&coal_desc->frag), - coal_desc->frag.page_offset + coal_desc->data_offset, + rmnet_frag_fill(new_frag, skb_frag_page(&coal_desc->frag), offset, coal_desc->gso_size * coal_desc->gso_segs); if (coal_desc->trans_proto == IPPROTO_TCP) { -- GitLab From add5ec7a203572dabd6f7339a96de3bdb49c3c9c Mon Sep 17 00:00:00 2001 From: Michael Adisumarta Date: Wed, 19 Jun 2019 15:09:47 -0700 Subject: [PATCH 0632/1121] msm: ipa3: Fix RNDIS Tethering Stats update for UDP UL Add the tx packet and bytes correctly to the total instead of resetting it every time for wlan UL stats. Change-Id: I4316485277351357f08b7241d53b732b74ca6073 Signed-off-by: Michael Adisumarta --- drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c index ab50dd06f9dd..d557303c7ab4 100644 --- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c @@ -3773,13 +3773,13 @@ static int rmnet_ipa3_query_tethering_stats_hw( con_stats->client[index].num_ipv6_bytes); /* update the wlan UL stats */ - data->ipv4_tx_packets = + data->ipv4_tx_packets += con_stats->client[index].num_ipv4_pkts; - data->ipv6_tx_packets = + data->ipv6_tx_packets += con_stats->client[index].num_ipv6_pkts; - data->ipv4_tx_bytes = + data->ipv4_tx_bytes += con_stats->client[index].num_ipv4_bytes; - data->ipv6_tx_bytes = + data->ipv6_tx_bytes += con_stats->client[index].num_ipv6_bytes; /* wlan UL stats on cv2 */ -- GitLab From c5e6acd01672bc44f29771cd133c9516cdf389c6 Mon Sep 17 00:00:00 2001 From: Xianbin Zhu Date: Mon, 17 Jun 2019 20:51:03 +0800 Subject: [PATCH 0633/1121] i2c: virtio: reallocate memory for each msg buffer We'd better reallocate memory for each msg buffer to avoid the memory in stack space be transferred to the backend for the driver of i2c virtualization. Change-Id: I6daa58cf819d4f612ae246b5a685898e28fbeb54 Signed-off-by: Xianbin Zhu --- drivers/i2c/busses/virtio-i2c.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/drivers/i2c/busses/virtio-i2c.c b/drivers/i2c/busses/virtio-i2c.c index 4607cf48f842..b10ddd03ec1e 100644 --- a/drivers/i2c/busses/virtio-i2c.c +++ b/drivers/i2c/busses/virtio-i2c.c @@ -130,20 +130,28 @@ static int virti2c_transfer_prepare(struct i2c_msg *msg_1, i2c_req->head.length = msg_1->len; if (IS_ERR_OR_NULL(msg_2)) { - i2c_req->head.type = (msg_1->flags & I2C_M_RD) ? - I2C_VIRTIO_RD : I2C_VIRTIO_WR; - i2c_req->buf = msg_1->buf; + i2c_req->buf = kzalloc(msg_1->len, GFP_KERNEL); + if (!i2c_req->buf) + return -ENOMEM; + + if (msg_1->flags & I2C_M_RD) { + i2c_req->head.type = I2C_VIRTIO_RD; + } else { + i2c_req->head.type = I2C_VIRTIO_WR; + memcpy(i2c_req->buf, msg_1->buf, msg_1->len); + } + } else { if (!msg_2->len || IS_ERR_OR_NULL(msg_2->buf)) return -EINVAL; - i2c_req->head.type = I2C_VIRTIO_RDWR; - i2c_req->head.total_length = msg_1->len + msg_2->len; - i2c_req->buf = kzalloc((msg_1->len + msg_2->len), GFP_KERNEL); - if (IS_ERR_OR_NULL(i2c_req->buf)) + if (!i2c_req->buf) return -ENOMEM; + i2c_req->head.type = I2C_VIRTIO_RDWR; + i2c_req->head.total_length = msg_1->len + msg_2->len; + memcpy(i2c_req->buf, msg_1->buf, msg_1->len); } @@ -153,13 +161,12 @@ static int virti2c_transfer_prepare(struct i2c_msg *msg_1, static void virti2c_transfer_end(struct virtio_i2c_req *req, struct i2c_msg *msg) { - if (req->head.type == I2C_VIRTIO_RDWR) { + if (req->head.type == I2C_VIRTIO_RDWR) memcpy(msg->buf, req->buf + req->head.length, msg->len); - kfree(req->buf); - req->buf = NULL; - } - - memset(req, 0, sizeof(struct virtio_i2c_req)); + else if (req->head.type == I2C_VIRTIO_RD) + memcpy(msg->buf, req->buf, msg->len); + kfree(req->buf); + req->buf = NULL; } static int virtio_i2c_master_xfer(struct i2c_adapter *adap, -- GitLab From 983dae0530c2cfd38fbfa7eba963c91f6d9e3e9e Mon Sep 17 00:00:00 2001 From: Kaushal Kumar Date: Wed, 19 Jun 2019 18:19:42 +0530 Subject: [PATCH 0634/1121] defconfig: msm: Enable KPTI on sa8155, sm8150 Enable KPTI mitigation on sa8155, sm8150 since it is needed as part of android CTS. The mitigation is to unmap kernel when running in userspace. Change-Id: I3ef97a7646ff07c1a7086c0aaaf069fc2bdef253 Signed-off-by: Kaushal Kumar --- arch/arm64/configs/vendor/sa8155-perf_defconfig | 1 - arch/arm64/configs/vendor/sa8155_defconfig | 1 - arch/arm64/configs/vendor/sm8150-perf_defconfig | 1 - arch/arm64/configs/vendor/sm8150_defconfig | 1 - 4 files changed, 4 deletions(-) diff --git a/arch/arm64/configs/vendor/sa8155-perf_defconfig b/arch/arm64/configs/vendor/sa8155-perf_defconfig index 33156827a505..ab10045c4e48 100644 --- a/arch/arm64/configs/vendor/sa8155-perf_defconfig +++ b/arch/arm64/configs/vendor/sa8155-perf_defconfig @@ -67,7 +67,6 @@ CONFIG_HZ_100=y CONFIG_CMA=y CONFIG_ZSMALLOC=y CONFIG_SECCOMP=y -# CONFIG_UNMAP_KERNEL_AT_EL0 is not set # CONFIG_HARDEN_BRANCH_PREDICTOR is not set CONFIG_ARMV8_DEPRECATED=y CONFIG_SWP_EMULATION=y diff --git a/arch/arm64/configs/vendor/sa8155_defconfig b/arch/arm64/configs/vendor/sa8155_defconfig index 804b904b712a..2c4bc5524158 100644 --- a/arch/arm64/configs/vendor/sa8155_defconfig +++ b/arch/arm64/configs/vendor/sa8155_defconfig @@ -73,7 +73,6 @@ CONFIG_CMA=y CONFIG_CMA_DEBUGFS=y CONFIG_ZSMALLOC=y CONFIG_SECCOMP=y -# CONFIG_UNMAP_KERNEL_AT_EL0 is not set # CONFIG_HARDEN_BRANCH_PREDICTOR is not set CONFIG_PRINT_VMEMLAYOUT=y CONFIG_ARMV8_DEPRECATED=y diff --git a/arch/arm64/configs/vendor/sm8150-perf_defconfig b/arch/arm64/configs/vendor/sm8150-perf_defconfig index dd384cb57a31..5cd27c061d9f 100644 --- a/arch/arm64/configs/vendor/sm8150-perf_defconfig +++ b/arch/arm64/configs/vendor/sm8150-perf_defconfig @@ -74,7 +74,6 @@ CONFIG_ZSMALLOC=y CONFIG_BALANCE_ANON_FILE_RECLAIM=y CONFIG_SECCOMP=y CONFIG_OKL4_GUEST=y -# CONFIG_UNMAP_KERNEL_AT_EL0 is not set CONFIG_ARMV8_DEPRECATED=y CONFIG_SWP_EMULATION=y CONFIG_CP15_BARRIER_EMULATION=y diff --git a/arch/arm64/configs/vendor/sm8150_defconfig b/arch/arm64/configs/vendor/sm8150_defconfig index 8d17e3d70648..af5199452eff 100644 --- a/arch/arm64/configs/vendor/sm8150_defconfig +++ b/arch/arm64/configs/vendor/sm8150_defconfig @@ -80,7 +80,6 @@ CONFIG_ZSMALLOC=y CONFIG_BALANCE_ANON_FILE_RECLAIM=y CONFIG_SECCOMP=y CONFIG_OKL4_GUEST=y -# CONFIG_UNMAP_KERNEL_AT_EL0 is not set CONFIG_PRINT_VMEMLAYOUT=y CONFIG_ARMV8_DEPRECATED=y CONFIG_SWP_EMULATION=y -- GitLab From 937c1f6639a48bfd0a93dfe25b82d396ee14a6ce Mon Sep 17 00:00:00 2001 From: Sahil Chandna Date: Wed, 12 Jun 2019 14:40:14 +0530 Subject: [PATCH 0635/1121] power: battery: smb5-lib: Introduce FCC Main Votable Currently FCC of main charger is set based on a power supply property. Introduce a new FCC MAIN votable to vote on setting the FCC of main Charger. Defining FCC and FCC main votables allows us to independently configure/specify the overall (target) FCC and the FCC requirement of the main charger. Thus, helping in CP based designs where the main charger runs with fixed FCC values. Reset the vote on charger removal. Change-Id: I32a28b10a582167edcde904536735290fbfa2bc1 Signed-off-by: Sahil Chandna --- drivers/power/supply/qcom/battery.c | 127 ++++++++++++--------------- drivers/power/supply/qcom/smb5-lib.c | 10 +++ drivers/power/supply/qcom/smb5-lib.h | 2 + 3 files changed, 68 insertions(+), 71 deletions(-) diff --git a/drivers/power/supply/qcom/battery.c b/drivers/power/supply/qcom/battery.c index 4ce909b22b24..e786e27bb02a 100644 --- a/drivers/power/supply/qcom/battery.c +++ b/drivers/power/supply/qcom/battery.c @@ -48,6 +48,7 @@ #define ICL_LIMIT_VOTER "ICL_LIMIT_VOTER" #define FCC_STEPPER_VOTER "FCC_STEPPER_VOTER" #define FCC_VOTER "FCC_VOTER" +#define MAIN_FCC_VOTER "MAIN_FCC_VOTER" struct pl_data { int pl_mode; @@ -67,6 +68,7 @@ struct pl_data { struct votable *pl_enable_votable_indirect; struct votable *cp_ilim_votable; struct votable *cp_disable_votable; + struct votable *fcc_main_votable; struct delayed_work status_change_work; struct work_struct pl_disable_forever_work; struct work_struct pl_taper_work; @@ -560,17 +562,9 @@ static void get_fcc_stepper_params(struct pl_data *chip, int main_fcc_ua, int parallel_fcc_ua) { union power_supply_propval pval = {0, }; - int rc; /* Read current FCC of main charger */ - rc = power_supply_get_property(chip->main_psy, - POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, &pval); - if (rc < 0) { - pr_err("Couldn't get main charger current fcc, rc=%d\n", rc); - return; - } - chip->main_fcc_ua = pval.intval; - + chip->main_fcc_ua = get_effective_result(chip->fcc_main_votable); chip->main_step_fcc_dir = (main_fcc_ua > pval.intval) ? STEP_UP : STEP_DOWN; chip->main_step_fcc_count = abs((main_fcc_ua - pval.intval) / @@ -690,6 +684,31 @@ static void pl_taper_work(struct work_struct *work) vote(chip->pl_awake_votable, TAPER_END_VOTER, false, 0); } +static bool is_main_available(struct pl_data *chip) +{ + if (chip->main_psy) + return true; + + chip->main_psy = power_supply_get_by_name("main"); + + return !!chip->main_psy; +} + +static int pl_fcc_main_vote_callback(struct votable *votable, void *data, + int fcc_main_ua, const char *client) +{ + struct pl_data *chip = data; + union power_supply_propval pval = {0,}; + + if (!is_main_available(chip)) + return 0; + + pval.intval = fcc_main_ua; + return power_supply_set_property(chip->main_psy, + POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, + &pval); +} + static int pl_fcc_vote_callback(struct votable *votable, void *data, int total_fcc_ua, const char *client) { @@ -738,6 +757,13 @@ static int pl_fcc_vote_callback(struct votable *votable, void *data, } rerun_election(chip->pl_disable_votable); + /* When FCC changes, trigger psy changed event for CC mode */ + if (!chip->cp_master_psy) + chip->cp_master_psy = + power_supply_get_by_name("charge_pump_master"); + + if (chip->cp_master_psy) + power_supply_changed(chip->cp_master_psy); return 0; } @@ -794,14 +820,7 @@ static void fcc_stepper_work(struct work_struct *work) } main_fcc = get_effective_result_locked(chip->fcc_votable); - pval.intval = main_fcc; - rc = power_supply_set_property(chip->main_psy, - POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, &pval); - if (rc < 0) { - pr_err("Couldn't set main charger fcc, rc=%d\n", rc); - goto out; - } - + vote(chip->fcc_main_votable, FCC_STEPPER_VOTER, true, main_fcc); goto stepper_exit; } @@ -862,22 +881,10 @@ static void fcc_stepper_work(struct work_struct *work) } /* Set main FCC */ - pval.intval = main_fcc; - rc = power_supply_set_property(chip->main_psy, - POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, &pval); - if (rc < 0) { - pr_err("Couldn't set main charger fcc, rc=%d\n", rc); - goto out; - } + vote(chip->fcc_main_votable, FCC_STEPPER_VOTER, true, main_fcc); } else { /* Set main FCC */ - pval.intval = main_fcc; - rc = power_supply_set_property(chip->main_psy, - POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, &pval); - if (rc < 0) { - pr_err("Couldn't set main charger fcc, rc=%d\n", rc); - goto out; - } + vote(chip->fcc_main_votable, FCC_STEPPER_VOTER, true, main_fcc); /* Set parallel FCC */ if (chip->pl_psy) { @@ -1063,16 +1070,6 @@ static void pl_awake_work(struct work_struct *work) vote(chip->pl_awake_votable, PL_VOTER, false, 0); } -static bool is_main_available(struct pl_data *chip) -{ - if (chip->main_psy) - return true; - - chip->main_psy = power_supply_get_by_name("main"); - - return !!chip->main_psy; -} - static bool is_batt_available(struct pl_data *chip) { if (!chip->batt_psy) @@ -1184,16 +1181,8 @@ static int pl_disable_vote_callback(struct votable *votable, * Set slave ICL then main FCC. */ if (slave_fcc_ua > chip->slave_fcc_ua) { - pval.intval = master_fcc_ua; - rc = power_supply_set_property(chip->main_psy, - POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, - &pval); - if (rc < 0) { - pr_err("Could not set main fcc, rc=%d\n", - rc); - return rc; - } - + vote(chip->fcc_main_votable, MAIN_FCC_VOTER, + true, master_fcc_ua); pval.intval = slave_fcc_ua; rc = power_supply_set_property(chip->pl_psy, POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, @@ -1217,16 +1206,8 @@ static int pl_disable_vote_callback(struct votable *votable, } chip->slave_fcc_ua = slave_fcc_ua; - - pval.intval = master_fcc_ua; - rc = power_supply_set_property(chip->main_psy, - POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, - &pval); - if (rc < 0) { - pr_err("Could not set main fcc, rc=%d\n", - rc); - return rc; - } + vote(chip->fcc_main_votable, MAIN_FCC_VOTER, + true, master_fcc_ua); } /* @@ -1288,15 +1269,8 @@ static int pl_disable_vote_callback(struct votable *votable, } /* main psy gets all share */ - pval.intval = total_fcc_ua; - rc = power_supply_set_property(chip->main_psy, - POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, - &pval); - if (rc < 0) { - pr_err("Could not set main fcc, rc=%d\n", rc); - return rc; - } - + vote(chip->fcc_main_votable, MAIN_FCC_VOTER, true, + total_fcc_ua); cp_configure_ilim(chip, FCC_VOTER, total_fcc_ua / 2); /* reset parallel FCC */ @@ -1711,13 +1685,22 @@ int qcom_batt_init(int smb_version) if (!chip->pl_ws) goto cleanup; + chip->fcc_main_votable = create_votable("FCC_MAIN", VOTE_MIN, + pl_fcc_main_vote_callback, + chip); + if (IS_ERR(chip->fcc_main_votable)) { + rc = PTR_ERR(chip->fcc_main_votable); + chip->fcc_main_votable = NULL; + goto release_wakeup_source; + } + chip->fcc_votable = create_votable("FCC", VOTE_MIN, pl_fcc_vote_callback, chip); if (IS_ERR(chip->fcc_votable)) { rc = PTR_ERR(chip->fcc_votable); chip->fcc_votable = NULL; - goto release_wakeup_source; + goto destroy_votable; } chip->fv_votable = create_votable("FV", VOTE_MIN, @@ -1813,6 +1796,7 @@ int qcom_batt_init(int smb_version) destroy_votable(chip->pl_disable_votable); destroy_votable(chip->fv_votable); destroy_votable(chip->fcc_votable); + destroy_votable(chip->fcc_main_votable); destroy_votable(chip->usb_icl_votable); release_wakeup_source: wakeup_source_unregister(chip->pl_ws); @@ -1840,6 +1824,7 @@ void qcom_batt_deinit(void) destroy_votable(chip->pl_disable_votable); destroy_votable(chip->fv_votable); destroy_votable(chip->fcc_votable); + destroy_votable(chip->fcc_main_votable); wakeup_source_unregister(chip->pl_ws); the_chip = NULL; kfree(chip); diff --git a/drivers/power/supply/qcom/smb5-lib.c b/drivers/power/supply/qcom/smb5-lib.c index 2f995b62861b..138fb9a1ffa4 100644 --- a/drivers/power/supply/qcom/smb5-lib.c +++ b/drivers/power/supply/qcom/smb5-lib.c @@ -5483,6 +5483,9 @@ static void typec_src_removal(struct smb_charger *chg) chg->voltage_max_uv = MICRO_5V; chg->usbin_forced_max_uv = 0; + /* Reset CC mode Votes */ + vote(chg->fcc_main_votable, MAIN_FCC_VOTER, false, 0); + /* write back the default FLOAT charger configuration */ rc = smblib_masked_write(chg, USBIN_OPTIONS_2_CFG_REG, (u8)FLOAT_OPTIONS_MASK, chg->float_cfg); @@ -6786,6 +6789,13 @@ static int smblib_create_votables(struct smb_charger *chg) return rc; } + chg->fcc_main_votable = find_votable("FCC_MAIN"); + if (chg->fcc_main_votable == NULL) { + rc = -EINVAL; + smblib_err(chg, "Couldn't find FCC Main votable rc=%d\n", rc); + return rc; + } + chg->fv_votable = find_votable("FV"); if (chg->fv_votable == NULL) { rc = -EINVAL; diff --git a/drivers/power/supply/qcom/smb5-lib.h b/drivers/power/supply/qcom/smb5-lib.h index aa347f22b6be..03e118696f47 100644 --- a/drivers/power/supply/qcom/smb5-lib.h +++ b/drivers/power/supply/qcom/smb5-lib.h @@ -80,6 +80,7 @@ enum print_reason { #define CHARGER_TYPE_VOTER "CHARGER_TYPE_VOTER" #define HDC_IRQ_VOTER "HDC_IRQ_VOTER" #define DETACH_DETECT_VOTER "DETACH_DETECT_VOTER" +#define MAIN_FCC_VOTER "MAIN_FCC_VOTER" #define BOOST_BACK_STORM_COUNT 3 #define WEAK_CHG_STORM_COUNT 8 @@ -406,6 +407,7 @@ struct smb_charger { /* votables */ struct votable *dc_suspend_votable; struct votable *fcc_votable; + struct votable *fcc_main_votable; struct votable *fv_votable; struct votable *usb_icl_votable; struct votable *awake_votable; -- GitLab From 6ade4aa6f95133cc5b6cbe81d619868702a1a55f Mon Sep 17 00:00:00 2001 From: Kaushal Kumar Date: Wed, 19 Jun 2019 18:19:42 +0530 Subject: [PATCH 0636/1121] defconfig: msm: Enable KPTI on sdmsteppe, trinket Enable KPTI mitigation on sdmsteppe, trinket since it is needed as part of android CTS. The mitigation is to unmap kernel when running in userspace. Change-Id: I95fc36f64811ffc2720ea1d64b59ace179192124 Signed-off-by: Kaushal Kumar --- arch/arm64/configs/vendor/sdmsteppe-perf_defconfig | 1 - arch/arm64/configs/vendor/sdmsteppe_defconfig | 1 - arch/arm64/configs/vendor/trinket-perf_defconfig | 1 - arch/arm64/configs/vendor/trinket_defconfig | 1 - 4 files changed, 4 deletions(-) diff --git a/arch/arm64/configs/vendor/sdmsteppe-perf_defconfig b/arch/arm64/configs/vendor/sdmsteppe-perf_defconfig index 3ce011349ca1..48dcd121fb6d 100644 --- a/arch/arm64/configs/vendor/sdmsteppe-perf_defconfig +++ b/arch/arm64/configs/vendor/sdmsteppe-perf_defconfig @@ -67,7 +67,6 @@ CONFIG_CMA=y CONFIG_ZSMALLOC=y CONFIG_BALANCE_ANON_FILE_RECLAIM=y CONFIG_SECCOMP=y -# CONFIG_UNMAP_KERNEL_AT_EL0 is not set CONFIG_ARMV8_DEPRECATED=y CONFIG_SWP_EMULATION=y CONFIG_CP15_BARRIER_EMULATION=y diff --git a/arch/arm64/configs/vendor/sdmsteppe_defconfig b/arch/arm64/configs/vendor/sdmsteppe_defconfig index aa236990de16..20c992da353d 100644 --- a/arch/arm64/configs/vendor/sdmsteppe_defconfig +++ b/arch/arm64/configs/vendor/sdmsteppe_defconfig @@ -72,7 +72,6 @@ CONFIG_CMA_DEBUGFS=y CONFIG_ZSMALLOC=y CONFIG_BALANCE_ANON_FILE_RECLAIM=y CONFIG_SECCOMP=y -# CONFIG_UNMAP_KERNEL_AT_EL0 is not set CONFIG_PRINT_VMEMLAYOUT=y CONFIG_ARMV8_DEPRECATED=y CONFIG_SWP_EMULATION=y diff --git a/arch/arm64/configs/vendor/trinket-perf_defconfig b/arch/arm64/configs/vendor/trinket-perf_defconfig index 87cb508d0973..0369dfa4c431 100644 --- a/arch/arm64/configs/vendor/trinket-perf_defconfig +++ b/arch/arm64/configs/vendor/trinket-perf_defconfig @@ -72,7 +72,6 @@ CONFIG_CMA=y CONFIG_ZSMALLOC=y CONFIG_BALANCE_ANON_FILE_RECLAIM=y CONFIG_SECCOMP=y -# CONFIG_UNMAP_KERNEL_AT_EL0 is not set CONFIG_ARMV8_DEPRECATED=y CONFIG_SWP_EMULATION=y CONFIG_CP15_BARRIER_EMULATION=y diff --git a/arch/arm64/configs/vendor/trinket_defconfig b/arch/arm64/configs/vendor/trinket_defconfig index e90883cb6c1d..6f7066686bef 100644 --- a/arch/arm64/configs/vendor/trinket_defconfig +++ b/arch/arm64/configs/vendor/trinket_defconfig @@ -77,7 +77,6 @@ CONFIG_CMA_DEBUGFS=y CONFIG_ZSMALLOC=y CONFIG_BALANCE_ANON_FILE_RECLAIM=y CONFIG_SECCOMP=y -# CONFIG_UNMAP_KERNEL_AT_EL0 is not set CONFIG_PRINT_VMEMLAYOUT=y CONFIG_ARMV8_DEPRECATED=y CONFIG_SWP_EMULATION=y -- GitLab From c7946a8f240e5e47be5aabebb110364939a7952b Mon Sep 17 00:00:00 2001 From: Yong Ding Date: Thu, 6 Jun 2019 15:43:41 +0800 Subject: [PATCH 0637/1121] ARM: dts: msm: set LV GVM's vmid as 3 in multi-GVMs model LV GVM's vmid is assigned as 3 in multi model while it is 2 in host model. So we add a separated device tree file for it. Change-Id: I6083f37ca1c1f9559ca3fda0642375a1b01f3199 Signed-off-by: Yong Ding --- arch/arm64/boot/dts/qcom/Makefile | 1 + arch/arm64/boot/dts/qcom/sa8155-vm-lv-mt.dts | 47 ++++++++++++++++++++ arch/arm64/boot/dts/qcom/sa8155-vm.dtsi | 2 +- 3 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 arch/arm64/boot/dts/qcom/sa8155-vm-lv-mt.dts diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index a48dcbb01b01..14be137d0cab 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -101,6 +101,7 @@ endif dtb-$(CONFIG_QTI_GVM) += sa8155-vm.dtb \ sa8155-vm-lv.dtb \ + sa8155-vm-lv-mt.dtb \ sa6155p-vm.dtb \ sa8195-vm.dtb diff --git a/arch/arm64/boot/dts/qcom/sa8155-vm-lv-mt.dts b/arch/arm64/boot/dts/qcom/sa8155-vm-lv-mt.dts new file mode 100644 index 000000000000..e686cf9d7d76 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sa8155-vm-lv-mt.dts @@ -0,0 +1,47 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "sa8155-vm.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. SA8155 Virtual Machine"; + compatible = "qcom,sa8155"; + qcom,pmic-name = "PM8150"; + qcom,board-id = <0 0>; +}; + +&hab { + vmid = <3>; +}; + +&slpi_tlmm { + status = "ok"; +}; + +&apps_smmu { + status = "ok"; +}; + +&usb0 { + status = "ok"; +}; + +&usb2_phy0 { + status = "ok"; +}; + +&sde_kms_hyp { + /delete-property/ qcom,client-id; + qcom,client-id = "7816"; +}; diff --git a/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi b/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi index 18e9c84778ab..9f8882698ea6 100644 --- a/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi @@ -146,7 +146,7 @@ }; - qcom,hab { + hab: qcom,hab { compatible = "qcom,hab"; vmid = <2>; -- GitLab From cd35d9b8c7123309f285c21c19b44f596e23272e Mon Sep 17 00:00:00 2001 From: Manoj Prabhu B Date: Thu, 20 Jun 2019 12:39:18 +0530 Subject: [PATCH 0638/1121] diag: Prevent using uninitialized mdlog session mask Add check to prevent using uninitialized session mask to translate kernel to user mask. Also remove unused macro definition for SMUX. Change-Id: I341f0308775a2c5a00856fe6ec8acf9b63e207d9 Signed-off-by: Manoj Prabhu B --- drivers/char/diag/diagchar.h | 3 +-- drivers/char/diag/diagchar_core.c | 7 ++++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h index e46b9de8efa6..4df87f9eee54 100644 --- a/drivers/char/diag/diagchar.h +++ b/drivers/char/diag/diagchar.h @@ -322,8 +322,7 @@ enum remote_procs { #define DIAG_MD_BRIDGE_BASE DIAG_MD_LOCAL_LAST #define DIAG_MD_MDM (DIAG_MD_BRIDGE_BASE) #define DIAG_MD_MDM2 (DIAG_MD_BRIDGE_BASE + 1) -#define DIAG_MD_SMUX (DIAG_MD_BRIDGE_BASE + 2) -#define DIAG_MD_BRIDGE_LAST (DIAG_MD_BRIDGE_BASE + 3) +#define DIAG_MD_BRIDGE_LAST (DIAG_MD_BRIDGE_BASE + 2) #ifndef CONFIG_DIAGFWD_BRIDGE_CODE #define NUM_DIAG_MD_DEV DIAG_MD_LOCAL_LAST diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c index e4ee6b53107e..5428ad8c1c00 100644 --- a/drivers/char/diag/diagchar_core.c +++ b/drivers/char/diag/diagchar_core.c @@ -453,7 +453,7 @@ void diag_clear_masks(int pid) static void diag_close_logging_process(const int pid) { int i, j; - int session_mask; + int session_mask = 0; int device_mask = 0; uint32_t p_mask; struct diag_md_session_t *session_info = NULL; @@ -492,8 +492,9 @@ static void diag_close_logging_process(const int pid) diag_clear_masks(pid); mutex_lock(&driver->diagchar_mutex); - p_mask = - diag_translate_kernel_to_user_mask(session_mask); + if (session_mask) + p_mask = + diag_translate_kernel_to_user_mask(session_mask); for (i = 0; i < NUM_MD_SESSIONS; i++) if (MD_PERIPHERAL_MASK(i) & session_mask) -- GitLab From 3c0f1d7f3a72d9225ba1a3411d6cfc64dbb9ba85 Mon Sep 17 00:00:00 2001 From: Srikanth Uyyala Date: Thu, 20 Jun 2019 13:58:29 +0530 Subject: [PATCH 0639/1121] msm: isp: camera_v2: use vfe0 when dual_isp_sync enabled when dual vfe sync is enabled vfe0 struct is used access common variable, if disabled use vfe1. Change-Id: Ib418cfe8c4ceec8c204f36482402e0746dc5755b Signed-off-by: Srikanth Uyyala --- .../platform/msm/camera_v2/isp/msm_isp_axi_util.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c index 7ceb09b8ec90..73ca32b1f7f8 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c @@ -695,7 +695,8 @@ void msm_isp_process_reg_upd_epoch_irq(struct vfe_device *vfe_dev, uint32_t drop_reconfig = vfe_dev->isp_page->drop_reconfig; if (stream_info->num_isp > 1 && - vfe_dev->pdev->id == ISP_VFE0) { + vfe_dev->pdev->id == ISP_VFE0 && + !vfe_dev->dual_vfe_sync_mode) { c_data = vfe_dev->common_data; temp = c_data->dual_vfe_res->vfe_dev[ ISP_VFE1]; @@ -3700,8 +3701,14 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev, return -EINVAL; } - /* return early for dual vfe0 */ - if (stream_info->num_isp > 1 && vfe_dev->pdev->id == ISP_VFE0) + /* return early for dual vfe */ + if (stream_info->num_isp > 1 && + vfe_dev->pdev->id == ISP_VFE1 && + vfe_dev->dual_vfe_sync_mode) + return 0; + if (stream_info->num_isp > 1 && + vfe_dev->pdev->id == ISP_VFE0 && + !vfe_dev->dual_vfe_sync_mode) return 0; if (stream_info->stream_src >= VFE_AXI_SRC_MAX) { -- GitLab From 3f41916cea25909b44400d4811264c37468cfd8c Mon Sep 17 00:00:00 2001 From: Arun Kumar Neelakantam Date: Thu, 13 Jun 2019 15:31:55 +0530 Subject: [PATCH 0640/1121] soc: qcom: qmi_interface: use qmi txn_lock to avoid use after free of txn In some cases txn is freed before mutex_unlock() API returns and causing invalid pointer access. Protect the txn with qmi txn_lock to avoid the invalid pointer access. CRs-Fixed: 2470638 Change-Id: I05ccde9a77d2913a396c8505bb3199b28fc021c2 Signed-off-by: Arun Kumar Neelakantam --- drivers/soc/qcom/qmi_interface.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/soc/qcom/qmi_interface.c b/drivers/soc/qcom/qmi_interface.c index 1508913df436..d37ca1186a3c 100644 --- a/drivers/soc/qcom/qmi_interface.c +++ b/drivers/soc/qcom/qmi_interface.c @@ -508,24 +508,24 @@ static void qmi_handle_message(struct qmi_handle *qmi, if (hdr->type == QMI_RESPONSE) { mutex_lock(&qmi->txn_lock); txn = idr_find(&qmi->txns, hdr->txn_id); - if (txn) - mutex_lock(&txn->lock); - mutex_unlock(&qmi->txn_lock); - } - - if (txn && txn->dest && txn->ei) { - ret = qmi_decode_message(buf, len, txn->ei, txn->dest); - if (ret < 0) - pr_err("failed to decode incoming message\n"); - - txn->result = ret; - complete(&txn->completion); - - mutex_unlock(&txn->lock); - } else if (txn) { - qmi_invoke_handler(qmi, sq, txn, buf, len); + /* Ignore unexpected responses */ + if (!txn) { + mutex_unlock(&qmi->txn_lock); + return; + } + mutex_lock(&txn->lock); + if (txn->dest && txn->ei) { + ret = qmi_decode_message(buf, len, txn->ei, txn->dest); + if (ret < 0) + pr_err("failed to decode incoming message\n"); + txn->result = ret; + complete(&txn->completion); + } else { + qmi_invoke_handler(qmi, sq, txn, buf, len); + } mutex_unlock(&txn->lock); + mutex_unlock(&qmi->txn_lock); } else { /* Create a txn based on the txn_id of the incoming message */ memset(&tmp_txn, 0, sizeof(tmp_txn)); -- GitLab From 03604d4385c0e4761f32a584247ff6df55d9839b Mon Sep 17 00:00:00 2001 From: Arun Kumar Neelakantam Date: Fri, 14 Jun 2019 14:15:29 +0530 Subject: [PATCH 0641/1121] soc: qcom: qmi_interface: Remove ineffective mutex lock from txn struct The same QMI transaction data is synchronized using two mutex locks. Remove ineffective transaction mutex lock because it is always covered by QMI txn_lock with same purpose. CRs-Fixed: 2470638 Change-Id: If53e006436c77d572b2d69507e1593e3d57e1cd4 Signed-off-by: Arun Kumar Neelakantam --- drivers/soc/qcom/qmi_interface.c | 12 ------------ include/linux/soc/qcom/qmi.h | 2 -- 2 files changed, 14 deletions(-) diff --git a/drivers/soc/qcom/qmi_interface.c b/drivers/soc/qcom/qmi_interface.c index d37ca1186a3c..f206c8442893 100644 --- a/drivers/soc/qcom/qmi_interface.c +++ b/drivers/soc/qcom/qmi_interface.c @@ -317,7 +317,6 @@ int qmi_txn_init(struct qmi_handle *qmi, struct qmi_txn *txn, memset(txn, 0, sizeof(*txn)); - mutex_init(&txn->lock); init_completion(&txn->completion); txn->qmi = qmi; txn->ei = ei; @@ -353,17 +352,12 @@ int qmi_txn_wait(struct qmi_txn *txn, unsigned long timeout) ret = wait_for_completion_timeout(&txn->completion, timeout); - mutex_lock(&txn->lock); if (txn->result == -ENETRESET) { - mutex_unlock(&txn->lock); return txn->result; } - mutex_unlock(&txn->lock); mutex_lock(&qmi->txn_lock); - mutex_lock(&txn->lock); idr_remove(&qmi->txns, txn->id); - mutex_unlock(&txn->lock); mutex_unlock(&qmi->txn_lock); if (ret == 0) @@ -382,9 +376,7 @@ void qmi_txn_cancel(struct qmi_txn *txn) struct qmi_handle *qmi = txn->qmi; mutex_lock(&qmi->txn_lock); - mutex_lock(&txn->lock); idr_remove(&qmi->txns, txn->id); - mutex_unlock(&txn->lock); mutex_unlock(&qmi->txn_lock); } EXPORT_SYMBOL(qmi_txn_cancel); @@ -513,7 +505,6 @@ static void qmi_handle_message(struct qmi_handle *qmi, mutex_unlock(&qmi->txn_lock); return; } - mutex_lock(&txn->lock); if (txn->dest && txn->ei) { ret = qmi_decode_message(buf, len, txn->ei, txn->dest); if (ret < 0) @@ -524,7 +515,6 @@ static void qmi_handle_message(struct qmi_handle *qmi, } else { qmi_invoke_handler(qmi, sq, txn, buf, len); } - mutex_unlock(&txn->lock); mutex_unlock(&qmi->txn_lock); } else { /* Create a txn based on the txn_id of the incoming message */ @@ -736,11 +726,9 @@ void qmi_handle_release(struct qmi_handle *qmi) mutex_lock(&qmi->txn_lock); idr_for_each_entry(&qmi->txns, txn, txn_id) { - mutex_lock(&txn->lock); idr_remove(&qmi->txns, txn->id); txn->result = -ENETRESET; complete(&txn->completion); - mutex_unlock(&txn->lock); } mutex_unlock(&qmi->txn_lock); idr_destroy(&qmi->txns); diff --git a/include/linux/soc/qcom/qmi.h b/include/linux/soc/qcom/qmi.h index 8a0fa18fa14f..e18648be7747 100644 --- a/include/linux/soc/qcom/qmi.h +++ b/include/linux/soc/qcom/qmi.h @@ -166,7 +166,6 @@ struct qmi_ops { * struct qmi_txn - transaction context * @qmi: QMI handle this transaction is associated with * @id: transaction id - * @lock: for synchronization between handler and waiter of messages * @completion: completion object as the transaction receives a response * @result: result code for the completed transaction * @ei: description of the QMI encoded response (optional) @@ -177,7 +176,6 @@ struct qmi_txn { u16 id; - struct mutex lock; struct completion completion; int result; -- GitLab From e2cce70fb6d9ee621c30567daba50560f8b1cfb8 Mon Sep 17 00:00:00 2001 From: Naveen Yadav Date: Fri, 7 Jun 2019 14:40:01 +0530 Subject: [PATCH 0642/1121] ARM: dts: msm: Update GCC node for sdxprairie v2 Update gcc node to support the clock frequency changes in SDXPRAIRIE V2. Change-Id: Iee071ac4d96b4d94cd51c8df0b9394e5b71c7040 Signed-off-by: Naveen Yadav --- arch/arm64/boot/dts/qcom/sdxprairie-v2.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdxprairie-v2.dtsi b/arch/arm64/boot/dts/qcom/sdxprairie-v2.dtsi index aeacf74c093a..a58b88f7b13d 100644 --- a/arch/arm64/boot/dts/qcom/sdxprairie-v2.dtsi +++ b/arch/arm64/boot/dts/qcom/sdxprairie-v2.dtsi @@ -25,3 +25,7 @@ &blsp1_uart2b_hs { status = "okay"; }; + +&clock_gcc { + compatible = "qcom,gcc-sdxprairie-v2", "syscon"; +}; -- GitLab From 051bf6d83fcac7c6043e10266b4e3cccdd7ce391 Mon Sep 17 00:00:00 2001 From: Naveen Yadav Date: Fri, 7 Jun 2019 14:37:58 +0530 Subject: [PATCH 0643/1121] clk: qcom: Update GCC driver for SDXPRAIRIE V2 Add the fixup function to reflect clock frequency changes in SDXPRAIRIE V2. Change-Id: Ib0256dcb2255a6b1da3ef43ed67f2df08fe9a3e9 Signed-off-by: Naveen Yadav --- drivers/clk/qcom/gcc-sdxprairie.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/drivers/clk/qcom/gcc-sdxprairie.c b/drivers/clk/qcom/gcc-sdxprairie.c index 869cf9ebf533..d36cb221077c 100644 --- a/drivers/clk/qcom/gcc-sdxprairie.c +++ b/drivers/clk/qcom/gcc-sdxprairie.c @@ -630,6 +630,13 @@ static const struct freq_tbl ftbl_gcc_emac_ptp_clk_src[] = { { } }; +static const struct freq_tbl ftbl_gcc_emac_ptp_clk_src_v2[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0), + F(230400000, P_GPLL5_OUT_MAIN, 3.5, 0, 0), + { } +}; + static struct clk_rcg2 gcc_emac_ptp_clk_src = { .cmd_rcgr = 0x47038, .mnd_width = 0, @@ -840,6 +847,11 @@ static const struct freq_tbl ftbl_gcc_usb30_mock_utmi_clk_src[] = { { } }; +static const struct freq_tbl ftbl_gcc_usb30_mock_utmi_clk_src_v2[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + static struct clk_rcg2 gcc_usb30_mock_utmi_clk_src = { .cmd_rcgr = 0xb03c, .mnd_width = 0, @@ -1882,15 +1894,25 @@ static const struct qcom_cc_desc gcc_sdxprairie_desc = { static const struct of_device_id gcc_sdxprairie_match_table[] = { { .compatible = "qcom,gcc-sdxprairie" }, + { .compatible = "qcom,gcc-sdxprairie-v2" }, { } }; MODULE_DEVICE_TABLE(of, gcc_sdxprairie_match_table); +static void gcc_sdxprairie_fixup_v2(void) +{ + gcc_usb30_mock_utmi_clk_src.freq_tbl = + ftbl_gcc_usb30_mock_utmi_clk_src_v2; + gcc_usb30_mock_utmi_clk_src.clkr.hw.init->rate_max[VDD_MIN] = 19200000; + gcc_emac_ptp_clk_src.freq_tbl = ftbl_gcc_emac_ptp_clk_src_v2; +} + static int gcc_sdxprairie_probe(struct platform_device *pdev) { struct clk *clk; struct device *dev = &pdev->dev; int ret = 0; + bool is_v2; clk = devm_clk_get(dev, "bi_tcxo"); if (IS_ERR(clk)) { @@ -1921,6 +1943,11 @@ static int gcc_sdxprairie_probe(struct platform_device *pdev) return PTR_ERR(vdd_mx.regulator[0]); } + is_v2 = of_device_is_compatible(pdev->dev.of_node, + "qcom,gcc-sdxprairie-v2"); + if (is_v2) + gcc_sdxprairie_fixup_v2(); + ret = qcom_cc_probe(pdev, &gcc_sdxprairie_desc); if (ret) { dev_err(&pdev->dev, "Failed to register GCC clocks\n"); -- GitLab From f7e86ee5998aa463df398eb716a3537a56d1b406 Mon Sep 17 00:00:00 2001 From: Sahil Chandna Date: Tue, 7 May 2019 19:19:57 +0530 Subject: [PATCH 0644/1121] power: smb5: Add support for PPS constant current(CC) mode Add support for PPS CC mode charging for dual charge pumps with MID-VBAT configuration. If a charging adapter is put in constant current (CC) mode during charging, the supply provides the requested constant current. As a result, its output voltage is automatically adjusted according to the load, and falls into charge pump operational range. For CC mode add an ability to configure the ICL and main-charger's FCC current using power-supply properties. Use POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT to report the total FCC which can be pumped into the battery at that point in time. On charger removal, reset all the votes casted during CC mode. Change-Id: I242e92b87753d962289c94eedb054b2e8b67b99d Signed-off-by: Sahil Chandna --- drivers/power/supply/qcom/qpnp-smb5.c | 72 +++++++++++++++++++++++++++ drivers/power/supply/qcom/smb5-lib.c | 5 +- drivers/power/supply/qcom/smb5-lib.h | 16 ++++++ 3 files changed, 92 insertions(+), 1 deletion(-) diff --git a/drivers/power/supply/qcom/qpnp-smb5.c b/drivers/power/supply/qcom/qpnp-smb5.c index c9099491a445..ae931091fe2a 100644 --- a/drivers/power/supply/qcom/qpnp-smb5.c +++ b/drivers/power/supply/qcom/qpnp-smb5.c @@ -255,6 +255,11 @@ enum { SMB_THERM, }; +static const struct clamp_config clamp_levels[] = { + { {0x11C6, 0x11F9, 0x13F1}, {0x60, 0x2E, 0x90} }, + { {0x11C6, 0x11F9, 0x13F1}, {0x60, 0x2B, 0x9C} }, +}; + #define PMI632_MAX_ICL_UA 3000000 #define PM6150_MAX_FCC_UA 3000000 static int smb5_chg_config_init(struct smb5 *chip) @@ -612,6 +617,33 @@ static int smb5_parse_dt(struct smb5 *chip) return 0; } +static int smb5_set_prop_comp_clamp_level(struct smb_charger *chg, + const union power_supply_propval *val) +{ + int rc = 0, i; + struct clamp_config clamp_config; + enum comp_clamp_levels level; + + level = val->intval; + if (level >= MAX_CLAMP_LEVEL) { + pr_err("Invalid comp clamp level=%d\n", val->intval); + return -EINVAL; + } + + for (i = 0; i < ARRAY_SIZE(clamp_config.reg); i++) { + rc = smblib_write(chg, clamp_levels[level].reg[i], + clamp_levels[level].val[i]); + if (rc < 0) + dev_err(chg->dev, + "Failed to configure comp clamp settings for reg=0x%04x rc=%d\n", + clamp_levels[level].reg[i], rc); + } + + chg->comp_clamp_level = val->intval; + + return rc; +} + /************************ * USB PSY REGISTRATION * ************************/ @@ -643,6 +675,7 @@ static enum power_supply_property smb5_usb_props[] = { POWER_SUPPLY_PROP_VOLTAGE_MAX_LIMIT, POWER_SUPPLY_PROP_SMB_EN_MODE, POWER_SUPPLY_PROP_SMB_EN_REASON, + POWER_SUPPLY_PROP_ADAPTER_CC_MODE, POWER_SUPPLY_PROP_SCOPE, POWER_SUPPLY_PROP_MOISTURE_DETECTED, POWER_SUPPLY_PROP_HVDCP_OPTI_ALLOWED, @@ -820,6 +853,9 @@ static int smb5_usb_get_prop(struct power_supply *psy, val->intval = get_client_vote(chg->usb_icl_votable, THERMAL_THROTTLE_VOTER); break; + case POWER_SUPPLY_PROP_ADAPTER_CC_MODE: + val->intval = chg->adapter_cc_mode; + break; default: pr_err("get prop %d is not supported in usb\n", psp); rc = -EINVAL; @@ -906,6 +942,9 @@ static int smb5_usb_set_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_VOLTAGE_MAX_LIMIT: smblib_set_prop_usb_voltage_max_limit(chg, val); break; + case POWER_SUPPLY_PROP_ADAPTER_CC_MODE: + chg->adapter_cc_mode = val->intval; + break; default: pr_err("set prop %d is not supported\n", psp); rc = -EINVAL; @@ -923,6 +962,7 @@ static int smb5_usb_prop_is_writeable(struct power_supply *psy, case POWER_SUPPLY_PROP_CONNECTOR_HEALTH: case POWER_SUPPLY_PROP_THERM_ICL_LIMIT: case POWER_SUPPLY_PROP_VOLTAGE_MAX_LIMIT: + case POWER_SUPPLY_PROP_ADAPTER_CC_MODE: return 1; default: break; @@ -1074,6 +1114,9 @@ static enum power_supply_property smb5_usb_main_props[] = { POWER_SUPPLY_PROP_TOGGLE_STAT, POWER_SUPPLY_PROP_MAIN_FCC_MAX, POWER_SUPPLY_PROP_IRQ_STATUS, + POWER_SUPPLY_PROP_FORCE_MAIN_FCC, + POWER_SUPPLY_PROP_FORCE_MAIN_ICL, + POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL, }; static int smb5_usb_main_get_prop(struct power_supply *psy, @@ -1122,6 +1165,17 @@ static int smb5_usb_main_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_IRQ_STATUS: rc = smblib_get_irq_status(chg, val); break; + case POWER_SUPPLY_PROP_FORCE_MAIN_FCC: + rc = smblib_get_charge_param(chg, &chg->param.fcc, + &val->intval); + break; + case POWER_SUPPLY_PROP_FORCE_MAIN_ICL: + rc = smblib_get_charge_param(chg, &chg->param.usb_icl, + &val->intval); + break; + case POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL: + val->intval = chg->comp_clamp_level; + break; default: pr_debug("get prop %d is not supported in usb-main\n", psp); rc = -EINVAL; @@ -1192,6 +1246,17 @@ static int smb5_usb_main_set_prop(struct power_supply *psy, chg->main_fcc_max = val->intval; rerun_election(chg->fcc_votable); break; + case POWER_SUPPLY_PROP_FORCE_MAIN_FCC: + vote_override(chg->fcc_main_votable, CC_MODE_VOTER, + (val->intval < 0) ? false : true, val->intval); + break; + case POWER_SUPPLY_PROP_FORCE_MAIN_ICL: + vote_override(chg->usb_icl_votable, CC_MODE_VOTER, + (val->intval < 0) ? false : true, val->intval); + break; + case POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL: + rc = smb5_set_prop_comp_clamp_level(chg, val); + break; default: pr_err("set prop %d is not supported\n", psp); rc = -EINVAL; @@ -1209,6 +1274,9 @@ static int smb5_usb_main_prop_is_writeable(struct power_supply *psy, switch (psp) { case POWER_SUPPLY_PROP_TOGGLE_STAT: case POWER_SUPPLY_PROP_MAIN_FCC_MAX: + case POWER_SUPPLY_PROP_FORCE_MAIN_FCC: + case POWER_SUPPLY_PROP_FORCE_MAIN_ICL: + case POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL: rc = 1; break; default: @@ -1399,6 +1467,7 @@ static enum power_supply_property smb5_batt_props[] = { POWER_SUPPLY_PROP_CURRENT_NOW, POWER_SUPPLY_PROP_CURRENT_QNOVO, POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, + POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT, POWER_SUPPLY_PROP_TEMP, POWER_SUPPLY_PROP_TECHNOLOGY, @@ -1493,6 +1562,9 @@ static int smb5_batt_get_prop(struct power_supply *psy, val->intval = get_client_vote(chg->fcc_votable, BATT_PROFILE_VOTER); break; + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: + val->intval = get_effective_result(chg->fcc_votable); + break; case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT: rc = smblib_get_prop_batt_iterm(chg, val); break; diff --git a/drivers/power/supply/qcom/smb5-lib.c b/drivers/power/supply/qcom/smb5-lib.c index 138fb9a1ffa4..0fb3ef0944f7 100644 --- a/drivers/power/supply/qcom/smb5-lib.c +++ b/drivers/power/supply/qcom/smb5-lib.c @@ -5483,8 +5483,11 @@ static void typec_src_removal(struct smb_charger *chg) chg->voltage_max_uv = MICRO_5V; chg->usbin_forced_max_uv = 0; - /* Reset CC mode Votes */ + /* Reset CC mode votes */ vote(chg->fcc_main_votable, MAIN_FCC_VOTER, false, 0); + chg->adapter_cc_mode = 0; + vote_override(chg->fcc_votable, CC_MODE_VOTER, false, 0); + vote_override(chg->usb_icl_votable, CC_MODE_VOTER, false, 0); /* write back the default FLOAT charger configuration */ rc = smblib_masked_write(chg, USBIN_OPTIONS_2_CFG_REG, diff --git a/drivers/power/supply/qcom/smb5-lib.h b/drivers/power/supply/qcom/smb5-lib.h index 03e118696f47..956c4425dd05 100644 --- a/drivers/power/supply/qcom/smb5-lib.h +++ b/drivers/power/supply/qcom/smb5-lib.h @@ -80,6 +80,7 @@ enum print_reason { #define CHARGER_TYPE_VOTER "CHARGER_TYPE_VOTER" #define HDC_IRQ_VOTER "HDC_IRQ_VOTER" #define DETACH_DETECT_VOTER "DETACH_DETECT_VOTER" +#define CC_MODE_VOTER "CC_MODE_VOTER" #define MAIN_FCC_VOTER "MAIN_FCC_VOTER" #define BOOST_BACK_STORM_COUNT 3 @@ -230,6 +231,17 @@ enum chg_term_config_src { ITERM_SRC_ANALOG }; +enum comp_clamp_levels { + CLAMP_LEVEL_DEFAULT = 0, + CLAMP_LEVEL_1, + MAX_CLAMP_LEVEL, +}; + +struct clamp_config { + u16 reg[3]; + u16 val[3]; +}; + struct smb_irq_info { const char *name; const irq_handler_t handler; @@ -399,6 +411,9 @@ struct smb_charger { /* parallel charging */ struct parallel_params pl; + /* CC Mode */ + int adapter_cc_mode; + /* regulators */ struct smb_regulator *vbus_vreg; struct smb_regulator *vconn_vreg; @@ -528,6 +543,7 @@ struct smb_charger { int dr_mode; int usbin_forced_max_uv; int init_thermal_ua; + u32 comp_clamp_level; /* workaround flag */ u32 wa_flags; -- GitLab From 368b28ac003beb8a5c5c9303a5e444f615eba881 Mon Sep 17 00:00:00 2001 From: Sahil Chandna Date: Thu, 13 Jun 2019 13:14:47 +0530 Subject: [PATCH 0645/1121] power: smb1390-psy: Support PPS constant current(CC) mode Add support for PPS CC mode for dual charge pumps with MID-VBAT configuration. If a charging adapter is put in constant current (cc) mode during charging, the supply provides the requested constant current. As a result, the output voltage is automatically adjusted according to the load, and falls into charge pump operational range. On USB insertion, if SOC is greater than the specified threshold, disable the charge pumps. During Taper, Disable Slave SMB1390 and Master SMB1390, when FCC drops below their respective cutoff thresholds. Change-Id: I2d821ff566f2059a36f9919d7b26ee5347b1820e Signed-off-by: Sahil Chandna --- .../power/supply/qcom/smb1390-charger-psy.c | 126 ++++++++++++++++-- 1 file changed, 117 insertions(+), 9 deletions(-) diff --git a/drivers/power/supply/qcom/smb1390-charger-psy.c b/drivers/power/supply/qcom/smb1390-charger-psy.c index 1014e49d8f42..c14f975c68a0 100644 --- a/drivers/power/supply/qcom/smb1390-charger-psy.c +++ b/drivers/power/supply/qcom/smb1390-charger-psy.c @@ -103,11 +103,15 @@ #define SWITCHER_TOGGLE_VOTER "SWITCHER_TOGGLE_VOTER" #define SOC_LEVEL_VOTER "SOC_LEVEL_VOTER" #define HW_DISABLE_VOTER "HW_DISABLE_VOTER" +#define CC_MODE_VOTER "CC_MODE_VOTER" #define CP_MASTER 0 #define CP_SLAVE 1 #define THERMAL_SUSPEND_DECIDEGC 1400 #define MAX_ILIM_UA 3200000 +#define MAX_ILIM_DUAL_CP_UA 6400000 +#define CC_MODE_TAPER_DELTA_UA 200000 +#define DEFAULT_TAPER_DELTA_UA 100000 #define smb1390_dbg(chip, reason, fmt, ...) \ do { \ @@ -202,6 +206,8 @@ struct smb1390 { u32 pl_output_mode; u32 cp_role; enum isns_mode current_capability; + bool batt_soc_validated; + int cp_slave_thr_taper_ua; }; struct smb_cfg { @@ -356,6 +362,28 @@ static int smb1390_isns_mode_control(struct smb1390 *chip, enum isns_mode mode) return rc; } +static bool smb1390_is_adapter_cc_mode(struct smb1390 *chip) +{ + int rc; + union power_supply_propval pval = {0, }; + + if (!chip->usb_psy) { + chip->usb_psy = power_supply_get_by_name("usb"); + if (!chip->usb_psy) + return false; + } + + rc = power_supply_get_property(chip->usb_psy, + POWER_SUPPLY_PROP_ADAPTER_CC_MODE, + &pval); + if (rc < 0) { + pr_err("Couldn't get PPS CC mode status rc=%d\n", rc); + return false; + } + + return pval.intval; +} + static bool is_cps_available(struct smb1390 *chip) { if (!chip->cps_psy) @@ -697,6 +725,30 @@ static int smb1390_get_isns_slave(struct smb1390 *chip, return rc; } +static int smb1390_get_cp_ilim(struct smb1390 *chip, + union power_supply_propval *val) +{ + int rc = 0, status; + + if (is_cps_available(chip)) { + if (!chip->ilim_votable) { + chip->ilim_votable = find_votable("CP_ILIM"); + if (!chip->ilim_votable) + return -EINVAL; + } + + val->intval = get_effective_result(chip->ilim_votable); + } else { + rc = smb1390_read(chip, CORE_FTRIM_ILIM_REG, &status); + if (!rc) + val->intval = + ((status & CFG_ILIM_MASK) * 100000) + + 500000; + } + + return rc; +} + static int smb1390_is_batt_soc_valid(struct smb1390 *chip) { int rc; @@ -825,7 +877,8 @@ static int smb1390_ilim_vote_cb(struct votable *votable, void *data, return -EINVAL; } - ilim_uA = min(ilim_uA, MAX_ILIM_UA); + ilim_uA = min(ilim_uA, (is_cps_available(chip) ? + MAX_ILIM_DUAL_CP_UA : MAX_ILIM_UA)); /* ILIM less than min_ilim_ua, disable charging */ if (ilim_uA < chip->min_ilim_ua) { smb1390_dbg(chip, PR_INFO, "ILIM %duA is too low to allow charging\n", @@ -926,8 +979,9 @@ static void smb1390_status_change_work(struct work_struct *work) if (!is_psy_voter_available(chip)) goto out; - vote(chip->disable_votable, SOC_LEVEL_VOTER, - smb1390_is_batt_soc_valid(chip) ? false : true, 0); + if (!smb1390_is_adapter_cc_mode(chip)) + vote(chip->disable_votable, SOC_LEVEL_VOTER, + smb1390_is_batt_soc_valid(chip) ? false : true, 0); rc = power_supply_get_property(chip->usb_psy, POWER_SUPPLY_PROP_SMB_EN_MODE, &pval); @@ -944,7 +998,14 @@ static void smb1390_status_change_work(struct work_struct *work) goto out; } + /* Check for SOC threshold only once before enabling CP */ vote(chip->disable_votable, SRC_VOTER, false, 0); + if (!chip->batt_soc_validated) { + vote(chip->disable_votable, SOC_LEVEL_VOTER, + smb1390_is_batt_soc_valid(chip) ? + false : true, 0); + chip->batt_soc_validated = true; + } if (pval.intval == POWER_SUPPLY_CP_WIRELESS) { vote(chip->ilim_votable, ICL_VOTER, false, 0); @@ -1014,10 +1075,12 @@ static void smb1390_status_change_work(struct work_struct *work) } } } else { + chip->batt_soc_validated = false; vote(chip->disable_votable, SRC_VOTER, true, 0); vote(chip->disable_votable, TAPER_END_VOTER, false, 0); vote(chip->fcc_votable, CP_VOTER, false, 0); vote(chip->disable_votable, SOC_LEVEL_VOTER, true, 0); + vote_override(chip->ilim_votable, CC_MODE_VOTER, false, 0); } out: @@ -1025,11 +1088,39 @@ static void smb1390_status_change_work(struct work_struct *work) chip->status_change_running = false; } +static int smb1390_validate_slave_chg_taper(struct smb1390 *chip, int fcc_uA) +{ + int rc = 0; + u8 mask; + + /* + * In Collapse mode, while in Taper, Disable the slave SMB1390 + * when FCC drops below a specified threshold. + */ + if (fcc_uA < (chip->cp_slave_thr_taper_ua) && is_cps_available(chip)) { + mask = CMD_EN_SWITCHER_BIT | CMD_EN_SL_BIT; + rc = smb1390_masked_write(chip, CORE_CONTROL1_REG, + mask, CMD_EN_SWITCHER_BIT); + if (rc < 0) + return rc; + /* + * Set ILIM of master SMB1390 to Max value = 3.2A once slave is + * disabled to prevent ILIM irq storm. + */ + smb1390_dbg(chip, PR_INFO, "Set Master ILIM to MAX, post Slave disable in taper, fcc=%d\n", + fcc_uA); + vote_override(chip->ilim_votable, CC_MODE_VOTER, + true, MAX_ILIM_DUAL_CP_UA); + } + + return rc; +} + static void smb1390_taper_work(struct work_struct *work) { struct smb1390 *chip = container_of(work, struct smb1390, taper_work); union power_supply_propval pval = {0, }; - int rc, fcc_uA; + int rc, fcc_uA, delta_fcc_uA; if (!is_psy_voter_available(chip)) goto out; @@ -1053,11 +1144,21 @@ static void smb1390_taper_work(struct work_struct *work) } if (pval.intval == POWER_SUPPLY_CHARGE_TYPE_TAPER) { + delta_fcc_uA = + (smb1390_is_adapter_cc_mode(chip) ? + CC_MODE_TAPER_DELTA_UA : + DEFAULT_TAPER_DELTA_UA); fcc_uA = get_effective_result(chip->fcc_votable) - - 100000; + - delta_fcc_uA; smb1390_dbg(chip, PR_INFO, "taper work reducing FCC to %duA\n", fcc_uA); vote(chip->fcc_votable, CP_VOTER, true, fcc_uA); + rc = smb1390_validate_slave_chg_taper(chip, fcc_uA); + if (rc < 0) { + pr_err("Couldn't Disable slave in Taper, rc=%d\n", + rc); + goto out; + } if (fcc_uA < (chip->min_ilim_ua * 2)) { vote(chip->disable_votable, TAPER_END_VOTER, @@ -1174,10 +1275,7 @@ static int smb1390_get_prop(struct power_supply *psy, val->intval |= status; break; case POWER_SUPPLY_PROP_CP_ILIM: - rc = smb1390_read(chip, CORE_FTRIM_ILIM_REG, &status); - if (!rc) - val->intval = ((status & CFG_ILIM_MASK) * 100000) - + 500000; + rc = smb1390_get_cp_ilim(chip, val); break; case POWER_SUPPLY_PROP_CHIP_VERSION: val->intval = chip->pmic_rev_id->rev4; @@ -1215,6 +1313,11 @@ static int smb1390_set_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_CP_IRQ_STATUS: chip->irq_status = val->intval; break; + case POWER_SUPPLY_PROP_CP_ILIM: + if (chip->ilim_votable) + vote_override(chip->ilim_votable, CC_MODE_VOTER, + true, val->intval); + break; default: smb1390_dbg(chip, PR_MISC, "charge pump power supply set prop %d not supported\n", prop); @@ -1233,6 +1336,7 @@ static int smb1390_prop_is_writeable(struct power_supply *psy, case POWER_SUPPLY_PROP_CP_IRQ_STATUS: case POWER_SUPPLY_PROP_INPUT_CURRENT_MAX: case POWER_SUPPLY_PROP_CURRENT_CAPABILITY: + case POWER_SUPPLY_PROP_CP_ILIM: return 1; default: break; @@ -1307,6 +1411,10 @@ static int smb1390_parse_dt(struct smb1390 *chip) chip->pl_output_mode = POWER_SUPPLY_PL_OUTPUT_VPH; of_property_read_u32(chip->dev->of_node, "qcom,parallel-output-mode", &chip->pl_output_mode); + + chip->cp_slave_thr_taper_ua = chip->min_ilim_ua * 3; + of_property_read_u32(chip->dev->of_node, "qcom,cp-slave-thr-taper-ua", + &chip->cp_slave_thr_taper_ua); return 0; } -- GitLab From 8798ed2c5a179d9fa00e380dc749b4cfcbeb4700 Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Fri, 26 Apr 2019 11:48:30 -0700 Subject: [PATCH 0646/1121] ARM: dts: msm: Add WLAN power pin definitions for sdmshrike Provide device tree entries for WLAN power pin definitions needed by sdmshrike. Change-Id: I1a7ebededc3ec2e0729bb97c85437b547491e700 Signed-off-by: Anant Goel --- .../boot/dts/qcom/sdmshrike-pinctrl.dtsi | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdmshrike-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sdmshrike-pinctrl.dtsi index d469d38a23e3..45c80e413d5e 100644 --- a/arch/arm64/boot/dts/qcom/sdmshrike-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/sdmshrike-pinctrl.dtsi @@ -2842,6 +2842,32 @@ }; }; + conn_power_1p8_active: conn_power_1p8_active { + mux { + pins = "gpio173"; + function = "gpio"; + }; + + config { + pins = "gpio173"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + conn_power_pa_active: conn_power_pa_active { + mux { + pins = "gpio174"; + function = "gpio"; + }; + + config { + pins = "gpio174"; + drive-strength = <2>; + bias-pull-up; + }; + }; + /* SE0 pin mappings */ qupv3_se0_i2c_pins: qupv3_se0_i2c_pins { qupv3_se0_i2c_active: qupv3_se0_i2c_active { -- GitLab From 48d9665d791c910ee33cd0e1e2bd0cc251a40845 Mon Sep 17 00:00:00 2001 From: Subash Abhinov Kasiviswanathan Date: Wed, 12 Jun 2019 19:07:02 -0600 Subject: [PATCH 0647/1121] soc: qcom: dfc: Purge packets on flow delete When a dedicated flow is deleted, the TX queue enable operation will flush pending packets to the transport. This could cause unexpected delay in processing packets on the default flow. This change purges pending packets for a TX queue when a dedicated bearer is deactivated. CRs-fixed: 2469775 Change-Id: Idd5e0498f7a2d577d768188411161b79210263b2 Acked-by: Weiyi Chen Signed-off-by: Subash Abhinov Kasiviswanathan --- drivers/soc/qcom/qmi_rmnet.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/drivers/soc/qcom/qmi_rmnet.c b/drivers/soc/qcom/qmi_rmnet.c index 8317223984fd..f387d6214571 100644 --- a/drivers/soc/qcom/qmi_rmnet.c +++ b/drivers/soc/qcom/qmi_rmnet.c @@ -198,6 +198,21 @@ int qmi_rmnet_flow_control(struct net_device *dev, u32 tcm_handle, int enable) return 0; } +static void qmi_rmnet_reset_txq(struct net_device *dev, unsigned int txq) +{ + struct Qdisc *qdisc; + + if (unlikely(txq >= dev->num_tx_queues)) + return; + + qdisc = rtnl_dereference(netdev_get_tx_queue(dev, txq)->qdisc); + if (qdisc) { + spin_lock_bh(qdisc_lock(qdisc)); + qdisc_reset(qdisc); + spin_unlock_bh(qdisc_lock(qdisc)); + } +} + static int qmi_rmnet_add_flow(struct net_device *dev, struct tcmsg *tcm, struct qmi_info *qmi) { @@ -261,7 +276,8 @@ static int qmi_rmnet_add_flow(struct net_device *dev, struct tcmsg *tcm, bearer->grant_size > 0 ? 1 : 0); trace_dfc_qmi_tc(dev->name, itm->bearer_id, itm->flow_id, - bearer->grant_size, 0, itm->tcm_handle, 1); + bearer->grant_size, 0, itm->tcm_handle, + bearer->grant_size > 0 ? 1 : 0); } spin_unlock_bh(&qos_info->qos_lock); @@ -300,18 +316,22 @@ qmi_rmnet_del_flow(struct net_device *dev, struct tcmsg *tcm, itm->tcm_handle, 0); list_del(&itm->list); - /* Enable flow to allow new call setup */ - qmi_rmnet_flow_control(dev, itm->tcm_handle, 1); - trace_dfc_qmi_tc(dev->name, itm->bearer_id, itm->flow_id, - 0, 0, itm->tcm_handle, 1); - /*clear bearer map*/ bearer = qmi_rmnet_get_bearer_map(qos_info, new_map.bearer_id); if (bearer && --bearer->flow_ref == 0) { list_del(&bearer->list); kfree(bearer); + + /* Purge pending packets for dedicated flow */ + if (itm->flow_id) + qmi_rmnet_reset_txq(dev, itm->tcm_handle); } + /* Enable flow to allow new flow setup */ + qmi_rmnet_flow_control(dev, itm->tcm_handle, 1); + trace_dfc_qmi_tc(dev->name, itm->bearer_id, itm->flow_id, + 0, 0, itm->tcm_handle, 1); + kfree(itm); } -- GitLab From 8adb9629951deb1577e0529747c95c69d3b6b8a9 Mon Sep 17 00:00:00 2001 From: Skylar Chang Date: Thu, 20 Jun 2019 18:22:33 -0700 Subject: [PATCH 0648/1121] msm: ipa3: add IOMMU_CACHE flag Add IOMMU_CACHE smmu flag when cache_coherent enable. Change-Id: Ied37df88a4586c8b8001b4b247d5097a3e477bf0 Signed-off-by: Skylar Chang --- drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c b/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c index 410efc789bd5..4dd6e46760ee 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c @@ -301,6 +301,7 @@ struct ipa_mpm_dev_info { struct ipa_mpm_iova_addr data; u32 chdb_base; u32 erdb_base; + bool is_cache_coherent; }; struct ipa_mpm_event_props { @@ -494,6 +495,12 @@ static dma_addr_t ipa_mpm_smmu_map(void *va_addr, unsigned long carved_iova = roundup(cb->next_addr, IPA_MPM_PAGE_SIZE); int ret = 0; + /* check cache coherent */ + if (ipa_mpm_ctx->dev_info.is_cache_coherent) { + IPA_MPM_DBG(" enable cache coherent\n"); + prot |= IOMMU_CACHE; + } + if (carved_iova >= cb->va_end) { IPA_MPM_ERR("running out of carved_iova %x\n", carved_iova); ipa_assert(); @@ -646,6 +653,12 @@ static u32 ipa_mpm_smmu_map_doorbell(enum mhip_smmu_domain_type smmu_domain, u32 iova = 0; u64 offset = 0; + /* check cache coherent */ + if (ipa_mpm_ctx->dev_info.is_cache_coherent) { + IPA_MPM_DBG(" enable cache coherent\n"); + prot |= IOMMU_CACHE; + } + if (carved_iova >= cb->va_end) { IPA_MPM_ERR("running out of carved_iova %x\n", carved_iova); ipa_assert(); @@ -2582,6 +2595,8 @@ static int ipa_mpm_populate_smmu_info(struct platform_device *pdev) ipa_mpm_ctx->dev_info.ipa_smmu_enabled = smmu_out.smmu_enable; + /* get cache_coherent enable or not */ + ipa_mpm_ctx->dev_info.is_cache_coherent = ap_cb->is_cache_coherent; if (of_property_read_u32_array(pdev->dev.of_node, "qcom,iova-mapping", carved_iova_ap_mapping, 2)) { IPA_MPM_ERR("failed to read of_node %s\n", -- GitLab From d032791e373f5da1a6826aa53f4354457cb6bac7 Mon Sep 17 00:00:00 2001 From: Jishnu Prakash Date: Fri, 7 Jun 2019 19:51:03 +0530 Subject: [PATCH 0649/1121] ARM: dts: msm: Add VADC and ADC_TM support for atoll Add VADC and ADC_TM nodes with channels and user thermal_zone entries for PM6150 and PM6150l for atoll. Change-Id: Ic06d38ca0adf7a7e3610e0ce19f47f165e3b5cdb Signed-off-by: Jishnu Prakash --- arch/arm64/boot/dts/qcom/atoll-idp.dtsi | 91 ++++++++++++ arch/arm64/boot/dts/qcom/atoll-thermal.dtsi | 121 ++++++++++++++++ arch/arm64/boot/dts/qcom/atoll.dtsi | 150 ++++++++++++++++++++ 3 files changed, 362 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/atoll-thermal.dtsi diff --git a/arch/arm64/boot/dts/qcom/atoll-idp.dtsi b/arch/arm64/boot/dts/qcom/atoll-idp.dtsi index 9132ac26e635..5a4b76171bcc 100644 --- a/arch/arm64/boot/dts/qcom/atoll-idp.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll-idp.dtsi @@ -12,3 +12,94 @@ &soc { }; + +&pm6150l_vadc { + pinctrl-0 = <&camera_flash_therm_default &tof_therm_default>; + + pa_therm1 { + reg = ; + label = "pa_therm1"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + tof_therm { + reg = ; + label = "tof_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; +}; + +&pm6150l_gpios { + tof_therm { + tof_therm_default: tof_therm_default { + pins = "gpio7"; + bias-high-impedance; + }; + }; +}; + +&pm6150l_adc_tm { + io-channels = <&pm6150l_vadc ADC_AMUX_THM1_PU2>, + <&pm6150l_vadc ADC_AMUX_THM2_PU2>, + <&pm6150l_vadc ADC_AMUX_THM3_PU2>, + <&pm6150l_vadc ADC_GPIO1_PU2>; + + pa_therm1 { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; +}; + +&spmi_bus { + qcom,pm6150l@4 { + pm6150l_adc_tm_iio: adc_tm@3400 { + compatible = "qcom,adc-tm5-iio"; + reg = <0x3400 0x100>; + #thermal-sensor-cells = <1>; + io-channels = <&pm6150l_vadc ADC_GPIO3_PU2>; + + tof_therm { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + }; + }; +}; + +&thermal_zones { + pa-therm1 { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm6150l_adc_tm ADC_AMUX_THM3_PU2>; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + tof-therm { + polling-delay-passive = <0>; + polling-delay = <5000>; + thermal-governor = "user_space"; + thermal-sensors = <&pm6150l_adc_tm_iio ADC_GPIO3_PU2>; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/atoll-thermal.dtsi b/arch/arm64/boot/dts/qcom/atoll-thermal.dtsi new file mode 100644 index 000000000000..5950a7a91f26 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/atoll-thermal.dtsi @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +&thermal_zones { + xo-therm-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm6150_adc_tm ADC_XO_THERM_PU2>; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + chg-skin-therm-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm6150_adc_tm ADC_AMUX_THM1_PU2>; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + nvm-therm-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm6150_adc_tm ADC_GPIO1_PU2>; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + sdm-skin-therm-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm6150_adc_tm ADC_GPIO2_PU2>; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + quiet-therm-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm6150l_adc_tm ADC_AMUX_THM1_PU2>; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + pa-therm0-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm6150l_adc_tm ADC_AMUX_THM2_PU2>; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + camera-therm-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm6150l_adc_tm ADC_GPIO1_PU2>; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index 08599320e9d0..0eb1443256f0 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -1754,3 +1754,153 @@ #include "atoll-coresight.dtsi" #include "atoll-stub-regulator.dtsi" #include "atoll-usb.dtsi" + +&pm6150_vadc { + pinctrl-names = "default"; + pinctrl-0 = <&nvm_therm_default &sdm_skin_therm_default>; + + chg_skin_therm { + reg = ; + label = "chg_skin_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + conn_therm { + reg = ; + label = "conn_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + nvm_therm { + reg = ; + label = "nvm_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + sdm_skin_therm { + reg = ; + label = "sdm_skin_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; +}; + +&pm6150_gpios { + nvm_therm { + nvm_therm_default: nvm_therm_default { + pins = "gpio1"; + bias-high-impedance; + }; + }; + + sdm_skin_therm { + sdm_skin_therm_default: sdm_skin_therm_default { + pins = "gpio8"; + bias-high-impedance; + }; + }; +}; + +&pm6150_adc_tm { + io-channels = <&pm6150_vadc ADC_XO_THERM_PU2>, + <&pm6150_vadc ADC_AMUX_THM1_PU2>, + <&pm6150_vadc ADC_GPIO1_PU2>, + <&pm6150_vadc ADC_GPIO2_PU2>; + + /* Channel nodes */ + xo_therm { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + + chg_skin_therm { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + + nvm_therm { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + + sdm_skin_therm { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; +}; + +&pm6150l_vadc { + pinctrl-names = "default"; + pinctrl-0 = <&camera_flash_therm_default>; + + quiet_therm { + reg = ; + label = "quiet_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + pa_therm0 { + reg = ; + label = "pa_therm0"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + camera_flash_therm { + reg = ; + label = "camera_flash_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; +}; + +&pm6150l_gpios { + camera_flash_therm { + camera_flash_therm_default: camera_flash_therm_default { + pins = "gpio5"; + bias-high-impedance; + }; + }; +}; + +&pm6150l_adc_tm { + io-channels = <&pm6150l_vadc ADC_AMUX_THM1_PU2>, + <&pm6150l_vadc ADC_AMUX_THM2_PU2>, + <&pm6150l_vadc ADC_GPIO1_PU2>; + + /* Channel nodes */ + quiet_therm { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + + pa_therm0 { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + + camera_flash_therm { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; +}; + +#include "atoll-thermal.dtsi" -- GitLab From 91c53c45333f5a3542301d4e6ad0bf811d7a62e5 Mon Sep 17 00:00:00 2001 From: Chaitanya Pratapa Date: Wed, 8 May 2019 14:46:33 +0530 Subject: [PATCH 0650/1121] ARM: dts: msm: Add ep delay workaround for sdxprairie EP delay HW bug is present on IPA 4.5 targets as well. Make a change to enable SW WA on SDxprairie which uses IPA4.5. Change-Id: I84da92603687cb92f42b016a5c67921814ba4bcd Signed-off-by: Chaitanya Pratapa --- arch/arm64/boot/dts/qcom/sdxprairie.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/qcom/sdxprairie.dtsi b/arch/arm64/boot/dts/qcom/sdxprairie.dtsi index d4f5d2ddb181..f232aff1f166 100644 --- a/arch/arm64/boot/dts/qcom/sdxprairie.dtsi +++ b/arch/arm64/boot/dts/qcom/sdxprairie.dtsi @@ -555,6 +555,7 @@ qcom,bandwidth-vote-for-ipa; qcom,msm-bus,name = "ipa"; qcom,ipa-wdi3-over-gsi; + qcom,ipa-endp-delay-wa; qcom,msm-bus,num-cases = <5>; qcom,msm-bus,num-paths = <5>; qcom,msm-bus,vectors-KBps = -- GitLab From b136fd5965cbdbeb993eb1e25f70e727523e01e2 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 30 Apr 2019 06:51:50 -0400 Subject: [PATCH 0651/1121] arm64/iommu: handle non-remapped addresses in ->mmap and ->get_sgtable commit a98d9ae937d256ed679a935fc82d9deaa710d98e upstream. DMA allocations that can't sleep may return non-remapped addresses, but we do not properly handle them in the mmap and get_sgtable methods. Resolve non-vmalloc addresses using virt_to_page to handle this corner case. Change-Id: I0e024fef3a3f9a8b0a6cb0a55545be9497d036e8 Cc: Acked-by: Catalin Marinas Reviewed-by: Robin Murphy Signed-off-by: Christoph Hellwig Signed-off-by: Will Deacon Signed-off-by: Greg Kroah-Hartman Git-Commit: cf3780155df66a2df28a0f894d524ea765385f08 Git-Repo: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git Signed-off-by: Vinayak Menon --- arch/arm64/mm/dma-mapping.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index 75b611997a52..b6c8491e7b1d 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -850,6 +850,11 @@ static int __iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma, if (dma_mmap_from_dev_coherent(dev, vma, cpu_addr, size, &ret)) return ret; + if (!is_vmalloc_addr(cpu_addr)) { + unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr)); + return __swiotlb_mmap_pfn(vma, pfn, size); + } + if (attrs & DMA_ATTR_FORCE_CONTIGUOUS) { /* * DMA_ATTR_FORCE_CONTIGUOUS allocations are always remapped, @@ -873,6 +878,11 @@ static int __iommu_get_sgtable(struct device *dev, struct sg_table *sgt, unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT; struct vm_struct *area = find_vm_area(cpu_addr); + if (!is_vmalloc_addr(cpu_addr)) { + struct page *page = virt_to_page(cpu_addr); + return __swiotlb_get_sgtable_page(sgt, page, size); + } + if (attrs & DMA_ATTR_FORCE_CONTIGUOUS) { /* * DMA_ATTR_FORCE_CONTIGUOUS allocations are always remapped, -- GitLab From 9d091f0f5aae68f386c9ec783c705fc9a842f031 Mon Sep 17 00:00:00 2001 From: Vinayak Menon Date: Fri, 21 Jun 2019 10:12:07 +0530 Subject: [PATCH 0652/1121] arm64/iommu: handle atomic pool addresses in ->get_sgtable and ->mmap Atomic dma pool is remapped to vmalloc area by default. get_sgtable and mmap on addresses from this pool returns an error now. Fix that. Change-Id: I2a5f4f5447ffc6fa6ee3baee05a496110de40b3c Signed-off-by: Vinayak Menon --- arch/arm64/mm/dma-mapping.c | 56 +++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 30 deletions(-) diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index b6c8491e7b1d..78ceb2ea71e9 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -843,6 +843,7 @@ static int __iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma, { struct vm_struct *area; int ret; + unsigned long pfn = 0; vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot, is_dma_coherent(dev, attrs)); @@ -850,25 +851,23 @@ static int __iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma, if (dma_mmap_from_dev_coherent(dev, vma, cpu_addr, size, &ret)) return ret; - if (!is_vmalloc_addr(cpu_addr)) { - unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr)); - return __swiotlb_mmap_pfn(vma, pfn, size); - } + area = find_vm_area(cpu_addr); - if (attrs & DMA_ATTR_FORCE_CONTIGUOUS) { + if (area && area->pages) + return iommu_dma_mmap(area->pages, size, vma); + else if (!is_vmalloc_addr(cpu_addr)) + pfn = page_to_pfn(virt_to_page(cpu_addr)); + else if (is_vmalloc_addr(cpu_addr)) /* - * DMA_ATTR_FORCE_CONTIGUOUS allocations are always remapped, - * hence in the vmalloc space. + * DMA_ATTR_FORCE_CONTIGUOUS and atomic pool allocations are + * always remapped, hence in the vmalloc space. */ - unsigned long pfn = vmalloc_to_pfn(cpu_addr); - return __swiotlb_mmap_pfn(vma, pfn, size); - } + pfn = vmalloc_to_pfn(cpu_addr); - area = find_vm_area(cpu_addr); - if (WARN_ON(!area || !area->pages)) - return -ENXIO; + if (pfn) + return __swiotlb_mmap_pfn(vma, pfn, size); - return iommu_dma_mmap(area->pages, size, vma); + return -ENXIO; } static int __iommu_get_sgtable(struct device *dev, struct sg_table *sgt, @@ -876,27 +875,24 @@ static int __iommu_get_sgtable(struct device *dev, struct sg_table *sgt, size_t size, unsigned long attrs) { unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT; + struct page *page = NULL; struct vm_struct *area = find_vm_area(cpu_addr); - if (!is_vmalloc_addr(cpu_addr)) { - struct page *page = virt_to_page(cpu_addr); - return __swiotlb_get_sgtable_page(sgt, page, size); - } - - if (attrs & DMA_ATTR_FORCE_CONTIGUOUS) { + if (area && area->pages) + return sg_alloc_table_from_pages(sgt, area->pages, count, 0, + size, GFP_KERNEL); + else if (!is_vmalloc_addr(cpu_addr)) + page = virt_to_page(cpu_addr); + else if (is_vmalloc_addr(cpu_addr)) /* - * DMA_ATTR_FORCE_CONTIGUOUS allocations are always remapped, - * hence in the vmalloc space. + * DMA_ATTR_FORCE_CONTIGUOUS and atomic pool allocations + * are always remapped, hence in the vmalloc space. */ - struct page *page = vmalloc_to_page(cpu_addr); - return __swiotlb_get_sgtable_page(sgt, page, size); - } + page = vmalloc_to_page(cpu_addr); - if (WARN_ON(!area || !area->pages)) - return -ENXIO; - - return sg_alloc_table_from_pages(sgt, area->pages, count, 0, size, - GFP_KERNEL); + if (page) + return __swiotlb_get_sgtable_page(sgt, page, size); + return -ENXIO; } static void __iommu_sync_single_for_cpu(struct device *dev, -- GitLab From 7275584f1a3e92ab3308e0bd1927e4f1508a84c5 Mon Sep 17 00:00:00 2001 From: Ritesh Kumar Date: Wed, 19 Jun 2019 09:13:45 +0530 Subject: [PATCH 0653/1121] ARM: dts: msm: Enable dynamic clock switch feature for sm6150 Enable dynamic clock switch feature for hx83112a video mode panel on sm6150 platform. Change-Id: I8c10a4f54a80d4ceacbd37b8244c4fc6ba43c120 Signed-off-by: Ritesh Kumar --- arch/arm64/boot/dts/qcom/sm6150-sde-display.dtsi | 3 +++ arch/arm64/boot/dts/qcom/sm6150.dtsi | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sm6150-sde-display.dtsi b/arch/arm64/boot/dts/qcom/sm6150-sde-display.dtsi index 63e1d55284d9..077a3155addb 100644 --- a/arch/arm64/boot/dts/qcom/sm6150-sde-display.dtsi +++ b/arch/arm64/boot/dts/qcom/sm6150-sde-display.dtsi @@ -367,6 +367,9 @@ qcom,mdss-dsi-panel-status-value = <0x9d 0x9d 0x9d 0x9d>; qcom,mdss-dsi-panel-on-check-value = <0x9d 0x9d 0x9d 0x9d>; qcom,mdss-dsi-panel-status-read-length = <4>; + qcom,dsi-dyn-clk-enable; + qcom,dsi-dyn-clk-list = + <924736320 909324048 913177120 917030184 920883256 928589392>; qcom,mdss-dsi-display-timings { timing@0{ qcom,mdss-dsi-panel-phy-timings = diff --git a/arch/arm64/boot/dts/qcom/sm6150.dtsi b/arch/arm64/boot/dts/qcom/sm6150.dtsi index d963e2e587d7..a11984a96e73 100644 --- a/arch/arm64/boot/dts/qcom/sm6150.dtsi +++ b/arch/arm64/boot/dts/qcom/sm6150.dtsi @@ -645,7 +645,7 @@ }; dfps_data_memory: dfps_data_region@9e300000 { - reg = <0x0 0x9e300000 0x0 0x0100000>; + reg = <0x0 0x9cf00000 0x0 0x0100000>; label = "dfps_data_region"; }; -- GitLab From e15c73fe93c1b831790f8b41a5ff20c5ff348814 Mon Sep 17 00:00:00 2001 From: Ritesh Kumar Date: Wed, 19 Jun 2019 09:21:11 +0530 Subject: [PATCH 0654/1121] ARM: dts: msm: Enable dynamic clock switch feature for sdmmagpie Enable dynamic clock switch feature for sw43404 amoled video mode panel on sdmmagpie platform. Change-Id: I4e8b2428919bb5f5e23611e7ecd2e24e60f9ab44 Signed-off-by: Ritesh Kumar --- arch/arm64/boot/dts/qcom/sdmmagpie-sde-display.dtsi | 3 +++ arch/arm64/boot/dts/qcom/sdmmagpie.dtsi | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sdmmagpie-sde-display.dtsi b/arch/arm64/boot/dts/qcom/sdmmagpie-sde-display.dtsi index 65b49c8d2be1..4bbb187fa85b 100644 --- a/arch/arm64/boot/dts/qcom/sdmmagpie-sde-display.dtsi +++ b/arch/arm64/boot/dts/qcom/sdmmagpie-sde-display.dtsi @@ -482,6 +482,9 @@ qcom,dsi-supported-dfps-list = <60 57 55>; qcom,mdss-dsi-pan-enable-dynamic-fps; qcom,mdss-dsi-pan-fps-update = "dfps_immediate_porch_mode_hfp"; + qcom,dsi-dyn-clk-enable; + qcom,dsi-dyn-clk-list = + <534712320 532484352 530256384 525800448 528028416>; qcom,mdss-dsi-display-timings { timing@0{ qcom,mdss-dsi-panel-phy-timings = [00 2e 08 0a 12 18 08 diff --git a/arch/arm64/boot/dts/qcom/sdmmagpie.dtsi b/arch/arm64/boot/dts/qcom/sdmmagpie.dtsi index f23c2edbeb6b..1083bda78f5e 100644 --- a/arch/arm64/boot/dts/qcom/sdmmagpie.dtsi +++ b/arch/arm64/boot/dts/qcom/sdmmagpie.dtsi @@ -660,7 +660,7 @@ }; dfps_data_memory: dfps_data_region@9e300000 { - reg = <0x0 0x9e300000 0x0 0x0100000>; + reg = <0x0 0x9d700000 0x0 0x0100000>; label = "dfps_data_region"; }; -- GitLab From 849f3f56fda9bd8d30c55966cf732e23468e9665 Mon Sep 17 00:00:00 2001 From: Prateek Sood Date: Fri, 21 Jun 2019 13:01:09 +0530 Subject: [PATCH 0655/1121] defconfig: enable XFRM_INTERFACE and MEMBARRIER Enable CONFIG_XFRM_INTERFACE and CONFIG_MEMBARRIER to be in sync with android base defconfig for android Q. Change-Id: I76cbf6e097e6adf602cbe0376a4f914028ff2468 Signed-off-by: Prateek Sood --- arch/arm64/configs/vendor/atoll-perf_defconfig | 2 +- arch/arm64/configs/vendor/atoll_defconfig | 2 +- arch/arm64/configs/vendor/sdmsteppe-perf_defconfig | 2 +- arch/arm64/configs/vendor/sdmsteppe_defconfig | 2 +- arch/arm64/configs/vendor/sm8150-perf_defconfig | 2 +- arch/arm64/configs/vendor/sm8150_defconfig | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm64/configs/vendor/atoll-perf_defconfig b/arch/arm64/configs/vendor/atoll-perf_defconfig index 2b0d8b75375f..0a1d220d5122 100644 --- a/arch/arm64/configs/vendor/atoll-perf_defconfig +++ b/arch/arm64/configs/vendor/atoll-perf_defconfig @@ -37,7 +37,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_RD_LZ4 is not set CONFIG_KALLSYMS_ALL=y CONFIG_BPF_SYSCALL=y -# CONFIG_MEMBARRIER is not set CONFIG_EMBEDDED=y # CONFIG_SLUB_DEBUG is not set # CONFIG_COMPAT_BRK is not set @@ -96,6 +95,7 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM_USER=y +CONFIG_XFRM_INTERFACE=y CONFIG_XFRM_STATISTICS=y CONFIG_NET_KEY=y CONFIG_INET=y diff --git a/arch/arm64/configs/vendor/atoll_defconfig b/arch/arm64/configs/vendor/atoll_defconfig index 23927235cf45..f27b39732be8 100644 --- a/arch/arm64/configs/vendor/atoll_defconfig +++ b/arch/arm64/configs/vendor/atoll_defconfig @@ -39,7 +39,6 @@ CONFIG_BLK_DEV_INITRD=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_KALLSYMS_ALL=y CONFIG_BPF_SYSCALL=y -# CONFIG_MEMBARRIER is not set CONFIG_EMBEDDED=y # CONFIG_COMPAT_BRK is not set CONFIG_SLAB_FREELIST_RANDOM=y @@ -101,6 +100,7 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM_USER=y +CONFIG_XFRM_INTERFACE=y CONFIG_XFRM_STATISTICS=y CONFIG_NET_KEY=y CONFIG_INET=y diff --git a/arch/arm64/configs/vendor/sdmsteppe-perf_defconfig b/arch/arm64/configs/vendor/sdmsteppe-perf_defconfig index 3ce011349ca1..9e99837a9d4c 100644 --- a/arch/arm64/configs/vendor/sdmsteppe-perf_defconfig +++ b/arch/arm64/configs/vendor/sdmsteppe-perf_defconfig @@ -37,7 +37,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_RD_LZ4 is not set CONFIG_KALLSYMS_ALL=y CONFIG_BPF_SYSCALL=y -# CONFIG_MEMBARRIER is not set CONFIG_EMBEDDED=y # CONFIG_SLUB_DEBUG is not set # CONFIG_COMPAT_BRK is not set @@ -97,6 +96,7 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM_USER=y +CONFIG_XFRM_INTERFACE=y CONFIG_XFRM_STATISTICS=y CONFIG_NET_KEY=y CONFIG_INET=y diff --git a/arch/arm64/configs/vendor/sdmsteppe_defconfig b/arch/arm64/configs/vendor/sdmsteppe_defconfig index aa236990de16..b7e05f18e1a6 100644 --- a/arch/arm64/configs/vendor/sdmsteppe_defconfig +++ b/arch/arm64/configs/vendor/sdmsteppe_defconfig @@ -39,7 +39,6 @@ CONFIG_BLK_DEV_INITRD=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_KALLSYMS_ALL=y CONFIG_BPF_SYSCALL=y -# CONFIG_MEMBARRIER is not set CONFIG_EMBEDDED=y # CONFIG_COMPAT_BRK is not set CONFIG_SLAB_FREELIST_RANDOM=y @@ -103,6 +102,7 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM_USER=y +CONFIG_XFRM_INTERFACE=y CONFIG_XFRM_STATISTICS=y CONFIG_NET_KEY=y CONFIG_INET=y diff --git a/arch/arm64/configs/vendor/sm8150-perf_defconfig b/arch/arm64/configs/vendor/sm8150-perf_defconfig index 5cd27c061d9f..ff178c26a817 100644 --- a/arch/arm64/configs/vendor/sm8150-perf_defconfig +++ b/arch/arm64/configs/vendor/sm8150-perf_defconfig @@ -38,7 +38,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_RD_LZ4 is not set CONFIG_KALLSYMS_ALL=y CONFIG_BPF_SYSCALL=y -# CONFIG_MEMBARRIER is not set CONFIG_EMBEDDED=y # CONFIG_SLUB_DEBUG is not set # CONFIG_COMPAT_BRK is not set @@ -104,6 +103,7 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM_USER=y +CONFIG_XFRM_INTERFACE=y CONFIG_XFRM_STATISTICS=y CONFIG_NET_KEY=y CONFIG_INET=y diff --git a/arch/arm64/configs/vendor/sm8150_defconfig b/arch/arm64/configs/vendor/sm8150_defconfig index af5199452eff..026aa27ae87c 100644 --- a/arch/arm64/configs/vendor/sm8150_defconfig +++ b/arch/arm64/configs/vendor/sm8150_defconfig @@ -40,7 +40,6 @@ CONFIG_BLK_DEV_INITRD=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_KALLSYMS_ALL=y CONFIG_BPF_SYSCALL=y -# CONFIG_MEMBARRIER is not set CONFIG_EMBEDDED=y # CONFIG_COMPAT_BRK is not set CONFIG_SLAB_FREELIST_RANDOM=y @@ -111,6 +110,7 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM_USER=y +CONFIG_XFRM_INTERFACE=y CONFIG_XFRM_STATISTICS=y CONFIG_NET_KEY=y CONFIG_INET=y -- GitLab From 7a3956a53957d37a860e1ba16bff380d2b8e44b5 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Thu, 9 May 2019 16:34:09 +0530 Subject: [PATCH 0656/1121] msm: vidc: Avoid information leak while accessing the packet Use trusted packet size on the received packet and check for the size of the data received against the expected size before accessing the packet. Change-Id: I1bd6008249a0bf4edeec711ec8d23cf7b8dac1f1 Signed-off-by: Priyanka Gujjula --- .../platform/msm/vidc/hfi_response_handler.c | 97 ++++++++++++++++--- 1 file changed, 86 insertions(+), 11 deletions(-) diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c index bb5661bd00ad..f2eb1ab3cbd0 100644 --- a/drivers/media/platform/msm/vidc/hfi_response_handler.c +++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c @@ -109,7 +109,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, struct msm_vidc_cb_info *info) { struct msm_vidc_cb_event event_notify = {0}; - int num_properties_changed; + u32 num_properties_changed; struct hfi_frame_size *frame_sz; struct hfi_profile_level *profile_level; struct hfi_bit_depth *pixel_depth; @@ -117,17 +117,23 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, struct hfi_buffer_requirements *buf_req; struct hfi_index_extradata_input_crop_payload *crop_info; struct hfi_dpb_counts *dpb_counts; - u32 entropy_mode = 0; + u32 rem_size, entropy_mode = 0; u8 *data_ptr; int prop_id; int luma_bit_depth, chroma_bit_depth; struct hfi_colour_space *colour_info; - if (sizeof(struct hfi_msg_event_notify_packet) > pkt->size) { - dprintk(VIDC_ERR, - "hal_process_session_init_done: bad_pkt_size\n"); +#define VALIDATE_PKT_SIZE(__rem_size, __msg_size) ({ \ + if (__rem_size < __msg_size) { \ + dprintk(VIDC_ERR, \ + "hal_process_session_init_done: bad_pkt_size\n"); \ + false; \ + } \ + true; \ + }) + if (!VALIDATE_PKT_SIZE(pkt->size, + sizeof(struct hfi_msg_event_notify_packet))) return -E2BIG; - } event_notify.device_id = device_id; event_notify.session_id = (void *)(uintptr_t)pkt->session_id; @@ -148,10 +154,18 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, if (num_properties_changed) { data_ptr = (u8 *) &pkt->rg_ext_event_data[0]; + rem_size = pkt->size - sizeof(struct + hfi_msg_event_notify_packet) + sizeof(u32); do { + if (!VALIDATE_PKT_SIZE(rem_size, sizeof(u32))) + return -E2BIG; prop_id = (int) *((u32 *)data_ptr); + rem_size -= sizeof(u32); switch (prop_id) { case HFI_PROPERTY_PARAM_FRAME_SIZE: + if (!VALIDATE_PKT_SIZE(rem_size, sizeof(struct + hfi_frame_size))) + return -E2BIG; data_ptr = data_ptr + sizeof(u32); frame_sz = (struct hfi_frame_size *) data_ptr; @@ -161,8 +175,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, frame_sz->height, frame_sz->width); data_ptr += sizeof(struct hfi_frame_size); + rem_size -= sizeof(struct hfi_frame_size); break; case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT: + if (!VALIDATE_PKT_SIZE(rem_size, sizeof(struct + hfi_profile_level))) + return -E2BIG; data_ptr = data_ptr + sizeof(u32); profile_level = (struct hfi_profile_level *) data_ptr; @@ -173,8 +191,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, profile_level->level); data_ptr += sizeof(struct hfi_profile_level); + rem_size -= sizeof(struct hfi_profile_level); break; case HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH: + if (!VALIDATE_PKT_SIZE(rem_size, sizeof(struct + hfi_bit_depth))) + return -E2BIG; data_ptr = data_ptr + sizeof(u32); pixel_depth = (struct hfi_bit_depth *) data_ptr; /* @@ -205,8 +227,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, event_notify.bit_depth, luma_bit_depth, chroma_bit_depth); data_ptr += sizeof(struct hfi_bit_depth); + rem_size -= sizeof(struct hfi_bit_depth); break; case HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT: + if (!VALIDATE_PKT_SIZE(rem_size, sizeof(struct + hfi_pic_struct))) + return -E2BIG; data_ptr = data_ptr + sizeof(u32); pic_struct = (struct hfi_pic_struct *) data_ptr; event_notify.pic_struct = @@ -216,8 +242,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, pic_struct->progressive_only); data_ptr += sizeof(struct hfi_pic_struct); + rem_size -= sizeof(struct hfi_pic_struct); break; case HFI_PROPERTY_PARAM_VDEC_DPB_COUNTS: + if (!VALIDATE_PKT_SIZE(rem_size, sizeof(struct + hfi_dpb_counts))) + return -E2BIG; data_ptr = data_ptr + sizeof(u32); dpb_counts = (struct hfi_dpb_counts *) data_ptr; event_notify.max_dpb_count = @@ -232,9 +262,13 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, dpb_counts->max_ref_count, dpb_counts->max_dec_buffering); data_ptr += - sizeof(struct hfi_pic_struct); + sizeof(struct hfi_dpb_counts); + rem_size -= sizeof(struct hfi_dpb_counts); break; case HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE: + if (!VALIDATE_PKT_SIZE(rem_size, sizeof(struct + hfi_colour_space))) + return -E2BIG; data_ptr = data_ptr + sizeof(u32); colour_info = (struct hfi_colour_space *) data_ptr; @@ -245,8 +279,11 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, colour_info->colour_space); data_ptr += sizeof(struct hfi_colour_space); + rem_size -= sizeof(struct hfi_colour_space); break; case HFI_PROPERTY_CONFIG_VDEC_ENTROPY: + if (!VALIDATE_PKT_SIZE(rem_size, sizeof(u32))) + return -E2BIG; data_ptr = data_ptr + sizeof(u32); entropy_mode = *(u32 *)data_ptr; event_notify.entropy_mode = entropy_mode; @@ -254,8 +291,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, "Entropy Mode: 0x%x\n", entropy_mode); data_ptr += sizeof(u32); + rem_size -= sizeof(u32); break; case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS: + if (!VALIDATE_PKT_SIZE(rem_size, sizeof(struct + hfi_buffer_requirements))) + return -E2BIG; data_ptr = data_ptr + sizeof(u32); buf_req = (struct hfi_buffer_requirements *) @@ -267,8 +308,13 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, event_notify.capture_buf_count); data_ptr += sizeof(struct hfi_buffer_requirements); + rem_size -= + sizeof(struct hfi_buffer_requirements); break; case HFI_INDEX_EXTRADATA_INPUT_CROP: + if (!VALIDATE_PKT_SIZE(rem_size, sizeof(struct + hfi_index_extradata_input_crop_payload))) + return -E2BIG; data_ptr = data_ptr + sizeof(u32); crop_info = (struct hfi_index_extradata_input_crop_payload *) @@ -289,6 +335,8 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, data_ptr += sizeof(struct hfi_index_extradata_input_crop_payload); + rem_size -= sizeof(struct + hfi_index_extradata_input_crop_payload); break; default: dprintk(VIDC_ERR, @@ -299,6 +347,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, num_properties_changed--; } while (num_properties_changed > 0); } +#undef VALIDATE_PKT_SIZE info->response_type = HAL_SESSION_EVENT_CHANGE; info->response.event = event_notify; @@ -754,7 +803,7 @@ static inline void copy_cap_prop( } static int hfi_fill_codec_info(u8 *data_ptr, - struct vidc_hal_sys_init_done *sys_init_done) + struct vidc_hal_sys_init_done *sys_init_done, u32 rem_size) { u32 i; u32 codecs = 0, codec_count = 0, size = 0; @@ -762,9 +811,20 @@ static int hfi_fill_codec_info(u8 *data_ptr, u32 prop_id = *((u32 *)data_ptr); u8 *orig_data_ptr = data_ptr; +#define VALIDATE_PKT_SIZE(__rem_size, __msg_size) ({ \ + if (__rem_size < __msg_size) { \ + dprintk(VIDC_ERR, \ + "hfi_msg_sys_init_done: Bad packet size\n"); \ + false; \ + } \ + true; \ + }) if (prop_id == HFI_PROPERTY_PARAM_CODEC_SUPPORTED) { struct hfi_codec_supported *prop; + if (!VALIDATE_PKT_SIZE(rem_size - sizeof(u32), + sizeof(struct hfi_codec_supported))) + return -E2BIG; data_ptr = data_ptr + sizeof(u32); prop = (struct hfi_codec_supported *) data_ptr; sys_init_done->dec_codec_supported = @@ -772,6 +832,8 @@ static int hfi_fill_codec_info(u8 *data_ptr, sys_init_done->enc_codec_supported = prop->encoder_codec_supported; size = sizeof(struct hfi_codec_supported) + sizeof(u32); + rem_size -= + sizeof(struct hfi_codec_supported) + sizeof(u32); } else { dprintk(VIDC_WARN, "%s: prop_id %#x, expected codec_supported property\n", @@ -812,17 +874,26 @@ static int hfi_fill_codec_info(u8 *data_ptr, } sys_init_done->codec_count = codec_count; + if (!VALIDATE_PKT_SIZE(rem_size, sizeof(u32))) + return -E2BIG; prop_id = *((u32 *)(orig_data_ptr + size)); if (prop_id == HFI_PROPERTY_PARAM_MAX_SESSIONS_SUPPORTED) { - struct hfi_max_sessions_supported *prop = - (struct hfi_max_sessions_supported *) + struct hfi_max_sessions_supported *prop; + + if (!VALIDATE_PKT_SIZE(rem_size - sizeof(u32), sizeof(struct + hfi_max_sessions_supported))) + return -E2BIG; + prop = (struct hfi_max_sessions_supported *) (orig_data_ptr + size + sizeof(u32)); sys_init_done->max_sessions_supported = prop->max_sessions; size += sizeof(struct hfi_max_sessions_supported) + sizeof(u32); + rem_size -= + sizeof(struct hfi_max_sessions_supported) + sizeof(u32); dprintk(VIDC_DBG, "max_sessions_supported %d\n", prop->max_sessions); } +#undef VALIDATE_PKT_SIZE return size; } @@ -1123,6 +1194,10 @@ enum vidc_status hfi_process_sys_init_done_prop_read( "hfi_msg_sys_init_done: Invalid input\n"); return VIDC_ERR_FAIL; } + if (pkt->size < sizeof(struct hfi_msg_sys_init_done_packet)) { + dprintk(VIDC_ERR, "hfi_msg_sys_init_done: bad packet size\n"); + return VIDC_ERR_FAIL; + } rem_bytes = pkt->size - sizeof(struct hfi_msg_sys_init_done_packet) + sizeof(u32); @@ -1150,7 +1225,7 @@ enum vidc_status hfi_process_sys_init_done_prop_read( "Venus didn't set any properties in SYS_INIT_DONE"); return status; } - bytes_read = hfi_fill_codec_info(data_ptr, sys_init_done); + bytes_read = hfi_fill_codec_info(data_ptr, sys_init_done, rem_bytes); data_ptr += bytes_read; rem_bytes -= bytes_read; num_properties--; -- GitLab From d4807257d40d408e85dca2c5135a40a46d493f17 Mon Sep 17 00:00:00 2001 From: Pavankumar Kondeti Date: Mon, 3 Jun 2019 10:01:03 +0530 Subject: [PATCH 0657/1121] cpu/hotplug: Abort disabling secondary CPUs if wakeup is pending When "deep" suspend is enabled, all CPUs except the primary CPU are frozen via CPU hotplug one by one. After all secondary CPUs are unplugged the wakeup pending condition is evaluated and if pending the suspend operation is aborted and the secondary CPUs are brought up again. CPU hotplug is a slow operation, so it makes sense to check for wakeup pending in the freezer loop before bringing down the next CPU. This improves the system suspend abort latency significantly. [ tglx: Massaged changelog and improved printk message ] Change-Id: I2f9b6afa5f05162964342743ba6ef73044a64586 Signed-off-by: Pavankumar Kondeti Signed-off-by: Thomas Gleixner Cc: "Rafael J. Wysocki" Cc: Len Brown Cc: Pavel Machek Cc: Josh Poimboeuf Cc: Peter Zijlstra Cc: Konrad Rzeszutek Wilk Cc: iri Kosina Cc: Mukesh Ojha Cc: linux-pm@vger.kernel.org Link: https://lkml.kernel.org/r/1559536263-16472-1-git-send-email-pkondeti@codeaurora.org Git-commit: a66d955e910ab0e598d7a7450cbe6139f52befe7 Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git Signed-off-by: Pavankumar Kondeti --- kernel/cpu.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/kernel/cpu.c b/kernel/cpu.c index ba4610936ca0..f15acf252bb1 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -1269,6 +1269,13 @@ int freeze_secondary_cpus(int primary) for_each_online_cpu(cpu) { if (cpu == primary) continue; + + if (pm_wakeup_pending()) { + pr_info("Wakeup pending. Abort CPU freeze\n"); + error = -EBUSY; + break; + } + trace_suspend_resume(TPS("CPU_OFF"), cpu, true); error = _cpu_down(cpu, 1, CPUHP_OFFLINE); trace_suspend_resume(TPS("CPU_OFF"), cpu, false); -- GitLab From 8819f223628c45a1934349cff8e7c7e2f27190c0 Mon Sep 17 00:00:00 2001 From: Tony Lijo Jose Date: Thu, 13 Jun 2019 20:04:12 +0530 Subject: [PATCH 0658/1121] msm: camera: sensor: Add check to know if device acquired Allow to submit the configdev packets only if the device is acquired. Change-Id: I18096104cdcb4f88b7a9fb7e2ccfae170103665b Signed-off-by: Tony Lijo Jose --- .../cam_sensor_module/cam_sensor/cam_sensor_core.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c index 36db52249f47..76878871aa78 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c @@ -927,6 +927,16 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl, } break; case CAM_CONFIG_DEV: { + if (s_ctrl->sensor_state < CAM_SENSOR_ACQUIRE) { + rc = -EINVAL; + CAM_ERR(CAM_SENSOR, + "sensor_id:[0x%x] not acquired to configure [%d] ", + s_ctrl->sensordata->slave_info.sensor_id, + s_ctrl->sensor_state + ); + goto release_mutex; + } + rc = cam_sensor_i2c_pkt_parse(s_ctrl, arg); if (rc < 0) { CAM_ERR(CAM_SENSOR, "Failed i2c pkt parse: %d", rc); -- GitLab From b07e017947e3f677f05f299ae80fae9fac56cbad Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Mon, 5 Nov 2018 11:40:11 -0800 Subject: [PATCH 0659/1121] clk: qcom: Support 'protected-clocks' property Certain firmware configurations "protect" clks and cause the entire system to reboot when a non-secure OS such as Linux tries to read or write protected clk registers. But other firmware configurations allow reading or writing the same registers, and they may actually require that the OS use the otherwise locked down clks. Support the 'protected-clocks' property by never registering these protected clks with the common clk framework. This way, when firmware is protecting these clks we won't have the chance to ever read or write these registers and take down the entire system. Change-Id: I3123ee6f8c3cf15d76cfbeeabdd3f2646e9433c8 Cc: Taniya Das Cc: Bjorn Andersson Signed-off-by: Stephen Boyd Reviewed-by: Bjorn Andersson Git-commit: b181b3b801da8893c8eb706e448dd5111b02de60 Git-repo: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/ Signed-off-by: Stephen Boyd Signed-off-by: Taniya Das --- drivers/clk/qcom/common.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c index 6fa3aa56b5a3..f82a70db381b 100644 --- a/drivers/clk/qcom/common.c +++ b/drivers/clk/qcom/common.c @@ -201,6 +201,22 @@ int qcom_cc_register_sleep_clk(struct device *dev) } EXPORT_SYMBOL_GPL(qcom_cc_register_sleep_clk); +/* Drop 'protected-clocks' from the list of clocks to register */ +static void qcom_cc_drop_protected(struct device *dev, struct qcom_cc *cc) +{ + struct device_node *np = dev->of_node; + struct property *prop; + const __be32 *p; + u32 i; + + of_property_for_each_u32(np, "protected-clocks", prop, p, i) { + if (i >= cc->num_rclks) + continue; + + cc->rclks[i] = NULL; + } +} + static struct clk_hw *qcom_cc_clk_hw_get(struct of_phandle_args *clkspec, void *data) { @@ -249,6 +265,8 @@ int qcom_cc_really_probe(struct platform_device *pdev, return ret; } + qcom_cc_drop_protected(dev, cc); + for (i = 0; i < num_clks; i++) { if (!rclks[i]) continue; -- GitLab From 44f40751ba98bf26438740f9c4491fcf32feebbd Mon Sep 17 00:00:00 2001 From: Jayadev K Date: Fri, 19 Apr 2019 18:32:52 +0530 Subject: [PATCH 0660/1121] clk: qcom: gcc: Add clocks for hsi2s driver The hsi2s driver needs lpass_sdr functional group clock support. Adding these entries to the gcc clock driver as protected clocks. The protected property is deleted for auto platform. Change-Id: I84e76dcb3348920120de960c780e31192f29fb6e Signed-off-by: Jayadev K --- arch/arm64/boot/dts/qcom/sa6155.dtsi | 1 + arch/arm64/boot/dts/qcom/sa6155p.dtsi | 1 + arch/arm64/boot/dts/qcom/sm6150.dtsi | 7 ++ drivers/clk/qcom/gcc-sm6150.c | 98 +++++++++++++++++++++ include/dt-bindings/clock/qcom,gcc-sm6150.h | 7 ++ 5 files changed, 114 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sa6155.dtsi b/arch/arm64/boot/dts/qcom/sa6155.dtsi index dfb7d0c3b268..b96141a10ea9 100644 --- a/arch/arm64/boot/dts/qcom/sa6155.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155.dtsi @@ -60,6 +60,7 @@ &clock_gcc { compatible = "qcom,gcc-sa6155", "syscon"; + /delete-property/ protected-clocks; }; &clock_videocc { diff --git a/arch/arm64/boot/dts/qcom/sa6155p.dtsi b/arch/arm64/boot/dts/qcom/sa6155p.dtsi index ca669db10029..63b81b59f399 100644 --- a/arch/arm64/boot/dts/qcom/sa6155p.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155p.dtsi @@ -95,6 +95,7 @@ &clock_gcc { compatible = "qcom,gcc-sa6155", "syscon"; + /delete-property/ protected-clocks; }; &clock_videocc { diff --git a/arch/arm64/boot/dts/qcom/sm6150.dtsi b/arch/arm64/boot/dts/qcom/sm6150.dtsi index d963e2e587d7..57285b37916c 100644 --- a/arch/arm64/boot/dts/qcom/sm6150.dtsi +++ b/arch/arm64/boot/dts/qcom/sm6150.dtsi @@ -822,6 +822,13 @@ reg-names = "cc_base"; vdd_cx-supply = <&VDD_CX_LEVEL>; vdd_cx_ao-supply = <&VDD_CX_LEVEL_AO>; + protected-clocks = , + , + , + , + , + , + ; #clock-cells = <1>; #reset-cells = <1>; }; diff --git a/drivers/clk/qcom/gcc-sm6150.c b/drivers/clk/qcom/gcc-sm6150.c index efd47757166b..4e448681c4d9 100644 --- a/drivers/clk/qcom/gcc-sm6150.c +++ b/drivers/clk/qcom/gcc-sm6150.c @@ -3243,6 +3243,97 @@ static struct clk_branch gcc_usb2_sec_clkref_clk = { }, }; +static struct clk_branch gcc_sdr_core_clk = { + .halt_reg = 0x46004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x46004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdr_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdr_wr0_mem_clk = { + .halt_reg = 0x46008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x46008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdr_wr0_mem_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdr_wr1_mem_clk = { + .halt_reg = 0x46010, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x46010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdr_wr1_mem_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdr_wr2_mem_clk = { + .halt_reg = 0x46018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x46018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdr_wr2_mem_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdr_csr_hclk = { + .halt_reg = 0x46020, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x46020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdr_csr_hclk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdr_pri_mi2s_clk = { + .halt_reg = 0x46024, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x46024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdr_pri_mi2s_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdr_sec_mi2s_clk = { + .halt_reg = 0x46028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x46028, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdr_sec_mi2s_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + /* Measure-only clock for ddrss_gcc_debug_clk. */ static struct clk_dummy measure_only_mccc_clk = { .rrate = 1000, @@ -3465,6 +3556,13 @@ static struct clk_regmap *gcc_sm6150_clocks[] = { [GCC_RX3_USB2_CLKREF_CLK] = &gcc_rx3_usb2_clkref_clk.clkr, [GCC_USB2_PRIM_CLKREF_CLK] = &gcc_usb2_prim_clkref_clk.clkr, [GCC_USB2_SEC_CLKREF_CLK] = &gcc_usb2_sec_clkref_clk.clkr, + [GCC_SDR_CORE_CLK] = &gcc_sdr_core_clk.clkr, + [GCC_SDR_WR0_MEM_CLK] = &gcc_sdr_wr0_mem_clk.clkr, + [GCC_SDR_WR1_MEM_CLK] = &gcc_sdr_wr1_mem_clk.clkr, + [GCC_SDR_WR2_MEM_CLK] = &gcc_sdr_wr2_mem_clk.clkr, + [GCC_SDR_CSR_HCLK] = &gcc_sdr_csr_hclk.clkr, + [GCC_SDR_PRI_MI2S_CLK] = &gcc_sdr_pri_mi2s_clk.clkr, + [GCC_SDR_SEC_MI2S_CLK] = &gcc_sdr_sec_mi2s_clk.clkr, }; static const struct qcom_reset_map gcc_sm6150_resets[] = { diff --git a/include/dt-bindings/clock/qcom,gcc-sm6150.h b/include/dt-bindings/clock/qcom,gcc-sm6150.h index 77a7fe92666c..6778bb2b2bfd 100644 --- a/include/dt-bindings/clock/qcom,gcc-sm6150.h +++ b/include/dt-bindings/clock/qcom,gcc-sm6150.h @@ -193,6 +193,13 @@ #define GCC_USB2_PRIM_CLKREF_CLK 173 #define GCC_USB2_SEC_CLKREF_CLK 174 #define GCC_RX3_USB2_CLKREF_CLK 175 +#define GCC_SDR_CORE_CLK 176 +#define GCC_SDR_WR0_MEM_CLK 177 +#define GCC_SDR_WR1_MEM_CLK 178 +#define GCC_SDR_WR2_MEM_CLK 179 +#define GCC_SDR_CSR_HCLK 180 +#define GCC_SDR_PRI_MI2S_CLK 181 +#define GCC_SDR_SEC_MI2S_CLK 182 /* GCC Resets */ #define GCC_QUSB2PHY_PRIM_BCR 0 -- GitLab From affdf7b0e95366f1310329e483a6be42757058eb Mon Sep 17 00:00:00 2001 From: Ajay Agarwal Date: Fri, 21 Jun 2019 17:01:37 +0530 Subject: [PATCH 0661/1121] ARM: dts: msm: Unconfigure QUSB PHY tcsr_clamp_dig_n register for SA6155p Unconfigure QUSB PHY tcsr_clamp_dig_n register for SA6155p to prevent stability issue on one PHY when disabling or enabling the digital clamp to other PHY. Change-Id: I69862208196327ae309190ac98fd605c0547b8db Signed-off-by: Ajay Agarwal --- arch/arm64/boot/dts/qcom/sa6155p.dtsi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sa6155p.dtsi b/arch/arm64/boot/dts/qcom/sa6155p.dtsi index ca669db10029..98a700eaca09 100644 --- a/arch/arm64/boot/dts/qcom/sa6155p.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155p.dtsi @@ -65,6 +65,12 @@ }; &qusb_phy0 { + reg = <0x88e2000 0x180>, + <0x007801f8 0x4>, + <0x01fcb3e4 0x4>; + reg-names = "qusb_phy_base", + "tune2_efuse_addr", + "tcsr_conn_box_spare_0"; vdd-supply = <&L5A>; vdda18-supply = <&L12A>; vdda33-supply = <&L13A>; -- GitLab From c0861ce0f521ac1dc4e5ab84cedc7a10bffc6dd8 Mon Sep 17 00:00:00 2001 From: Rajesh Kemisetti Date: Wed, 19 Jun 2019 20:53:52 +0530 Subject: [PATCH 0662/1121] msm: kgsl: Add missing check for snapshot IB dump During ringbuffer parsing, same IB can exist multiple times but size validation happens only for the first time. This leads to out of bound access if the subsequent sizes are greater than the allocated size. Add a check to make sure that requested size is within the allocated range. Change-Id: Ie5d3c02c1669de2e6188821399e985f0991aa57c Signed-off-by: Rajesh Kemisetti --- drivers/gpu/msm/adreno_snapshot.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/gpu/msm/adreno_snapshot.c b/drivers/gpu/msm/adreno_snapshot.c index 3ed79af8982d..ab53ff396c63 100644 --- a/drivers/gpu/msm/adreno_snapshot.c +++ b/drivers/gpu/msm/adreno_snapshot.c @@ -70,6 +70,19 @@ void kgsl_snapshot_push_object(struct kgsl_process_private *process, for (index = 0; index < objbufptr; index++) { if (objbuf[index].gpuaddr == gpuaddr && objbuf[index].entry->priv == process) { + /* + * Check if newly requested size is within the + * allocated range or not, otherwise continue + * with previous size. + */ + if (!kgsl_gpuaddr_in_memdesc( + &objbuf[index].entry->memdesc, + gpuaddr, dwords << 2)) { + KGSL_CORE_ERR( + "snapshot: IB 0x%016llx size is not within the memdesc range\n", + gpuaddr); + return; + } objbuf[index].size = max_t(uint64_t, objbuf[index].size, -- GitLab From d889c4d98e4c395fda65cb6824fa4d6869ab04f7 Mon Sep 17 00:00:00 2001 From: Bojun Pan Date: Thu, 13 Jun 2019 12:53:22 -0700 Subject: [PATCH 0663/1121] msm: IPA: uC debug stats correction for USB pipes There are multiple place to call gsi_channel_start for USB pipe, the fix here is to correct the stats monitor logic on suspend /resume and other unhandled scenarios. Change-Id: I17986b15e0a8577805d533068b576a213d766b60 Signed-off-by: Bojun Pan --- drivers/platform/msm/ipa/ipa_v3/ipa_client.c | 114 +++++++++++------- .../msm/ipa/ipa_v3/ipa_uc_offload_i.h | 2 + drivers/platform/msm/ipa/ipa_v3/ipa_utils.c | 16 +-- 3 files changed, 78 insertions(+), 54 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c index 89f228e259c1..515b2903c3f7 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c @@ -36,6 +36,7 @@ static int ipa3_is_xdci_channel_empty(struct ipa3_ep_context *ep, bool *is_empty); +static void ipa3_start_gsi_debug_monitor(u32 clnt_hdl); int ipa3_enable_data_path(u32 clnt_hdl) { @@ -254,6 +255,68 @@ static bool ipa3_is_legal_params(struct ipa_request_gsi_channel_params *params) return true; } +static void ipa3_start_gsi_debug_monitor(u32 clnt_hdl) +{ + struct IpaHwOffloadStatsAllocCmdData_t *gsi_info; + struct ipa3_ep_context *ep; + enum ipa_client_type client_type; + + IPADBG("entry\n"); + if (clnt_hdl >= ipa3_ctx->ipa_num_pipes || + ipa3_ctx->ep[clnt_hdl].valid == 0) { + IPAERR("Bad parameters.\n"); + return; + } + + ep = &ipa3_ctx->ep[clnt_hdl]; + client_type = ipa3_get_client_mapping(clnt_hdl); + + /* start uC gsi dbg stats monitor */ + if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5) { + switch (client_type) { + case IPA_CLIENT_MHI_PRIME_TETH_PROD: + gsi_info = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_MHIP]; + gsi_info->ch_id_info[0].ch_id = ep->gsi_chan_hdl; + gsi_info->ch_id_info[0].dir = DIR_PRODUCER; + ipa3_uc_debug_stats_alloc(*gsi_info); + break; + case IPA_CLIENT_MHI_PRIME_TETH_CONS: + gsi_info = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_MHIP]; + gsi_info->ch_id_info[1].ch_id = ep->gsi_chan_hdl; + gsi_info->ch_id_info[1].dir = DIR_CONSUMER; + ipa3_uc_debug_stats_alloc(*gsi_info); + break; + case IPA_CLIENT_MHI_PRIME_RMNET_PROD: + gsi_info = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_MHIP]; + gsi_info->ch_id_info[2].ch_id = ep->gsi_chan_hdl; + gsi_info->ch_id_info[2].dir = DIR_PRODUCER; + ipa3_uc_debug_stats_alloc(*gsi_info); + break; + case IPA_CLIENT_MHI_PRIME_RMNET_CONS: + gsi_info = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_MHIP]; + gsi_info->ch_id_info[3].ch_id = ep->gsi_chan_hdl; + gsi_info->ch_id_info[3].dir = DIR_CONSUMER; + ipa3_uc_debug_stats_alloc(*gsi_info); + break; + case IPA_CLIENT_USB_PROD: + gsi_info = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_USB]; + gsi_info->ch_id_info[0].ch_id = ep->gsi_chan_hdl; + gsi_info->ch_id_info[0].dir = DIR_PRODUCER; + ipa3_uc_debug_stats_alloc(*gsi_info); + break; + case IPA_CLIENT_USB_CONS: + gsi_info = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_USB]; + gsi_info->ch_id_info[1].ch_id = ep->gsi_chan_hdl; + gsi_info->ch_id_info[1].dir = DIR_CONSUMER; + ipa3_uc_debug_stats_alloc(*gsi_info); + break; + default: + IPADBG("client_type %d not supported\n", + client_type); + } + } +} + int ipa3_smmu_map_peer_reg(phys_addr_t phys_addr, bool map, enum ipa_smmu_cb_type cb_type) { @@ -756,6 +819,7 @@ int ipa3_xdci_start(u32 clnt_hdl, u8 xferrscidx, bool xferrscidx_valid) IPAERR("Error starting channel: %d\n", gsi_res); goto write_chan_scratch_fail; } + ipa3_start_gsi_debug_monitor(clnt_hdl); if (!ep->keep_ipa_awake) IPA_ACTIVE_CLIENTS_DEC_EP(ipa3_get_client_mapping(clnt_hdl)); @@ -1517,6 +1581,7 @@ int ipa3_xdci_suspend(u32 ul_clnt_hdl, u32 dl_clnt_hdl, start_dl_and_exit: gsi_start_channel(dl_ep->gsi_chan_hdl); + ipa3_start_gsi_debug_monitor(dl_clnt_hdl); unsuspend_dl_and_exit: if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_0) { /* Unsuspend the DL EP */ @@ -1535,7 +1600,6 @@ int ipa3_start_gsi_channel(u32 clnt_hdl) int result = -EFAULT; enum gsi_status gsi_res; enum ipa_client_type client_type; - struct IpaHwOffloadStatsAllocCmdData_t *gsi_info; IPADBG("entry\n"); if (clnt_hdl >= ipa3_ctx->ipa_num_pipes || @@ -1554,51 +1618,7 @@ int ipa3_start_gsi_channel(u32 clnt_hdl) IPAERR("Error starting channel: %d\n", gsi_res); goto start_chan_fail; } - - /* start uC gsi dbg stats monitor */ - if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5) { - switch (client_type) { - case IPA_CLIENT_MHI_PRIME_TETH_PROD: - gsi_info = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_MHIP]; - gsi_info->ch_id_info[0].ch_id = ep->gsi_chan_hdl; - gsi_info->ch_id_info[0].dir = DIR_PRODUCER; - ipa3_uc_debug_stats_alloc(*gsi_info); - break; - case IPA_CLIENT_MHI_PRIME_TETH_CONS: - gsi_info = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_MHIP]; - gsi_info->ch_id_info[1].ch_id = ep->gsi_chan_hdl; - gsi_info->ch_id_info[1].dir = DIR_CONSUMER; - ipa3_uc_debug_stats_alloc(*gsi_info); - break; - case IPA_CLIENT_MHI_PRIME_RMNET_PROD: - gsi_info = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_MHIP]; - gsi_info->ch_id_info[2].ch_id = ep->gsi_chan_hdl; - gsi_info->ch_id_info[2].dir = DIR_PRODUCER; - ipa3_uc_debug_stats_alloc(*gsi_info); - break; - case IPA_CLIENT_MHI_PRIME_RMNET_CONS: - gsi_info = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_MHIP]; - gsi_info->ch_id_info[3].ch_id = ep->gsi_chan_hdl; - gsi_info->ch_id_info[3].dir = DIR_CONSUMER; - ipa3_uc_debug_stats_alloc(*gsi_info); - break; - case IPA_CLIENT_USB_PROD: - gsi_info = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_USB]; - gsi_info->ch_id_info[0].ch_id = ep->gsi_chan_hdl; - gsi_info->ch_id_info[0].dir = DIR_PRODUCER; - ipa3_uc_debug_stats_alloc(*gsi_info); - break; - case IPA_CLIENT_USB_CONS: - gsi_info = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_USB]; - gsi_info->ch_id_info[0].ch_id = ep->gsi_chan_hdl; - gsi_info->ch_id_info[0].dir = DIR_CONSUMER; - ipa3_uc_debug_stats_alloc(*gsi_info); - break; - default: - IPADBG("client_type %d not supported\n", - client_type); - } - } + ipa3_start_gsi_debug_monitor(clnt_hdl); if (!ep->keep_ipa_awake) IPA_ACTIVE_CLIENTS_DEC_EP(client_type); @@ -1646,12 +1666,14 @@ int ipa3_xdci_resume(u32 ul_clnt_hdl, u32 dl_clnt_hdl, bool is_dpl) gsi_res = gsi_start_channel(dl_ep->gsi_chan_hdl); if (gsi_res != GSI_STATUS_SUCCESS) IPAERR("Error starting DL channel: %d\n", gsi_res); + ipa3_start_gsi_debug_monitor(dl_clnt_hdl); /* Start UL channel */ if (!is_dpl) { gsi_res = gsi_start_channel(ul_ep->gsi_chan_hdl); if (gsi_res != GSI_STATUS_SUCCESS) IPAERR("Error starting UL channel: %d\n", gsi_res); + ipa3_start_gsi_debug_monitor(ul_clnt_hdl); } IPA_ACTIVE_CLIENTS_DEC_EP(ipa3_get_client_mapping(dl_clnt_hdl)); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_offload_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_offload_i.h index 8a31fb8e6b6a..42c6feea8000 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_offload_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_offload_i.h @@ -84,6 +84,8 @@ enum ipa3_hw_features { * @IPA_HW_PROTOCOL_WDI : protocol related to WDI operation in IPA HW * @IPA_HW_PROTOCOL_WDI3: protocol related to WDI3 operation in IPA HW * @IPA_HW_PROTOCOL_ETH : protocol related to ETH operation in IPA HW +* @IPA_HW_PROTOCOL_MHIP: protocol related to MHIP operation in IPA HW +* @IPA_HW_PROTOCOL_USB : protocol related to USB operation in IPA HW */ enum ipa4_hw_protocol { IPA_HW_PROTOCOL_COMMON = 0x0, diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c index 4e689348c0b6..ac754b13db58 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c @@ -7152,43 +7152,43 @@ static int __ipa3_stop_gsi_channel(u32 clnt_hdl) client_type = ipa3_get_client_mapping(clnt_hdl); memset(&mem, 0, sizeof(mem)); - /* start uC gsi dbg stats monitor */ + /* stop uC gsi dbg stats monitor */ if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5) { switch (client_type) { case IPA_CLIENT_MHI_PRIME_TETH_PROD: gsi_info = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_MHIP]; - gsi_info->ch_id_info[0].ch_id = ep->gsi_chan_hdl; + gsi_info->ch_id_info[0].ch_id = 0xff; gsi_info->ch_id_info[0].dir = DIR_PRODUCER; ipa3_uc_debug_stats_alloc(*gsi_info); break; case IPA_CLIENT_MHI_PRIME_TETH_CONS: gsi_info = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_MHIP]; - gsi_info->ch_id_info[1].ch_id = ep->gsi_chan_hdl; + gsi_info->ch_id_info[1].ch_id = 0xff; gsi_info->ch_id_info[1].dir = DIR_CONSUMER; ipa3_uc_debug_stats_alloc(*gsi_info); break; case IPA_CLIENT_MHI_PRIME_RMNET_PROD: gsi_info = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_MHIP]; - gsi_info->ch_id_info[2].ch_id = ep->gsi_chan_hdl; + gsi_info->ch_id_info[2].ch_id = 0xff; gsi_info->ch_id_info[2].dir = DIR_PRODUCER; ipa3_uc_debug_stats_alloc(*gsi_info); break; case IPA_CLIENT_MHI_PRIME_RMNET_CONS: gsi_info = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_MHIP]; - gsi_info->ch_id_info[3].ch_id = ep->gsi_chan_hdl; + gsi_info->ch_id_info[3].ch_id = 0xff; gsi_info->ch_id_info[3].dir = DIR_CONSUMER; ipa3_uc_debug_stats_alloc(*gsi_info); break; case IPA_CLIENT_USB_PROD: gsi_info = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_USB]; - gsi_info->ch_id_info[0].ch_id = ep->gsi_chan_hdl; + gsi_info->ch_id_info[0].ch_id = 0xff; gsi_info->ch_id_info[0].dir = DIR_PRODUCER; ipa3_uc_debug_stats_alloc(*gsi_info); break; case IPA_CLIENT_USB_CONS: gsi_info = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_USB]; - gsi_info->ch_id_info[0].ch_id = ep->gsi_chan_hdl; - gsi_info->ch_id_info[0].dir = DIR_CONSUMER; + gsi_info->ch_id_info[1].ch_id = 0xff; + gsi_info->ch_id_info[1].dir = DIR_CONSUMER; ipa3_uc_debug_stats_alloc(*gsi_info); break; default: -- GitLab From 69e13334a925e5c1fc6f1cf444a527ff7c479e9e Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Sun, 23 Jun 2019 12:34:45 +0530 Subject: [PATCH 0664/1121] msm: vidc: add check to avoid out-of-buffer write Possibility of dereferencing userspace ptr in kernel for invalid cmd. So added check to return error if unsupported cmd is given as input to ioctl. Change-Id: I3466fbd06e5b600f748824b9e16bcfdb4438bdef Signed-off-by: Govindaraj Rajagopal --- drivers/media/platform/msm/vidc/msm_vidc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c index 8a198efb8a4e..9c708bc7e1e3 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc.c +++ b/drivers/media/platform/msm/vidc/msm_vidc.c @@ -1613,6 +1613,12 @@ int msm_vidc_private(void *vidc_inst, unsigned int cmd, int rc = 0; struct msm_vidc_inst *inst = (struct msm_vidc_inst *)vidc_inst; + if (cmd != VIDIOC_VIDEO_CMD) { + dprintk(VIDC_ERR, + "%s: invalid private cmd %#x\n", __func__, cmd); + return -ENOIOCTLCMD; + } + if (!inst || !arg) { dprintk(VIDC_ERR, "%s: invalid args\n", __func__); return -EINVAL; -- GitLab From 96d633371a25212b5e7499bbade42082c5368581 Mon Sep 17 00:00:00 2001 From: Shumin Qiu Date: Mon, 17 Jun 2019 14:08:24 +0800 Subject: [PATCH 0665/1121] Dm: init: Enable rootfs mount as dm-verity during boot without ramdisk If the rootfs image has HASH tree appended, we need mount the rootfs as dm-verity in boot phase. This commit make rootfs mount as dm-verity without ramdisk. Change-Id: I10329ba09d57b832482cd9b5f668acc88bddf548 Signed-off-by: Shumin Qiu --- arch/arm64/boot/dts/qcom/dm-verity-boot.dtsi | 28 +++ arch/arm64/boot/dts/qcom/sa8155.dtsi | 2 + drivers/md/dm-ioctl.c | 35 ++++ drivers/md/dm-ioctrl.h | 20 ++ init/Makefile | 1 + init/do_mounts.c | 1 + init/do_mounts.h | 14 ++ init/do_mounts_verity.c | 193 +++++++++++++++++++ 8 files changed, 294 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/dm-verity-boot.dtsi create mode 100644 drivers/md/dm-ioctrl.h create mode 100644 init/do_mounts_verity.c diff --git a/arch/arm64/boot/dts/qcom/dm-verity-boot.dtsi b/arch/arm64/boot/dts/qcom/dm-verity-boot.dtsi new file mode 100644 index 000000000000..3aee6a4295f9 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/dm-verity-boot.dtsi @@ -0,0 +1,28 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +dm_verity { + dmname="disabled"; + version="1"; + data_device="/dev/sda6"; + hash_device="/dev/sda6"; + data_block_size="4096"; + hash_block_size="4096"; + number_of_data_blocks="262144"; + hash_start_block="262145"; + algorithm="sha256"; + // root hash: 64 bytes long + digest= + "b0fe12d7da6e23a1e19b5a69252c7aaf7b249191eb13bba3f566d630b3f2828a"; + salt="a2df040e00f02c3b2a19e90e5aa76fe1a303f4e08584aaf40e87f088a32b7709"; + // restart_on_corruption ignore_corruption ignore_zero_blocks + opt="restart_on_corruption"; +}; diff --git a/arch/arm64/boot/dts/qcom/sa8155.dtsi b/arch/arm64/boot/dts/qcom/sa8155.dtsi index 0efa2b9e1346..9e1752d2f128 100644 --- a/arch/arm64/boot/dts/qcom/sa8155.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8155.dtsi @@ -598,6 +598,8 @@ read-only; ranges; }; + + /include/ "dm-verity-boot.dtsi" }; &ipa_hw { diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index 787afba77b2e..33d6011ac461 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -6,6 +6,7 @@ */ #include "dm-core.h" +#include "dm-ioctrl.h" #include #include @@ -2056,3 +2057,37 @@ int dm_copy_name_and_uuid(struct mapped_device *md, char *name, char *uuid) return r; } + +int __init dm_ioctrl(uint cmd, struct dm_ioctl *param) +{ + int r = 0; + int ioctl_flags; + ioctl_fn fn = NULL; + size_t input_param_size; + + /* + * Nothing more to do for the version command. + */ + if (cmd == DM_VERSION_CMD) + return 0; + + DMDEBUG("dm_ctl_ioctl: command 0x%x", cmd); + + fn = lookup_ioctl(cmd, &ioctl_flags); + if (!fn) { + DMWARN("dm_ctl_ioctl: unknown command 0x%x", cmd); + return -ENOTTY; + } + + input_param_size = param->data_size; + param->data_size = sizeof(*param); + + r = fn(NULL, param, input_param_size); + + if (unlikely(param->flags & DM_BUFFER_FULL_FLAG) && + unlikely(ioctl_flags & IOCTL_FLAGS_NO_PARAMS)) + DMERR("ioctl %d but has IOCTL_FLAGS_NO_PARAMS set", cmd); + + return r; +} +EXPORT_SYMBOL(dm_ioctrl); diff --git a/drivers/md/dm-ioctrl.h b/drivers/md/dm-ioctrl.h new file mode 100644 index 000000000000..d331fcd83df4 --- /dev/null +++ b/drivers/md/dm-ioctrl.h @@ -0,0 +1,20 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef DM_IOCTRL_INTERNAL_H +#define DM_IOCTRL_INTERNAL_H + +#include + +int dm_ioctrl(uint cmd, struct dm_ioctl *param); + +#endif diff --git a/init/Makefile b/init/Makefile index 0320e1a0705d..00b39d4cf5d9 100644 --- a/init/Makefile +++ b/init/Makefile @@ -19,6 +19,7 @@ mounts-$(CONFIG_BLK_DEV_RAM) += do_mounts_rd.o mounts-$(CONFIG_BLK_DEV_INITRD) += do_mounts_initrd.o mounts-$(CONFIG_BLK_DEV_MD) += do_mounts_md.o mounts-$(CONFIG_BLK_DEV_DM) += do_mounts_dm.o +mounts-$(CONFIG_BLK_DEV_DM) += do_mounts_verity.o # dependencies on generated files need to be listed explicitly $(obj)/version.o: include/generated/compile.h diff --git a/init/do_mounts.c b/init/do_mounts.c index ca5de99f311c..f44460bc8372 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -576,6 +576,7 @@ void __init prepare_namespace(void) md_run_setup(); dm_run_setup(); + dm_verity_setup(); if (saved_root_name[0]) { root_device_name = saved_root_name; diff --git a/init/do_mounts.h b/init/do_mounts.h index cd201124714b..9dfd4138aca8 100644 --- a/init/do_mounts.h +++ b/init/do_mounts.h @@ -8,6 +8,8 @@ #include #include #include +#include "uapi/linux/dm-ioctl.h" +#include void change_floppy(char *fmt, ...); void mount_block_root(char *name, int flags); @@ -71,3 +73,15 @@ void dm_run_setup(void); static inline void dm_run_setup(void) {} #endif + +#ifdef CONFIG_BLK_DEV_DM + +void dm_verity_setup(void); +extern int dm_ioctrl(uint cmd, struct dm_ioctl *param); +extern void dm_table_destroy(struct dm_table *t); + +#else + +static inline void dm_verity_setup(void) {} + +#endif diff --git a/init/do_mounts_verity.c b/init/do_mounts_verity.c new file mode 100644 index 000000000000..aa5893db2a01 --- /dev/null +++ b/init/do_mounts_verity.c @@ -0,0 +1,193 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include "uapi/linux/dm-ioctl.h" +#include +#include +#include "do_mounts.h" + +#define DM_BUF_SIZE 4096 + +#define DM_MSG_PREFIX "verity" + +static void __init init_param(struct dm_ioctl *param, const char *name) +{ + memset(param, 0, DM_BUF_SIZE); + param->data_size = DM_BUF_SIZE; + param->data_start = sizeof(struct dm_ioctl); + param->version[0] = 4; + param->version[1] = 0; + param->version[2] = 0; + param->flags = DM_READONLY_FLAG; + strlcpy(param->name, name, sizeof(param->name)); +} + +static void __init dm_setup_drive(void) +{ + struct device_node *dt_node; + const char *name; + const char *version; + const char *data_device; + const char *hash_device; + const char *data_block_size; + const char *hash_block_size; + const char *number_of_data_blocks; + const char *hash_start_block; + const char *algorithm; + const char *digest; + const char *salt; + const char *opt; + int len; + unsigned long long data_blocks; + char dummy; + char *verity_params; + size_t bufsize; + char *buffer = kzalloc(DM_BUF_SIZE, GFP_KERNEL); + struct dm_ioctl *param = (struct dm_ioctl *) buffer; + size_t dm_sz = sizeof(struct dm_ioctl); + struct dm_target_spec *tgt = (struct dm_target_spec *) &buffer[dm_sz]; + + if (!buffer) + goto fail; + dt_node = of_find_node_by_path("/soc/dm_verity"); + if (!dt_node) { + DMERR("(E) Failed to find device-tree node: /soc/dm_verity"); + goto fail; + } + + name = of_get_property(dt_node, "dmname", &len); + if (name == NULL) + goto fail; + DMDEBUG("(I) name=%s", name); + + if (strcmp(name, "disabled") == 0) { + pr_info("dm: dm-verity is disabled."); + kfree(buffer); + return; + } + + version = of_get_property(dt_node, "version", &len); + if (version == NULL) + goto fail; + DMDEBUG("(I) version=%s", version); + + data_device = of_get_property(dt_node, "data_device", &len); + if (data_device == NULL) + goto fail; + DMDEBUG("(I) data_device=%s", data_device); + + hash_device = of_get_property(dt_node, "hash_device", &len); + if (hash_device == NULL) + goto fail; + DMDEBUG("(I) hash_device=%s", hash_device); + + data_block_size = of_get_property(dt_node, "data_block_size", &len); + if (data_block_size == NULL) + goto fail; + DMDEBUG("(I) data_block_size=%s", data_block_size); + + hash_block_size = of_get_property(dt_node, "hash_block_size", &len); + if (hash_block_size == NULL) + goto fail; + DMDEBUG("(I) hash_block_size=%s", hash_block_size); + + number_of_data_blocks = of_get_property(dt_node, + "number_of_data_blocks", + &len); + if (number_of_data_blocks == NULL) + goto fail; + DMDEBUG("(I) number_of_data_blocks=%s", number_of_data_blocks); + + hash_start_block = of_get_property(dt_node, "hash_start_block", &len); + if (hash_start_block == NULL) + goto fail; + DMDEBUG("(I) hash_start_block=%s", hash_start_block); + + algorithm = of_get_property(dt_node, "algorithm", &len); + if (algorithm == NULL) + goto fail; + DMDEBUG("(I) algorithm=%s", algorithm); + + digest = of_get_property(dt_node, "digest", &len); + if (digest == NULL) + goto fail; + DMDEBUG("(I) digest=%s", digest); + + salt = of_get_property(dt_node, "salt", &len); + if (salt == NULL) + goto fail; + DMDEBUG("(I) salt=%s", salt); + + opt = of_get_property(dt_node, "opt", &len); + if (opt == NULL) + goto fail; + DMDEBUG("(I) opt=%s", opt); + + init_param(param, name); + if (dm_ioctrl(DM_DEV_CREATE_CMD, param)) { + DMERR("(E) failed to create the device"); + goto fail; + } + + init_param(param, name); + param->target_count = 1; + /* set tgt arguments */ + tgt->status = 0; + tgt->sector_start = 0; + if (sscanf(number_of_data_blocks, "%llu%c", &data_blocks, &dummy) != 1) + goto fail; + + tgt->length = data_blocks*4096/512; /* size in sector of data dev */ + strlcpy(tgt->target_type, "verity", sizeof(tgt->target_type)); + /* build the verity params here */ + verity_params = buffer + dm_sz + sizeof(struct dm_target_spec); + bufsize = DM_BUF_SIZE - (verity_params - buffer); + + verity_params += snprintf(verity_params, bufsize, + "%s %s %s %s %s %s %s %s %s %s 1 %s", + version, + data_device, hash_device, + data_block_size, hash_block_size, + number_of_data_blocks, hash_start_block, + algorithm, digest, salt, opt); + + tgt->next = verity_params - buffer; + if (dm_ioctrl(DM_TABLE_LOAD_CMD, param)) { + DMERR("(E) failed to load the device"); + goto fail; + } + + init_param(param, name); + if (dm_ioctrl(DM_DEV_SUSPEND_CMD, param)) { + DMERR("(E) failed to suspend the device"); + goto fail; + } + + pr_info("dm: dm-0 (%s) is ready", data_device); + kfree(buffer); + return; + +fail: + pr_info("dm: starting dm-0 failed"); + kfree(buffer); + return; + +} + +void __init dm_verity_setup(void) +{ + pr_info("dm: attempting early device configuration."); + dm_setup_drive(); +} -- GitLab From 843d07753d020c245e0b73f5c984e01e6c15ca18 Mon Sep 17 00:00:00 2001 From: Shaoqing Liu Date: Wed, 8 May 2019 19:08:12 +0800 Subject: [PATCH 0666/1121] ARM: dts: msm: set QDSS channel num-elements as 128 Set QDSS channel num-elements as 128. Change-Id: I6022ffda7009d5e52bfb7ed7fd57aed548264eda Signed-off-by: Shaoqing Liu --- arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi b/arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi index b8cf1a76475b..3ec7c086acc4 100644 --- a/arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi @@ -34,6 +34,11 @@ mhi_channels { #address-cells = <1>; #size-cells = <0>; + + mhi_chan@9 { + mhi,num-elements = <128>; + }; + mhi_chan@25 { status = "disabled"; }; -- GitLab From aa1bce1ff489ab9a18427a1e14bb2fb6fbca8d03 Mon Sep 17 00:00:00 2001 From: Jiacheng Zheng Date: Fri, 21 Jun 2019 18:03:23 +0800 Subject: [PATCH 0667/1121] soc: qcom: hab: add error handling when dt item is missing If certain testgipc node under aliases in device tree is missing, ep_path remains NULL and it will cause NULL dereference problem later in the code. We need to go to error handler and deinitialize everything under this condition. Change-Id: Ib687390402a6210b63fe2a39500b3216c2ae21e3 Signed-off-by: Jiacheng Zheng --- drivers/soc/qcom/hab/hab_ghs.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/soc/qcom/hab/hab_ghs.c b/drivers/soc/qcom/hab/hab_ghs.c index a445aa1a6707..575804c48abf 100644 --- a/drivers/soc/qcom/hab/hab_ghs.c +++ b/drivers/soc/qcom/hab/hab_ghs.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -169,6 +169,7 @@ int habhyp_commdev_alloc(void **commdev, int is_be, char *name, int vmid_remote, mmid_device->name, mmid_device->id, dt_name_idx); + of_node_put(gvh_dn); ret = -ENOENT; goto err; } @@ -176,9 +177,13 @@ int habhyp_commdev_alloc(void **commdev, int is_be, char *name, int vmid_remote, ret = of_property_read_string(gvh_dn, ghs_vmm_plugin_info.dt_name[dt_name_idx], &ep_path); - if (ret) + if (ret) { pr_err("failed to read endpoint str ret %d\n", ret); + of_node_put(gvh_dn); + ret = -ENOENT; + goto err; + } of_node_put(gvh_dn); ep_dn = of_find_node_by_path(ep_path); -- GitLab From 042a43a7c568182cccd8f4b33e1449161f8c2ced Mon Sep 17 00:00:00 2001 From: Jayadev K Date: Fri, 19 Apr 2019 18:43:20 +0530 Subject: [PATCH 0668/1121] ARM: dts: qcom: Add device tree support for hsi2s driver Adding device nodes and pinctrl definitions for hsi2s interfaces in the device tree. Change-Id: I9a53cbe07de24c2f061da03ad49563168b8a2216 Signed-off-by: Jayadev K --- .../devicetree/bindings/sound/qcom,hsi2s.txt | 81 +++++++++ arch/arm64/boot/dts/qcom/sa6155-adp-star.dtsi | 47 +++++ arch/arm64/boot/dts/qcom/sm6150-pinctrl.dtsi | 168 ++++++++++++++++++ 3 files changed, 296 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/qcom,hsi2s.txt diff --git a/Documentation/devicetree/bindings/sound/qcom,hsi2s.txt b/Documentation/devicetree/bindings/sound/qcom,hsi2s.txt new file mode 100644 index 000000000000..debeef5780d6 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/qcom,hsi2s.txt @@ -0,0 +1,81 @@ +Qualcomm Technologies, Inc. High Speed I2S Interface + +* HS-I2S generic node + +Required properties: + + - compatible : Should be "qcom,hsi2s" + - number-of-interfaces : Denotes the number of HS-I2S interfaces + - reg : Specifies the base physical address and the size of the HS-I2S + register space + - reg-names : "lpa_if" - string to identify the HS-I2S base register + - interrupts : Interrupt number used by this interface + - clocks : Core clocks used by this interface + - clock-names : Clock names for each core clock + +* HS-I2S interface nodes + +Required properties: + + - compatible : Should be "qcom,hsi2s-interface" + - minor-number : Minor number of the character device interface + Should be 0 for HS0 interface + Should be 1 for HS1 interface + - clocks : Interface clock used by this interface + - clock-names : Clock name for the interface clock + - pinctrl-names : Pinctrl state names for each pin group configuration + - pinctrl-x : Defines pinctrl state for each pin group + - iommus: The phandle and stream IDs for the SMMU used by this root + - qcom,iova-mapping: Specifies the start address and size of iova space + +Optional properties: + + - qcom,smmu-s1-bypass: Boolean, if present S1 bypass is enabled + +Example: + +hsi2s: qcom,hsi2s { + compatible = "qcom,hsi2s"; + number-of-interfaces = <2>; + reg = <0x1B40000 0x28000>; + reg-names = "lpa_if"; + interrupts = ; + clocks = <&clock_gcc GCC_SDR_CORE_CLK>, + <&clock_gcc GCC_SDR_WR0_MEM_CLK>, + <&clock_gcc GCC_SDR_WR1_MEM_CLK>, + <&clock_gcc GCC_SDR_WR2_MEM_CLK>, + <&clock_gcc GCC_SDR_CSR_HCLK>; + clock-names = "core_clk", "wr0_mem_clk", + "wr1_mem_clk", "wr2_mem_clk", + "csr_hclk"; + + sdr0: qcom,hs0_i2s { + compatible = "qcom,hsi2s-interface"; + minor-number = <0>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&hs0_i2s_sck_active &hs0_i2s_data0_active + &hs0_i2s_data1_active>; + pinctrl-1 = <&hs0_i2s_sck_sleep &hs0_i2s_data0_sleep + &hs0_i2s_data1_sleep>; + clocks = <&clock_gcc GCC_SDR_PRI_MI2S_CLK>; + clock-names = "pri_mi2s_clk"; + iommus = <&apps_smmu 0x035C 0x0>; + qcom,smmu-s1-bypass; + qcom,iova-mapping = <0x0 0xFFFFFFFF>; + }; + + sdr1: qcom,hs1_i2s { + compatible = "qcom,hsi2s-interface"; + minor-number = <1>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&hs1_i2s_sck_active &hs1_i2s_data0_active + &hs1_i2s_data1_active>; + pinctrl-1 = <&hs1_i2s_sck_sleep &hs1_i2s_data0_sleep + &hs1_i2s_data1_sleep>; + clocks = <&clock_gcc GCC_SDR_SEC_MI2S_CLK>; + clock-names = "sec_mi2s_clk"; + iommus = <&apps_smmu 0x035D 0x0>; + qcom,smmu-s1-bypass; + qcom,iova-mapping = <0x0 0xFFFFFFFF>; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/sa6155-adp-star.dtsi b/arch/arm64/boot/dts/qcom/sa6155-adp-star.dtsi index 9c9908c51f6c..78c3bce754e6 100644 --- a/arch/arm64/boot/dts/qcom/sa6155-adp-star.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155-adp-star.dtsi @@ -42,6 +42,53 @@ status = "disabled"; }; }; + + hsi2s: qcom,hsi2s { + compatible = "qcom,hsi2s"; + number-of-interfaces = <2>; + reg = <0x1B40000 0x28000>; + reg-names = "lpa_if"; + interrupts = ; + clocks = <&clock_gcc GCC_SDR_CORE_CLK>, + <&clock_gcc GCC_SDR_WR0_MEM_CLK>, + <&clock_gcc GCC_SDR_WR1_MEM_CLK>, + <&clock_gcc GCC_SDR_WR2_MEM_CLK>, + <&clock_gcc GCC_SDR_CSR_HCLK>; + clock-names = "core_clk", "wr0_mem_clk", + "wr1_mem_clk", "wr2_mem_clk", + "csr_hclk"; + + sdr0: qcom,hs0_i2s { + compatible = "qcom,hsi2s-interface"; + minor-number = <0>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&hs0_i2s_sck_active &hs0_i2s_data0_active + &hs0_i2s_data1_active>; + pinctrl-1 = <&hs0_i2s_sck_sleep &hs0_i2s_data0_sleep + &hs0_i2s_data1_sleep>; + clocks = <&clock_gcc GCC_SDR_PRI_MI2S_CLK>; + clock-names = "pri_mi2s_clk"; + iommus = <&apps_smmu 0x035C 0x0>; + qcom,smmu-s1-bypass; + qcom,iova-mapping = <0x0 0xFFFFFFFF>; + }; + + sdr1: qcom,hs1_i2s { + compatible = "qcom,hsi2s-interface"; + minor-number = <1>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&hs1_i2s_sck_active &hs1_i2s_data0_active + &hs1_i2s_data1_active>; + pinctrl-1 = <&hs1_i2s_sck_sleep &hs1_i2s_data0_sleep + &hs1_i2s_data1_sleep>; + clocks = <&clock_gcc GCC_SDR_SEC_MI2S_CLK>; + clock-names = "sec_mi2s_clk"; + iommus = <&apps_smmu 0x035D 0x0>; + qcom,smmu-s1-bypass; + qcom,iova-mapping = <0x0 0xFFFFFFFF>; + }; + }; + emac_hw: qcom,emac@20000 { compatible = "qcom,emac-dwc-eqos"; qcom,arm-smmu; diff --git a/arch/arm64/boot/dts/qcom/sm6150-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sm6150-pinctrl.dtsi index 296ceb69f8f4..b8d91f451eaf 100644 --- a/arch/arm64/boot/dts/qcom/sm6150-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/sm6150-pinctrl.dtsi @@ -1713,6 +1713,174 @@ }; }; + hs0_i2s_sck_ws { + hs0_i2s_sck_sleep: hs0_i2s_sck_sleep { + mux { + pins = "gpio36", "gpio37"; + function = "hs0_mi2s"; + }; + + config { + pins = "gpio36", "gpio37"; + drive-strength = <2>; /* 2 mA */ + }; + }; + + hs0_i2s_sck_active: hs0_i2s_sck_active { + mux { + pins = "gpio36", "gpio37"; + function = "hs0_mi2s"; + }; + + config { + pins = "gpio36", "gpio37"; + drive-strength = <4>; /* 4 mA */ + bias-no-pull; + input-enable; + }; + }; + }; + + hs0_i2s_data0 { + hs0_i2s_data0_sleep: hs0_i2s_data0_sleep { + mux { + pins = "gpio38"; + function = "hs0_mi2s"; + }; + + config { + pins = "gpio38"; + drive-strength = <2>; /* 2 mA */ + }; + }; + + hs0_i2s_data0_active: hs0_i2s_data0_active { + mux { + pins = "gpio38"; + function = "hs0_mi2s"; + }; + + config { + pins = "gpio38"; + drive-strength = <4>; /* 4 mA */ + bias-no-pull; + input-enable; + }; + }; + }; + + hs0_i2s_data1 { + hs0_i2s_data1_sleep: hs0_i2s_data1_sleep { + mux { + pins = "gpio39"; + function = "hs0_mi2s"; + }; + + config { + pins = "gpio39"; + drive-strength = <2>; /* 2 mA */ + }; + }; + + hs0_i2s_data1_active: hs0_i2s_data1_active { + mux { + pins = "gpio39"; + function = "hs0_mi2s"; + }; + + config { + pins = "gpio39"; + drive-strength = <4>; /* 4 mA */ + bias-no-pull; + output-high; + }; + }; + }; + + hs1_i2s_sck_ws { + hs1_i2s_sck_sleep: hs1_i2s_sck_sleep { + mux { + pins = "gpio24", "gpio25"; + function = "hs1_mi2s"; + }; + + config { + pins = "gpio24", "gpio25"; + drive-strength = <2>; /* 2 mA */ + }; + }; + + hs1_i2s_sck_active: hs1_i2s_sck_active { + mux { + pins = "gpio24", "gpio25"; + function = "hs1_mi2s"; + }; + + config { + pins = "gpio24", "gpio25"; + drive-strength = <4>; /* 4 mA */ + bias-no-pull; + input-enable; + }; + }; + }; + + hs1_i2s_data0 { + hs1_i2s_data0_sleep: hs1_i2s_data0_sleep { + mux { + pins = "gpio26"; + function = "hs1_mi2s"; + }; + + config { + pins = "gpio26"; + drive-strength = <2>; /* 2 mA */ + }; + }; + + hs1_i2s_data0_active: hs1_i2s_data0_active { + mux { + pins = "gpio26"; + function = "hs1_mi2s"; + }; + + config { + pins = "gpio26"; + drive-strength = <4>; /* 4 mA */ + bias-no-pull; + input-enable; + }; + }; + }; + + hs1_i2s_data1 { + hs1_i2s_data1_sleep: hs1_i2s_data1_sleep { + mux { + pins = "gpio27"; + function = "hs1_mi2s"; + }; + + config { + pins = "gpio27"; + drive-strength = <2>; /* 2 mA */ + }; + }; + + hs1_i2s_data1_active: hs1_i2s_data1_active { + mux { + pins = "gpio27"; + function = "hs1_mi2s"; + }; + + config { + pins = "gpio27"; + drive-strength = <4>; /* 4 mA */ + bias-no-pull; + output-high; + }; + }; + }; + emac { emac_mdc: emac_mdc { mux { -- GitLab From c270eb57dcd5eb49289151f1179e2d67a15f4491 Mon Sep 17 00:00:00 2001 From: Nijun Gong Date: Thu, 13 Jun 2019 16:00:01 +0800 Subject: [PATCH 0669/1121] ARM: dts: msm: add cnss dt node for sa6155p vm add cnss dt node for rome wlan on sa6155p virtual machine. Change-Id: I82a855afd430a0e5f6818ebf335e5edd7ce179c8 Signed-off-by: Nijun Gong --- arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi | 33 ++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi b/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi index 9a271d717613..d40f305255bc 100644 --- a/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi @@ -405,6 +405,39 @@ regulator-name = "pcie_0_gdsc"; status = "okay"; }; + + vreg_wlan: vreg_wlan { + compatible = "qcom,stub-regulator"; + regulator-name = "vreg_wlan"; + }; + + cnss_pcie: qcom,cnss { + compatible = "qcom,cnss"; + wlan-en-gpio = <&tlmm 98 0>; + vdd-wlan-supply = <&vreg_wlan>; + reg = <0x10000000 0x10000000>, + <0x20000000 0x10000>; + reg-names = "smmu_iova_base", "smmu_iova_ipa"; + qcom,smmu-s1-enable; + qcom,notify-modem-status; + pinctrl-names = "wlan_en_active", "wlan_en_sleep"; + pinctrl-0 = <&cnss_wlan_en_active>; + pinctrl-1 = <&cnss_wlan_en_sleep>; + qcom,wlan-rc-num = <0>; + qcom,wlan-ramdump-dynamic = <0x200000>; + + qcom,msm-bus,name = "msm-cnss"; + qcom,msm-bus,num-cases = <4>; + qcom,msm-bus,num-paths = <2>; + qcom,msm-bus,vectors-KBps = + <45 512 0 0>, <1 512 0 0>, + /* Upto 200 Mbps */ + <45 512 41421 655360>, <1 512 41421 655360>, + /* Upto 400 Mbps */ + <45 512 98572 655360>, <1 512 98572 1600000>, + /* Upto 800 Mbps */ + <45 512 207108 1146880>, <1 512 207108 3124992>; + }; }; #include "sa6155p-vm-pinctrl.dtsi" -- GitLab From ba995ab41f5f839aa19c58662f780abba4c37cd6 Mon Sep 17 00:00:00 2001 From: Tharun Kumar Merugu Date: Mon, 24 Jun 2019 10:55:01 +0530 Subject: [PATCH 0670/1121] msm: adsprpc: change logging of rpmsg callback error message Since logging of rpmsg callback function error message on console is causing increase in latency, changing it to debug. Change-Id: Ic5cb75d755d9363f1bd9440e6451a39fd4807f34 Acked-by: Maitreyi Gupta Signed-off-by: Tharun Kumar Merugu --- drivers/char/adsprpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index a404057e647f..465f278502c1 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -2849,7 +2849,7 @@ static int fastrpc_rpmsg_callback(struct rpmsg_device *rpdev, void *data, context_notify_user(me->ctxtable[index], rsp->retval); bail: if (err) - pr_err("adsprpc: invalid response or context\n"); + pr_debug("adsprpc: invalid response or context\n"); return err; } -- GitLab From 6dfa79826a900fcc3a6d32ac28e716d3a598c7ae Mon Sep 17 00:00:00 2001 From: Kaushal Kumar Date: Mon, 24 Jun 2019 11:04:58 +0530 Subject: [PATCH 0671/1121] defconfig: msm: enable XFRM_INTERFACE, MEMBARRIER for trinket Enable CONFIG_XFRM_INTERFACE and CONFIG_MEMBARRIER for trinket to be in sync with android base defconfig for android Q. Change-Id: I380b7d56b0e1e081fde762b3459c63555e1e4e22 Signed-off-by: Kaushal Kumar --- arch/arm64/configs/vendor/trinket-perf_defconfig | 2 +- arch/arm64/configs/vendor/trinket_defconfig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/configs/vendor/trinket-perf_defconfig b/arch/arm64/configs/vendor/trinket-perf_defconfig index 87cb508d0973..f5c43545d892 100644 --- a/arch/arm64/configs/vendor/trinket-perf_defconfig +++ b/arch/arm64/configs/vendor/trinket-perf_defconfig @@ -38,7 +38,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_RD_LZ4 is not set CONFIG_KALLSYMS_ALL=y CONFIG_BPF_SYSCALL=y -# CONFIG_MEMBARRIER is not set CONFIG_EMBEDDED=y # CONFIG_COMPAT_BRK is not set CONFIG_SLAB_FREELIST_RANDOM=y @@ -102,6 +101,7 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM_USER=y +CONFIG_XFRM_INTERFACE=y CONFIG_XFRM_STATISTICS=y CONFIG_NET_KEY=y CONFIG_INET=y diff --git a/arch/arm64/configs/vendor/trinket_defconfig b/arch/arm64/configs/vendor/trinket_defconfig index e90883cb6c1d..46a23330b34e 100644 --- a/arch/arm64/configs/vendor/trinket_defconfig +++ b/arch/arm64/configs/vendor/trinket_defconfig @@ -40,7 +40,6 @@ CONFIG_BLK_DEV_INITRD=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_KALLSYMS_ALL=y CONFIG_BPF_SYSCALL=y -# CONFIG_MEMBARRIER is not set CONFIG_EMBEDDED=y # CONFIG_COMPAT_BRK is not set CONFIG_SLAB_FREELIST_RANDOM=y @@ -109,6 +108,7 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM_USER=y +CONFIG_XFRM_INTERFACE=y CONFIG_XFRM_STATISTICS=y CONFIG_NET_KEY=y CONFIG_INET=y -- GitLab From b9e210d42bc9573663f1d5f482b62acac691c756 Mon Sep 17 00:00:00 2001 From: Ankita Bajaj Date: Tue, 11 Jun 2019 15:12:18 +0530 Subject: [PATCH 0672/1121] nl80211: Keep optional check for KCK in set rekey In case of new AKM suites (example FILS-SHA256), KCK is optional in rekey data. commit 5dedc7670e5b ("cfg80211: Include length of kek in rekey data") brings in the change to make KCK optional but does not remove the kernel change already present to always check for KCK in set rekey data. This commit addresses the same by removing the check. CRs-Fixed: 2469060 Change-Id: Iac8292c973b5562bde33ccc8a054a7a06927d517 Signed-off-by: Ankita Bajaj --- net/wireless/nl80211.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 5f4d37ac3c45..504928f31c13 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -11023,9 +11023,6 @@ static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info) if (err) return err; - if (!tb[NL80211_REKEY_DATA_REPLAY_CTR] || !tb[NL80211_REKEY_DATA_KEK] || - !tb[NL80211_REKEY_DATA_KCK]) - return -EINVAL; if (!tb[NL80211_REKEY_DATA_KEK] || !tb[NL80211_REKEY_DATA_REPLAY_CTR] || (!wiphy_ext_feature_isset(&rdev->wiphy, NL80211_EXT_FEATURE_FILS_SK_OFFLOAD) && -- GitLab From 17c63bd3a1bea2c3267c23a7fbe92be095aa384f Mon Sep 17 00:00:00 2001 From: Archana Sriram Date: Mon, 21 Jan 2019 15:17:32 +0530 Subject: [PATCH 0673/1121] msm: kgsl: Change data type for GPU ib vote Change data type for gpu ib vote to unsigned long to suit the bw vote data type in devfreq governor functions. Change-Id: I6aeb201ee67d111ee527c17e051b5125968a9683 Signed-off-by: Archana Sriram --- drivers/gpu/msm/kgsl_pwrctrl.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c index 8d651cf31718..3bb141ed1bbc 100644 --- a/drivers/gpu/msm/kgsl_pwrctrl.c +++ b/drivers/gpu/msm/kgsl_pwrctrl.c @@ -65,7 +65,7 @@ static const char * const clocks[] = { "smmu_vote", }; -static unsigned int ib_votes[KGSL_MAX_BUSLEVELS]; +static unsigned long ib_votes[KGSL_MAX_BUSLEVELS]; static int last_vote_buslevel; static int max_vote_buslevel; @@ -129,7 +129,7 @@ static void _record_pwrevent(struct kgsl_device *device, /** * kgsl_get_bw() - Return latest msm bus IB vote */ -static unsigned int kgsl_get_bw(void) +static unsigned long kgsl_get_bw(void) { return ib_votes[last_vote_buslevel]; } @@ -143,8 +143,8 @@ static unsigned int kgsl_get_bw(void) static void _ab_buslevel_update(struct kgsl_pwrctrl *pwr, unsigned long *ab) { - unsigned int ib = ib_votes[last_vote_buslevel]; - unsigned int max_bw = ib_votes[max_vote_buslevel]; + unsigned long ib = ib_votes[last_vote_buslevel]; + unsigned long max_bw = ib_votes[max_vote_buslevel]; if (!ab) return; -- GitLab From d173c910730381c130d79d4ef91dd6b602c5cd33 Mon Sep 17 00:00:00 2001 From: Ramachandran Venkataramani Date: Fri, 19 Apr 2019 08:47:07 -0700 Subject: [PATCH 0674/1121] clk: qcom: Add clkref enable for PCIe and USB clkrefs Add clkref enables required by the PCIe and sde_dp phy drivers. Change-Id: I329ec36f6abfa5729b62493c2df5a280b3a2bb9d Signed-off-by: Ramachandran Venkataramani --- drivers/clk/qcom/gcc-sdmshrike.c | 56 +++++++++++++++++++ .../dt-bindings/clock/qcom,gcc-sdmshrike.h | 4 ++ 2 files changed, 60 insertions(+) diff --git a/drivers/clk/qcom/gcc-sdmshrike.c b/drivers/clk/qcom/gcc-sdmshrike.c index d88f11e7729a..1d42142095fc 100644 --- a/drivers/clk/qcom/gcc-sdmshrike.c +++ b/drivers/clk/qcom/gcc-sdmshrike.c @@ -2662,6 +2662,19 @@ static struct clk_branch gcc_pcie_0_cfg_ahb_clk = { }, }; +static struct clk_branch gcc_pcie_0_clkref_clk = { + .halt_reg = 0x8c00c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8c00c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_0_clkref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch gcc_pcie_0_mstr_axi_clk = { .halt_reg = 0x6b018, .halt_check = BRANCH_HALT_VOTED, @@ -2749,6 +2762,19 @@ static struct clk_branch gcc_pcie_1_cfg_ahb_clk = { }, }; +static struct clk_branch gcc_pcie_1_clkref_clk = { + .halt_reg = 0x8c02c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8c02c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_1_clkref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch gcc_pcie_1_mstr_axi_clk = { .halt_reg = 0x8d018, .halt_check = BRANCH_HALT_VOTED, @@ -4524,6 +4550,19 @@ static struct clk_branch gcc_usb3_mp_phy_pipe_1_clk = { }, }; +static struct clk_branch gcc_usb3_prim_clkref_clk = { + .halt_reg = 0x8c008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8c008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_prim_clkref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch gcc_usb3_prim_phy_aux_clk = { .halt_reg = 0xf050, .halt_check = BRANCH_HALT, @@ -4572,6 +4611,19 @@ static struct clk_gate2 gcc_usb3_prim_phy_pipe_clk = { }, }; +static struct clk_branch gcc_usb3_sec_clkref_clk = { + .halt_reg = 0x8c028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8c028, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_sec_clkref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch gcc_usb3_sec_phy_aux_clk = { .halt_reg = 0x10050, .halt_check = BRANCH_HALT, @@ -4757,6 +4809,7 @@ static struct clk_regmap *gcc_sdmshrike_clocks[] = { [GCC_PCIE_0_AUX_CLK] = &gcc_pcie_0_aux_clk.clkr, [GCC_PCIE_0_AUX_CLK_SRC] = &gcc_pcie_0_aux_clk_src.clkr, [GCC_PCIE_0_CFG_AHB_CLK] = &gcc_pcie_0_cfg_ahb_clk.clkr, + [GCC_PCIE_0_CLKREF_CLK] = &gcc_pcie_0_clkref_clk.clkr, [GCC_PCIE_0_MSTR_AXI_CLK] = &gcc_pcie_0_mstr_axi_clk.clkr, [GCC_PCIE_0_PIPE_CLK] = &gcc_pcie_0_pipe_clk.clkr, [GCC_PCIE_0_SLV_AXI_CLK] = &gcc_pcie_0_slv_axi_clk.clkr, @@ -4764,6 +4817,7 @@ static struct clk_regmap *gcc_sdmshrike_clocks[] = { [GCC_PCIE_1_AUX_CLK] = &gcc_pcie_1_aux_clk.clkr, [GCC_PCIE_1_AUX_CLK_SRC] = &gcc_pcie_1_aux_clk_src.clkr, [GCC_PCIE_1_CFG_AHB_CLK] = &gcc_pcie_1_cfg_ahb_clk.clkr, + [GCC_PCIE_1_CLKREF_CLK] = &gcc_pcie_1_clkref_clk.clkr, [GCC_PCIE_1_MSTR_AXI_CLK] = &gcc_pcie_1_mstr_axi_clk.clkr, [GCC_PCIE_1_PIPE_CLK] = &gcc_pcie_1_pipe_clk.clkr, [GCC_PCIE_1_SLV_AXI_CLK] = &gcc_pcie_1_slv_axi_clk.clkr, @@ -4932,10 +4986,12 @@ static struct clk_regmap *gcc_sdmshrike_clocks[] = { [GCC_USB3_MP_PHY_COM_AUX_CLK] = &gcc_usb3_mp_phy_com_aux_clk.clkr, [GCC_USB3_MP_PHY_PIPE_0_CLK] = &gcc_usb3_mp_phy_pipe_0_clk.clkr, [GCC_USB3_MP_PHY_PIPE_1_CLK] = &gcc_usb3_mp_phy_pipe_1_clk.clkr, + [GCC_USB3_PRIM_CLKREF_CLK] = &gcc_usb3_prim_clkref_clk.clkr, [GCC_USB3_PRIM_PHY_AUX_CLK] = &gcc_usb3_prim_phy_aux_clk.clkr, [GCC_USB3_PRIM_PHY_AUX_CLK_SRC] = &gcc_usb3_prim_phy_aux_clk_src.clkr, [GCC_USB3_PRIM_PHY_COM_AUX_CLK] = &gcc_usb3_prim_phy_com_aux_clk.clkr, [GCC_USB3_PRIM_PHY_PIPE_CLK] = &gcc_usb3_prim_phy_pipe_clk.clkr, + [GCC_USB3_SEC_CLKREF_CLK] = &gcc_usb3_sec_clkref_clk.clkr, [GCC_USB3_SEC_PHY_AUX_CLK] = &gcc_usb3_sec_phy_aux_clk.clkr, [GCC_USB3_SEC_PHY_AUX_CLK_SRC] = &gcc_usb3_sec_phy_aux_clk_src.clkr, [GCC_USB3_SEC_PHY_COM_AUX_CLK] = &gcc_usb3_sec_phy_com_aux_clk.clkr, diff --git a/include/dt-bindings/clock/qcom,gcc-sdmshrike.h b/include/dt-bindings/clock/qcom,gcc-sdmshrike.h index ef166ef737fd..deeb23e72cc2 100644 --- a/include/dt-bindings/clock/qcom,gcc-sdmshrike.h +++ b/include/dt-bindings/clock/qcom,gcc-sdmshrike.h @@ -257,6 +257,10 @@ #define GPLL1 240 #define GPLL4 241 #define GPLL7 242 +#define GCC_PCIE_0_CLKREF_CLK 243 +#define GCC_PCIE_1_CLKREF_CLK 244 +#define GCC_USB3_PRIM_CLKREF_CLK 245 +#define GCC_USB3_SEC_CLKREF_CLK 246 #define GCC_EMAC_BCR 0 #define GCC_GPU_BCR 1 -- GitLab From 2b088298bdc63e988b9ab0be33d043caa005d88a Mon Sep 17 00:00:00 2001 From: Rishabh Jain Date: Wed, 19 Jun 2019 10:16:41 +0530 Subject: [PATCH 0675/1121] msm: camera: cpas: Avoid array underflow during client registration CPAS driver maintains an array of clients and accordingly takes the lock on them. While registering the client if the client name is not present in the existing clients' list, CPAS driver should avoid the registration and throw error. This change introduces the same and hence avoiding array underflow. Change-Id: I537b99b0b1e76afa60834f546dfc2e622b203dac Signed-off-by: Rishabh Jain --- drivers/media/platform/msm/camera/cam_cpas/cam_cpas_hw.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/media/platform/msm/camera/cam_cpas/cam_cpas_hw.c b/drivers/media/platform/msm/camera/cam_cpas/cam_cpas_hw.c index 4276b356da73..a68032cf6c19 100644 --- a/drivers/media/platform/msm/camera/cam_cpas/cam_cpas_hw.c +++ b/drivers/media/platform/msm/camera/cam_cpas/cam_cpas_hw.c @@ -1234,6 +1234,13 @@ static int cam_cpas_hw_register_client(struct cam_hw_info *cpas_hw, rc = cam_common_util_get_string_index(soc_private->client_name, soc_private->num_clients, client_name, &client_indx); + if (rc) { + CAM_ERR(CAM_CPAS, "No match found for client %s", + client_name); + mutex_unlock(&cpas_hw->hw_mutex); + return rc; + } + mutex_lock(&cpas_core->client_mutex[client_indx]); if (rc || !CAM_CPAS_CLIENT_VALID(client_indx) || -- GitLab From 4ff5de1ac782f46366ae8503c9485477c224d68b Mon Sep 17 00:00:00 2001 From: Ajay Agarwal Date: Mon, 27 May 2019 12:30:41 +0530 Subject: [PATCH 0676/1121] defconfig: QCS405: Enable USB diag_bridge, QRTR and RMNET host drivers Enable USB diagfwd and diag_bridge drivers which are required to communicate with connected diag device and diag forwarding to host PC via USB. Also enable QRTR USB transport driver which interfaces with QRTR framework to allow IPC between QCS405 and connected device. Also enable USB host driver which probes a connected RMNET interface on QCS405 and allows DATA message exchange with device. Change-Id: I0649bf59ff6e3d33f3820dbf5f2c3cb96705bb5d Signed-off-by: Ajay Agarwal --- arch/arm64/configs/vendor/qcs405-perf_defconfig | 3 +++ arch/arm64/configs/vendor/qcs405_defconfig | 3 +++ 2 files changed, 6 insertions(+) diff --git a/arch/arm64/configs/vendor/qcs405-perf_defconfig b/arch/arm64/configs/vendor/qcs405-perf_defconfig index e173e75613ce..8c759619f54a 100644 --- a/arch/arm64/configs/vendor/qcs405-perf_defconfig +++ b/arch/arm64/configs/vendor/qcs405-perf_defconfig @@ -200,6 +200,8 @@ CONFIG_NET_EMATCH_TEXT=y CONFIG_NET_CLS_ACT=y CONFIG_QRTR=y CONFIG_QRTR_SMD=y +CONFIG_QRTR_USB=y +CONFIG_RMNET_USB=y CONFIG_BT=y # CONFIG_BT_BREDR is not set # CONFIG_BT_LE is not set @@ -381,6 +383,7 @@ CONFIG_USB_SERIAL=y CONFIG_USB_EHSET_TEST_FIXTURE=y CONFIG_USB_LINK_LAYER_TEST=y CONFIG_USB_TYPEC_MUX_NXP5150A=y +CONFIG_USB_QCOM_DIAG_BRIDGE=y CONFIG_NOP_USB_XCEIV=y CONFIG_MSM_SNPS_FEMTO_PHY=y CONFIG_USB_MSM_SSPHY=y diff --git a/arch/arm64/configs/vendor/qcs405_defconfig b/arch/arm64/configs/vendor/qcs405_defconfig index 693525ccae6f..6f32a26228a8 100644 --- a/arch/arm64/configs/vendor/qcs405_defconfig +++ b/arch/arm64/configs/vendor/qcs405_defconfig @@ -206,6 +206,8 @@ CONFIG_NET_EMATCH_TEXT=y CONFIG_NET_CLS_ACT=y CONFIG_QRTR=y CONFIG_QRTR_SMD=y +CONFIG_QRTR_USB=y +CONFIG_RMNET_USB=y CONFIG_BT=y # CONFIG_BT_BREDR is not set # CONFIG_BT_LE is not set @@ -391,6 +393,7 @@ CONFIG_USB_SERIAL=y CONFIG_USB_EHSET_TEST_FIXTURE=y CONFIG_USB_LINK_LAYER_TEST=y CONFIG_USB_TYPEC_MUX_NXP5150A=y +CONFIG_USB_QCOM_DIAG_BRIDGE=y CONFIG_NOP_USB_XCEIV=y CONFIG_MSM_SNPS_FEMTO_PHY=y CONFIG_USB_MSM_SSPHY=y -- GitLab From e0b8ba2d45c752d2ce06829aac7c08287e1e608d Mon Sep 17 00:00:00 2001 From: Bojun Pan Date: Thu, 20 Jun 2019 16:51:36 -0700 Subject: [PATCH 0677/1121] msm: IPA: add functional flag for MHI Proxy Android Q update, enable MHI Proxy on msm-4.14 master branch. Add functional flag to only call MHI proxy functions when MHI proxy functional flag enabled. Change-Id: I342d0c9aefcf958226a0b697e6e8fce68bf81d15 Signed-off-by: Bojun Pan --- arch/arm64/boot/dts/qcom/sm8150-sdx50m.dtsi | 4 ++++ drivers/platform/msm/ipa/ipa_v3/ipa.c | 8 ++++++++ drivers/platform/msm/ipa/ipa_v3/ipa_i.h | 2 ++ drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c | 7 ++++--- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sm8150-sdx50m.dtsi b/arch/arm64/boot/dts/qcom/sm8150-sdx50m.dtsi index 6055d6eabd0e..63b6df46735a 100644 --- a/arch/arm64/boot/dts/qcom/sm8150-sdx50m.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150-sdx50m.dtsi @@ -249,6 +249,10 @@ }; &soc { + ipa_hw: qcom,ipa@1e00000 { + qcom,ipa-mhi-proxy; + }; + imp: qcom,ipa-mhi-proxy { compatible = "qcom,ipa-mhi-proxy"; qcom,mhi-chdb-base = <0x40300300>; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index b8d3951d316b..840bb914eaef 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -6216,6 +6216,7 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p, ipa3_ctx->ipa_endp_delay_wa = resource_p->ipa_endp_delay_wa; ipa3_ctx->secure_debug_check_action = resource_p->secure_debug_check_action; + ipa3_ctx->ipa_mhi_proxy = resource_p->ipa_mhi_proxy; if (ipa3_ctx->secure_debug_check_action == USE_SCM) { if (ipa_is_mem_dump_allowed()) @@ -7013,6 +7014,13 @@ static int get_ipa_dts_configuration(struct platform_device *pdev, ipa_drv_res->tethered_flow_control ? "True" : "False"); + ipa_drv_res->ipa_mhi_proxy = + of_property_read_bool(pdev->dev.of_node, + "qcom,ipa-mhi-proxy"); + IPADBG(": Use mhi proxy = %s\n", + ipa_drv_res->ipa_mhi_proxy + ? "True" : "False"); + /* Get IPA wrapper address */ resource = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ipa-base"); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index b5aa2715d59a..c45bc1a1ed99 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -1904,6 +1904,7 @@ struct ipa3_context { bool fw_loaded; struct IpaHwOffloadStatsAllocCmdData_t gsi_info[IPA_HW_PROTOCOL_MAX]; + bool ipa_mhi_proxy; }; struct ipa3_plat_drv_res { @@ -1949,6 +1950,7 @@ struct ipa3_plat_drv_res { bool do_non_tn_collection_on_crash; bool ipa_endp_delay_wa; u32 secure_debug_check_action; + bool ipa_mhi_proxy; }; /** diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c index d557303c7ab4..566b62017893 100644 --- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c @@ -3023,7 +3023,8 @@ static int ipa3_lcl_mdm_ssr_notifier_cb(struct notifier_block *this, ipa_stop_polling_stats(); if (atomic_read(&rmnet_ipa3_ctx->is_initialized)) platform_driver_unregister(&rmnet_ipa_driver); - imp_handle_modem_shutdown(); + if (ipa3_ctx->ipa_mhi_proxy) + imp_handle_modem_shutdown(); if (atomic_read(&rmnet_ipa3_ctx->is_ssr) && ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0) ipa3_q6_post_shutdown_cleanup(); @@ -4050,8 +4051,8 @@ void ipa3_q6_handshake_complete(bool ssr_bootup) */ rmnet_ipa_get_network_stats_and_update(); } - - imp_handle_modem_ready(); + if (ipa3_ctx->ipa_mhi_proxy) + imp_handle_modem_ready(); } static inline bool rmnet_ipa3_check_any_client_inited -- GitLab From 46cd55e3cdc0207b1cec7076fdd803aa35680255 Mon Sep 17 00:00:00 2001 From: Ramachandran Venkataramani Date: Mon, 24 Jun 2019 11:08:33 -0700 Subject: [PATCH 0678/1121] ARM: dts: msm: Fix include files for SA8195p Update the include files in SA8195p DT files to fix compilation issues. Change-Id: I5949283aba663fceeab2a205dfdd3a2164384837 Signed-off-by: Ramachandran Venkataramani --- arch/arm64/boot/dts/qcom/sa8195p-adp-star.dtsi | 2 +- arch/arm64/boot/dts/qcom/sa8195p.dts | 2 +- arch/arm64/boot/dts/qcom/sdmshrike.dtsi | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sa8195p-adp-star.dtsi b/arch/arm64/boot/dts/qcom/sa8195p-adp-star.dtsi index f35258968995..02e46d986949 100644 --- a/arch/arm64/boot/dts/qcom/sa8195p-adp-star.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8195p-adp-star.dtsi @@ -10,7 +10,7 @@ * GNU General Public License for more details. */ -#include "sdmshrike-v2.dtsi" +#include &qupv3_se0_spi { status = "ok"; diff --git a/arch/arm64/boot/dts/qcom/sa8195p.dts b/arch/arm64/boot/dts/qcom/sa8195p.dts index d664faba5624..da96aeda0b5d 100644 --- a/arch/arm64/boot/dts/qcom/sa8195p.dts +++ b/arch/arm64/boot/dts/qcom/sa8195p.dts @@ -12,7 +12,7 @@ /dts-v1/; -#include "sdmshrike-v2.dtsi" +#include "sa8195p.dtsi" / { model = "Qualcomm Technologies, Inc. SA8195P AU SoC"; diff --git a/arch/arm64/boot/dts/qcom/sdmshrike.dtsi b/arch/arm64/boot/dts/qcom/sdmshrike.dtsi index 1ecb7cda8b37..10adcd5b3833 100644 --- a/arch/arm64/boot/dts/qcom/sdmshrike.dtsi +++ b/arch/arm64/boot/dts/qcom/sdmshrike.dtsi @@ -21,9 +21,12 @@ #include #include #include +#include #include #include +#include #include +#include #define MHZ_TO_MBPS(mhz, w) ((mhz * 1000000 * w) / (1024 * 1024)) #define BW_OPP_ENTRY(mhz, w) opp-mhz {opp-hz = /bits/ 64 ;} @@ -2171,6 +2174,7 @@ #include "sdmshrike-usb.dtsi" #include "sdmshrike-qupv3.dtsi" #include "sm8150-audio.dtsi" +#include "sm8150-vidc.dtsi" #include "sm8150-pm.dtsi" #include "sdmshrike-gpu.dtsi" #include "sdmshrike-thermal.dtsi" -- GitLab From da944666ad380ebf8af1c6091fb2a92fafb82aa4 Mon Sep 17 00:00:00 2001 From: Tony Lijo Jose Date: Wed, 6 Feb 2019 14:02:23 +0530 Subject: [PATCH 0679/1121] ARM: dts: msm: Update clock source for csi phy3 for sdmmagpie Update the CSI PHY3 clock sources with correct values. Change-Id: I0bfa84da0bbd6f163135d8b17249cca48b212f2c Signed-off-by: Tony Lijo Jose --- arch/arm64/boot/dts/qcom/sdmmagpie-camera.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdmmagpie-camera.dtsi b/arch/arm64/boot/dts/qcom/sdmmagpie-camera.dtsi index bdfc630e5127..7a81796fdeba 100644 --- a/arch/arm64/boot/dts/qcom/sdmmagpie-camera.dtsi +++ b/arch/arm64/boot/dts/qcom/sdmmagpie-camera.dtsi @@ -127,9 +127,9 @@ mipi-csi-vdd-supply = <&pm6150l_l3>; clocks = <&clock_camcc CAM_CC_CPHY_RX_CLK_SRC>, <&clock_camcc CAM_CC_CSIPHY0_CLK>, - <&clock_camcc CAM_CC_CSIPHY2_CLK>, - <&clock_camcc CAM_CC_CSI2PHYTIMER_CLK_SRC>, - <&clock_camcc CAM_CC_CSI2PHYTIMER_CLK>; + <&clock_camcc CAM_CC_CSIPHY3_CLK>, + <&clock_camcc CAM_CC_CSI3PHYTIMER_CLK_SRC>, + <&clock_camcc CAM_CC_CSI3PHYTIMER_CLK>; clock-names = "cphy_rx_clk_src", "csiphy0_clk", "csiphy3_clk", -- GitLab From 4bc592ecdc78c7270e8e5caebbffbde502ac8f3e Mon Sep 17 00:00:00 2001 From: Patrick Daly Date: Wed, 1 May 2019 18:09:40 -0700 Subject: [PATCH 0680/1121] of: of_reserved_mem: Increase limit on number of regions Double the number of possible carveout regions. Change-Id: Id7a1a94eb360082c89166c0cf3bae0a72a04af71 Signed-off-by: Patrick Daly --- drivers/of/of_reserved_mem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c index 3729fd1544b4..b2ea3b1b782d 100644 --- a/drivers/of/of_reserved_mem.c +++ b/drivers/of/of_reserved_mem.c @@ -26,7 +26,7 @@ #include #include -#define MAX_RESERVED_REGIONS 32 +#define MAX_RESERVED_REGIONS 64 static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS]; static int reserved_mem_count; -- GitLab From a51c726ecfc08063b16a13d29ae83c0353dcdee3 Mon Sep 17 00:00:00 2001 From: Sujeev Dias Date: Wed, 15 May 2019 11:02:56 -0700 Subject: [PATCH 0681/1121] mhi: cntrl: qcom: do not cache PCIe endpoint config space We do not need to save a reference config space since PCIe framework will automatically restore necessary config space during re-init. CRs-Fixed: 2454278 Change-Id: I2d0e82cb5c0c4e12cd3714f79cf23fda148b632d Signed-off-by: Sujeev Dias --- drivers/bus/mhi/controllers/mhi_arch_qcom.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/bus/mhi/controllers/mhi_arch_qcom.c b/drivers/bus/mhi/controllers/mhi_arch_qcom.c index ebfc8e3b4198..362635464f07 100644 --- a/drivers/bus/mhi/controllers/mhi_arch_qcom.c +++ b/drivers/bus/mhi/controllers/mhi_arch_qcom.c @@ -35,7 +35,6 @@ struct arch_info { u32 bus_client; struct msm_pcie_register_event pcie_reg_event; struct pci_saved_state *pcie_state; - struct pci_saved_state *ref_pcie_state; struct dma_iommu_mapping *mapping; async_cookie_t cookie; void *boot_ipc_log; @@ -108,7 +107,6 @@ static int mhi_arch_esoc_ops_power_on(void *priv, unsigned int flags) struct mhi_controller *mhi_cntrl = priv; struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl); struct pci_dev *pci_dev = mhi_dev->pci_dev; - struct arch_info *arch_info = mhi_dev->arch_info; int ret; mutex_lock(&mhi_cntrl->pm_mutex); @@ -138,7 +136,6 @@ static int mhi_arch_esoc_ops_power_on(void *priv, unsigned int flags) MHI_ERR("Failed to resume pcie bus ret %d\n", ret); return ret; } - pci_load_saved_state(pci_dev, arch_info->ref_pcie_state); return mhi_pci_probe(pci_dev, NULL); } @@ -442,9 +439,6 @@ int mhi_arch_pcie_init(struct mhi_controller *mhi_cntrl) MHI_ERR("Failed to register esoc ops\n"); } - /* save reference state for pcie config space */ - arch_info->ref_pcie_state = pci_store_saved_state( - mhi_dev->pci_dev); /* * MHI host driver has full autonomy to manage power state. * Disable all automatic power collapse features -- GitLab From 5f26f1f7a0b58909ae6ac233d53dcf9d3fbff8f8 Mon Sep 17 00:00:00 2001 From: Sujeev Dias Date: Fri, 12 Apr 2019 12:18:18 -0700 Subject: [PATCH 0682/1121] mhi: core: avoid triggering SYSERR if device is already in RDDM If device gets a fatal error and a kernel panic follows, MHI host would trigger the device to RDDM when it has already entered RDDM. This would result in a stall on the device blocking ramdump collection. Avoid sending SYS_ERROR to trigger device to RDDM from kernel panic path if it is already in RDDM. CRs-Fixed: 2425417 Change-Id: I86132e2d485f57c3f68dc97faeb1c0f90bde8832 Acked-by: Bhaumik Vasav Bhatt Signed-off-by: Sujeev Dias --- drivers/bus/mhi/core/mhi_boot.c | 48 ++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/drivers/bus/mhi/core/mhi_boot.c b/drivers/bus/mhi/core/mhi_boot.c index 291c41b2dca2..74fca23a627e 100644 --- a/drivers/bus/mhi/core/mhi_boot.c +++ b/drivers/bus/mhi/core/mhi_boot.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -100,28 +100,40 @@ static int __mhi_download_rddm_in_panic(struct mhi_controller *mhi_cntrl) BHIE_RXVECDB_SEQNUM_BMSK, BHIE_RXVECDB_SEQNUM_SHFT, sequence_id); - MHI_LOG("Trigger device into RDDM mode\n"); - mhi_set_mhi_state(mhi_cntrl, MHI_STATE_SYS_ERR); + /* + * Make sure device is not already in RDDM. + * In case device asserts and a kernel panic follows, device will + * already be in RDDM. Do not trigger SYS ERR again and proceed with + * waiting for image download completion. + */ + ee = mhi_get_exec_env(mhi_cntrl); + if (ee != MHI_EE_RDDM) { - MHI_LOG("Waiting for device to enter RDDM\n"); - while (rddm_retry--) { - ee = mhi_get_exec_env(mhi_cntrl); - if (ee == MHI_EE_RDDM) - break; + MHI_LOG("Trigger device into RDDM mode using SYSERR\n"); + mhi_set_mhi_state(mhi_cntrl, MHI_STATE_SYS_ERR); - udelay(delayus); - } + MHI_LOG("Waiting for device to enter RDDM\n"); + while (rddm_retry--) { + ee = mhi_get_exec_env(mhi_cntrl); + if (ee == MHI_EE_RDDM) + break; - if (rddm_retry <= 0) { - /* This is a hardware reset, will force device to enter rddm */ - MHI_LOG( - "Did not enter RDDM triggering host req. reset to force rddm\n"); - mhi_write_reg(mhi_cntrl, mhi_cntrl->regs, - MHI_SOC_RESET_REQ_OFFSET, MHI_SOC_RESET_REQ); - udelay(delayus); + udelay(delayus); + } + + if (rddm_retry <= 0) { + /* Hardware reset; force device to enter rddm */ + MHI_LOG( + "Did not enter RDDM, do a host req. reset\n"); + mhi_write_reg(mhi_cntrl, mhi_cntrl->regs, + MHI_SOC_RESET_REQ_OFFSET, + MHI_SOC_RESET_REQ); + udelay(delayus); + } + + ee = mhi_get_exec_env(mhi_cntrl); } - ee = mhi_get_exec_env(mhi_cntrl); MHI_LOG("Waiting for image download completion, current EE:%s\n", TO_MHI_EXEC_STR(ee)); while (retry--) { -- GitLab From cd8051d1f01ed41b78da4ad5383241cb535b630d Mon Sep 17 00:00:00 2001 From: Sujeev Dias Date: Wed, 10 Apr 2019 14:28:24 -0700 Subject: [PATCH 0683/1121] mhi: core: initialize MHI lpm_mutex before use Initialize the mutex to avoid null ptr access during usage. CRs-Fixed: 2432460 Change-Id: Iedc6152b9616b825e31efab61d699a613cc73ac9 Acked-by: Bhaumik Vasav Bhatt Signed-off-by: Sujeev Dias --- drivers/bus/mhi/core/mhi_init.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/bus/mhi/core/mhi_init.c b/drivers/bus/mhi/core/mhi_init.c index 0afa43283ddd..f0ba61de19e0 100644 --- a/drivers/bus/mhi/core/mhi_init.c +++ b/drivers/bus/mhi/core/mhi_init.c @@ -549,6 +549,7 @@ int mhi_init_timesync(struct mhi_controller *mhi_cntrl) return -ENOMEM; spin_lock_init(&mhi_tsync->lock); + mutex_init(&mhi_tsync->lpm_mutex); INIT_LIST_HEAD(&mhi_tsync->head); init_completion(&mhi_tsync->completion); -- GitLab From 5b46ee6785af9c993c6a3e227e3836058b0bf2c5 Mon Sep 17 00:00:00 2001 From: Sujeev Dias Date: Tue, 14 May 2019 19:21:30 -0700 Subject: [PATCH 0684/1121] mhi: core: change to vmalloc for memory allocations larger than 32KB Certain large memory allocations are likely to exceed 32KB or order of 3. It is recommended to switch to using vmalloc instead to avoid possible failures while allocating memory. CRs-Fixed: 2446873 Change-Id: I62ddc505956e116f55e8b3b974de3d5b039b0404 Acked-by: Bhaumik Vasav Bhatt Signed-off-by: Sujeev Dias --- drivers/bus/mhi/core/mhi_init.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/bus/mhi/core/mhi_init.c b/drivers/bus/mhi/core/mhi_init.c index f0ba61de19e0..57dd599f6e90 100644 --- a/drivers/bus/mhi/core/mhi_init.c +++ b/drivers/bus/mhi/core/mhi_init.c @@ -759,7 +759,7 @@ void mhi_deinit_chan_ctxt(struct mhi_controller *mhi_cntrl, mhi_free_coherent(mhi_cntrl, tre_ring->alloc_size, tre_ring->pre_aligned, tre_ring->dma_handle); - kfree(buf_ring->base); + vfree(buf_ring->base); buf_ring->base = tre_ring->base = NULL; chan_ctxt->rbase = 0; @@ -784,7 +784,7 @@ int mhi_init_chan_ctxt(struct mhi_controller *mhi_cntrl, buf_ring->el_size = sizeof(struct mhi_buf_info); buf_ring->len = buf_ring->el_size * buf_ring->elements; - buf_ring->base = kzalloc(buf_ring->len, GFP_KERNEL); + buf_ring->base = vzalloc(buf_ring->len); if (!buf_ring->base) { mhi_free_coherent(mhi_cntrl, tre_ring->alloc_size, @@ -998,8 +998,8 @@ static int of_parse_ch_cfg(struct mhi_controller *mhi_cntrl, if (!of_node) return -EINVAL; - mhi_cntrl->mhi_chan = kcalloc(mhi_cntrl->max_chan, - sizeof(*mhi_cntrl->mhi_chan), GFP_KERNEL); + mhi_cntrl->mhi_chan = vzalloc(mhi_cntrl->max_chan * + sizeof(*mhi_cntrl->mhi_chan)); if (!mhi_cntrl->mhi_chan) return -ENOMEM; @@ -1146,7 +1146,7 @@ static int of_parse_ch_cfg(struct mhi_controller *mhi_cntrl, return 0; error_chan_cfg: - kfree(mhi_cntrl->mhi_chan); + vfree(mhi_cntrl->mhi_chan); return -EINVAL; } -- GitLab From 7afc516711e692d93f3845eaa98927e17a0f1243 Mon Sep 17 00:00:00 2001 From: Shaoqing Liu Date: Mon, 10 Jun 2019 15:26:06 +0800 Subject: [PATCH 0685/1121] soc: qcom: qdss_bridge: Get buffer num from mhi and enlarge buffer size Update buffer number get from mhi device tree instead of hardcode and modify buffer size as 32KB. Change-Id: I304cbf01e6d5b5a55848d4aa8775eecd95293bb3 Signed-off-by: Shaoqing Liu --- drivers/soc/qcom/qdss_bridge.c | 26 +++++++++----------------- drivers/soc/qcom/qdss_bridge.h | 3 ++- 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/drivers/soc/qcom/qdss_bridge.c b/drivers/soc/qcom/qdss_bridge.c index 5f2575a313a1..1e5debbb598e 100644 --- a/drivers/soc/qcom/qdss_bridge.c +++ b/drivers/soc/qcom/qdss_bridge.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -31,17 +31,6 @@ #define MODULE_NAME "qdss_bridge" -#define QDSS_BUF_SIZE (16*1024) -#define MHI_CLIENT_QDSS_IN 9 - -/* Max number of objects needed */ -static int poolsize = 32; -module_param(poolsize, int, 0644); - -/* Size of single buffer */ -static int itemsize = QDSS_BUF_SIZE; -module_param(itemsize, int, 0644); - static struct class *mhi_class; static const char * const str_mhi_transfer_mode[] = { @@ -106,8 +95,12 @@ static int qdss_create_buf_tbl(struct qdss_bridge_drvdata *drvdata) void *buf; struct qdss_request *usb_req; int i; + struct mhi_device *mhi_dev = drvdata->mhi_dev; + + drvdata->nr_trbs = mhi_get_no_free_descriptors(mhi_dev, + DMA_FROM_DEVICE); - for (i = 0; i < poolsize; i++) { + for (i = 0; i < drvdata->nr_trbs; i++) { entry = kzalloc(sizeof(*entry), GFP_KERNEL); if (!entry) goto err; @@ -455,7 +448,7 @@ static void usb_notifier(void *priv, unsigned int event, switch (event) { case USB_QDSS_CONNECT: - usb_qdss_alloc_req(ch, poolsize, 0); + usb_qdss_alloc_req(ch, drvdata->nr_trbs, 0); mhi_queue_read(drvdata); break; @@ -709,12 +702,11 @@ static ssize_t mhi_uci_read(struct file *file, static int mhi_queue_inbound(struct qdss_bridge_drvdata *drvdata) { struct mhi_device *mhi_dev = drvdata->mhi_dev; - int nr_trbs = mhi_get_no_free_descriptors(mhi_dev, DMA_FROM_DEVICE); void *buf; struct qdss_mhi_buf_tbl_t *entry; int ret = -EIO, i; - for (i = 0; i < nr_trbs; i++) { + for (i = 0; i < drvdata->nr_trbs; i++) { entry = kzalloc(sizeof(*entry), GFP_KERNEL); if (!entry) goto err; @@ -922,7 +914,7 @@ static int qdss_mhi_probe(struct mhi_device *mhi_dev, } static const struct mhi_device_id qdss_mhi_match_table[] = { - { .chan = "QDSS", .driver_data = 0x4000 }, + { .chan = "QDSS", .driver_data = 0x8000 }, {}, }; diff --git a/drivers/soc/qcom/qdss_bridge.h b/drivers/soc/qcom/qdss_bridge.h index f5e119b0ce84..128e4bf0b82b 100644 --- a/drivers/soc/qcom/qdss_bridge.h +++ b/drivers/soc/qcom/qdss_bridge.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -39,6 +39,7 @@ enum open_status { struct qdss_bridge_drvdata { int alias; + int nr_trbs; enum open_status opened; struct completion completion; size_t mtu; -- GitLab From 428da9a154ff7870d05c4aaa53973a6b8330d950 Mon Sep 17 00:00:00 2001 From: Rajasekaran Kalidoss Date: Tue, 16 Oct 2018 19:30:14 +0530 Subject: [PATCH 0686/1121] cnss2: Update WLAN composite USB I/F number for QCN7605 For QCN7605 composite usb ,the WLAN interface number is 2. update this number to register CNSS as driver for WLAN I/F. Change-Id: I8dd97d18bf57e4268f194f846ad7c2e7b77afe50 Signed-off-by: Rajasekaran Kalidoss --- drivers/net/wireless/cnss2/usb.c | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/cnss2/usb.c b/drivers/net/wireless/cnss2/usb.c index 0d28ebe3e6dc..e93a84c76b25 100644 --- a/drivers/net/wireless/cnss2/usb.c +++ b/drivers/net/wireless/cnss2/usb.c @@ -185,7 +185,8 @@ int cnss_usb_call_driver_remove(struct cnss_usb_data *usb_priv) } static struct usb_driver cnss_usb_driver; -#define QCN7605_WLAN_INTERFACE_NUM 0x0000 +#define QCN7605_WLAN_STANDALONE_INTERFACE_NUM 0x0000 +#define QCN7605_WLAN_COMPOSITE_INTERFACE_NUM 0x0002 static int cnss_usb_probe(struct usb_interface *interface, const struct usb_device_id *id) @@ -207,15 +208,6 @@ static int cnss_usb_probe(struct usb_interface *interface, goto out; } - if (interface->cur_altsetting->desc.bInterfaceNumber == - QCN7605_WLAN_INTERFACE_NUM) { - if (usb_driver_claim_interface(&cnss_usb_driver, - interface, - NULL)) { - ret = -ENODEV; - goto reset_priv; - } - } bcd_device = le16_to_cpu(usb_dev->descriptor.bcdDevice); usb_priv->plat_priv = plat_priv; usb_priv->usb_intf = interface; @@ -256,7 +248,6 @@ static int cnss_usb_probe(struct usb_interface *interface, cnss_unregister_subsys(plat_priv); reset_ctx: plat_priv->bus_priv = NULL; -reset_priv: devm_kfree(&usb_dev->dev, usb_priv); out: return ret; @@ -317,15 +308,13 @@ static int cnss_usb_reset_resume(struct usb_interface *interface) } static struct usb_device_id cnss_usb_id_table[] = { - { USB_DEVICE_AND_INTERFACE_INFO(QCN7605_USB_VENDOR_ID, - QCN7605_COMPOSITE_PRODUCT_ID, - QCN7605_WLAN_INTERFACE_NUM, - 0xFF, 0xFF) }, - { USB_DEVICE_AND_INTERFACE_INFO(QCN7605_USB_VENDOR_ID, - QCN7605_STANDALONE_PRODUCT_ID, - QCN7605_WLAN_INTERFACE_NUM, - 0xFF, 0xFF) }, - {} /* Terminating entry */ + { USB_DEVICE_INTERFACE_NUMBER(QCN7605_USB_VENDOR_ID, + QCN7605_COMPOSITE_PRODUCT_ID, + QCN7605_WLAN_COMPOSITE_INTERFACE_NUM) }, + { USB_DEVICE_INTERFACE_NUMBER(QCN7605_USB_VENDOR_ID, + QCN7605_STANDALONE_PRODUCT_ID, + QCN7605_WLAN_STANDALONE_INTERFACE_NUM) }, + {} /* Terminating entry */ }; static struct usb_driver cnss_usb_driver = { -- GitLab From 2ed8c2432b304499950ebf0e74bf01d268132251 Mon Sep 17 00:00:00 2001 From: Jayadev K Date: Tue, 25 Jun 2019 12:08:42 +0530 Subject: [PATCH 0687/1121] ARM: dts: qcom: Add device tree support for hsi2s driver Adding device nodes for hsi2s interfaces in the sa6155 adp air device tree. Change-Id: If739bb32048fb5c208ffca5be2d380a134894fbf Signed-off-by: Jayadev K --- arch/arm64/boot/dts/qcom/sa6155-adp-air.dtsi | 47 ++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sa6155-adp-air.dtsi b/arch/arm64/boot/dts/qcom/sa6155-adp-air.dtsi index ba6c68a60bb5..a7a4d95902b6 100644 --- a/arch/arm64/boot/dts/qcom/sa6155-adp-air.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155-adp-air.dtsi @@ -42,6 +42,53 @@ status = "disabled"; }; }; + + hsi2s: qcom,hsi2s { + compatible = "qcom,hsi2s"; + number-of-interfaces = <2>; + reg = <0x1B40000 0x28000>; + reg-names = "lpa_if"; + interrupts = ; + clocks = <&clock_gcc GCC_SDR_CORE_CLK>, + <&clock_gcc GCC_SDR_WR0_MEM_CLK>, + <&clock_gcc GCC_SDR_WR1_MEM_CLK>, + <&clock_gcc GCC_SDR_WR2_MEM_CLK>, + <&clock_gcc GCC_SDR_CSR_HCLK>; + clock-names = "core_clk", "wr0_mem_clk", + "wr1_mem_clk", "wr2_mem_clk", + "csr_hclk"; + + sdr0: qcom,hs0_i2s { + compatible = "qcom,hsi2s-interface"; + minor-number = <0>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&hs0_i2s_sck_active &hs0_i2s_data0_active + &hs0_i2s_data1_active>; + pinctrl-1 = <&hs0_i2s_sck_sleep &hs0_i2s_data0_sleep + &hs0_i2s_data1_sleep>; + clocks = <&clock_gcc GCC_SDR_PRI_MI2S_CLK>; + clock-names = "pri_mi2s_clk"; + iommus = <&apps_smmu 0x035C 0x0>; + qcom,smmu-s1-bypass; + qcom,iova-mapping = <0x0 0xFFFFFFFF>; + }; + + sdr1: qcom,hs1_i2s { + compatible = "qcom,hsi2s-interface"; + minor-number = <1>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&hs1_i2s_sck_active &hs1_i2s_data0_active + &hs1_i2s_data1_active>; + pinctrl-1 = <&hs1_i2s_sck_sleep &hs1_i2s_data0_sleep + &hs1_i2s_data1_sleep>; + clocks = <&clock_gcc GCC_SDR_SEC_MI2S_CLK>; + clock-names = "sec_mi2s_clk"; + iommus = <&apps_smmu 0x035D 0x0>; + qcom,smmu-s1-bypass; + qcom,iova-mapping = <0x0 0xFFFFFFFF>; + }; + }; + emac_hw: qcom,emac@20000 { compatible = "qcom,emac-dwc-eqos"; qcom,arm-smmu; -- GitLab From c400005042def066221770842af03db896417493 Mon Sep 17 00:00:00 2001 From: Blagovest Kolenichev Date: Mon, 27 May 2019 04:06:44 -0700 Subject: [PATCH 0688/1121] dm: Restore reverted changes This is a preparation change for merging android-4.14.114 into msm-4.14 branch. The following changes need to be reverted, otherwise boot stuck on rootfs mount: efe836537c Revert "CHROMIUM: dm: boot time specification of dm=" afaef20542 Revert "ANDROID: dm: do_mounts_dm: Rebase on top of 4.9" 357c3d3132 Revert "ANDROID: dm: do_mounts_dm: fix dm_substitute_devices()" 71eb40b792 Revert "ANDROID: dm: do_mounts_dm: Update init/do_mounts_dm.c to the latest ChromiumOS version." The above reverted changes are required when 'system is root' and the mount instructions (including dm-verity) for system image is provided by the bootloader through the kernel cmdline even with AVB 2.0. Dynamic/Super partition has not been enabled internally which will ensure system image is mounted by early init. Since this will only be supported for new launches of Q, still these changes are required to be present for OTA devices. Change-Id: Ie6c093cdd2d1dc1e578ebce06b3923f81c06ed6f Signed-off-by: Blagovest Kolenichev --- .../admin-guide/kernel-parameters.txt | 3 + Documentation/device-mapper/boot.txt | 42 ++ drivers/md/dm-ioctl.c | 39 ++ drivers/md/dm-table.c | 1 + drivers/md/dm.h | 2 - include/linux/device-mapper.h | 13 + init/Makefile | 1 + init/do_mounts.c | 1 + init/do_mounts.h | 10 + init/do_mounts_dm.c | 547 ++++++++++-------- 10 files changed, 414 insertions(+), 245 deletions(-) create mode 100644 Documentation/device-mapper/boot.txt diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index f6a77b9a9d26..3971554ca0d0 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -837,6 +837,9 @@ dis_ucode_ldr [X86] Disable the microcode loader. + dm= [DM] Allows early creation of a device-mapper device. + See Documentation/device-mapper/boot.txt. + dma_debug=off If the kernel is compiled with DMA_API_DEBUG support, this option disables the debugging code at boot. diff --git a/Documentation/device-mapper/boot.txt b/Documentation/device-mapper/boot.txt new file mode 100644 index 000000000000..adcaad5e5e32 --- /dev/null +++ b/Documentation/device-mapper/boot.txt @@ -0,0 +1,42 @@ +Boot time creation of mapped devices +=================================== + +It is possible to configure a device mapper device to act as the root +device for your system in two ways. + +The first is to build an initial ramdisk which boots to a minimal +userspace which configures the device, then pivot_root(8) in to it. + +For simple device mapper configurations, it is possible to boot directly +using the following kernel command line: + +dm=" ,table line 1,...,table line n" + +name = the name to associate with the device + after boot, udev, if used, will use that name to label + the device node. +uuid = may be 'none' or the UUID desired for the device. +ro = may be "ro" or "rw". If "ro", the device and device table will be + marked read-only. + +Each table line may be as normal when using the dmsetup tool except for +two variations: +1. Any use of commas will be interpreted as a newline +2. Quotation marks cannot be escaped and cannot be used without + terminating the dm= argument. + +Unless renamed by udev, the device node created will be dm-0 as the +first minor number for the device-mapper is used during early creation. + +Example +======= + +- Booting to a linear array made up of user-mode linux block devices: + + dm="lroot none 0, 0 4096 linear 98:16 0, 4096 4096 linear 98:32 0" \ + root=/dev/dm-0 + +Will boot to a rw dm-linear target of 8192 sectors split across two +block devices identified by their major:minor numbers. After boot, udev +will rename this target to /dev/mapper/lroot (depending on the rules). +No uuid was assigned. diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index ca948155191a..787afba77b2e 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -1986,6 +1986,45 @@ void dm_interface_exit(void) dm_hash_exit(); } + +/** + * dm_ioctl_export - Permanently export a mapped device via the ioctl interface + * @md: Pointer to mapped_device + * @name: Buffer (size DM_NAME_LEN) for name + * @uuid: Buffer (size DM_UUID_LEN) for uuid or NULL if not desired + */ +int dm_ioctl_export(struct mapped_device *md, const char *name, + const char *uuid) +{ + int r = 0; + struct hash_cell *hc; + + if (!md) { + r = -ENXIO; + goto out; + } + + /* The name and uuid can only be set once. */ + mutex_lock(&dm_hash_cells_mutex); + hc = dm_get_mdptr(md); + mutex_unlock(&dm_hash_cells_mutex); + if (hc) { + DMERR("%s: already exported", dm_device_name(md)); + r = -ENXIO; + goto out; + } + + r = dm_hash_insert(name, uuid, md); + if (r) { + DMERR("%s: could not bind to '%s'", dm_device_name(md), name); + goto out; + } + + /* Let udev know we've changed. */ + dm_kobject_uevent(md, KOBJ_CHANGE, dm_get_event_nr(md)); +out: + return r; +} /** * dm_copy_name_and_uuid - Copy mapped device name & uuid into supplied buffers * @md: Pointer to mapped_device diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 3aabcb239c22..ba69d1b88752 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/md/dm.h b/drivers/md/dm.h index 38c84c0a35d4..ab289ce9c3cd 100644 --- a/drivers/md/dm.h +++ b/drivers/md/dm.h @@ -80,8 +80,6 @@ void dm_set_md_type(struct mapped_device *md, enum dm_queue_mode type); enum dm_queue_mode dm_get_md_type(struct mapped_device *md); struct target_type *dm_get_immutable_target_type(struct mapped_device *md); -int dm_setup_md_queue(struct mapped_device *md, struct dm_table *t); - /* * To check the return value from dm_table_find_target(). */ diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 91a063a1f3b3..be0eb0118992 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -430,6 +430,12 @@ void dm_put(struct mapped_device *md); void dm_set_mdptr(struct mapped_device *md, void *ptr); void *dm_get_mdptr(struct mapped_device *md); +/* + * Export the device via the ioctl interface (uses mdptr). + */ +int dm_ioctl_export(struct mapped_device *md, const char *name, + const char *uuid); + /* * A device can still be used while suspended, but I/O is deferred. */ @@ -459,6 +465,13 @@ union map_info *dm_get_rq_mapinfo(struct request *rq); struct queue_limits *dm_get_queue_limits(struct mapped_device *md); +void dm_lock_md_type(struct mapped_device *md); +void dm_unlock_md_type(struct mapped_device *md); +void dm_set_md_type(struct mapped_device *md, unsigned type); +unsigned dm_get_md_type(struct mapped_device *md); +int dm_setup_md_queue(struct mapped_device *md, struct dm_table *t); +unsigned dm_table_get_type(struct dm_table *t); + /* * Geometry functions. */ diff --git a/init/Makefile b/init/Makefile index a04f1c18b58c..0320e1a0705d 100644 --- a/init/Makefile +++ b/init/Makefile @@ -18,6 +18,7 @@ mounts-y := do_mounts.o mounts-$(CONFIG_BLK_DEV_RAM) += do_mounts_rd.o mounts-$(CONFIG_BLK_DEV_INITRD) += do_mounts_initrd.o mounts-$(CONFIG_BLK_DEV_MD) += do_mounts_md.o +mounts-$(CONFIG_BLK_DEV_DM) += do_mounts_dm.o # dependencies on generated files need to be listed explicitly $(obj)/version.o: include/generated/compile.h diff --git a/init/do_mounts.c b/init/do_mounts.c index 7cf4f6dafd5f..27826694ea26 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -565,6 +565,7 @@ void __init prepare_namespace(void) wait_for_device_probe(); md_run_setup(); + dm_run_setup(); if (saved_root_name[0]) { root_device_name = saved_root_name; diff --git a/init/do_mounts.h b/init/do_mounts.h index 5b05c8f93f47..cd201124714b 100644 --- a/init/do_mounts.h +++ b/init/do_mounts.h @@ -61,3 +61,13 @@ void md_run_setup(void); static inline void md_run_setup(void) {} #endif + +#ifdef CONFIG_BLK_DEV_DM + +void dm_run_setup(void); + +#else + +static inline void dm_run_setup(void) {} + +#endif diff --git a/init/do_mounts_dm.c b/init/do_mounts_dm.c index e76c137a4cb6..af84b01ccfbc 100644 --- a/init/do_mounts_dm.c +++ b/init/do_mounts_dm.c @@ -5,12 +5,17 @@ * * This file is released under the GPL. */ +#include +#include #include #include #include +#include #include "do_mounts.h" +#define DM_MAX_DEVICES 256 +#define DM_MAX_TARGETS 256 #define DM_MAX_NAME 32 #define DM_MAX_UUID 129 #define DM_NO_UUID "none" @@ -18,14 +23,47 @@ #define DM_MSG_PREFIX "init" /* Separators used for parsing the dm= argument. */ -#define DM_FIELD_SEP ' ' -#define DM_LINE_SEP ',' +#define DM_FIELD_SEP " " +#define DM_LINE_SEP "," +#define DM_ANY_SEP DM_FIELD_SEP DM_LINE_SEP /* * When the device-mapper and any targets are compiled into the kernel - * (not a module), one target may be created and used as the root device at - * boot time with the parameters given with the boot line dm=... - * The code for that is here. + * (not a module), one or more device-mappers may be created and used + * as the root device at boot time with the parameters given with the + * boot line dm=... + * + * Multiple device-mappers can be stacked specifing the number of + * devices. A device can have multiple targets if the the number of + * targets is specified. + * + * TODO(taysom:defect 32847) + * In the future, the field will be mandatory. + * + * ::= [] + + * ::= "," + + * ::= [] + * ::= "," + * ::= "ro" | "rw" + * ::= xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx | "none" + * ::= "verity" | "bootcache" | ... + * + * Example: + * 2 vboot none ro 1, + * 0 1768000 bootcache + * device=aa55b119-2a47-8c45-946a-5ac57765011f+1 + * signature=76e9be054b15884a9fa85973e9cb274c93afadb6 + * cache_start=1768000 max_blocks=100000 size_limit=23 max_trace=20000, + * vroot none ro 1, + * 0 1740800 verity payload=254:0 hashtree=254:0 hashstart=1740800 alg=sha1 + * root_hexdigest=76e9be054b15884a9fa85973e9cb274c93afadb6 + * salt=5b3549d54d6c7a3837b9b81ed72e49463a64c03680c47835bef94d768e5646fe + * + * Notes: + * 1. uuid is a label for the device and we set it to "none". + * 2. The field will be optional initially and assumed to be 1. + * Once all the scripts that set these fields have been set, it will + * be made mandatory. */ struct dm_setup_target { @@ -37,365 +75,388 @@ struct dm_setup_target { struct dm_setup_target *next; }; -static struct { +struct dm_device { int minor; int ro; char name[DM_MAX_NAME]; char uuid[DM_MAX_UUID]; - char *targets; + unsigned long num_targets; struct dm_setup_target *target; int target_count; + struct dm_device *next; +}; + +struct dm_option { + char *start; + char *next; + size_t len; + char delim; +}; + +static struct { + unsigned long num_devices; + char *str; } dm_setup_args __initdata; static __initdata int dm_early_setup; -static size_t __init get_dm_option(char *str, char **next, char sep) +static int __init get_dm_option(struct dm_option *opt, const char *accept) { - size_t len = 0; - char *endp = NULL; + char *str = opt->next; + char *endp; if (!str) return 0; - endp = strchr(str, sep); + str = skip_spaces(str); + opt->start = str; + endp = strpbrk(str, accept); if (!endp) { /* act like strchrnul */ - len = strlen(str); - endp = str + len; + opt->len = strlen(str); + endp = str + opt->len; } else { - len = endp - str; + opt->len = endp - str; } - - if (endp == str) - return 0; - - if (!next) - return len; - + opt->delim = *endp; if (*endp == 0) { /* Don't advance past the nul. */ - *next = endp; + opt->next = endp; } else { - *next = endp + 1; + opt->next = endp + 1; } - return len; + return opt->len != 0; } -static int __init dm_setup_args_init(void) +static int __init dm_setup_cleanup(struct dm_device *devices) { - dm_setup_args.minor = 0; - dm_setup_args.ro = 0; - dm_setup_args.target = NULL; - dm_setup_args.target_count = 0; - return 0; -} - -static int __init dm_setup_cleanup(void) -{ - struct dm_setup_target *target = dm_setup_args.target; - struct dm_setup_target *old_target = NULL; - while (target) { - kfree(target->type); - kfree(target->params); - old_target = target; - target = target->next; - kfree(old_target); - dm_setup_args.target_count--; + struct dm_device *dev = devices; + + while (dev) { + struct dm_device *old_dev = dev; + struct dm_setup_target *target = dev->target; + while (target) { + struct dm_setup_target *old_target = target; + kfree(target->type); + kfree(target->params); + target = target->next; + kfree(old_target); + dev->target_count--; + } + BUG_ON(dev->target_count); + dev = dev->next; + kfree(old_dev); } - BUG_ON(dm_setup_args.target_count); return 0; } -static char * __init dm_setup_parse_device_args(char *str) +static char * __init dm_parse_device(struct dm_device *dev, char *str) { - char *next = NULL; - size_t len = 0; + struct dm_option opt; + size_t len; /* Grab the logical name of the device to be exported to udev */ - len = get_dm_option(str, &next, DM_FIELD_SEP); - if (!len) { + opt.next = str; + if (!get_dm_option(&opt, DM_FIELD_SEP)) { DMERR("failed to parse device name"); goto parse_fail; } - len = min(len + 1, sizeof(dm_setup_args.name)); - strlcpy(dm_setup_args.name, str, len); /* includes nul */ - str = skip_spaces(next); + len = min(opt.len + 1, sizeof(dev->name)); + strlcpy(dev->name, opt.start, len); /* includes nul */ /* Grab the UUID value or "none" */ - len = get_dm_option(str, &next, DM_FIELD_SEP); - if (!len) { + if (!get_dm_option(&opt, DM_FIELD_SEP)) { DMERR("failed to parse device uuid"); goto parse_fail; } - len = min(len + 1, sizeof(dm_setup_args.uuid)); - strlcpy(dm_setup_args.uuid, str, len); - str = skip_spaces(next); + len = min(opt.len + 1, sizeof(dev->uuid)); + strlcpy(dev->uuid, opt.start, len); /* Determine if the table/device will be read only or read-write */ - if (!strncmp("ro,", str, 3)) { - dm_setup_args.ro = 1; - } else if (!strncmp("rw,", str, 3)) { - dm_setup_args.ro = 0; + get_dm_option(&opt, DM_ANY_SEP); + if (!strncmp("ro", opt.start, opt.len)) { + dev->ro = 1; + } else if (!strncmp("rw", opt.start, opt.len)) { + dev->ro = 0; } else { DMERR("failed to parse table mode"); goto parse_fail; } - str = skip_spaces(str + 3); - return str; + /* Optional number field */ + /* XXX: The field will be mandatory in the next round */ + if (opt.delim == DM_FIELD_SEP[0]) { + if (!get_dm_option(&opt, DM_LINE_SEP)) + return NULL; + dev->num_targets = simple_strtoul(opt.start, NULL, 10); + } else { + dev->num_targets = 1; + } + if (dev->num_targets > DM_MAX_TARGETS) { + DMERR("too many targets %lu > %d", + dev->num_targets, DM_MAX_TARGETS); + } + return opt.next; parse_fail: return NULL; } -static void __init dm_substitute_devices(char *str, size_t str_len) +static char * __init dm_parse_targets(struct dm_device *dev, char *str) { - char *candidate = str; - char *candidate_end = str; - char old_char; - size_t len = 0; - dev_t dev; - - if (str_len < 3) - return; - - while (str && *str) { - candidate = strchr(str, '/'); - if (!candidate) - break; - - /* Avoid embedded slashes */ - if (candidate != str && *(candidate - 1) != DM_FIELD_SEP) { - str = strchr(candidate, DM_FIELD_SEP); - continue; - } - - len = get_dm_option(candidate, &candidate_end, DM_FIELD_SEP); - str = skip_spaces(candidate_end); - if (len < 3 || len > 37) /* name_to_dev_t max; maj:mix min */ - continue; - - /* Temporarily terminate with a nul */ - candidate_end--; - old_char = *candidate_end; - *candidate_end = '\0'; - - DMDEBUG("converting candidate device '%s' to dev_t", candidate); - /* Use the boot-time specific device naming */ - dev = name_to_dev_t(candidate); - *candidate_end = old_char; - - DMDEBUG(" -> %u", dev); - /* No suitable replacement found */ - if (!dev) - continue; - - /* Rewrite the /dev/path as a major:minor */ - len = snprintf(candidate, len, "%u:%u", MAJOR(dev), MINOR(dev)); - if (!len) { - DMERR("error substituting device major/minor."); - break; - } - candidate += len; - /* Pad out with spaces (fixing our nul) */ - while (candidate < candidate_end) - *(candidate++) = DM_FIELD_SEP; - } -} - -static int __init dm_setup_parse_targets(char *str) -{ - char *next = NULL; - size_t len = 0; - struct dm_setup_target **target = NULL; + struct dm_option opt; + struct dm_setup_target **target = &dev->target; + unsigned long num_targets = dev->num_targets; + unsigned long i; /* Targets are defined as per the table format but with a * comma as a newline separator. */ - target = &dm_setup_args.target; - while (str && *str) { + opt.next = str; + for (i = 0; i < num_targets; i++) { *target = kzalloc(sizeof(struct dm_setup_target), GFP_KERNEL); if (!*target) { - DMERR("failed to allocate memory for target %d", - dm_setup_args.target_count); + DMERR("failed to allocate memory for target %s<%ld>", + dev->name, i); goto parse_fail; } - dm_setup_args.target_count++; + dev->target_count++; - (*target)->begin = simple_strtoull(str, &next, 10); - if (!next || *next != DM_FIELD_SEP) { - DMERR("failed to parse starting sector for target %d", - dm_setup_args.target_count - 1); + if (!get_dm_option(&opt, DM_FIELD_SEP)) { + DMERR("failed to parse starting sector" + " for target %s<%ld>", dev->name, i); goto parse_fail; } - str = skip_spaces(next + 1); + (*target)->begin = simple_strtoull(opt.start, NULL, 10); - (*target)->length = simple_strtoull(str, &next, 10); - if (!next || *next != DM_FIELD_SEP) { - DMERR("failed to parse length for target %d", - dm_setup_args.target_count - 1); + if (!get_dm_option(&opt, DM_FIELD_SEP)) { + DMERR("failed to parse length for target %s<%ld>", + dev->name, i); goto parse_fail; } - str = skip_spaces(next + 1); - - len = get_dm_option(str, &next, DM_FIELD_SEP); - if (!len || - !((*target)->type = kstrndup(str, len, GFP_KERNEL))) { - DMERR("failed to parse type for target %d", - dm_setup_args.target_count - 1); + (*target)->length = simple_strtoull(opt.start, NULL, 10); + + if (get_dm_option(&opt, DM_FIELD_SEP)) + (*target)->type = kstrndup(opt.start, opt.len, + GFP_KERNEL); + if (!((*target)->type)) { + DMERR("failed to parse type for target %s<%ld>", + dev->name, i); goto parse_fail; } - str = skip_spaces(next); - - len = get_dm_option(str, &next, DM_LINE_SEP); - if (!len || - !((*target)->params = kstrndup(str, len, GFP_KERNEL))) { - DMERR("failed to parse params for target %d", - dm_setup_args.target_count - 1); + if (get_dm_option(&opt, DM_LINE_SEP)) + (*target)->params = kstrndup(opt.start, opt.len, + GFP_KERNEL); + if (!((*target)->params)) { + DMERR("failed to parse params for target %s<%ld>", + dev->name, i); goto parse_fail; } - str = skip_spaces(next); - - /* Before moving on, walk through the copied target and - * attempt to replace all /dev/xxx with the major:minor number. - * It may not be possible to resolve them traditionally at - * boot-time. */ - dm_substitute_devices((*target)->params, len); - target = &((*target)->next); } - DMDEBUG("parsed %d targets", dm_setup_args.target_count); + DMDEBUG("parsed %d targets", dev->target_count); - return 0; + return opt.next; parse_fail: - return 1; + return NULL; +} + +static struct dm_device * __init dm_parse_args(void) +{ + struct dm_device *devices = NULL; + struct dm_device **tail = &devices; + struct dm_device *dev; + char *str = dm_setup_args.str; + unsigned long num_devices = dm_setup_args.num_devices; + unsigned long i; + + if (!str) + return NULL; + for (i = 0; i < num_devices; i++) { + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) { + DMERR("failed to allocated memory for dev"); + goto error; + } + *tail = dev; + tail = &dev->next; + /* + * devices are given minor numbers 0 - n-1 + * in the order they are found in the arg + * string. + */ + dev->minor = i; + str = dm_parse_device(dev, str); + if (!str) /* NULL indicates error in parsing, bail */ + goto error; + + str = dm_parse_targets(dev, str); + if (!str) + goto error; + } + return devices; +error: + dm_setup_cleanup(devices); + return NULL; } /* * Parse the command-line parameters given our kernel, but do not * actually try to invoke the DM device now; that is handled by - * dm_setup_drive after the low-level disk drivers have initialised. - * dm format is as follows: - * dm="name uuid fmode,[table line 1],[table line 2],..." - * May be used with root=/dev/dm-0 as it always uses the first dm minor. + * dm_setup_drives after the low-level disk drivers have initialised. + * dm format is described at the top of the file. + * + * Because dm minor numbers are assigned in assending order starting with 0, + * You can assume the first device is /dev/dm-0, the next device is /dev/dm-1, + * and so forth. */ - static int __init dm_setup(char *str) { - dm_setup_args_init(); + struct dm_option opt; + unsigned long num_devices; - str = dm_setup_parse_device_args(str); if (!str) { DMDEBUG("str is NULL"); goto parse_fail; } - - /* Target parsing is delayed until we have dynamic memory */ - dm_setup_args.targets = str; - - printk(KERN_INFO "dm: will configure '%s' on dm-%d\n", - dm_setup_args.name, dm_setup_args.minor); - + opt.next = str; + if (!get_dm_option(&opt, DM_FIELD_SEP)) + goto parse_fail; + if (isdigit(opt.start[0])) { /* XXX: Optional number field */ + num_devices = simple_strtoul(opt.start, NULL, 10); + str = opt.next; + } else { + num_devices = 1; + /* Don't advance str */ + } + if (num_devices > DM_MAX_DEVICES) { + DMDEBUG("too many devices %lu > %d", + num_devices, DM_MAX_DEVICES); + } + dm_setup_args.str = str; + dm_setup_args.num_devices = num_devices; + DMINFO("will configure %lu devices", num_devices); dm_early_setup = 1; return 1; parse_fail: - printk(KERN_WARNING "dm: Invalid arguments supplied to dm=.\n"); + DMWARN("Invalid arguments supplied to dm=."); return 0; } - -static void __init dm_setup_drive(void) +static void __init dm_setup_drives(void) { struct mapped_device *md = NULL; struct dm_table *table = NULL; struct dm_setup_target *target; - char *uuid = dm_setup_args.uuid; + struct dm_device *dev; + char *uuid; fmode_t fmode = FMODE_READ; + struct dm_device *devices; - /* Finish parsing the targets. */ - if (dm_setup_parse_targets(dm_setup_args.targets)) - goto parse_fail; + devices = dm_parse_args(); - if (dm_create(dm_setup_args.minor, &md)) { - DMDEBUG("failed to create the device"); - goto dm_create_fail; - } - DMDEBUG("created device '%s'", dm_device_name(md)); + for (dev = devices; dev; dev = dev->next) { + if (dm_create(dev->minor, &md)) { + DMDEBUG("failed to create the device"); + goto dm_create_fail; + } + DMDEBUG("created device '%s'", dm_device_name(md)); + + /* + * In addition to flagging the table below, the disk must be + * set explicitly ro/rw. + */ + set_disk_ro(dm_disk(md), dev->ro); + + if (!dev->ro) + fmode |= FMODE_WRITE; + if (dm_table_create(&table, fmode, dev->target_count, md)) { + DMDEBUG("failed to create the table"); + goto dm_table_create_fail; + } + + dm_lock_md_type(md); + + for (target = dev->target; target; target = target->next) { + DMINFO("adding target '%llu %llu %s %s'", + (unsigned long long) target->begin, + (unsigned long long) target->length, + target->type, target->params); + if (dm_table_add_target(table, target->type, + target->begin, + target->length, + target->params)) { + DMDEBUG("failed to add the target" + " to the table"); + goto add_target_fail; + } + } + if (dm_table_complete(table)) { + DMDEBUG("failed to complete the table"); + goto table_complete_fail; + } - /* In addition to flagging the table below, the disk must be - * set explicitly ro/rw. */ - set_disk_ro(dm_disk(md), dm_setup_args.ro); + /* Suspend the device so that we can bind it to the table. */ + if (dm_suspend(md, 0)) { + DMDEBUG("failed to suspend the device pre-bind"); + goto suspend_fail; + } - if (!dm_setup_args.ro) - fmode |= FMODE_WRITE; - if (dm_table_create(&table, fmode, dm_setup_args.target_count, md)) { - DMDEBUG("failed to create the table"); - goto dm_table_create_fail; - } + /* Initial table load: acquire type of table. */ + dm_set_md_type(md, dm_table_get_type(table)); - target = dm_setup_args.target; - while (target) { - DMINFO("adding target '%llu %llu %s %s'", - (unsigned long long) target->begin, - (unsigned long long) target->length, target->type, - target->params); - if (dm_table_add_target(table, target->type, target->begin, - target->length, target->params)) { - DMDEBUG("failed to add the target to the table"); - goto add_target_fail; + /* Setup md->queue to reflect md's type. */ + if (dm_setup_md_queue(md, table)) { + DMWARN("unable to set up device queue for new table."); + goto setup_md_queue_fail; } - target = target->next; - } - if (dm_table_complete(table)) { - DMDEBUG("failed to complete the table"); - goto table_complete_fail; - } + /* + * Bind the table to the device. This is the only way + * to associate md->map with the table and set the disk + * capacity directly. + */ + if (dm_swap_table(md, table)) { /* should return NULL. */ + DMDEBUG("failed to bind the device to the table"); + goto table_bind_fail; + } - /* Suspend the device so that we can bind it to the table. */ - if (dm_suspend(md, 0)) { - DMDEBUG("failed to suspend the device pre-bind"); - goto suspend_fail; - } + /* Finally, resume and the device should be ready. */ + if (dm_resume(md)) { + DMDEBUG("failed to resume the device"); + goto resume_fail; + } - /* Bind the table to the device. This is the only way to associate - * md->map with the table and set the disk capacity directly. */ - if (dm_swap_table(md, table)) { /* should return NULL. */ - DMDEBUG("failed to bind the device to the table"); - goto table_bind_fail; - } + /* Export the dm device via the ioctl interface */ + if (!strcmp(DM_NO_UUID, dev->uuid)) + uuid = NULL; + if (dm_ioctl_export(md, dev->name, uuid)) { + DMDEBUG("failed to export device with given" + " name and uuid"); + goto export_fail; + } - /* Finally, resume and the device should be ready. */ - if (dm_resume(md)) { - DMDEBUG("failed to resume the device"); - goto resume_fail; - } + dm_unlock_md_type(md); - /* Export the dm device via the ioctl interface */ - if (!strcmp(DM_NO_UUID, dm_setup_args.uuid)) - uuid = NULL; - if (dm_ioctl_export(md, dm_setup_args.name, uuid)) { - DMDEBUG("failed to export device with given name and uuid"); - goto export_fail; + DMINFO("dm-%d is ready", dev->minor); } - printk(KERN_INFO "dm: dm-%d is ready\n", dm_setup_args.minor); - - dm_setup_cleanup(); + dm_setup_cleanup(devices); return; export_fail: resume_fail: table_bind_fail: +setup_md_queue_fail: suspend_fail: table_complete_fail: add_target_fail: + dm_unlock_md_type(md); dm_table_create_fail: dm_put(md); dm_create_fail: - dm_setup_cleanup(); -parse_fail: - printk(KERN_WARNING "dm: starting dm-%d (%s) failed\n", - dm_setup_args.minor, dm_setup_args.name); + DMWARN("starting dm-%d (%s) failed", + dev->minor, dev->name); + dm_setup_cleanup(devices); } __setup("dm=", dm_setup); @@ -404,6 +465,6 @@ void __init dm_run_setup(void) { if (!dm_early_setup) return; - printk(KERN_INFO "dm: attempting early device configuration.\n"); - dm_setup_drive(); + DMINFO("attempting early device configuration."); + dm_setup_drives(); } -- GitLab From 2dbba5a0ee4af36acc0713590974d63d8758a8e6 Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Tue, 18 Jun 2019 18:03:14 -0700 Subject: [PATCH 0689/1121] ARM: dts: msm: Add a common device tree for VM platforms Add a common device tree for automotive virtual machine platforms to reduce code duplication across virtual machine targets. This device tree will apply to the SA 6155, SA 8155, and SA 8195 VM targets. Change-Id: If6d89d9ba1d17c1b1f1370d0888e23d38837e617 Signed-off-by: Anant Goel --- arch/arm64/boot/dts/qcom/quin-vm-common.dtsi | 251 +++++++++++++++++++ arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi | 172 +------------ arch/arm64/boot/dts/qcom/sa8155-vm.dtsi | 234 +---------------- arch/arm64/boot/dts/qcom/sa8195-vm.dtsi | 139 +--------- 4 files changed, 254 insertions(+), 542 deletions(-) create mode 100644 arch/arm64/boot/dts/qcom/quin-vm-common.dtsi diff --git a/arch/arm64/boot/dts/qcom/quin-vm-common.dtsi b/arch/arm64/boot/dts/qcom/quin-vm-common.dtsi new file mode 100644 index 000000000000..3d353aa5dfca --- /dev/null +++ b/arch/arm64/boot/dts/qcom/quin-vm-common.dtsi @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/ { + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + chosen { + bootargs = "rcupdate.rcu_expedited=1 rcu_nocbs=0-7 cgroup.memory=nokmem,nosocket"; + }; + + soc: soc { }; + + reserved_memory: reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + /* global autoconfigured region for contiguous allocations */ + linux,cma { + compatible = "shared-dma-pool"; + alloc-ranges = <0x0 0x00000000 0x0 0xffffffff>; + reusable; + alignment = <0x0 0x400000>; + size = <0x0 0x2000000>; + linux,cma-default; + }; + + qseecom_mem: qseecom_region@0x9e400000 { + compatible = "shared-dma-pool"; + alloc-ranges = <0 0x00000000 0 0xffffffff>; + reusable; + alignment = <0 0x400000>; + size = <0 0x1400000>; + }; + + qseecom_ta_mem: qseecom_ta_region { + compatible = "shared-dma-pool"; + alloc-ranges = <0 0x00000000 0 0xffffffff>; + reusable; + alignment = <0 0x400000>; + size = <0 0x1000000>; + }; + }; + + firmware: firmware { + android { + compatible = "android,firmware"; + vbmeta { + compatible = "android,vbmeta"; + parts = "vbmeta,boot,system,vendor,dtbo"; + }; + fstab { + compatible = "android,fstab"; + vendor { + compatible = "android,vendor"; + dev="/dev/block/platform/vdevs/1c0f0000.virtio_blk/vdc"; + type = "ext4"; + mnt_flags = "ro,barrier=1,discard"; + fsmgr_flags = "wait"; + status = "ok"; + }; + }; + }; + }; +}; + +&soc { + #address-cells = <1>; + #size-cells = <1>; + virtual-interrupt-parent = "gic"; + ranges = <0 0 0 0xffffffff>; + compatible = "simple-bus"; + + clock_gcc: qcom,gcc { + compatible = "qcom,dummycc"; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + clock_rpmh: qcom,rpmh { + compatible = "qcom,dummycc"; + #clock-cells = <1>; + }; + + qcom,ion { + compatible = "qcom,msm-ion"; + #address-cells = <1>; + #size-cells = <0>; + + system_heap: qcom,ion-heap@25 { + reg = <25>; + qcom,ion-heap-type = "SYSTEM"; + }; + + qcom,ion-heap@27 { /* QSEECOM HEAP */ + reg = <27>; + memory-region = <&qseecom_mem>; + qcom,ion-heap-type = "DMA"; + }; + + qcom,ion-heap@19 { /* QSEECOM TA HEAP */ + reg = <19>; + memory-region = <&qseecom_ta_mem>; + qcom,ion-heap-type = "DMA"; + }; + }; + + hab: qcom,hab { + compatible = "qcom,hab"; + vmid = <2>; + + mmidgrp100: mmidgrp100 { + grp-start-id = <100>; + role = "fe"; + remote-vmids = <0>; + }; + + mmidgrp200: mmidgrp200 { + grp-start-id = <200>; + role = "fe"; + remote-vmids = <0>; + }; + + mmidgrp300: mmidgrp300 { + grp-start-id = <300>; + role = "fe"; + remote-vmids = <0>; + }; + + mmidgrp400: mmidgrp400 { + grp-start-id = <400>; + role = "fe"; + remote-vmids = <0>; + }; + + mmidgrp500: mmidgrp500 { + grp-start-id = <500>; + role = "fe"; + remote-vmids = <0>; + }; + + mmidgrp600: mmidgrp600 { + grp-start-id = <600>; + role = "fe"; + remote-vmids = <0>; + }; + + mmidgrp700: mmidgrp700 { + grp-start-id = <700>; + role = "fe"; + remote-vmids = <0>; + }; + + mmidgrp800: mmidgrp800 { + grp-start-id = <800>; + role = "fe"; + remote-vmids = <0>; + }; + + mmidgrp900: mmidgrp900 { + grp-start-id = <900>; + role = "fe"; + remote-vmids = <0>; + }; + + mmidgrp1000: mmidgrp1000 { + grp-start-id = <1000>; + role = "fe"; + remote-vmids = <0>; + }; + }; + + sde_kms_hyp: qcom,sde_kms_hyp@ae00000 { + compatible = "qcom,sde-kms-hyp"; + qcom,client-id = "7815"; + }; + + wdog: qcom,wdt@17c10000{ + compatible = "qcom,msm-watchdog"; + reg = <0x17c10000 0x1000>; + reg-names = "wdt-base"; + interrupts = <0 0 0>, <0 1 0>; + qcom,bark-time = <11000>; + qcom,pet-time = <9360>; + qcom,ipi-ping; + qcom,wakeup-enable; + qcom,scandump-sizes = <0x10100 0x10100 0x10100 0x10100 + 0x18100 0x18100 0x18100 0x18100>; + }; + + qcom,msm-imem@14680000 { + compatible = "qcom,msm-imem"; + reg = <0x14680000 0x1000>; + ranges = <0x0 0x14680000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + + mem_dump_table@10 { + compatible = "qcom,msm-imem-mem_dump_table"; + reg = <0x10 8>; + }; + + restart_reason@65c { + compatible = "qcom,msm-imem-restart_reason"; + reg = <0x65c 4>; + }; + + dload_type@1c { + compatible = "qcom,msm-imem-dload-type"; + reg = <0x1c 0x4>; + }; + + boot_stats@6b0 { + compatible = "qcom,msm-imem-boot_stats"; + reg = <0x6b0 32>; + }; + + kaslr_offset@6d0 { + compatible = "qcom,msm-imem-kaslr_offset"; + reg = <0x6d0 12>; + }; + + pil@94c { + compatible = "qcom,msm-imem-pil"; + reg = <0x94c 200>; + }; + + diag_dload@c8 { + compatible = "qcom,msm-imem-diag-dload"; + reg = <0xc8 200>; + }; + }; + + vm_restart: restart { + compatible = "qcom,vm-restart"; + status = "ok"; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi b/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi index 9a271d717613..1e2ee1852dd7 100644 --- a/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi @@ -16,6 +16,7 @@ #include #include #include +#include "quin-vm-common.dtsi" / { model = "Qualcomm Technologies, Inc. SA6155P Virtual Machine"; @@ -26,83 +27,16 @@ pci-domain0 = &pcie0; /* PCIe0 domain */ }; - psci { - compatible = "arm,psci-1.0"; - method = "smc"; - }; - - chosen { - bootargs = "rcupdate.rcu_expedited=1 rcu_nocbs=0-7 cgroup.memory=nokmem,nosocket"; - }; - - soc: soc { }; - reserved_memory: reserved-memory { - #address-cells = <2>; - #size-cells = <2>; - ranges; - - /* global autoconfigured region for contiguous allocations */ - linux,cma { - compatible = "shared-dma-pool"; - alloc-ranges = <0x0 0x00000000 0x0 0xffffffff>; - reusable; - alignment = <0x0 0x400000>; - size = <0x0 0x2000000>; - linux,cma-default; - }; pmem_shared: pmem_shared_region@a1600000 { reg = <0x0 0xa1600000 0x0 0x20000000>; label = "pmem_shared_mem"; }; - - qseecom_mem: qseecom_region@0x9e400000 { - compatible = "shared-dma-pool"; - alloc-ranges = <0 0x00000000 0 0xffffffff>; - reusable; - alignment = <0 0x400000>; - size = <0 0x1400000>; - }; - - qseecom_ta_mem: qseecom_ta_region { - compatible = "shared-dma-pool"; - alloc-ranges = <0 0x00000000 0 0xffffffff>; - reusable; - alignment = <0 0x400000>; - size = <0 0x1000000>; - }; - }; - - firmware: firmware { - android { - compatible = "android,firmware"; - vbmeta { - compatible = "android,vbmeta"; - parts = "vbmeta,boot,system,vendor,dtbo"; - }; - fstab { - compatible = "android,fstab"; - vendor { - compatible = "android,vendor"; - dev="/dev/block/platform/vdevs/1c0f0000.virtio_blk/vdc"; - type = "ext4"; - mnt_flags = "ro,barrier=1,discard"; - fsmgr_flags = "wait"; - status = "ok"; - }; - }; - }; }; }; &soc { - #address-cells = <1>; - #size-cells = <1>; - virtual-interrupt-parent = "gic"; - ranges = <0 0 0 0xffffffff>; - compatible = "simple-bus"; - clock_virt: qcom,virt-gcc { compatible = "qcom,virt-clk-sm6150-gcc"; #clock-cells = <1>; @@ -115,110 +49,6 @@ #reset-cells = <1>; }; - clock_gcc: qcom,gcc { - compatible = "qcom,dummycc"; - #clock-cells = <1>; - #reset-cells = <1>; - }; - - clock_rpmh: qcom,rpmh { - compatible = "qcom,dummycc"; - #clock-cells = <1>; - }; - - qcom,ion { - compatible = "qcom,msm-ion"; - #address-cells = <1>; - #size-cells = <0>; - - system_heap: qcom,ion-heap@25 { - reg = <25>; - qcom,ion-heap-type = "SYSTEM"; - }; - - qcom,ion-heap@27 { /* QSEECOM HEAP */ - reg = <27>; - memory-region = <&qseecom_mem>; - qcom,ion-heap-type = "DMA"; - }; - - qcom,ion-heap@19 { /* QSEECOM TA HEAP */ - reg = <19>; - memory-region = <&qseecom_ta_mem>; - qcom,ion-heap-type = "DMA"; - }; - }; - - qcom,hab { - compatible = "qcom,hab"; - vmid = <2>; - - mmidgrp100: mmidgrp100 { - grp-start-id = <100>; - role = "fe"; - remote-vmids = <0>; - }; - - mmidgrp200: mmidgrp200 { - grp-start-id = <200>; - role = "fe"; - remote-vmids = <0>; - }; - - mmidgrp300: mmidgrp300 { - grp-start-id = <300>; - role = "fe"; - remote-vmids = <0>; - }; - - mmidgrp400: mmidgrp400 { - grp-start-id = <400>; - role = "fe"; - remote-vmids = <0>; - }; - - mmidgrp500: mmidgrp500 { - grp-start-id = <500>; - role = "fe"; - remote-vmids = <0>; - }; - - mmidgrp600: mmidgrp600 { - grp-start-id = <600>; - role = "fe"; - remote-vmids = <0>; - }; - - mmidgrp700: mmidgrp700 { - grp-start-id = <700>; - role = "fe"; - remote-vmids = <0>; - }; - - mmidgrp800: mmidgrp800 { - grp-start-id = <800>; - role = "fe"; - remote-vmids = <0>; - }; - - mmidgrp900: mmidgrp900 { - grp-start-id = <900>; - role = "fe"; - remote-vmids = <0>; - }; - - mmidgrp1000: mmidgrp1000 { - grp-start-id = <1000>; - role = "fe"; - remote-vmids = <0>; - }; - }; - - sde_kms_hyp: qcom,sde_kms_hyp@ae00000 { - compatible = "qcom,sde-kms-hyp"; - qcom,client-id = "7815"; - }; - apps_smmu: apps-smmu@0x15000000 { compatible = "qcom,qsmmu-v500"; reg = <0x15000000 0x80000>, diff --git a/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi b/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi index 9f8882698ea6..be8537c57965 100644 --- a/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi @@ -8,6 +8,7 @@ #include #include #include +#include "quin-vm-common.dtsi" / { model = "Qualcomm Technologies, Inc. SA8155 Virtual Machine"; @@ -18,83 +19,16 @@ pci-domain0 = &pcie0; /* PCIe0 domain */ }; - psci { - compatible = "arm,psci-1.0"; - method = "smc"; - }; - - chosen { - bootargs = "rcupdate.rcu_expedited=1 rcu_nocbs=0-7 cgroup.memory=nokmem,nosocket"; - }; - - soc: soc { }; - reserved_memory: reserved-memory { - #address-cells = <2>; - #size-cells = <2>; - ranges; - - /* global autoconfigured region for contiguous allocations */ - linux,cma { - compatible = "shared-dma-pool"; - alloc-ranges = <0x0 0x00000000 0x0 0xffffffff>; - reusable; - alignment = <0x0 0x400000>; - size = <0x0 0x2000000>; - linux,cma-default; - }; pmem_shared: pmem_shared_region@a0000000 { reg = <0x0 0xa0000000 0x0 0x20000000>; label = "pmem_shared_mem"; }; - - qseecom_mem: qseecom_region@0x9e400000 { - compatible = "shared-dma-pool"; - alloc-ranges = <0 0x00000000 0 0xffffffff>; - reusable; - alignment = <0 0x400000>; - size = <0 0x1400000>; - }; - - qseecom_ta_mem: qseecom_ta_region { - compatible = "shared-dma-pool"; - alloc-ranges = <0x0 0x00000000 0x0 0xffffffff>; - reusable; - alignment = <0x0 0x400000>; - size = <0x0 0x1000000>; - }; - }; - - firmware: firmware { - android { - compatible = "android,firmware"; - vbmeta { - compatible = "android,vbmeta"; - parts = "vbmeta,boot,system,vendor,dtbo"; - }; - fstab { - compatible = "android,fstab"; - vendor { - compatible = "android,vendor"; - dev="/dev/block/platform/vdevs/1c0f0000.virtio_blk/vdc"; - type = "ext4"; - mnt_flags = "ro,barrier=1,discard"; - fsmgr_flags = "wait"; - status = "ok"; - }; - }; - }; }; }; &soc { - #address-cells = <1>; - #size-cells = <1>; - virtual-interrupt-parent = "gic"; - ranges = <0 0 0 0xffffffff>; - compatible = "simple-bus"; - clock_virt: qcom,virtio-gcc { compatible = "virtio,mmio"; reg = <0x1c200000 0x1000>; @@ -111,111 +45,6 @@ #reset-cells = <1>; }; - clock_gcc: qcom,gcc { - compatible = "qcom,dummycc"; - #clock-cells = <1>; - #reset-cells = <1>; - }; - - clock_rpmh: qcom,rpmh { - compatible = "qcom,dummycc"; - #clock-cells = <1>; - }; - - qcom,ion { - compatible = "qcom,msm-ion"; - #address-cells = <1>; - #size-cells = <0>; - - system_heap: qcom,ion-heap@25 { - reg = <25>; - qcom,ion-heap-type = "SYSTEM"; - }; - - qcom,ion-heap@27 { /* QSEECOM HEAP */ - reg = <27>; - memory-region = <&qseecom_mem>; - qcom,ion-heap-type = "DMA"; - }; - - qcom,ion-heap@19 { /* QSEECOM TA HEAP */ - reg = <19>; - memory-region = <&qseecom_ta_mem>; - qcom,ion-heap-type = "DMA"; - }; - - }; - - hab: qcom,hab { - compatible = "qcom,hab"; - vmid = <2>; - - mmidgrp100: mmidgrp100 { - grp-start-id = <100>; - role = "fe"; - remote-vmids = <0>; - }; - - mmidgrp200: mmidgrp200 { - grp-start-id = <200>; - role = "fe"; - remote-vmids = <0>; - }; - - mmidgrp300: mmidgrp300 { - grp-start-id = <300>; - role = "fe"; - remote-vmids = <0>; - }; - - mmidgrp400: mmidgrp400 { - grp-start-id = <400>; - role = "fe"; - remote-vmids = <0>; - }; - - mmidgrp500: mmidgrp500 { - grp-start-id = <500>; - role = "fe"; - remote-vmids = <0>; - }; - - mmidgrp600: mmidgrp600 { - grp-start-id = <600>; - role = "fe"; - remote-vmids = <0>; - }; - - mmidgrp700: mmidgrp700 { - grp-start-id = <700>; - role = "fe"; - remote-vmids = <0>; - }; - - mmidgrp800: mmidgrp800 { - grp-start-id = <800>; - role = "fe"; - remote-vmids = <0>; - }; - - mmidgrp900: mmidgrp900 { - grp-start-id = <900>; - role = "fe"; - remote-vmids = <0>; - }; - - mmidgrp1000: mmidgrp1000 { - grp-start-id = <1000>; - role = "fe"; - remote-vmids = <0>; - }; - }; - - sde_kms_hyp: qcom,sde_kms_hyp@ae00000 { - compatible = "qcom,sde-kms-hyp"; - qcom,client-id = "7815"; - }; - apps_smmu: apps-smmu@0x15000000 { compatible = "qcom,qsmmu-v500"; reg = <0x15000000 0x100000>, @@ -489,67 +318,6 @@ status = "ok"; }; - wdog: qcom,wdt@17c10000{ - compatible = "qcom,msm-watchdog"; - reg = <0x17c10000 0x1000>; - reg-names = "wdt-base"; - interrupts = <0 0 0>, <0 1 0>; - qcom,bark-time = <11000>; - qcom,pet-time = <9360>; - qcom,ipi-ping; - qcom,wakeup-enable; - qcom,scandump-sizes = <0x10100 0x10100 0x10100 0x10100 - 0x18100 0x18100 0x18100 0x18100>; - }; - - qcom,msm-imem@14680000 { - compatible = "qcom,msm-imem"; - reg = <0x14680000 0x1000>; - ranges = <0x0 0x14680000 0x1000>; - #address-cells = <1>; - #size-cells = <1>; - - mem_dump_table@10 { - compatible = "qcom,msm-imem-mem_dump_table"; - reg = <0x10 8>; - }; - - restart_reason@65c { - compatible = "qcom,msm-imem-restart_reason"; - reg = <0x65c 4>; - }; - - dload_type@1c { - compatible = "qcom,msm-imem-dload-type"; - reg = <0x1c 0x4>; - }; - - boot_stats@6b0 { - compatible = "qcom,msm-imem-boot_stats"; - reg = <0x6b0 32>; - }; - - kaslr_offset@6d0 { - compatible = "qcom,msm-imem-kaslr_offset"; - reg = <0x6d0 12>; - }; - - pil@94c { - compatible = "qcom,msm-imem-pil"; - reg = <0x94c 200>; - }; - - diag_dload@c8 { - compatible = "qcom,msm-imem-diag-dload"; - reg = <0xc8 200>; - }; - }; - - vm_restart: restart { - compatible = "qcom,vm-restart"; - status = "ok"; - }; - qcom,cnss-qca-converged { compatible = "qcom,cnss-qca-converged"; diff --git a/arch/arm64/boot/dts/qcom/sa8195-vm.dtsi b/arch/arm64/boot/dts/qcom/sa8195-vm.dtsi index 6764393a4210..12c910533271 100644 --- a/arch/arm64/boot/dts/qcom/sa8195-vm.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8195-vm.dtsi @@ -14,73 +14,23 @@ #include #include #include +#include "quin-vm-common.dtsi" / { model = "Qualcomm Technologies, Inc. SA8195 Virtual Machine"; qcom,msm-name = "SA8195P"; qcom,msm-id = <405 0x20000>; - psci { - compatible = "arm,psci-1.0"; - method = "smc"; - }; - - chosen { - bootargs = "rcupdate.rcu_expedited=1 rcu_nocbs=0-7 cgroup.memory=nokmem,nosocket"; - }; - - soc: soc { }; - reserved_memory: reserved-memory { - #address-cells = <2>; - #size-cells = <2>; - ranges; - - /* global autoconfigured region for contiguous allocations */ - linux,cma { - compatible = "shared-dma-pool"; - alloc-ranges = <0x0 0x00000000 0x0 0xffffffff>; - reusable; - alignment = <0x0 0x400000>; - size = <0x0 0x2000000>; - linux,cma-default; - }; pmem_shared: pmem_shared_region@a0000000 { reg = <0x0 0xa0000000 0x0 0x20000000>; label = "pmem_shared_mem"; }; }; - - firmware: firmware { - android { - compatible = "android,firmware"; - vbmeta { - compatible = "android,vbmeta"; - parts = "vbmeta,boot,system,vendor,dtbo"; - }; - fstab { - compatible = "android,fstab"; - vendor { - compatible = "android,vendor"; - dev="/dev/block/platform/vdevs/1c0f0000.virtio_blk/vdc"; - type = "ext4"; - mnt_flags = "ro,barrier=1,discard"; - fsmgr_flags = "wait"; - status = "ok"; - }; - }; - }; - }; }; &soc { - #address-cells = <1>; - #size-cells = <1>; - virtual-interrupt-parent = "gic"; - ranges = <0 0 0 0xffffffff>; - compatible = "simple-bus"; - clock_virt: qcom,virt-gcc { compatible = "qcom,virt-clk-sm8150-gcc"; #clock-cells = <1>; @@ -93,93 +43,6 @@ #reset-cells = <1>; }; - clock_gcc: qcom,gcc { - compatible = "qcom,dummycc"; - #clock-cells = <1>; - #reset-cells = <1>; - }; - - qcom,ion { - compatible = "qcom,msm-ion"; - #address-cells = <1>; - #size-cells = <0>; - - system_heap: qcom,ion-heap@25 { - reg = <25>; - qcom,ion-heap-type = "SYSTEM"; - }; - }; - - qcom,hab { - compatible = "qcom,hab"; - vmid = <2>; - - mmidgrp100: mmidgrp100 { - grp-start-id = <100>; - role = "fe"; - remote-vmids = <0>; - }; - - mmidgrp200: mmidgrp200 { - grp-start-id = <200>; - role = "fe"; - remote-vmids = <0>; - }; - - mmidgrp300: mmidgrp300 { - grp-start-id = <300>; - role = "fe"; - remote-vmids = <0>; - }; - - mmidgrp400: mmidgrp400 { - grp-start-id = <400>; - role = "fe"; - remote-vmids = <0>; - }; - - mmidgrp500: mmidgrp500 { - grp-start-id = <500>; - role = "fe"; - remote-vmids = <0>; - }; - - mmidgrp600: mmidgrp600 { - grp-start-id = <600>; - role = "fe"; - remote-vmids = <0>; - }; - - mmidgrp700: mmidgrp700 { - grp-start-id = <700>; - role = "fe"; - remote-vmids = <0>; - }; - - mmidgrp800: mmidgrp800 { - grp-start-id = <800>; - role = "fe"; - remote-vmids = <0>; - }; - - mmidgrp900: mmidgrp900 { - grp-start-id = <900>; - role = "fe"; - remote-vmids = <0>; - }; - - mmidgrp1000: mmidgrp1000 { - grp-start-id = <1000>; - role = "fe"; - remote-vmids = <0>; - }; - }; - - sde_kms_hyp: qcom,sde_kms_hyp@ae00000 { - compatible = "qcom,sde-kms-hyp"; - qcom,client-id = "7815"; - }; - apps_smmu: apps-smmu@0x15000000 { compatible = "qcom,qsmmu-v500"; reg = <0x15000000 0x100000>, -- GitLab From b81c4927c9f1ce421ba218b52419cdd0138b3436 Mon Sep 17 00:00:00 2001 From: Bhuvan Varshney Date: Mon, 17 Jun 2019 18:41:54 +0530 Subject: [PATCH 0690/1121] NFC: Fix device node probing issue Probing fails after retrying maximum times to receive response for NCI core reset command. Changed method of receiving response from poll mode to interrupt mode to receive response of the NCI commands sent. Change-Id: I41b0fc8e99fc31fd8b573549a21087737f540ed8 Signed-off-by: Bhuvan Varshney --- drivers/nfc/nq-nci.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/nfc/nq-nci.c b/drivers/nfc/nq-nci.c index 4f46155cf22a..19829a9a8623 100644 --- a/drivers/nfc/nq-nci.c +++ b/drivers/nfc/nq-nci.c @@ -841,6 +841,9 @@ static int nfcc_hw_check(struct i2c_client *client, struct nqx_dev *nqx_dev) reset_enable_gpio: /* making sure that the NFCC starts in a clean state. */ + gpio_set_value(enable_gpio, 1);/* HPD : Enable*/ + /* hardware dependent delay */ + usleep_range(10000, 10100); gpio_set_value(enable_gpio, 0);/* ULPM: Disable */ /* hardware dependent delay */ usleep_range(10000, 10100); @@ -906,8 +909,12 @@ static int nfcc_hw_check(struct i2c_client *client, struct nqx_dev *nqx_dev) } goto err_nfcc_reset_failed; } - /* hardware dependent delay */ - msleep(30); + nqx_enable_irq(nqx_dev); + ret = wait_event_interruptible(nqx_dev->read_wq, !nqx_dev->irq_enabled); + if (ret < 0) { + nqx_disable_irq(nqx_dev); + goto err_nfcc_hw_check; + } /* Read Response of RESET command */ ret = i2c_master_recv(client, nci_reset_rsp, NCI_RESET_RSP_LEN); @@ -919,9 +926,12 @@ static int nfcc_hw_check(struct i2c_client *client, struct nqx_dev *nqx_dev) goto reset_enable_gpio; goto err_nfcc_hw_check; } - - /* hardware dependent delay */ - msleep(30); + nqx_enable_irq(nqx_dev); + ret = wait_event_interruptible(nqx_dev->read_wq, !nqx_dev->irq_enabled); + if (ret < 0) { + nqx_disable_irq(nqx_dev); + goto err_nfcc_hw_check; + } /* Read Notification of RESET command */ ret = i2c_master_recv(client, nci_reset_ntf, NCI_RESET_NTF_LEN); -- GitLab From 65d32c91e11571fd04e8ea03585ce661ca66653f Mon Sep 17 00:00:00 2001 From: Bojun Pan Date: Thu, 20 Jun 2019 15:25:50 -0700 Subject: [PATCH 0691/1121] msm: IPA4: Enable MHI Proxy on msm-4.14 master branch Android Q update, enable MHI Proxy on msm-4.14 master branch. Change-Id: Ib3cb6d198ee2e1d59a3f51d4678879e684c16f14 Signed-off-by: Bojun Pan --- arch/arm64/configs/vendor/sm8150-perf_defconfig | 1 + arch/arm64/configs/vendor/sm8150_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm64/configs/vendor/sm8150-perf_defconfig b/arch/arm64/configs/vendor/sm8150-perf_defconfig index ff178c26a817..21918d41533f 100644 --- a/arch/arm64/configs/vendor/sm8150-perf_defconfig +++ b/arch/arm64/configs/vendor/sm8150-perf_defconfig @@ -515,6 +515,7 @@ CONFIG_IPA3=y CONFIG_IPA_WDI_UNIFIED_API=y CONFIG_RMNET_IPA3=y CONFIG_RNDIS_IPA=y +CONFIG_IPA3_MHI_PROXY=y CONFIG_IPA3_MHI_PRIME_MANAGER=y CONFIG_IPA_UT=y CONFIG_MSM_11AD=m diff --git a/arch/arm64/configs/vendor/sm8150_defconfig b/arch/arm64/configs/vendor/sm8150_defconfig index 026aa27ae87c..44bd6ad2404c 100644 --- a/arch/arm64/configs/vendor/sm8150_defconfig +++ b/arch/arm64/configs/vendor/sm8150_defconfig @@ -539,6 +539,7 @@ CONFIG_IPA_DEBUG=y CONFIG_IPA_WDI_UNIFIED_API=y CONFIG_RMNET_IPA3=y CONFIG_RNDIS_IPA=y +CONFIG_IPA3_MHI_PROXY=y CONFIG_IPA3_MHI_PRIME_MANAGER=y CONFIG_IPA_UT=y CONFIG_MSM_11AD=m -- GitLab From 1702b2d6c69e58d8e5511feb906272251e8f7414 Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Mon, 17 Jun 2019 16:58:21 -0700 Subject: [PATCH 0692/1121] pinctrl: qcom: Add direct connect configuration support for sdmshrike Provide the direct connect interrupt array. This array is used to associate GPIOs with the TLMM tile's direct connect hardware interrupt. Change-Id: I66daf2b1fd33029a50dddd7c225b7c00a0ad9676 Signed-off-by: Anant Goel --- drivers/pinctrl/qcom/pinctrl-sdmshrike.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/pinctrl/qcom/pinctrl-sdmshrike.c b/drivers/pinctrl/qcom/pinctrl-sdmshrike.c index 2212eb334f41..e1b753d225b5 100644 --- a/drivers/pinctrl/qcom/pinctrl-sdmshrike.c +++ b/drivers/pinctrl/qcom/pinctrl-sdmshrike.c @@ -55,6 +55,9 @@ .intr_cfg_reg = base + 0x8 + REG_SIZE * id, \ .intr_status_reg = base + 0xc + REG_SIZE * id, \ .intr_target_reg = base + 0x8 + REG_SIZE * id, \ + .dir_conn_reg = (base == EAST) ? base + 0xcc000 : \ + ((base == WEST) ? base + 0xcc000 : \ + ((base == NORTH) ? EAST + 0xcc000 : base + 0xcd000)), \ .mux_bit = 2, \ .pull_bit = 0, \ .drv_bit = 6, \ @@ -69,6 +72,7 @@ .intr_polarity_bit = 1, \ .intr_detection_bit = 2, \ .intr_detection_width = 2, \ + .dir_conn_en_bit = 8, \ } #define SDC_QDSD_PINGROUP(pg_name, ctl, pull, drv) \ @@ -2240,6 +2244,17 @@ static const struct msm_pingroup sdmshrike_groups[] = { [193] = UFS_RESET(ufs_reset, 0xdb6004), }; +static struct msm_dir_conn sdmshrike_dir_conn[] = { + {-1, 216}, + {-1, 215}, + {-1, 214}, + {-1, 213}, + {-1, 212}, + {-1, 211}, + {-1, 210}, + {-1, 209}, +}; + static const struct msm_pinctrl_soc_data sdmshrike_pinctrl = { .pins = sdmshrike_pins, .npins = ARRAY_SIZE(sdmshrike_pins), @@ -2248,6 +2263,9 @@ static const struct msm_pinctrl_soc_data sdmshrike_pinctrl = { .groups = sdmshrike_groups, .ngroups = ARRAY_SIZE(sdmshrike_groups), .ngpios = 190, + .dir_conn = sdmshrike_dir_conn, + .n_dir_conns = ARRAY_SIZE(sdmshrike_dir_conn), + .dir_conn_irq_base = 216, }; static int sdmshrike_pinctrl_probe(struct platform_device *pdev) -- GitLab From 697185ee143644302214679630fa7c4f7b95d307 Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Tue, 25 Jun 2019 15:04:29 -0700 Subject: [PATCH 0693/1121] ARM: dts: msm: Add cDSP, adsprpc, and fastrpc nodes to sdmshrike Provide entries for the cDSP loader, adsprpc memory region, and fastrpc compute context banks for the sdmshrike target. Change-Id: I93c2db94e0b3dfb753a0ad74d2c664641043138e Signed-off-by: Anant Goel --- arch/arm64/boot/dts/qcom/sdmshrike.dtsi | 135 ++++++++++++++++++++++++ 1 file changed, 135 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdmshrike.dtsi b/arch/arm64/boot/dts/qcom/sdmshrike.dtsi index 10adcd5b3833..46a32adabb65 100644 --- a/arch/arm64/boot/dts/qcom/sdmshrike.dtsi +++ b/arch/arm64/boot/dts/qcom/sdmshrike.dtsi @@ -1909,6 +1909,141 @@ status = "disabled"; }; + qcom,msm-cdsp-loader { + compatible = "qcom,cdsp-loader"; + qcom,proc-img-to-load = "cdsp"; + }; + + qcom,msm-adsprpc-mem { + compatible = "qcom,msm-adsprpc-mem-region"; + memory-region = <&adsp_mem>; + }; + + msm_fastrpc: qcom,msm_fastrpc { + compatible = "qcom,msm-fastrpc-compute"; + qcom,fastrpc-adsp-audio-pdr; + qcom,rpc-latency-us = <235>; + + qcom,msm_fastrpc_compute_cb1 { + compatible = "qcom,msm-fastrpc-compute-cb"; + label = "cdsprpc-smd"; + iommus = <&apps_smmu 0x1401 0x2040>, + <&apps_smmu 0x1421 0x0>, + <&apps_smmu 0x2001 0x420>, + <&apps_smmu 0x2041 0x0>; + dma-coherent; + }; + + qcom,msm_fastrpc_compute_cb4 { + compatible = "qcom,msm-fastrpc-compute-cb"; + label = "cdsprpc-smd"; + iommus = <&apps_smmu 0x4 0x3440>, + <&apps_smmu 0x24 0x3400>; + dma-coherent; + }; + + qcom,msm_fastrpc_compute_cb5 { + compatible = "qcom,msm-fastrpc-compute-cb"; + label = "cdsprpc-smd"; + iommus = <&apps_smmu 0x5 0x3440>, + <&apps_smmu 0x25 0x3400>; + dma-coherent; + }; + + qcom,msm_fastrpc_compute_cb6 { + compatible = "qcom,msm-fastrpc-compute-cb"; + label = "cdsprpc-smd"; + iommus = <&apps_smmu 0x6 0x3460>; + dma-coherent; + }; + + qcom,msm_fastrpc_compute_cb7 { + compatible = "qcom,msm-fastrpc-compute-cb"; + label = "cdsprpc-smd"; + iommus = <&apps_smmu 0x7 0x3460>; + dma-coherent; + }; + + qcom,msm_fastrpc_compute_cb8 { + compatible = "qcom,msm-fastrpc-compute-cb"; + label = "cdsprpc-smd"; + iommus = <&apps_smmu 0x8 0x3460>; + dma-coherent; + }; + + qcom,msm_fastrpc_compute_cb2 { + compatible = "qcom,msm-fastrpc-compute-cb"; + label = "cdsprpc-smd"; + iommus = <&apps_smmu 0x2 0x3440>, + <&apps_smmu 0x22 0x3400>; + dma-coherent; + }; + + qcom,msm_fastrpc_compute_cb3 { + compatible = "qcom,msm-fastrpc-compute-cb"; + label = "cdsprpc-smd"; + iommus = <&apps_smmu 0x3 0x3440>, + <&apps_smmu 0x1423 0x0>, + <&apps_smmu 0x2023 0x0>; + dma-coherent; + }; + + qcom,msm_fastrpc_compute_cb9 { + compatible = "qcom,msm-fastrpc-compute-cb"; + label = "cdsprpc-smd"; + qcom,secure-context-bank; + iommus = <&apps_smmu 0x9 0x3460>; + dma-coherent; + }; + + qcom,msm_fastrpc_compute_cb10 { + compatible = "qcom,msm-fastrpc-compute-cb"; + label = "adsprpc-smd"; + iommus = <&apps_smmu 0x1b23 0x0>; + dma-coherent; + }; + + qcom,msm_fastrpc_compute_cb11 { + compatible = "qcom,msm-fastrpc-compute-cb"; + label = "adsprpc-smd"; + iommus = <&apps_smmu 0x1b24 0x0>; + dma-coherent; + }; + + qcom,msm_fastrpc_compute_cb12 { + compatible = "qcom,msm-fastrpc-compute-cb"; + label = "adsprpc-smd"; + iommus = <&apps_smmu 0x1b25 0x0>; + dma-coherent; + }; + + qcom,msm_fastrpc_compute_cb13 { + compatible = "qcom,msm-fastrpc-compute-cb"; + label = "sdsprpc-smd"; + iommus = <&apps_smmu 0x5a1 0x0>; + dma-coherent; + }; + + qcom,msm_fastrpc_compute_cb14 { + compatible = "qcom,msm-fastrpc-compute-cb"; + label = "sdsprpc-smd"; + iommus = <&apps_smmu 0x5a2 0x0>; + dma-coherent; + }; + + qcom,msm_fastrpc_compute_cb15 { + compatible = "qcom,msm-fastrpc-compute-cb"; + label = "sdsprpc-smd"; + iommus = <&apps_smmu 0x5a3 0x0>; + shared-cb = <4>; + dma-coherent; + }; + }; + + system_pm { + compatible = "qcom,system-pm"; + mboxes = <&apps_rsc 0>; + }; mem_dump { compatible = "qcom,mem-dump"; memory-region = <&dump_mem>; -- GitLab From 4803d1a3902cfabacc3b0aa5954ded0830169a21 Mon Sep 17 00:00:00 2001 From: Sujeev Dias Date: Tue, 25 Jun 2019 13:40:48 -0700 Subject: [PATCH 0694/1121] arm: io: add missing read and write no_log variants Add missing read and write no_log macros for support in 32-bit arm. CRs-Fixed: 2478833 Change-Id: Ib265c53201fe56c532287b4c9456b2adcf81827b Acked-by: Bhaumik Vasav Bhatt Signed-off-by: Sujeev Dias --- arch/arm/include/asm/io.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index 932606488408..c61b1db9e4c9 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h @@ -401,6 +401,24 @@ extern void _memset_io(volatile void __iomem *, int, size_t); #define writesw(p,d,l) __raw_writesw(p,d,l) #define writesl(p,d,l) __raw_writesl(p,d,l) +#define readb_no_log(c) \ + ({ u8 __v = readb_relaxed_no_log(c); __iormb(); __v; }) +#define readw_no_log(c) \ + ({ u16 __v = readw_relaxed_no_log(c); __iormb(); __v; }) +#define readl_no_log(c) \ + ({ u32 __v = readl_relaxed_no_log(c); __iormb(); __v; }) +#define readq_no_log(c) \ + ({ u64 __v = readq_relaxed_no_log(c); __iormb(); __v; }) + +#define writeb_no_log(v, c) \ + ({ __iowmb(); writeb_relaxed_no_log((v), (c)); }) +#define writew_no_log(v, c) \ + ({ __iowmb(); writew_relaxed_no_log((v), (c)); }) +#define writel_no_log(v, c) \ + ({ __iowmb(); writel_relaxed_no_log((v), (c)); }) +#define writeq_no_log(v, c) \ + ({ __iowmb(); writeq_relaxed_no_log((v), (c)); }) + #ifndef __ARMBE__ static inline void memset_io(volatile void __iomem *dst, unsigned c, size_t count) -- GitLab From 0708e0efe315b15984aebf67f1bf5f860f1c0c68 Mon Sep 17 00:00:00 2001 From: Omkar Savagaonkar Date: Mon, 24 Jun 2019 15:01:44 +0530 Subject: [PATCH 0695/1121] msm: watchdog: Add hibernation support Currently watchdog code is registering to suspend and resume callbacks only. During hibernation lifecycle freeze, thaw and restore callbacks are called(dev_pm_ops).Hook up hibernation ops using macro SET_NOIRQ_SYSTEM_SLEEP_PM_OPS. Change-Id: I439d29d1cdcd85a4ab0841252bac888fb17498fc Signed-off-by: Omkar Savagaonkar --- drivers/soc/qcom/watchdog_v2.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/soc/qcom/watchdog_v2.c b/drivers/soc/qcom/watchdog_v2.c index 7a48f8386f0d..e0f768cf14b2 100644 --- a/drivers/soc/qcom/watchdog_v2.c +++ b/drivers/soc/qcom/watchdog_v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -922,8 +922,7 @@ static int msm_watchdog_probe(struct platform_device *pdev) } static const struct dev_pm_ops msm_watchdog_dev_pm_ops = { - .suspend_noirq = msm_watchdog_suspend, - .resume_noirq = msm_watchdog_resume, + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(msm_watchdog_suspend, msm_watchdog_resume) }; static struct platform_driver msm_watchdog_driver = { -- GitLab From ff0dcdcbbc1f3faee72cb144f21b34ff0994ee4e Mon Sep 17 00:00:00 2001 From: YUE CHEN Date: Thu, 20 Jun 2019 15:59:55 +0800 Subject: [PATCH 0696/1121] msm: ais: support setting framedrop by io config update hfr through IO config to set frame drop parameters Change-Id: I52eda48dcfc244d40e44cdf63d64687ed55ed51e Signed-off-by: YUE CHEN --- .../hw_utils/cam_isp_packet_parser.c | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c index 1b64913f0919..21b0d03075d1 100644 --- a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c +++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c @@ -686,7 +686,52 @@ int cam_isp_add_io_buffers( rc = -ENOMEM; return rc; } + io_cfg_used_bytes += update_buf.cmd.used_bytes; + + if ((kmd_buf_info->used_bytes + io_cfg_used_bytes) < + kmd_buf_info->size) { + kmd_buf_remain_size = kmd_buf_info->size - + (kmd_buf_info->used_bytes + + io_cfg_used_bytes); + } else { + CAM_ERR(CAM_ISP, + "no free kmd memory for base %d", + base_idx); + rc = -ENOMEM; + return rc; + } + + update_buf.res = res; + update_buf.cmd_type = CAM_ISP_HW_CMD_GET_HFR_UPDATE; + update_buf.cmd.cmd_buf_addr = kmd_buf_info->cpu_addr + + kmd_buf_info->used_bytes/4 + + io_cfg_used_bytes/4; + + update_buf.cmd.size = kmd_buf_remain_size; + update_buf.hfr_update->framedrop_pattern = + io_cfg[i].framedrop_pattern; + update_buf.hfr_update->framedrop_period = + io_cfg[i].framedrop_period; + update_buf.hfr_update->subsample_pattern = + io_cfg[i].subsample_pattern; + update_buf.hfr_update->subsample_period = + io_cfg[i].subsample_period; + + rc = res->hw_intf->hw_ops.process_cmd( + res->hw_intf->hw_priv, + CAM_ISP_HW_CMD_GET_HFR_UPDATE, &update_buf, + sizeof(struct cam_isp_hw_get_cmd_update)); + + if (rc) { + CAM_ERR(CAM_ISP, "get buf cmd error:%d", + res->res_id); + rc = -ENOMEM; + return rc; + } + + io_cfg_used_bytes += update_buf.cmd.used_bytes; + } for (j = 0; j < CAM_ISP_HW_SPLIT_MAX && io_cfg[i].direction == CAM_BUF_INPUT; j++) { -- GitLab From 00a66db7ff7c8e263f001d8599c50d73bd5f7280 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Wed, 26 Jun 2019 12:35:21 +0530 Subject: [PATCH 0697/1121] clk: qcom: sm8150: Remove usage of use_max_uV for voting The clock driver framework would always vote INT_MAX as the max corner for any voltage rail. Thus clean up the usage of use_max_uV from all clock drivers. Change-Id: I143217a927ff3f647ba88667b5b1164b958f9861 Signed-off-by: Taniya Das --- drivers/clk/qcom/camcc-sm8150.c | 1 - drivers/clk/qcom/dispcc-sm8150.c | 1 - drivers/clk/qcom/gcc-sm8150.c | 1 - drivers/clk/qcom/videocc-sm8150.c | 1 - 4 files changed, 4 deletions(-) diff --git a/drivers/clk/qcom/camcc-sm8150.c b/drivers/clk/qcom/camcc-sm8150.c index 7459b40a56c5..c49ac2115ef2 100644 --- a/drivers/clk/qcom/camcc-sm8150.c +++ b/drivers/clk/qcom/camcc-sm8150.c @@ -2494,7 +2494,6 @@ static int cam_cc_sm8150_probe(struct platform_device *pdev) "Unable to get vdd_mm regulator\n"); return PTR_ERR(vdd_mm.regulator[0]); } - vdd_mm.use_max_uV = true; camcc_bus_id = msm_bus_scale_register_client(&clk_debugfs_scale_table); if (!camcc_bus_id) { diff --git a/drivers/clk/qcom/dispcc-sm8150.c b/drivers/clk/qcom/dispcc-sm8150.c index ecb95bf864e2..343a8c1f084e 100644 --- a/drivers/clk/qcom/dispcc-sm8150.c +++ b/drivers/clk/qcom/dispcc-sm8150.c @@ -1637,7 +1637,6 @@ static int disp_cc_sm8150_probe(struct platform_device *pdev) "Unable to get vdd_mm regulator\n"); return PTR_ERR(vdd_mm.regulator[0]); } - vdd_mm.use_max_uV = true; dispcc_bus_id = msm_bus_scale_register_client(&clk_debugfs_scale_table); if (!dispcc_bus_id) { diff --git a/drivers/clk/qcom/gcc-sm8150.c b/drivers/clk/qcom/gcc-sm8150.c index 758fd30ac423..77d4e6e1a88c 100644 --- a/drivers/clk/qcom/gcc-sm8150.c +++ b/drivers/clk/qcom/gcc-sm8150.c @@ -4262,7 +4262,6 @@ static int gcc_sm8150_probe(struct platform_device *pdev) dev_err(&pdev->dev, "Unable to get vdd_mm regulator\n"); return PTR_ERR(vdd_mm.regulator[0]); } - vdd_mm.use_max_uV = true; /* register hardware clocks */ for (i = 0; i < ARRAY_SIZE(gcc_sm8150_hws); i++) { diff --git a/drivers/clk/qcom/videocc-sm8150.c b/drivers/clk/qcom/videocc-sm8150.c index b896e26a26ab..e26618f53824 100644 --- a/drivers/clk/qcom/videocc-sm8150.c +++ b/drivers/clk/qcom/videocc-sm8150.c @@ -374,7 +374,6 @@ static int video_cc_sm8150_probe(struct platform_device *pdev) dev_err(&pdev->dev, "Unable to get vdd_mm regulator\n"); return PTR_ERR(vdd_mm.regulator[0]); } - vdd_mm.use_max_uV = true; videocc_bus_id = msm_bus_scale_register_client(&clk_debugfs_scale_table); -- GitLab From 80386df9c15fc4ac1517c0d71b0b0c3f7ce00519 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Fri, 17 May 2019 13:27:17 +0530 Subject: [PATCH 0698/1121] clk: Always vote INT_MAX as maximum voltage for a rail Update regulator set voltage requests to always send INT_MAX as the max voltage, this will ensure clocks never set any upper bound request for any voltage regulator. This avoids regulator_set_voltage() failures arising from different regulator consumers specifying different max voltages. Change-Id: Ie803d45623dbc4b9b2c31502e240c311db261f66 Signed-off-by: Taniya Das --- drivers/clk/clk.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 07a9d39a6fa0..e68700ef36d5 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -572,8 +572,7 @@ static int clk_update_vdd(struct clk_vdd_class *vdd_class) for (i = 0; i < vdd_class->num_regulators; i++) { pr_debug("Set Voltage level Min %d, Max %d\n", uv[new_base + i], uv[max_lvl + i]); - rc = regulator_set_voltage(r[i], uv[new_base + i], - vdd_class->use_max_uV ? INT_MAX : uv[max_lvl + i]); + rc = regulator_set_voltage(r[i], uv[new_base + i], INT_MAX); if (rc) goto set_voltage_fail; @@ -594,13 +593,11 @@ static int clk_update_vdd(struct clk_vdd_class *vdd_class) return rc; enable_disable_fail: - regulator_set_voltage(r[i], uv[cur_base + i], - vdd_class->use_max_uV ? INT_MAX : uv[max_lvl + i]); + regulator_set_voltage(r[i], uv[cur_base + i], INT_MAX); set_voltage_fail: for (i--; i >= 0; i--) { - regulator_set_voltage(r[i], uv[cur_base + i], - vdd_class->use_max_uV ? INT_MAX : uv[max_lvl + i]); + regulator_set_voltage(r[i], uv[cur_base + i], INT_MAX); if (cur_lvl == 0 || cur_lvl == vdd_class->num_levels) regulator_disable(r[i]); else if (level == 0) -- GitLab From 6a207f4abac980fcab43c1943544eaeb109eb7ca Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Mon, 20 May 2019 09:34:16 +0530 Subject: [PATCH 0699/1121] clk: provider: cleanup of unused use_max_uV As clock framework now votes for INT_MAX default as maximum voltage, this variable is no longer being used. Thus cleanup the same. Change-Id: Iceaf32c90d9acae02f01c847a197d8dfbce99abd Signed-off-by: Taniya Das --- include/linux/clk-provider.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index b53b4812290a..4cd30f8ad907 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -310,7 +310,6 @@ struct regulator; * @level_votes: array of votes for each level * @num_levels: specifies the size of level_votes array * @skip_handoff: do not vote for the max possible voltage during init - * @use_max_uV: use INT_MAX for max_uV when calling regulator_set_voltage * @cur_level: the currently set voltage level * @lock: lock to protect this struct */ @@ -323,7 +322,6 @@ struct clk_vdd_class { int *level_votes; int num_levels; bool skip_handoff; - bool use_max_uV; unsigned long cur_level; struct mutex lock; }; -- GitLab From 691e2c8760299ee70ade49b13694264e5441bbc3 Mon Sep 17 00:00:00 2001 From: Prakasha Nayak Date: Mon, 22 Apr 2019 20:22:31 +0530 Subject: [PATCH 0700/1121] msm: camera: jpeg: Check the HW state before accessing register Check the hardware state before accessing registers to prevent unclocked access. Change-Id: Ie6cabd3bdf19d4404f5efdfa14390a76cb622bbe Signed-off-by: Prakasha Nayak --- .../jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c index 52907cd6803e..225f859674f1 100644 --- a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c +++ b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c @@ -91,6 +91,9 @@ int cam_jpeg_enc_init_hw(void *device_priv, CAM_ERR(CAM_JPEG, "soc enable is failed %d", rc); goto soc_failed; } + spin_lock(&jpeg_enc_dev->hw_lock); + jpeg_enc_dev->hw_state = CAM_HW_STATE_POWER_UP; + spin_unlock(&jpeg_enc_dev->hw_lock); mutex_unlock(&core_info->core_mutex); @@ -140,6 +143,9 @@ int cam_jpeg_enc_deinit_hw(void *device_priv, return -EFAULT; } + spin_lock(&jpeg_enc_dev->hw_lock); + jpeg_enc_dev->hw_state = CAM_HW_STATE_POWER_DOWN; + spin_unlock(&jpeg_enc_dev->hw_lock); rc = cam_jpeg_enc_disable_soc_resources(soc_info); if (rc) CAM_ERR(CAM_JPEG, "soc disable failed %d", rc); @@ -173,12 +179,19 @@ irqreturn_t cam_jpeg_enc_irq(int irq_num, void *data) hw_info = core_info->jpeg_enc_hw_info; mem_base = soc_info->reg_map[0].mem_base; + spin_lock(&jpeg_enc_dev->hw_lock); + if (jpeg_enc_dev->hw_state == CAM_HW_STATE_POWER_DOWN) { + CAM_ERR(CAM_JPEG, "JPEG HW is in off state"); + spin_unlock(&jpeg_enc_dev->hw_lock); + return -EINVAL; + } irq_status = cam_io_r_mb(mem_base + core_info->jpeg_enc_hw_info->reg_offset.int_status); cam_io_w_mb(irq_status, soc_info->reg_map[0].mem_base + core_info->jpeg_enc_hw_info->reg_offset.int_clr); + spin_unlock(&jpeg_enc_dev->hw_lock); CAM_DBG(CAM_JPEG, "irq_num %d irq_status = %x , core_state %d", irq_num, irq_status, core_info->core_state); @@ -268,6 +281,12 @@ int cam_jpeg_enc_reset_hw(void *data, mutex_lock(&core_info->core_mutex); spin_lock(&jpeg_enc_dev->hw_lock); + if (jpeg_enc_dev->hw_state == CAM_HW_STATE_POWER_DOWN) { + CAM_ERR(CAM_JPEG, "JPEG HW is in off state"); + spin_unlock(&jpeg_enc_dev->hw_lock); + mutex_unlock(&core_info->core_mutex); + return -EINVAL; + } if (core_info->core_state == CAM_JPEG_ENC_CORE_RESETTING) { CAM_ERR(CAM_JPEG, "alrady resetting"); spin_unlock(&jpeg_enc_dev->hw_lock); @@ -319,10 +338,18 @@ int cam_jpeg_enc_start_hw(void *data, hw_info = core_info->jpeg_enc_hw_info; mem_base = soc_info->reg_map[0].mem_base; + spin_lock(&jpeg_enc_dev->hw_lock); + if (jpeg_enc_dev->hw_state == CAM_HW_STATE_POWER_DOWN) { + CAM_ERR(CAM_JPEG, "JPEG HW is in off state"); + spin_unlock(&jpeg_enc_dev->hw_lock); + return -EINVAL; + } if (core_info->core_state != CAM_JPEG_ENC_CORE_READY) { CAM_ERR(CAM_JPEG, "Error not ready"); + spin_unlock(&jpeg_enc_dev->hw_lock); return -EINVAL; } + spin_unlock(&jpeg_enc_dev->hw_lock); cam_io_w_mb(hw_info->reg_val.hw_cmd_start, mem_base + hw_info->reg_offset.hw_cmd); @@ -352,6 +379,12 @@ int cam_jpeg_enc_stop_hw(void *data, mutex_lock(&core_info->core_mutex); spin_lock(&jpeg_enc_dev->hw_lock); + if (jpeg_enc_dev->hw_state == CAM_HW_STATE_POWER_DOWN) { + CAM_ERR(CAM_JPEG, "JPEG HW is in off state"); + spin_unlock(&jpeg_enc_dev->hw_lock); + mutex_unlock(&core_info->core_mutex); + return -EINVAL; + } if (core_info->core_state == CAM_JPEG_ENC_CORE_ABORTING) { CAM_ERR(CAM_JPEG, "alrady stopping"); spin_unlock(&jpeg_enc_dev->hw_lock); -- GitLab From c9e1a17629b9370c52f10e69574905125f049335 Mon Sep 17 00:00:00 2001 From: Ajay Agarwal Date: Mon, 27 May 2019 18:22:13 +0530 Subject: [PATCH 0701/1121] usb: Add support for 90fd PID Add 05c6 VID and 90fd PID with proper interface numbers to device ID tables of diag_bridge, qrtr USB and rmnet_usb drivers, so that the diag, IPC and RmNet functions can be probed by host on cable connect. Change-Id: Icbbd3578c6192eff267cf4610002b739601f0644 Signed-off-by: Ajay Agarwal --- drivers/usb/misc/diag_bridge.c | 2 ++ net/qrtr/usb.c | 1 + net/rmnet_usb/rmnet_usb.c | 8 ++++++++ 3 files changed, 11 insertions(+) diff --git a/drivers/usb/misc/diag_bridge.c b/drivers/usb/misc/diag_bridge.c index a5dec0800d63..eecea3704be1 100644 --- a/drivers/usb/misc/diag_bridge.c +++ b/drivers/usb/misc/diag_bridge.c @@ -646,6 +646,8 @@ static const struct usb_device_id diag_bridge_ids[] = { .driver_info = DEV_ID(1), }, { USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x90F3, 0), .driver_info = DEV_ID(0), }, + { USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x90FD, 0), + .driver_info = DEV_ID(0), }, {} /* terminating entry */ }; diff --git a/net/qrtr/usb.c b/net/qrtr/usb.c index 93566e395523..d475b3125eb0 100644 --- a/net/qrtr/usb.c +++ b/net/qrtr/usb.c @@ -302,6 +302,7 @@ static const struct usb_device_id qcom_usb_qrtr_ids[] = { { USB_DEVICE_INTERFACE_NUMBER(QRTR_VENDOR_ID, 0x90ef, 3) }, { USB_DEVICE_INTERFACE_NUMBER(QRTR_VENDOR_ID, 0x90f0, 3) }, { USB_DEVICE_INTERFACE_NUMBER(QRTR_VENDOR_ID, 0x90f3, 2) }, + { USB_DEVICE_INTERFACE_NUMBER(QRTR_VENDOR_ID, 0x90fd, 1) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, qcom_usb_qrtr_ids); diff --git a/net/rmnet_usb/rmnet_usb.c b/net/rmnet_usb/rmnet_usb.c index 9e978eb9d499..e77c0ad52ad0 100644 --- a/net/rmnet_usb/rmnet_usb.c +++ b/net/rmnet_usb/rmnet_usb.c @@ -428,6 +428,14 @@ static const struct usb_device_id rmnet_usb_ids[] = { USB_DEVICE_INTERFACE_NUMBER(RMNET_VENDOR_ID, 0x90F3, 1), .driver_info = (unsigned long)&rmnet_usb_info, }, + { + USB_DEVICE_INTERFACE_NUMBER(RMNET_VENDOR_ID, 0x90FD, 2), + .driver_info = (unsigned long)&rmnet_usb_info, + }, + { + USB_DEVICE_INTERFACE_NUMBER(RMNET_VENDOR_ID, 0x90FD, 3), + .driver_info = (unsigned long)&rmnet_usb_info, + }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, rmnet_usb_ids); -- GitLab From 8bee800ae11c910d21ce24aed4c4b80ae8eee18e Mon Sep 17 00:00:00 2001 From: Narender Ankam Date: Wed, 26 Jun 2019 20:28:04 +0530 Subject: [PATCH 0702/1121] ARM: msm: dts: remove unused DSI panel node Remove unused DSI panel node for qcs610-iot target. Change-Id: Ic0cf62a95b3ff2e5eda23cd49bde5bf607831da2 Signed-off-by: Narender Ankam --- arch/arm64/boot/dts/qcom/qcs610-iot.dtsi | 9 --------- 1 file changed, 9 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/qcs610-iot.dtsi b/arch/arm64/boot/dts/qcom/qcs610-iot.dtsi index b23676e2e1c4..937ff9b02306 100644 --- a/arch/arm64/boot/dts/qcom/qcs610-iot.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs610-iot.dtsi @@ -322,15 +322,6 @@ regulator-max-microvolt = <2912000>; }; -&dsi_hx83112a_truly_video { - qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; - qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; - qcom,mdss-dsi-bl-min-level = <1>; - qcom,mdss-dsi-bl-max-level = <4095>; - qcom,platform-te-gpio = <&tlmm 90 0>; - qcom,platform-reset-gpio = <&tlmm 91 0>; -}; - &qupv3_se1_i2c { status = "ok"; lt9611: lt,lt9611@3b { -- GitLab From a68238da04922532327acdbbe2a2cd352422710e Mon Sep 17 00:00:00 2001 From: Narender Ankam Date: Wed, 26 Jun 2019 20:33:46 +0530 Subject: [PATCH 0703/1121] ARM: msm: dts: disable DP related device nodes As there is no DP support, remove DP controller and PLL device nodes for qcs610-iot target device. Change-Id: I0de290ad0f4bc95b110f112879bd81238825382f Signed-off-by: Narender Ankam --- arch/arm64/boot/dts/qcom/qcs610-iot.dtsi | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/qcs610-iot.dtsi b/arch/arm64/boot/dts/qcom/qcs610-iot.dtsi index 937ff9b02306..18621f2f866a 100644 --- a/arch/arm64/boot/dts/qcom/qcs610-iot.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs610-iot.dtsi @@ -322,6 +322,18 @@ regulator-max-microvolt = <2912000>; }; +&sde_dp { + status="disabled"; +}; + +&mdss_dp_pll { + status="disabled"; +}; + +&mdss_mdp { + connectors = <&sde_rscc &sde_wb &sde_dsi>; +}; + &qupv3_se1_i2c { status = "ok"; lt9611: lt,lt9611@3b { -- GitLab From a3fdf9b3115aab6f6c63b02ceaae91043c61cf37 Mon Sep 17 00:00:00 2001 From: Deepak Kumar Date: Wed, 26 Jun 2019 10:37:22 +0530 Subject: [PATCH 0704/1121] msm: kgsl: Use event workqueue for event work instead of RT Kthread worker Currently, both dispatcher work and event work is handled by real time kthread worker. This results in two problems: 1) Event work can result in freeing memory either as part of free on timestamp or while putting a context. As freeing memory can take time it shouldn't be done as part of RT thread as it can result in hogging CPU for longer duration and not giving chance to other tasks to run. 2) Event work remains unprocessed till kthread worker finishes dispatcher work. As dispatcher work first schedules the event work for previously retired commands and then tries to submit new commands. The scheduled event work doesn't get processed till dispatcher work finishes. This can result in even longer delays in case dispatcher work gets blocked after scheduling event work because of mutexes locks etc. To avoid this, use event workqueue for event work. This will decouple both dispatcher and event work and will also make sure that high latency work like freeing-up memory is not done as part of RT thread. Change-Id: I74734a1bc177feecaac6626109349752da44da80 Signed-off-by: Deepak Kumar --- drivers/gpu/msm/kgsl.h | 4 ++-- drivers/gpu/msm/kgsl_events.c | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/msm/kgsl.h b/drivers/gpu/msm/kgsl.h index dfb5050c734b..d668d4561e05 100644 --- a/drivers/gpu/msm/kgsl.h +++ b/drivers/gpu/msm/kgsl.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2008-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -319,7 +319,7 @@ struct kgsl_event { void *priv; struct list_head node; unsigned int created; - struct kthread_work work; + struct work_struct work; int result; struct kgsl_event_group *group; }; diff --git a/drivers/gpu/msm/kgsl_events.c b/drivers/gpu/msm/kgsl_events.c index 9bdd05a2b9df..d4f4a618d895 100644 --- a/drivers/gpu/msm/kgsl_events.c +++ b/drivers/gpu/msm/kgsl_events.c @@ -32,7 +32,7 @@ static inline void signal_event(struct kgsl_device *device, { list_del(&event->node); event->result = result; - kthread_queue_work(&kgsl_driver.worker, &event->work); + queue_work(device->events_wq, &event->work); } /** @@ -42,7 +42,7 @@ static inline void signal_event(struct kgsl_device *device, * Each event callback has its own work struct and is run on a event specific * workqeuue. This is the worker that queues up the event callback function. */ -static void _kgsl_event_worker(struct kthread_work *work) +static void _kgsl_event_worker(struct work_struct *work) { struct kgsl_event *event = container_of(work, struct kgsl_event, work); int id = KGSL_CONTEXT_ID(event->context); @@ -286,7 +286,7 @@ int kgsl_add_event(struct kgsl_device *device, struct kgsl_event_group *group, event->created = jiffies; event->group = group; - kthread_init_work(&event->work, _kgsl_event_worker); + INIT_WORK(&event->work, _kgsl_event_worker); trace_kgsl_register_event(KGSL_CONTEXT_ID(context), timestamp, func); @@ -301,7 +301,7 @@ int kgsl_add_event(struct kgsl_device *device, struct kgsl_event_group *group, if (timestamp_cmp(retired, timestamp) >= 0) { event->result = KGSL_EVENT_RETIRED; - kthread_queue_work(&kgsl_driver.worker, &event->work); + queue_work(device->events_wq, &event->work); spin_unlock(&group->lock); return 0; } -- GitLab From 426392640796a6b7d666c50ecb8806eb42999569 Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Wed, 26 Jun 2019 15:30:23 -0700 Subject: [PATCH 0705/1121] ARM: dts: add hostless QUIN TDM config on sa6155 platform Add hostless quinary TDM to its group TDM configuration with tdm-quin-tx-7 and tdm-quin-rx-7. Change-Id: I088ca5d8a01b0c35f47523c78f7cad48405a7ffa Signed-off-by: Derek Chen --- arch/arm64/boot/dts/qcom/sa6155-audio.dtsi | 34 +++++++++++++++------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sa6155-audio.dtsi b/arch/arm64/boot/dts/qcom/sa6155-audio.dtsi index e67566916662..ccff6e021534 100644 --- a/arch/arm64/boot/dts/qcom/sa6155-audio.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155-audio.dtsi @@ -360,8 +360,9 @@ tdm_quin_rx: qcom,msm-dai-tdm-quin-rx { compatible = "qcom,msm-dai-tdm"; qcom,msm-cpudai-tdm-group-id = <37184>; - qcom,msm-cpudai-tdm-group-num-ports = <4>; - qcom,msm-cpudai-tdm-group-port-id = <36928 36930 36932 36934>; + qcom,msm-cpudai-tdm-group-num-ports = <5>; + qcom,msm-cpudai-tdm-group-port-id = <36928 36930 36932 + 36934 36942>; qcom,msm-cpudai-tdm-clk-rate = <12288000>; qcom,msm-cpudai-tdm-clk-internal = <0>; qcom,msm-cpudai-tdm-sync-mode = <1>; @@ -397,13 +398,19 @@ qcom,msm-cpudai-tdm-dev-id = <36934>; qcom,msm-cpudai-tdm-data-align = <0>; }; + dai_quin_tdm_rx_7: qcom,msm-dai-q6-tdm-quin-rx-7 { + compatible = "qcom,msm-dai-q6-tdm"; + qcom,msm-cpudai-tdm-dev-id = <36942>; + qcom,msm-cpudai-tdm-data-align = <0>; + }; }; tdm_quin_tx: qcom,msm-dai-tdm-quin-tx { compatible = "qcom,msm-dai-tdm"; qcom,msm-cpudai-tdm-group-id = <37185>; - qcom,msm-cpudai-tdm-group-num-ports = <4>; - qcom,msm-cpudai-tdm-group-port-id = <36929 36931 36933 36935>; + qcom,msm-cpudai-tdm-group-num-ports = <5>; + qcom,msm-cpudai-tdm-group-port-id = <36929 36931 36933 + 36935 36943>; qcom,msm-cpudai-tdm-clk-rate = <12288000>; qcom,msm-cpudai-tdm-clk-internal = <0>; qcom,msm-cpudai-tdm-sync-mode = <1>; @@ -434,6 +441,11 @@ qcom,msm-cpudai-tdm-dev-id = <36935>; qcom,msm-cpudai-tdm-data-align = <0>; }; + dai_quin_tdm_tx_7: qcom,msm-dai-q6-tdm-quin-tx-7 { + compatible = "qcom,msm-dai-q6-tdm"; + qcom,msm-cpudai-tdm-dev-id = <36943>; + qcom,msm-cpudai-tdm-data-align = <0>; + }; }; dai_pri_auxpcm: qcom,msm-pri-auxpcm { @@ -514,9 +526,10 @@ <&dai_quat_tdm_tx_2>, <&dai_quat_tdm_tx_3>, <&dai_quat_tdm_tx_7>, <&dai_quin_tdm_rx_0>, <&dai_quin_tdm_rx_1>, <&dai_quin_tdm_rx_2>, - <&dai_quin_tdm_rx_3>, <&dai_quin_tdm_tx_0>, - <&dai_quin_tdm_tx_1>, <&dai_quin_tdm_tx_2>, - <&dai_quin_tdm_tx_3>; + <&dai_quin_tdm_rx_3>, <&dai_quin_tdm_rx_7>, + <&dai_quin_tdm_tx_0>, <&dai_quin_tdm_tx_1>, + <&dai_quin_tdm_tx_2>, <&dai_quin_tdm_tx_3>, + <&dai_quin_tdm_tx_7>; asoc-cpu-names = "msm-dai-q6-hdmi.8", "msm-dai-q6-dp.24608", "msm-dai-q6-mi2s.0", "msm-dai-q6-mi2s.1", "msm-dai-q6-mi2s.2", "msm-dai-q6-mi2s.3", @@ -548,9 +561,10 @@ "msm-dai-q6-tdm.36917", "msm-dai-q6-tdm.36919", "msm-dai-q6-tdm.36927", "msm-dai-q6-tdm.36928", "msm-dai-q6-tdm.36930", "msm-dai-q6-tdm.36932", - "msm-dai-q6-tdm.36934", "msm-dai-q6-tdm.36929", - "msm-dai-q6-tdm.36931", "msm-dai-q6-tdm.36933", - "msm-dai-q6-tdm.36935"; + "msm-dai-q6-tdm.36934", "msm-dai-q6-tdm.36942", + "msm-dai-q6-tdm.36929", "msm-dai-q6-tdm.36931", + "msm-dai-q6-tdm.36933", "msm-dai-q6-tdm.36935", + "msm-dai-q6-tdm.36943"; asoc-codec = <&stub_codec>; asoc-codec-names = "msm-stub-codec.1"; qcom,msm_audio_ssr_devs = <&audio_apr>, <&q6core>; -- GitLab From aff90b7834d5e16236324868013f9ccc7a3ca0af Mon Sep 17 00:00:00 2001 From: Michael Adisumarta Date: Wed, 26 Jun 2019 15:55:37 -0700 Subject: [PATCH 0706/1121] msm: ipa3: WA to handle of mhi prime channel start failure This change gives WA to handle mhi prime channels start failure on device side to have mhi-driver to call remove_cb once 5g modem is up. Change-Id: Ic5ef1908038d17a49d37751ca8c1df4d8b6db518 Acked-by: Jyothi Signed-off-by: Michael Adisumarta --- drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c b/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c index 4dd6e46760ee..31c430cc7ab7 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c @@ -1839,7 +1839,7 @@ static int ipa_mpm_mhi_probe_cb(struct mhi_device *mhi_dev, if (ipa_mpm_ctx->md[probe_id].init_complete) { IPA_MPM_ERR("Probe initialization already done, returning\n"); - return -EPERM; + return 0; } IPA_MPM_DBG("Received probe for id=%d\n", probe_id); @@ -1996,7 +1996,17 @@ static int ipa_mpm_mhi_probe_cb(struct mhi_device *mhi_dev, ret = mhi_prepare_for_transfer(ipa_mpm_ctx->md[probe_id].mhi_dev); if (ret) { IPA_MPM_ERR("mhi_prepare_for_transfer failed %d\n", ret); - goto fail_smmu; + WARN_ON(1); + /* + * WA to handle prepare_for_tx failures. + * Though prepare for transfer fails, indicate success + * to MHI driver. remove_cb will be called eventually when + * Device side comes from where pending cleanup happens. + */ + atomic_inc(&ipa_mpm_ctx->probe_cnt); + ipa_mpm_ctx->md[probe_id].init_complete = true; + IPA_MPM_FUNC_EXIT(); + return 0; } /* -- GitLab From 0acb99110f3fe6b45c4fabc8f538942af5d53ede Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Wed, 26 Jun 2019 13:32:28 -0700 Subject: [PATCH 0707/1121] usb: core: Power up SS phy before handling port suspend If SS phy is power down writing to PORTSC of SS port gets stuck because pipe clock is off. Fix this issue by powering up SS phy perform port suspend and power it down. Change-Id: I8a13c79255d50b4ddf32537e14d61f1d7fea9822 Signed-off-by: Hemant Kumar --- drivers/usb/core/hub.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 8ce80fa255a6..595b8246a14d 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -3600,6 +3600,7 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg) { struct usb_hub *hub = usb_get_intfdata(intf); struct usb_device *hdev = hub->hdev; + struct usb_hcd *hcd = bus_to_hcd(hdev->bus); unsigned port1; int status; @@ -3633,6 +3634,9 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg) } if (hub_is_superspeed(hdev) && hdev->do_remote_wakeup) { + if (!hdev->parent && hcd->primary_hcd) + usb_phy_powerup(hcd->primary_hcd->usb3_phy); + /* Enable hub to send remote wakeup for all ports. */ for (port1 = 1; port1 <= hdev->maxchild; port1++) { status = set_port_feature(hdev, @@ -3642,6 +3646,9 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg) USB_PORT_FEAT_REMOTE_WAKE_OVER_CURRENT, USB_PORT_FEAT_REMOTE_WAKE_MASK); } + + if (!hdev->parent && hcd->primary_hcd) + usb_phy_powerdown(hcd->primary_hcd->usb3_phy); } dev_dbg(&intf->dev, "%s\n", __func__); -- GitLab From 884b0ec5697149d65bc1109e764b7193b367100e Mon Sep 17 00:00:00 2001 From: YUE CHEN Date: Wed, 26 Jun 2019 13:38:34 +0800 Subject: [PATCH 0708/1121] msm: ais: fix issue for 4 cameras on lite IFE need config stride for RDI3 Change-Id: I4a9a0db4ff38ffeaa573a7929bc8890537e605ae Signed-off-by: YUE CHEN --- .../isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c index bf2b33c81313..b1751a16e101 100644 --- a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c +++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c @@ -153,6 +153,7 @@ struct cam_vfe_bus_ver2_wm_resource_data { uint32_t en_cfg; uint32_t is_dual; + uint32_t is_lite; }; struct cam_vfe_bus_ver2_comp_grp_data { @@ -918,13 +919,14 @@ static int cam_vfe_bus_acquire_wm( rsrc_data->width = out_port_info->width; rsrc_data->height = out_port_info->height; rsrc_data->is_dual = is_dual; + rsrc_data->is_lite = ver2_bus_priv->is_lite; /* Set WM offset value to default */ rsrc_data->offset = 0; CAM_DBG(CAM_ISP, "WM %d width %d height %d", rsrc_data->index, rsrc_data->width, rsrc_data->height); if (rsrc_data->index < 3 || - (ver2_bus_priv->is_lite && rsrc_data->index == 3)) { + (rsrc_data->is_lite && rsrc_data->index == 3)) { /* Write master 0-2 refers to RDI 0/ RDI 1/RDI 2 */ if ((out_port_info->reserved >> 8) & 0x01) { /* frame based mode as default */ @@ -1161,7 +1163,8 @@ static int cam_vfe_bus_start_wm(struct cam_isp_resource_node *wm_res) common_data->mem_base + rsrc_data->hw_regs->packer_cfg); /* Configure stride for RDIs */ - if (rsrc_data->index < 3) + if (rsrc_data->index < 3 || + (rsrc_data->is_lite && rsrc_data->index == 3)) cam_io_w_mb(rsrc_data->stride, (common_data->mem_base + rsrc_data->hw_regs->stride)); -- GitLab From c334419bd6c8f5615fdb411c12ec1e0ba025b6c1 Mon Sep 17 00:00:00 2001 From: Sankeerth Billakanti Date: Mon, 8 Apr 2019 20:56:18 +0530 Subject: [PATCH 0709/1121] ARM: dts: msm: enable displayport driver for trinket DT changes to enable the DisplayPort driver for trinket. Change-Id: Ic15fde5e15c3913e6c5f20eaee9d9621dd60e953 Signed-off-by: Sankeerth Billakanti --- .../boot/dts/qcom/trinket-audio-overlay.dtsi | 7 +- arch/arm64/boot/dts/qcom/trinket-pinctrl.dtsi | 54 +++++++ arch/arm64/boot/dts/qcom/trinket-sde-pll.dtsi | 41 +++++ arch/arm64/boot/dts/qcom/trinket-sde.dtsi | 146 ++++++++++++++++++ arch/arm64/boot/dts/qcom/trinket.dtsi | 4 + 5 files changed, 249 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/trinket-audio-overlay.dtsi b/arch/arm64/boot/dts/qcom/trinket-audio-overlay.dtsi index d2ab4cb4ecb6..2568fab8077b 100644 --- a/arch/arm64/boot/dts/qcom/trinket-audio-overlay.dtsi +++ b/arch/arm64/boot/dts/qcom/trinket-audio-overlay.dtsi @@ -186,7 +186,7 @@ &sm6150_snd { qcom,model = "trinket-idp-snd-card"; qcom,msm-mi2s-master = <1>, <1>, <1>, <1>, <1>; - qcom,ext-disp-audio-rx = <0>; + qcom,ext-disp-audio-rx = <1>; qcom,audio-routing = "AMIC2", "MIC BIAS2", "MIC BIAS2", "Analog Mic2", @@ -227,8 +227,9 @@ qcom,msm-mbhc-gnd-swh = <1>; qcom,cdc-dmic01-gpios = <&cdc_dmic01_gpios>; qcom,cdc-dmic23-gpios = <&cdc_dmic23_gpios>; - asoc-codec = <&stub_codec>, <&bolero>; - asoc-codec-names = "msm-stub-codec.1", "bolero_codec"; + asoc-codec = <&stub_codec>, <&bolero>, <&ext_disp_audio_codec>; + asoc-codec-names = "msm-stub-codec.1", "bolero_codec", + "msm-ext-disp-audio-codec-rx"; qcom,wsa-max-devs = <1>; qcom,wsa-devs = <&wsa881x_0211>, <&wsa881x_0212>, <&wsa881x_0213>, <&wsa881x_0214>; diff --git a/arch/arm64/boot/dts/qcom/trinket-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/trinket-pinctrl.dtsi index a59cc200ba1d..19c93d69922b 100644 --- a/arch/arm64/boot/dts/qcom/trinket-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/trinket-pinctrl.dtsi @@ -1255,6 +1255,60 @@ }; }; + sde_dp_usbplug_cc_active: sde_dp_usbplug_cc_active { + mux { + pins = "gpio102"; + function = "gpio"; + }; + + config { + pins = "gpio102"; + bias-disable; + drive-strength = <16>; + }; + }; + + sde_dp_usbplug_cc_suspend: sde_dp_usbplug_cc_suspend { + mux { + pins = "gpio102"; + function = "gpio"; + }; + + config { + pins = "gpio102"; + bias-pull-down; + drive-strength = <2>; + }; + }; + + sde_dp_hotplug_ctrl: sde_dp_hotplug_ctrl { + mux { + pins = "gpio100"; + function = "dp_hot"; + }; + + config { + pins = "gpio100"; + bias-disable; + input-enable; + drive-strength = <2>; + }; + }; + + sde_dp_hotplug_tlmm: sde_dp_hotplug_tlmm { + mux { + pins = "gpio100"; + function = "gpio"; + }; + + config { + pins = "gpio100"; + bias-disable; + input-enable; + drive-strength = <2>; + }; + }; + /* SDC pin type */ sdc1_clk_on: sdc1_clk_on { config { diff --git a/arch/arm64/boot/dts/qcom/trinket-sde-pll.dtsi b/arch/arm64/boot/dts/qcom/trinket-sde-pll.dtsi index 052a163c6556..701bb570f20e 100644 --- a/arch/arm64/boot/dts/qcom/trinket-sde-pll.dtsi +++ b/arch/arm64/boot/dts/qcom/trinket-sde-pll.dtsi @@ -41,4 +41,45 @@ }; }; }; + + mdss_dp_pll: qcom,mdss_dp_pll@1616000 { + status = "disabled"; + compatible = "qcom,mdss_dp_pll_14nm"; + label = "MDSS DP PLL"; + cell-index = <0>; + #clock-cells = <1>; + + reg = <0x01616c00 0x1c4>, + <0x01616000 0x17c>, + <0x01616400 0x10c>, + <0x01616800 0x10c>, + <0x05f03000 0xc>; + reg-names = "pll_base", "phy_base", "ln_tx0_base", + "ln_tx1_base", "gdsc_base"; + + clocks = <&clock_dispcc DISP_CC_MDSS_AHB_CLK>, + <&clock_rpmcc CXO_SMD_OTG_CLK>, + <&clock_gcc GCC_AHB2PHY_USB_CLK>, + <&clock_gcc GCC_USB3_PRIM_PHY_PIPE_CLK>, + <&clock_gcc GCC_USB3_PRIM_CLKREF_CLK>; + clock-names = "iface_clk", + "ref_clk_src", + "cfg_ahb_clk", + "gcc_iface", "ref_clk"; + clock-rate = <0>; + + gdsc-supply = <&mdss_core_gdsc>; + qcom,platform-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + qcom,platform-supply-entry@0 { + reg = <0>; + qcom,supply-name = "gdsc"; + qcom,supply-min-voltage = <0>; + qcom,supply-max-voltage = <0>; + qcom,supply-enable-load = <0>; + qcom,supply-disable-load = <0>; + }; + }; + }; }; diff --git a/arch/arm64/boot/dts/qcom/trinket-sde.dtsi b/arch/arm64/boot/dts/qcom/trinket-sde.dtsi index d1420bfd09a4..7419634f0b0d 100644 --- a/arch/arm64/boot/dts/qcom/trinket-sde.dtsi +++ b/arch/arm64/boot/dts/qcom/trinket-sde.dtsi @@ -414,4 +414,150 @@ }; }; }; + + ext_disp: qcom,msm-ext-disp { + compatible = "qcom,msm-ext-disp"; + + ext_disp_audio_codec: qcom,msm-ext-disp-audio-codec-rx { + compatible = "qcom,msm-ext-disp-audio-codec-rx"; + }; + }; + + sde_dp: qcom,dp_display@0{ + status = "disabled"; + cell-index = <0>; + compatible = "qcom,dp-display"; + + vdda-1p8-supply = <&pm6125_l10>; + vdda-0p9-supply = <&pm6125_l7>; + vdda-3p1-supply = <&pm6125_l15>; + hpd-pwr-supply = <&pm6125_l9>; + + reg = <0x05e90000 0xf4>, + <0x05e90200 0xc0>, + <0x05e90400 0x600>, + <0x05e90a00 0x98>, + <0x01616000 0x17c>, + <0x01616400 0x10c>, + <0x01616800 0x10c>, + <0x05f0212c 0x8>, + <0x01b40000 0x7000>, + <0x01616c30 0x10>, + <0x05ee1000 0x2c>, + <0x003cb248 0x4>; + reg-names = "dp_ahb", "dp_aux", "dp_link", "dp_p0", + "dp_phy", "dp_ln_tx0", "dp_ln_tx1", + "dp_pixel_mn", "qfprom_physical", "dp_pll", + "hdcp_physical", "dp_tcsr"; + + interrupt-parent = <&mdss_mdp>; + interrupts = <12 0>; + + clocks = <&clock_dispcc DISP_CC_MDSS_DP_AUX_CLK>, + <&clock_gcc GCC_AHB2PHY_USB_CLK>, + <&clock_rpmcc CXO_SMD_OTG_CLK>, + <&clock_gcc GCC_USB3_PRIM_CLKREF_CLK>, + <&clock_gcc GCC_USB3_PRIM_PHY_PIPE_CLK>, + <&clock_dispcc DISP_CC_MDSS_DP_LINK_CLK>, + <&clock_dispcc DISP_CC_MDSS_DP_LINK_INTF_CLK>, + <&clock_dispcc DISP_CC_MDSS_DP_CRYPTO_CLK>, + <&clock_dispcc DISP_CC_MDSS_DP_PIXEL_CLK_SRC>, + <&mdss_dp_pll DP_PHY_PLL_VCO_DIV_CLK>, + <&clock_dispcc DISP_CC_MDSS_DP_PIXEL_CLK>; + + clock-names = "core_aux_clk", "core_usb_ahb_clk", + "core_usb_ref_clk_src", + "core_usb_ref_clk", + "core_usb_pipe_clk", "link_clk", "link_iface_clk", + "crypto_clk", "pixel_clk_rcg", "pixel_parent", + "strm0_pixel_clk"; + + qcom,phy-version = <0x200>; + qcom,aux-cfg0-settings = [20 00]; + qcom,aux-cfg1-settings = [24 13 23 1d]; + qcom,aux-cfg2-settings = [28 24]; + qcom,aux-cfg3-settings = [2c 00]; + qcom,aux-cfg4-settings = [30 0a]; + qcom,aux-cfg5-settings = [34 26]; + qcom,aux-cfg6-settings = [38 0a]; + qcom,aux-cfg7-settings = [3c 03]; + qcom,aux-cfg8-settings = [40 bb]; + qcom,aux-cfg9-settings = [44 03]; + + qcom,logical2physical-lane-map = [00 01 02 03]; + + qcom,max-lclk-frequency-khz = <540000>; + qcom,max-pclk-frequency-khz = <200000>; + + qcom,ext-disp = <&ext_disp>; + + qcom,usbplug-cc-gpio = <&tlmm 102 0>; + + pinctrl-names = "mdss_dp_active", "mdss_dp_sleep", + "mdss_dp_hpd_active", "mdss_dp_hpd_tlmm", + "mdss_dp_hpd_ctrl"; + pinctrl-0 = <&sde_dp_usbplug_cc_active>; + pinctrl-1 = <&sde_dp_usbplug_cc_suspend>; + pinctrl-2 = <&sde_dp_hotplug_tlmm>; + pinctrl-3 = <&sde_dp_hotplug_tlmm>; + pinctrl-4 = <&sde_dp_hotplug_ctrl>; + + qcom,ctrl-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,ctrl-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vdda-1p8"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1896000>; + qcom,supply-enable-load = <20000>; + qcom,supply-disable-load = <0>; + }; + }; + + qcom,phy-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,phy-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vdda-0p9"; + qcom,supply-min-voltage = <872000>; + qcom,supply-max-voltage = <976000>; + qcom,supply-enable-load = <50000>; + qcom,supply-disable-load = <0>; + }; + qcom,phy-supply-entry@1 { + reg = <1>; + qcom,supply-name = "vdda-3p1"; + qcom,supply-min-voltage = <3104000>; + qcom,supply-max-voltage = <3232000>; + qcom,supply-enable-load = <5250>; + qcom,supply-disable-load = <0>; + }; + qcom,phy-supply-entry@2 { + reg = <2>; + qcom,supply-name = "hpd-pwr"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1896000>; + qcom,supply-enable-load = <10000>; + qcom,supply-disable-load = <0>; + }; + }; + + qcom,core-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,core-supply-entry@0 { + reg = <0>; + qcom,supply-name = "refgen"; + qcom,supply-min-voltage = <0>; + qcom,supply-max-voltage = <0>; + qcom,supply-enable-load = <0>; + qcom,supply-disable-load = <0>; + }; + }; + }; }; diff --git a/arch/arm64/boot/dts/qcom/trinket.dtsi b/arch/arm64/boot/dts/qcom/trinket.dtsi index f99e6907a58e..12df0695e95d 100644 --- a/arch/arm64/boot/dts/qcom/trinket.dtsi +++ b/arch/arm64/boot/dts/qcom/trinket.dtsi @@ -2072,6 +2072,10 @@ <&apps_smmu 0x01B6 0x0011>; }; + qcom_msmhdcp: qcom,msm_hdcp { + compatible = "qcom,msm-hdcp"; + }; + qcom_crypto: qcrypto@1b20000 { compatible = "qcom,qcrypto"; reg = <0x1b20000 0x20000>, -- GitLab From 86869ea160813d16584d168d37668993e9a9ac89 Mon Sep 17 00:00:00 2001 From: Sankeerth Billakanti Date: Tue, 9 Apr 2019 18:09:07 +0530 Subject: [PATCH 0710/1121] ARM: dts: msm: enable displayport hpd through lphw gpio Enable Displayport HPD via LPHW gpio on trinket devices without PD controller. Change-Id: I590d503cc44e5c59c30c7ae4c230bb3c303ed095 Signed-off-by: Sankeerth Billakanti --- .../boot/dts/qcom/trinket-dp-idp-overlay.dts | 21 +++++++++++++++++++ arch/arm64/boot/dts/qcom/trinket-dp-idp.dts | 21 +++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/trinket-dp-idp-overlay.dts b/arch/arm64/boot/dts/qcom/trinket-dp-idp-overlay.dts index 0607e35329bf..930307886ea1 100644 --- a/arch/arm64/boot/dts/qcom/trinket-dp-idp-overlay.dts +++ b/arch/arm64/boot/dts/qcom/trinket-dp-idp-overlay.dts @@ -28,3 +28,24 @@ &dsi_td4330_truly_cmd_display { qcom,dsi-display-active; }; + +&sde_dp { + status = "ok"; + qcom,dp-hpd-gpio = <&tlmm 100 0>; + qcom,dp-low-power-hw-hpd; +}; + +&mdss_dp_pll { + status = "ok"; +}; + +&usb0 { + dwc3@4e00000 { + usb-phy = <&qusb_phy0>, <&usb_nop_phy>; + maximum-speed = "high-speed"; + }; +}; + +&mdss_mdp { + connectors = <&sde_wb &sde_dsi &sde_dp>; +}; diff --git a/arch/arm64/boot/dts/qcom/trinket-dp-idp.dts b/arch/arm64/boot/dts/qcom/trinket-dp-idp.dts index a8ee1e96b57f..8321f5877c74 100644 --- a/arch/arm64/boot/dts/qcom/trinket-dp-idp.dts +++ b/arch/arm64/boot/dts/qcom/trinket-dp-idp.dts @@ -21,3 +21,24 @@ compatible = "qcom,trinket-idp", "qcom,trinket", "qcom,idp"; qcom,board-id = <34 4>; }; + +&sde_dp { + status = "ok"; + qcom,dp-hpd-gpio = <&tlmm 100 0>; + qcom,dp-low-power-hw-hpd; +}; + +&mdss_dp_pll { + status = "ok"; +}; + +&usb0 { + dwc3@4e00000 { + usb-phy = <&qusb_phy0>, <&usb_nop_phy>; + maximum-speed = "high-speed"; + }; +}; + +&mdss_mdp { + connectors = <&sde_wb &sde_dsi &sde_dp>; +}; -- GitLab From efea50fdfaf22551fc0623d0384b1aa40d0fb679 Mon Sep 17 00:00:00 2001 From: Ramesh V Date: Tue, 18 Jun 2019 11:42:57 +0530 Subject: [PATCH 0711/1121] msm: camera_v2: isp: Fix ub allocation logic To overcome vfe overflow issues, modify ub allocation logic for vfe wm, when we allocate ub proportionally for pix and rdi, consider min_ub as 96 (Qwords) for pix interface and 192 (Qwords) for rdi interface. Change-Id: I924f3f869eab663710ad326b7c2d5f7c84f4af1f Signed-off-by: Ramesh V --- .../platform/msm/camera_v2/isp/msm_isp47.c | 49 +++++++++++++------ 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c index 5d77e7565dcc..d9d05be5407f 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c @@ -1895,20 +1895,37 @@ void msm_vfe47_cfg_axi_ub_equal_default( struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; uint32_t total_image_size = 0; - uint8_t num_used_wms = 0; + uint8_t pix_num_used_wms = 0; + uint8_t rdi_num_used_wms = 0; uint32_t prop_size = 0; uint32_t wm_ub_size; + uint32_t min_ub; uint64_t delta; + uint32_t vfe_ub_size = 0; for (i = 0; i < axi_data->hw_info->num_wm; i++) { if (axi_data->free_wm[i]) { - num_used_wms++; + /* separate wm for each interface as min_ub is different for + * both pix and rdi + */ + if (VFE_PIX_0 == SRC_TO_INTF( + HANDLE_TO_IDX(axi_data->free_wm[i]))) + pix_num_used_wms++; + else + rdi_num_used_wms++; total_image_size += axi_data->wm_image_size[i]; } } - prop_size = vfe_dev->hw_info->vfe_ops.axi_ops.get_ub_size( - vfe_dev) - axi_data->hw_info->min_wm_ub * num_used_wms; + /* get ub for each vfe */ + vfe_ub_size = vfe_dev->hw_info->vfe_ops.axi_ops.get_ub_size(vfe_dev); + /* calculate min_ub needed for both pix and rdi wm + * for pix min_ub 96 and rdi 192 as per hw + */ + min_ub = (axi_data->hw_info->min_wm_ub * pix_num_used_wms) + + (axi_data->hw_info->min_wm_ub * 2 * rdi_num_used_wms); + /* calculate propotional ub for all wm */ + prop_size = vfe_ub_size - min_ub; for (i = 0; i < axi_data->hw_info->num_wm; i++) { if (!axi_data->free_wm[i]) { msm_camera_io_w(0, @@ -1917,20 +1934,22 @@ void msm_vfe47_cfg_axi_ub_equal_default( vfe_dev, i)); continue; } - - if (frame_src != SRC_TO_INTF( - HANDLE_TO_IDX(axi_data->free_wm[i]))) - continue; - + /* calcualte delta by considering + * wm_image_size + total imagesize + */ delta = (uint64_t)axi_data->wm_image_size[i] * (uint64_t)prop_size; do_div(delta, total_image_size); - if (frame_src != VFE_PIX_0) { - if (delta <= axi_data->hw_info->min_wm_ub) - delta = axi_data->hw_info->min_wm_ub; - } - wm_ub_size = axi_data->hw_info->min_wm_ub + - (uint32_t)delta; + /* to meet hw constraint add min_ub of 192 + * for RDI and 96 for pix + */ + if (VFE_PIX_0 != SRC_TO_INTF( + HANDLE_TO_IDX(axi_data->free_wm[i]))) + wm_ub_size = (axi_data->hw_info->min_wm_ub * 2) + + (uint32_t)delta; + else + wm_ub_size = axi_data->hw_info->min_wm_ub + + (uint32_t)delta; msm_camera_io_w(ub_offset << 16 | (wm_ub_size - 1), vfe_dev->vfe_base + vfe_dev->hw_info->vfe_ops.axi_ops.ub_reg_offset( -- GitLab From 70f8c63322222ff0f3cf5d3c0bc19d7a81750d48 Mon Sep 17 00:00:00 2001 From: vagdhan kumar kanukurthi Date: Thu, 27 Jun 2019 09:37:43 +0530 Subject: [PATCH 0712/1121] ARM: dts: msm: Add sdcard support for sa6155p vm Add sdhc_2 for sa6155p virtual machine. Change-Id: I19daeaaf999cd21bae97864ef84bdcf241824f2f Signed-off-by: Vagdhan Kanukurthi --- arch/arm64/boot/dts/qcom/sa6155p-vm.dts | 5 ++ arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi | 73 ++++++++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sa6155p-vm.dts b/arch/arm64/boot/dts/qcom/sa6155p-vm.dts index 3c98b8ac0a0c..0caf78c1b2e6 100644 --- a/arch/arm64/boot/dts/qcom/sa6155p-vm.dts +++ b/arch/arm64/boot/dts/qcom/sa6155p-vm.dts @@ -45,3 +45,8 @@ &pcie0 { status = "ok"; }; + +&sdhc_2 { + status = "ok"; +}; + diff --git a/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi b/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi index 48bd17ec222c..7432a67530ed 100644 --- a/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi @@ -27,6 +27,10 @@ pci-domain0 = &pcie0; /* PCIe0 domain */ }; + aliases { + sdhc2 = &sdhc_2; /* SDC2 SD Card slot */ + }; + reserved_memory: reserved-memory { pmem_shared: pmem_shared_region@a1600000 { @@ -268,6 +272,75 @@ /* Upto 800 Mbps */ <45 512 207108 1146880>, <1 512 207108 3124992>; }; + + sdhc_2: sdhci@8804000 { + compatible = "qcom,sdhci-msm-v5"; + reg = <0x8804000 0x1000>; + reg-names = "hc_mem"; + interrupts = <0 204 0>, <0 222 0>; + interrupt-names = "hc_irq", "pwr_irq"; + qcom,bus-width = <4>; + qcom,large-address-bus; + qcom,clk-rates = <400000 20000000 25000000 + 50000000 100000000 202000000>; + qcom,bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50", + "SDR104"; + qcom,devfreq,freq-table = <50000000 202000000>; + qcom,msm-bus,name = "sdhc2"; + qcom,msm-bus,num-cases = <8>; + qcom,msm-bus,num-paths = <2>; + qcom,msm-bus,vectors-KBps = + /* No vote */ + <81 512 0 0>, <1 608 0 0>, + /* 400 KB/s*/ + <81 512 1046 1600>, + <1 608 1600 1600>, + /* 20 MB/s */ + <81 512 52286 80000>, + <1 608 80000 80000>, + /* 25 MB/s */ + <81 512 65360 100000>, + <1 608 100000 100000>, + /* 50 MB/s */ + <81 512 130718 200000>, + <1 608 133320 133320>, + /* 100 MB/s */ + <81 512 261438 200000>, + <1 608 150000 150000>, + /* 200 MB/s */ + <81 512 261438 400000>, + <1 608 300000 300000>, + /* Max. bandwidth */ + <81 512 1338562 4096000>, + <1 608 1338562 4096000>; + qcom,bus-bw-vectors-bps = <0 400000 20000000 25000000 50000000 + 100750000 200000000 4294967295>; + /* PM QoS */ + qcom,pm-qos-irq-type = "affine_irq"; + qcom,pm-qos-irq-latency = <67 67>; + qcom,pm-qos-cpu-groups = <0x3f 0xc0>; + qcom,pm-qos-legacy-latency-us = <67 67>, <67 67>; + clocks = <&clock_virt GCC_SDCC2_AHB_CLK>, + <&clock_virt GCC_SDCC2_APPS_CLK>; + clock-names = "iface_clk", "core_clk"; + /* DLL HSR settings. Refer go/hsr - DLL settings */ + qcom,dll-hsr-list = <0x0007642C 0x0 0x0 0x00010800 0x80040868>; + + vdd-supply = <&pm6155_1_l10>; + qcom,vdd-voltage-level = <2950000 2950000>; + qcom,vdd-current-level = <0 800000>; + vdd-io-supply = <&pm6155_1_l2>; + qcom,vdd-io-voltage-level = <1800000 3100000>; + qcom,vdd-io-current-level = <0 22000>; + pinctrl-names = "active", "sleep"; + pinctrl-0 = <&sdc2_clk_on + &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>; + pinctrl-1 = <&sdc2_clk_off + &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>; + cd-gpios = <&tlmm 99 1>; + + status = "disabled"; + }; }; #include "sa6155p-vm-pinctrl.dtsi" -- GitLab From cf8207dc2ff2d6bbc86a9503156d00317f56041e Mon Sep 17 00:00:00 2001 From: Naresh Munagala Date: Tue, 11 Jun 2019 16:16:24 +0530 Subject: [PATCH 0713/1121] drivers: gnss: Add SiRFStart GNSS chip power controls This is a driver to handle SiRFStar GNSS chip power controls, a device node is created to interact with driver power controls and exposes set of IOCTLs. These IOCTLs provide mechanisms to transition of GNSS receiver power state. Change-Id: I96056fc860c5be66e4b5bbdfecf6b572eaae971f Signed-off-by: Naresh Munagala --- .../bindings/gnsssirf/gnss_sirf.txt | 47 +++ Documentation/gnsssirf/gnss_sirf.txt | 17 ++ drivers/Kconfig | 2 + drivers/Makefile | 2 + drivers/gnsssirf/Kconfig | 11 + drivers/gnsssirf/Makefile | 3 + drivers/gnsssirf/gnss_sirf.c | 267 ++++++++++++++++++ drivers/gnsssirf/gnss_sirf.h | 31 ++ 8 files changed, 380 insertions(+) create mode 100644 Documentation/devicetree/bindings/gnsssirf/gnss_sirf.txt create mode 100644 Documentation/gnsssirf/gnss_sirf.txt create mode 100644 drivers/gnsssirf/Kconfig create mode 100644 drivers/gnsssirf/Makefile create mode 100644 drivers/gnsssirf/gnss_sirf.c create mode 100644 drivers/gnsssirf/gnss_sirf.h diff --git a/Documentation/devicetree/bindings/gnsssirf/gnss_sirf.txt b/Documentation/devicetree/bindings/gnsssirf/gnss_sirf.txt new file mode 100644 index 000000000000..18e8b251d9c5 --- /dev/null +++ b/Documentation/devicetree/bindings/gnsssirf/gnss_sirf.txt @@ -0,0 +1,47 @@ +Binding for SIRF GNSS receiver control driver +GPIO pins are toggled to control GNSS receiver power states either to +wake it from sleep or put receiver into sleep mode + +Required properties: +- compatible: must be "gnss_sirf" +- #gpio-pins: + 0: GPIO 18 + 1: GPIO 87 + +Example: + ss5_pwr_ctrl0 { + compatible = "gnss_sirf"; + pinctrl-0 = <&ss5_pwr_ctrl_rst_on>; + ssVreset-gpio = <&tlmm 87 1>; + ssVonoff-gpio = <&tlmm 18 1>; + }; + + ss5_pwr_ctrl_pins: ss5_pwr_ctrl_pins { + ss5_pwr_ctrl_rst_on: ss5_pwr_ctrl_rst_on { + mux { + pins = "gpio87", "gpio18"; + function = "gpio"; + }; + + config { + pins = "gpio87", "gpio18"; + drive-strength = <16>; /* 16 mA */ + bias-pull-up; + output-high; + }; + }; + + ss5_pwr_ctrl_rst_off: ss5_pwr_ctrl_off { + mux { + pins = "gpio87", "gpio18"; + function = "gpio"; + }; + + config { + pins = "gpio87", "gpio18"; + drive-strength = <16>; /* 16 mA */ + bias-pull-up; + output-high; + }; + }; + }; diff --git a/Documentation/gnsssirf/gnss_sirf.txt b/Documentation/gnsssirf/gnss_sirf.txt new file mode 100644 index 000000000000..77cc06a07374 --- /dev/null +++ b/Documentation/gnsssirf/gnss_sirf.txt @@ -0,0 +1,17 @@ +GNSS Driver for SiRFStar Chip +============================= + +Description: +This is a driver to handle SiRFStar GNSS chip power controls, a device node +is created to interact with driver power controls and exposes set of IOCTLs. +These IOCTLs provide mechanisms to transition of GNSS receiver power state. + +GPIO Usage: + probe will provide GPIO pins information to driver to control GNSS power + +Device Node Creation: + A device node is will be created as /dev/gnss_sirf + +Device Node Usage: + Device node /dev/gnss_sirf can be used to control ON_OFF & RESET pins of + SiRFStar GNSS receiver using exposed IOCTLS diff --git a/drivers/Kconfig b/drivers/Kconfig index 29096a4caa44..ed96eb7d8ba2 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -71,6 +71,8 @@ source "drivers/pinctrl/Kconfig" source "drivers/gpio/Kconfig" +source "drivers/gnsssirf/Kconfig" + source "drivers/w1/Kconfig" source "drivers/power/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index f409e6ddf143..cef0160448bc 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -188,3 +188,5 @@ obj-$(CONFIG_TEE) += tee/ obj-$(CONFIG_MULTIPLEXER) += mux/ obj-$(CONFIG_SENSORS_SSC) += sensors/ obj-$(CONFIG_ESOC) += esoc/ +# GNSS driver +obj-$(CONFIG_GNSS_SIRF) += gnsssirf/ diff --git a/drivers/gnsssirf/Kconfig b/drivers/gnsssirf/Kconfig new file mode 100644 index 000000000000..559a6b62f815 --- /dev/null +++ b/drivers/gnsssirf/Kconfig @@ -0,0 +1,11 @@ +# +# SIRF GNSS receiver configuration +# + +menu "GNSS SIRF controls" +config GNSS_SIRF + bool "GNSS SIRF" + help + Driver for ports of GNSS SIRF functionality + +endmenu diff --git a/drivers/gnsssirf/Makefile b/drivers/gnsssirf/Makefile new file mode 100644 index 000000000000..e8400ec13ea2 --- /dev/null +++ b/drivers/gnsssirf/Makefile @@ -0,0 +1,3 @@ +# SIRF GNSS driver makefile. + +obj-$(CONFIG_GNSS_SIRF) += gnss_sirf.o \ No newline at end of file diff --git a/drivers/gnsssirf/gnss_sirf.c b/drivers/gnsssirf/gnss_sirf.c new file mode 100644 index 000000000000..5281cecb6f15 --- /dev/null +++ b/drivers/gnsssirf/gnss_sirf.c @@ -0,0 +1,267 @@ +/* + * + * SiRF GNSS Driver + * + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "gnss_sirf.h" + + +static int resetPin; +static int onOffPin; + +static dev_t gnssDev; +static struct cdev c_dev; +static struct class *devClass; + +static int gnss_sirf_driver_open(struct inode *inode, struct file *filp); +static ssize_t gnss_sirf_driver_read(struct file *filp, char *buf, + size_t count, loff_t *f_pos); +static ssize_t gnss_sirf_driver_write(struct file *filp, const char *buf, + size_t count, loff_t *f_pos); +static int gnss_sirf_driver_release(struct inode *inode, struct file *filp); +static long gnss_sirf_driver_ioctl(struct file *file, unsigned int cmd, + unsigned long arg); + +static int gnss_sirf_probe(struct platform_device *pdev); +static int gnss_sirf_remove(struct platform_device *pdev); + + +static const struct of_device_id gnss_sirf_match_table[] = { + { .compatible = "gnss_sirf" }, + { } +}; + +static const struct file_operations gnss_sirf_fops = { + .open = gnss_sirf_driver_open, + .read = gnss_sirf_driver_read, + .write = gnss_sirf_driver_write, + .release = gnss_sirf_driver_release, + .unlocked_ioctl = gnss_sirf_driver_ioctl, + .owner = THIS_MODULE +}; + +static struct platform_driver gnss_sirf_drv = { + .driver = { + .name = "gnss_sirf", + .of_match_table = gnss_sirf_match_table, + .owner = THIS_MODULE, + }, + .probe = gnss_sirf_probe, + .remove = gnss_sirf_remove, +}; + +static int gnss_sirf_driver_open(struct inode *inode, struct file *filp) +{ + return 0; +} + +static ssize_t gnss_sirf_driver_read(struct file *filp, + char *buf, + size_t count, + loff_t *f_pos) +{ + return 0; +} + +static ssize_t gnss_sirf_driver_write(struct file *filp, + const char *buf, + size_t count, + loff_t *f_pos) +{ + return count; +} + +static int gnss_sirf_driver_release(struct inode *inode, + struct file *filp) +{ + return 0; +} + +static long gnss_sirf_driver_ioctl(struct file *file, + unsigned int cmd, + unsigned long arg) +{ + switch (cmd) { + case IO_CONTROL_SIRF_RESET_CLEAR: + gpio_direction_output(resetPin, 0); + break; + case IO_CONTROL_SIRF_RESET_SET: + gpio_direction_output(resetPin, 1); + break; + case IO_CONTROL_SIRF_ON_OFF_CLEAR: + gpio_direction_output(onOffPin, 0); + break; + case IO_CONTROL_SIRF_ON_OFF_SET: + gpio_direction_output(onOffPin, 1); + break; + default: + break; + } + return 0; +} + + +static int gnss_sirf_init_ports(void) +{ + gpio_direction_output(resetPin, 1); + gpio_direction_output(onOffPin, 1); + return 0; +} + +static int gnss_sirf_deInit_sirf_ports(void) +{ + gpio_direction_output(resetPin, 0); + gpio_direction_output(onOffPin, 0); + return 0; +} + + +static int gnss_sirf_cteate_device(void) +{ + if (alloc_chrdev_region(&gnssDev, 0, 1, "gnss_sirf") < 0) + return -ENODEV; + devClass = class_create(THIS_MODULE, "gnssdevClass"); + if (devClass == NULL) { + unregister_chrdev_region(gnssDev, 1); + return -ENODEV; + } + if (device_create(devClass, NULL, gnssDev, NULL, "gnss_sirf") == NULL) { + class_destroy(devClass); + unregister_chrdev_region(gnssDev, 1); + return -ENODEV; + } + cdev_init(&c_dev, &gnss_sirf_fops); + if (cdev_add(&c_dev, gnssDev, 1) == -1) { + device_destroy(devClass, gnssDev); + class_destroy(devClass); + unregister_chrdev_region(gnssDev, 1); + return -ENODEV; + } + return 0; +} + +static int gnss_sirf_delete_device(void) +{ + /* Remove Char device */ + cdev_del(&c_dev); + device_destroy(devClass, gnssDev); + class_destroy(devClass); + unregister_chrdev_region(gnssDev, 1); + return 0; +} + +static int gnss_sirf_probe(struct platform_device *pdev) +{ + int ret = -ENODEV; + struct device *dev; + + dev = &pdev->dev; + dev_info(dev, "%s", __func__); + if (pdev != NULL) { + if (pdev->name) { + resetPin = of_get_named_gpio(pdev->dev.of_node, + "ssVreset-gpio", 0); + onOffPin = of_get_named_gpio(pdev->dev.of_node, + "ssVonoff-gpio", 0); + if (gpio_is_valid(resetPin)) { + ret = gpio_request(resetPin, "ssVreset-gpio"); + if (ret < 0) { + pr_err("failed to request gpio %d: error:%d\n", + resetPin, ret); + return ret; + } + } + if (gpio_is_valid(onOffPin)) { + ret = gpio_request(onOffPin, "ssVonoff-gpio"); + if (ret < 0) { + pr_err("failed to request gpio %d: error:%d\n", + onOffPin, ret); + return ret; + } + } + gpio_direction_output(resetPin, 1); + gpio_direction_output(onOffPin, 1); + if (gnss_sirf_init_ports() < 0) + pr_err("gnss_sirf_init_ports failed\n"); + else + ret = 0; + } + } + return ret; +} + + +static int gnss_sirf_remove(struct platform_device *pdev) +{ + gnss_sirf_delete_device(); + + if (gnss_sirf_deInit_sirf_ports() < 0) { + pr_err("gnss_sirf_deInit_sirf_ports failed\n"); + return -ENODEV; + } + return 0; +} + + +static int __init gnss_sirf_init(void) +{ + int retVal; + + retVal = platform_driver_register(&gnss_sirf_drv); + if (retVal) { + pr_err("GNSS platform driver registation Failed !!!!\n"); + return retVal; + } + + retVal = gnss_sirf_cteate_device(); + return retVal; +} + + +static void __exit gnss_sirf_exit(void) +{ + platform_driver_unregister(&gnss_sirf_drv); +} + + +module_init(gnss_sirf_init); +module_exit(gnss_sirf_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("SIRF GNSS reciver control driver"); diff --git a/drivers/gnsssirf/gnss_sirf.h b/drivers/gnsssirf/gnss_sirf.h new file mode 100644 index 000000000000..ad87709f65d2 --- /dev/null +++ b/drivers/gnsssirf/gnss_sirf.h @@ -0,0 +1,31 @@ +/* + * + * SiRF GNSS Driver + * + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _GNSS_SIRF_H_ +#define _GNSS_SIRF_H_ + +#include + + +/* IO Control used to interface with SiRF GNSS receiver */ +#define IO_CONTROL_SIRF_MAGIC_CODE 'Q' +#define IO_CONTROL_SIRF_RESET_CLEAR _IOW(IO_CONTROL_SIRF_MAGIC_CODE, 0, int) +#define IO_CONTROL_SIRF_RESET_SET _IOW(IO_CONTROL_SIRF_MAGIC_CODE, 1, int) +#define IO_CONTROL_SIRF_ON_OFF_CLEAR _IOW(IO_CONTROL_SIRF_MAGIC_CODE, 2, int) +#define IO_CONTROL_SIRF_ON_OFF_SET _IOW(IO_CONTROL_SIRF_MAGIC_CODE, 3, int) + +#endif //_GNSS_SIRF_H_ -- GitLab From bc979a53fa78a84566d5f571a22da8a536410699 Mon Sep 17 00:00:00 2001 From: Suraj Jaiswal Date: Tue, 25 Jun 2019 16:44:34 +0530 Subject: [PATCH 0714/1121] msm: defconfig: Disable IPA for sm6150 auto IPA accelerator is not needed for SM6150 auto products. Make a change to disable the defconfig. Change-Id: Ia3a6283435e5d812c79e1a2675507401fbafdaa1 Signed-off-by: Suraj Jaiswal --- arch/arm64/configs/vendor/sdmsteppe-auto-perf_defconfig | 6 +----- arch/arm64/configs/vendor/sdmsteppe-auto_defconfig | 7 +------ 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/arch/arm64/configs/vendor/sdmsteppe-auto-perf_defconfig b/arch/arm64/configs/vendor/sdmsteppe-auto-perf_defconfig index ec0ea0708667..a449ce2f4880 100644 --- a/arch/arm64/configs/vendor/sdmsteppe-auto-perf_defconfig +++ b/arch/arm64/configs/vendor/sdmsteppe-auto-perf_defconfig @@ -515,11 +515,7 @@ CONFIG_QPNP_REVID=y CONFIG_SPS=y CONFIG_SPS_SUPPORT_NDP_BAM=y CONFIG_USB_BAM=y -CONFIG_IPA3=y -CONFIG_IPA_WDI_UNIFIED_API=y -CONFIG_RMNET_IPA3=y -CONFIG_RNDIS_IPA=y -CONFIG_IPA_UT=y +CONFIG_GSI=y CONFIG_MSM_11AD=m CONFIG_QCOM_MDSS_PLL=y CONFIG_SPMI_PMIC_CLKDIV=y diff --git a/arch/arm64/configs/vendor/sdmsteppe-auto_defconfig b/arch/arm64/configs/vendor/sdmsteppe-auto_defconfig index cc453bb6e587..ec93b2066a87 100644 --- a/arch/arm64/configs/vendor/sdmsteppe-auto_defconfig +++ b/arch/arm64/configs/vendor/sdmsteppe-auto_defconfig @@ -539,12 +539,7 @@ CONFIG_QPNP_REVID=y CONFIG_SPS=y CONFIG_SPS_SUPPORT_NDP_BAM=y CONFIG_USB_BAM=y -CONFIG_IPA3=y -CONFIG_IPA_DEBUG=y -CONFIG_IPA_WDI_UNIFIED_API=y -CONFIG_RMNET_IPA3=y -CONFIG_RNDIS_IPA=y -CONFIG_IPA_UT=y +CONFIG_GSI=y CONFIG_MSM_11AD=m CONFIG_QCOM_MDSS_PLL=y CONFIG_SPMI_PMIC_CLKDIV=y -- GitLab From bde1baf18d852f9777a6c80d742980197d5a3e26 Mon Sep 17 00:00:00 2001 From: Chaitanya Pratapa Date: Mon, 24 Jun 2019 22:56:19 +0530 Subject: [PATCH 0715/1121] msm: ipa3: Fix to recycle buffers Make a change to protect cleaning up of recycle buffers as there can be a race between clean up and recycling. Change-Id: I7cc4f40ea87fb0a2b9ce76ff24b47c5d8a02d94f Signed-off-by: Chaitanya Pratapa --- drivers/platform/msm/ipa/ipa_v3/ipa_dp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c index 1fbe078b9621..1e8391a41084 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c @@ -2396,6 +2396,7 @@ static void ipa3_cleanup_rx(struct ipa3_sys_context *sys) * provided to gsi */ + spin_lock_bh(&sys->spinlock); list_for_each_entry_safe(rx_pkt, r, &sys->rcycl_list, link) { list_del(&rx_pkt->link); @@ -2404,6 +2405,7 @@ static void ipa3_cleanup_rx(struct ipa3_sys_context *sys) sys->free_skb(rx_pkt->data.skb); kmem_cache_free(ipa3_ctx->rx_pkt_wrapper_cache, rx_pkt); } + spin_unlock_bh(&sys->spinlock); if (sys->repl) { head = atomic_read(&sys->repl->head_idx); -- GitLab From ccf8af271ebe202db46451a6df87ac825ea40a61 Mon Sep 17 00:00:00 2001 From: Hardik Arya Date: Wed, 17 Apr 2019 20:25:52 +0530 Subject: [PATCH 0716/1121] diag: Free global buffer properly after receiving write done Currently diag apps buffer are not free properly after receiving write done completion, which is leading to use after free. The patch frees global hdlc and non_hdlc data buffer from mempool properly after receiving write done. Change-Id: If60de6be206ddd796a876dcf8060259cfd8a5424 Signed-off-by: Hardik Arya --- drivers/char/diag/diagchar.h | 12 ++++ drivers/char/diag/diagchar_core.c | 114 ++++++++++++++++++++++-------- drivers/char/diag/diagfwd.c | 19 ++++- 3 files changed, 111 insertions(+), 34 deletions(-) diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h index 4df87f9eee54..2c49615c5581 100644 --- a/drivers/char/diag/diagchar.h +++ b/drivers/char/diag/diagchar.h @@ -641,6 +641,7 @@ struct diagchar_dev { unsigned int poolsize_dci; unsigned int poolsize_user; spinlock_t diagmem_lock; + wait_queue_head_t hdlc_wait_q; /* Buffers for masks */ struct mutex diag_cntl_mutex; /* Members for Sending response */ @@ -745,6 +746,17 @@ extern struct diagchar_dev *driver; extern int wrap_enabled; extern uint16_t wrap_count; +struct diag_apps_data_t { + void *buf; + uint32_t len; + int ctxt; + uint8_t allocated; + uint8_t flushed; +}; + +extern struct diag_apps_data_t hdlc_data; +extern struct diag_apps_data_t non_hdlc_data; + void diag_get_timestamp(char *time_str); void check_drain_timer(void); int diag_get_remote(int remote_info); diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c index 5428ad8c1c00..789f1184ffcc 100644 --- a/drivers/char/diag/diagchar_core.c +++ b/drivers/char/diag/diagchar_core.c @@ -156,14 +156,8 @@ static int timer_in_progress; static int diag_mask_clear_param = 1; module_param(diag_mask_clear_param, int, 0644); -struct diag_apps_data_t { - void *buf; - uint32_t len; - int ctxt; -}; - -static struct diag_apps_data_t hdlc_data; -static struct diag_apps_data_t non_hdlc_data; +struct diag_apps_data_t hdlc_data; +struct diag_apps_data_t non_hdlc_data; static struct mutex apps_data_mutex; #define DIAGPKT_MAX_DELAYED_RSP 0xFFFF @@ -225,14 +219,21 @@ static void diag_drain_apps_data(struct diag_apps_data_t *data) if (!data || !data->buf) return; + spin_lock_irqsave(&driver->diagmem_lock, flags); + data->flushed = 1; + spin_unlock_irqrestore(&driver->diagmem_lock, flags); err = diag_mux_write(DIAG_LOCAL_PROC, data->buf, data->len, data->ctxt); - spin_lock_irqsave(&driver->diagmem_lock, flags); - if (err) + + if (err) { + spin_lock_irqsave(&driver->diagmem_lock, flags); diagmem_free(driver, data->buf, POOL_TYPE_HDLC); - data->buf = NULL; - data->len = 0; - spin_unlock_irqrestore(&driver->diagmem_lock, flags); + data->buf = NULL; + data->len = 0; + data->allocated = 0; + data->flushed = 0; + spin_unlock_irqrestore(&driver->diagmem_lock, flags); + } } void diag_update_user_client_work_fn(struct work_struct *work) @@ -305,6 +306,7 @@ static void diag_mempool_init(void) diagmem_init(driver, POOL_TYPE_DCI); spin_lock_init(&driver->diagmem_lock); + init_waitqueue_head(&driver->hdlc_wait_q); } static void diag_mempool_exit(void) @@ -3060,31 +3062,47 @@ static int diag_process_apps_data_hdlc(unsigned char *buf, int len, send.last = (void *)(buf + len - 1); send.terminate = 1; - if (!data->buf) + wait_event_interruptible(driver->hdlc_wait_q, + (data->flushed == 0)); + if (!data->buf) { + spin_lock_irqsave(&driver->diagmem_lock, flags); data->buf = diagmem_alloc(driver, DIAG_MAX_HDLC_BUF_SIZE + APF_DIAG_PADDING, POOL_TYPE_HDLC); - if (!data->buf) { - ret = PKT_DROP; - goto fail_ret; + if (!data->buf) { + ret = PKT_DROP; + spin_unlock_irqrestore(&driver->diagmem_lock, flags); + goto fail_ret; + } + data->allocated = 1; + data->flushed = 0; + spin_unlock_irqrestore(&driver->diagmem_lock, flags); } if ((DIAG_MAX_HDLC_BUF_SIZE - data->len) <= max_encoded_size) { + spin_lock_irqsave(&driver->diagmem_lock, flags); + data->flushed = 1; + spin_unlock_irqrestore(&driver->diagmem_lock, flags); err = diag_mux_write(DIAG_LOCAL_PROC, data->buf, data->len, data->ctxt); if (err) { ret = -EIO; goto fail_free_buf; } - data->buf = NULL; - data->len = 0; + wait_event_interruptible(driver->hdlc_wait_q, + (data->flushed == 0)); + spin_lock_irqsave(&driver->diagmem_lock, flags); data->buf = diagmem_alloc(driver, DIAG_MAX_HDLC_BUF_SIZE + APF_DIAG_PADDING, POOL_TYPE_HDLC); if (!data->buf) { ret = PKT_DROP; + spin_unlock_irqrestore(&driver->diagmem_lock, flags); goto fail_ret; } + data->allocated = 1; + data->flushed = 0; + spin_unlock_irqrestore(&driver->diagmem_lock, flags); } enc.dest = data->buf + data->len; @@ -3099,21 +3117,29 @@ static int diag_process_apps_data_hdlc(unsigned char *buf, int len, */ if ((uintptr_t)enc.dest >= (uintptr_t)(data->buf + DIAG_MAX_HDLC_BUF_SIZE)) { + spin_lock_irqsave(&driver->diagmem_lock, flags); + data->flushed = 1; + spin_unlock_irqrestore(&driver->diagmem_lock, flags); err = diag_mux_write(DIAG_LOCAL_PROC, data->buf, data->len, data->ctxt); if (err) { ret = -EIO; goto fail_free_buf; } - data->buf = NULL; - data->len = 0; + wait_event_interruptible(driver->hdlc_wait_q, + (data->flushed == 0)); + spin_lock_irqsave(&driver->diagmem_lock, flags); data->buf = diagmem_alloc(driver, DIAG_MAX_HDLC_BUF_SIZE + APF_DIAG_PADDING, POOL_TYPE_HDLC); if (!data->buf) { ret = PKT_DROP; + spin_unlock_irqrestore(&driver->diagmem_lock, flags); goto fail_ret; } + data->allocated = 1; + data->flushed = 0; + spin_unlock_irqrestore(&driver->diagmem_lock, flags); enc.dest = data->buf + data->len; enc.dest_last = (void *)(data->buf + data->len + @@ -3127,23 +3153,27 @@ static int diag_process_apps_data_hdlc(unsigned char *buf, int len, DIAG_MAX_HDLC_BUF_SIZE; if (pkt_type == DATA_TYPE_RESPONSE) { + spin_lock_irqsave(&driver->diagmem_lock, flags); + data->flushed = 1; + spin_unlock_irqrestore(&driver->diagmem_lock, flags); err = diag_mux_write(DIAG_LOCAL_PROC, data->buf, data->len, data->ctxt); if (err) { ret = -EIO; goto fail_free_buf; } - data->buf = NULL; - data->len = 0; } return PKT_ALLOC; fail_free_buf: spin_lock_irqsave(&driver->diagmem_lock, flags); - diagmem_free(driver, data->buf, POOL_TYPE_HDLC); + if (data->allocated) + diagmem_free(driver, data->buf, POOL_TYPE_HDLC); data->buf = NULL; data->len = 0; + data->allocated = 0; + data->flushed = 0; spin_unlock_irqrestore(&driver->diagmem_lock, flags); fail_ret: return ret; @@ -3169,33 +3199,47 @@ static int diag_process_apps_data_non_hdlc(unsigned char *buf, int len, __func__, buf, len); return -EIO; } - + wait_event_interruptible(driver->hdlc_wait_q, + (data->flushed == 0)); if (!data->buf) { + spin_lock_irqsave(&driver->diagmem_lock, flags); data->buf = diagmem_alloc(driver, DIAG_MAX_HDLC_BUF_SIZE + APF_DIAG_PADDING, POOL_TYPE_HDLC); if (!data->buf) { ret = PKT_DROP; + spin_unlock_irqrestore(&driver->diagmem_lock, flags); goto fail_ret; } + data->allocated = 1; + data->flushed = 0; + spin_unlock_irqrestore(&driver->diagmem_lock, flags); } - if ((DIAG_MAX_HDLC_BUF_SIZE - data->len) <= max_pkt_size) { + spin_lock_irqsave(&driver->diagmem_lock, flags); + data->flushed = 1; + spin_unlock_irqrestore(&driver->diagmem_lock, flags); err = diag_mux_write(DIAG_LOCAL_PROC, data->buf, data->len, data->ctxt); if (err) { ret = -EIO; goto fail_free_buf; } - data->buf = NULL; - data->len = 0; + wait_event_interruptible(driver->hdlc_wait_q, + (data->flushed == 0)); + + spin_lock_irqsave(&driver->diagmem_lock, flags); data->buf = diagmem_alloc(driver, DIAG_MAX_HDLC_BUF_SIZE + APF_DIAG_PADDING, POOL_TYPE_HDLC); if (!data->buf) { ret = PKT_DROP; + spin_unlock_irqrestore(&driver->diagmem_lock, flags); goto fail_ret; } + data->allocated = 1; + data->flushed = 0; + spin_unlock_irqrestore(&driver->diagmem_lock, flags); } header.start = CONTROL_CHAR; @@ -3208,23 +3252,27 @@ static int diag_process_apps_data_non_hdlc(unsigned char *buf, int len, *(uint8_t *)(data->buf + data->len) = CONTROL_CHAR; data->len += sizeof(uint8_t); if (pkt_type == DATA_TYPE_RESPONSE) { + spin_lock_irqsave(&driver->diagmem_lock, flags); + data->flushed = 1; + spin_unlock_irqrestore(&driver->diagmem_lock, flags); err = diag_mux_write(DIAG_LOCAL_PROC, data->buf, data->len, data->ctxt); if (err) { ret = -EIO; goto fail_free_buf; } - data->buf = NULL; - data->len = 0; } return PKT_ALLOC; fail_free_buf: spin_lock_irqsave(&driver->diagmem_lock, flags); - diagmem_free(driver, data->buf, POOL_TYPE_HDLC); + if (data->allocated) + diagmem_free(driver, data->buf, POOL_TYPE_HDLC); data->buf = NULL; data->len = 0; + data->allocated = 0; + data->flushed = 0; spin_unlock_irqrestore(&driver->diagmem_lock, flags); fail_ret: return ret; @@ -4355,8 +4403,12 @@ static int __init diagchar_init(void) driver->rsp_buf_ctxt = SET_BUF_CTXT(APPS_DATA, TYPE_CMD, TYPE_CMD); hdlc_data.ctxt = SET_BUF_CTXT(APPS_DATA, TYPE_DATA, 1); hdlc_data.len = 0; + hdlc_data.allocated = 0; + hdlc_data.flushed = 0; non_hdlc_data.ctxt = SET_BUF_CTXT(APPS_DATA, TYPE_DATA, 1); non_hdlc_data.len = 0; + non_hdlc_data.allocated = 0; + non_hdlc_data.flushed = 0; mutex_init(&driver->hdlc_disable_mutex); mutex_init(&driver->diagchar_mutex); mutex_init(&driver->diag_notifier_mutex); diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c index da6d60e56f2e..ffc360bccea2 100644 --- a/drivers/char/diag/diagfwd.c +++ b/drivers/char/diag/diagfwd.c @@ -1835,6 +1835,7 @@ static int diagfwd_mux_write_done(unsigned char *buf, int len, int buf_ctxt, int peripheral = -1; int type = -1; int num = -1; + struct diag_apps_data_t *temp = NULL; if (!buf || len < 0) return -EINVAL; @@ -1853,9 +1854,21 @@ static int diagfwd_mux_write_done(unsigned char *buf, int len, int buf_ctxt, diag_ws_on_copy(DIAG_WS_MUX); } else if (peripheral == APPS_DATA) { spin_lock_irqsave(&driver->diagmem_lock, flags); - diagmem_free(driver, (unsigned char *)buf, - POOL_TYPE_HDLC); - buf = NULL; + if (hdlc_data.allocated) + temp = &hdlc_data; + else if (non_hdlc_data.allocated) + temp = &non_hdlc_data; + else + DIAG_LOG(DIAG_DEBUG_PERIPHERALS, + "No apps data buffer is allocated to be freed\n"); + if (temp) { + diagmem_free(driver, temp->buf, POOL_TYPE_HDLC); + temp->buf = NULL; + temp->len = 0; + temp->allocated = 0; + temp->flushed = 0; + wake_up_interruptible(&driver->hdlc_wait_q); + } spin_unlock_irqrestore(&driver->diagmem_lock, flags); } else { pr_err_ratelimited("diag: Invalid peripheral %d in %s, type: %d\n", -- GitLab From 5388dc5b7cf03f7c4299de8a3fd4a85889b4e7a7 Mon Sep 17 00:00:00 2001 From: Tejas Prajapati Date: Wed, 26 Jun 2019 11:58:13 +0530 Subject: [PATCH 0717/1121] msm: camera: isp: remove the check for bpp bpp parameter received in the ioconfig structure is invalid, so removing the check for bpp. Change-Id: Ibab274ee9131c422367ed92ea77c3dc946154d98 Signed-off-by: Tejas Prajapati --- .../media/platform/msm/camera/cam_utils/cam_packet_util.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.c b/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.c index ecb4fe4c401a..4eae9ae5f276 100644 --- a/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.c +++ b/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.c @@ -361,7 +361,6 @@ int32_t cam_packet_validate_plane_size( { int rc = 0; uint32_t kmd_plane_size = 0; - uint32_t bpp = io_cfg->bpp; uint32_t plane_stride = 0; uint32_t slice_height = 0; uint32_t metadata_size = 0; @@ -406,12 +405,7 @@ int32_t cam_packet_validate_plane_size( case CAM_FORMAT_PLAIN16_12: case CAM_FORMAT_PLAIN16_14: case CAM_FORMAT_PLAIN16_16: - if (bpp == 8 || bpp == 10 || bpp == 12 - || bpp == 14 || bpp == 16) - kmd_plane_size = plane_stride * slice_height; - break; case CAM_FORMAT_PLAIN64: - if (bpp == 64) kmd_plane_size = plane_stride * slice_height; break; case CAM_FORMAT_NV21: -- GitLab From d792ad38640aabeea7c56c28fb75fb13c399ad6f Mon Sep 17 00:00:00 2001 From: Rajeshwar Kurapaty Date: Mon, 17 Jun 2019 17:50:45 +0530 Subject: [PATCH 0718/1121] ARM: dts: msm: Add secure display heap configuration for ATOLL Add secure display heap configuration to enable secure memory allocations for secure display/camera usecases. Change-Id: I44840ce37db9f616e38b4023f090bf743f91ba67 Signed-off-by: Rajeshwar Kurapaty --- arch/arm64/boot/dts/qcom/atoll-ion.dtsi | 6 ++++++ arch/arm64/boot/dts/qcom/atoll.dtsi | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/atoll-ion.dtsi b/arch/arm64/boot/dts/qcom/atoll-ion.dtsi index 2966fd20d235..fa7262d64552 100644 --- a/arch/arm64/boot/dts/qcom/atoll-ion.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll-ion.dtsi @@ -31,5 +31,11 @@ reg = <9>; qcom,ion-heap-type = "SYSTEM_SECURE"; }; + + qcom,ion-heap@10 { /* SECURE DISPLAY HEAP */ + reg = <10>; + memory-region = <&secure_display_memory>; + qcom,ion-heap-type = "HYP_CMA"; + }; }; }; diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index 0f766895227c..d3f1d7f17fa9 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -557,6 +557,15 @@ no-map; reg = <0 0x9f400000 0 0xc00000>; }; + + secure_display_memory: secure_display_region { + compatible = "shared-dma-pool"; + alloc-ranges = <0 0x00000000 0 0xffffffff>; + reusable; + alignment = <0 0x400000>; + size = <0 0x8c00000>; + }; + /* global autoconfigured region for contiguous allocations */ linux,cma { compatible = "shared-dma-pool"; -- GitLab From 77a6180c4799804d75d4023ceadcc08117659850 Mon Sep 17 00:00:00 2001 From: Odelu Kukatla Date: Wed, 19 Jun 2019 14:41:18 +0530 Subject: [PATCH 0719/1121] clk: qcom: Use regmap_update_bits() to update the clock flags Currently clk_cbcr_set_flags() reads the CBCR register content, modifies the flags and writes back the updated value into it. Sometimes clk_set_flags() gets invoked for the same clock while clk_enable() is in progress causing the CLK_ENABLE bit getting updated outside of clk_enable() path. Therefore, use regmap_update_bits() to update the flags in CBCR register. Also add a barrier in clock enable/disable path to make sure that register write goes through. Change-Id: I8018f8033d05273320fd92cc7d21fcdce0885dfc Signed-off-by: Odelu Kukatla --- drivers/clk/qcom/clk-branch.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/clk/qcom/clk-branch.c b/drivers/clk/qcom/clk-branch.c index 3055c359c167..ed12f6b99393 100644 --- a/drivers/clk/qcom/clk-branch.c +++ b/drivers/clk/qcom/clk-branch.c @@ -125,6 +125,12 @@ static int clk_branch_toggle(struct clk_hw *hw, bool en, clk_disable_regmap(hw); } + /* + * Make sure enable/disable request goes through before waiting + * for CLK_OFF status to get updated. + */ + mb(); + return clk_branch_wait(br, en, check_halt); } @@ -136,34 +142,36 @@ static int clk_branch_enable(struct clk_hw *hw) static int clk_cbcr_set_flags(struct regmap *regmap, unsigned int reg, unsigned long flags) { - u32 cbcr_val; - - regmap_read(regmap, reg, &cbcr_val); + u32 cbcr_val = 0; + u32 cbcr_mask; + int ret; switch (flags) { case CLKFLAG_PERIPH_OFF_SET: - cbcr_val |= BIT(12); + cbcr_val = cbcr_mask = BIT(12); break; case CLKFLAG_PERIPH_OFF_CLEAR: - cbcr_val &= ~BIT(12); + cbcr_mask = BIT(12); break; case CLKFLAG_RETAIN_PERIPH: - cbcr_val |= BIT(13); + cbcr_val = cbcr_mask = BIT(13); break; case CLKFLAG_NORETAIN_PERIPH: - cbcr_val &= ~BIT(13); + cbcr_mask = BIT(13); break; case CLKFLAG_RETAIN_MEM: - cbcr_val |= BIT(14); + cbcr_val = cbcr_mask = BIT(14); break; case CLKFLAG_NORETAIN_MEM: - cbcr_val &= ~BIT(14); + cbcr_mask = BIT(14); break; default: return -EINVAL; } - regmap_write(regmap, reg, cbcr_val); + ret = regmap_update_bits(regmap, reg, cbcr_mask, cbcr_val); + if (ret) + return ret; /* Make sure power is enabled/disabled before returning. */ mb(); -- GitLab From fba9fa0f6bf260b16ba149a91a4e763550bf45f9 Mon Sep 17 00:00:00 2001 From: Siva Kumar Akkireddi Date: Thu, 27 Jun 2019 17:03:29 +0530 Subject: [PATCH 0720/1121] ARM: dts: msm: Add device node support for TSENS in atoll Add TSENS node and user thermal zone configurations for TSENS sensors in atoll. Change-Id: Ie7633c2896d18a6a3f75c0780d25745acb0a31e5 Signed-off-by: Siva Kumar Akkireddi --- arch/arm64/boot/dts/qcom/atoll-thermal.dtsi | 500 ++++++++++++++++++++ arch/arm64/boot/dts/qcom/atoll.dtsi | 22 + 2 files changed, 522 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/atoll-thermal.dtsi b/arch/arm64/boot/dts/qcom/atoll-thermal.dtsi index 5950a7a91f26..3397ad51b4b2 100644 --- a/arch/arm64/boot/dts/qcom/atoll-thermal.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll-thermal.dtsi @@ -14,6 +14,506 @@ #include &thermal_zones { + aoss-0-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&tsens0 0>; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + reset-mon-cfg { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + cpu-0-0-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&tsens0 1>; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + reset-mon-cfg { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + cpu-0-1-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&tsens0 2>; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + reset-mon-cfg { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + cpu-0-2-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&tsens0 3>; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + reset-mon-cfg { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + cpu-0-3-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 4>; + thermal-governor = "user_space"; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + reset-mon-cfg { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + cpu-0-4-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 5>; + thermal-governor = "user_space"; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + reset-mon-cfg { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + cpu-0-5-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 6>; + thermal-governor = "user_space"; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + reset-mon-cfg { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + cpuss-0-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 7>; + thermal-governor = "user_space"; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + reset-mon-cfg { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + cpuss-1-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 8>; + thermal-governor = "user_space"; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + reset-mon-cfg { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + cpu-1-0-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 9>; + thermal-governor = "user_space"; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + reset-mon-cfg { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + cpu-1-1-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 10>; + thermal-governor = "user_space"; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + reset-mon-cfg { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + cpu-1-2-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 11>; + thermal-governor = "user_space"; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + reset-mon-cfg { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + cpu-1-3-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 12>; + thermal-governor = "user_space"; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + reset-mon-cfg { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + gpuss-0-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 13>; + thermal-governor = "user_space"; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + reset-mon-cfg { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + gpuss-1-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 14>; + thermal-governor = "user_space"; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + reset-mon-cfg { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + aoss-1-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens1 0>; + thermal-governor = "user_space"; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + reset-mon-cfg { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + cwlan-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens1 1>; + thermal-governor = "user_space"; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + reset-mon-cfg { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + audio-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens1 2>; + thermal-governor = "user_space"; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + reset-mon-cfg { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + ddr-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens1 3>; + thermal-governor = "user_space"; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + reset-mon-cfg { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + q6-hvx-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens1 4>; + thermal-governor = "user_space"; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + reset-mon-cfg { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + camera-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens1 5>; + thermal-governor = "user_space"; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + reset-mon-cfg { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + mdm-core-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens1 6>; + thermal-governor = "user_space"; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + reset-mon-cfg { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + mdm-dsp-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens1 7>; + thermal-governor = "user_space"; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + reset-mon-cfg { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + npu-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens1 8>; + thermal-governor = "user_space"; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + reset-mon-cfg { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + video-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens1 9>; + thermal-governor = "user_space"; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + reset-mon-cfg { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + xo-therm-usr { polling-delay-passive = <0>; polling-delay = <0>; diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index 0f766895227c..63c9ff153ddb 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -1889,6 +1889,28 @@ }; thermal_zones: thermal-zones {}; + + tsens0: tsens@c222000 { + compatible = "qcom,tsens24xx"; + reg = <0xc222000 0x8>, + <0xc263000 0x1ff>; + reg-names = "tsens_srot_physical", + "tsens_tm_physical"; + interrupts = <0 506 0>, <0 508 0>; + interrupt-names = "tsens-upper-lower", "tsens-critical"; + #thermal-sensor-cells = <1>; + }; + + tsens1: tsens@c223000 { + compatible = "qcom,tsens24xx"; + reg = <0xc223000 0x8>, + <0xc265000 0x1ff>; + reg-names = "tsens_srot_physical", + "tsens_tm_physical"; + interrupts = <0 507 0>, <0 509 0>; + interrupt-names = "tsens-upper-lower", "tsens-critical"; + #thermal-sensor-cells = <1>; + }; }; #include "atoll-gdsc.dtsi" -- GitLab From a54ebbb38549095494bf6252babbf7939cc68e36 Mon Sep 17 00:00:00 2001 From: Sushmita Susheelendra Date: Thu, 27 Jun 2019 10:55:28 -0600 Subject: [PATCH 0721/1121] msm: kgsl: Only read throttle counters if GMU is enabled Throttle counters are only used with GMU. Platforms without the GMU should return early without reading them. Change-Id: I0df614439c0629afbc7a1ebaca279e4a1042949d Signed-off-by: Sushmita Susheelendra --- drivers/gpu/msm/adreno_a6xx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/msm/adreno_a6xx.c b/drivers/gpu/msm/adreno_a6xx.c index 81a93c5dbfa8..d770f0fee593 100644 --- a/drivers/gpu/msm/adreno_a6xx.c +++ b/drivers/gpu/msm/adreno_a6xx.c @@ -1449,6 +1449,9 @@ static int64_t a6xx_read_throttling_counters(struct adreno_device *adreno_dev) struct kgsl_device *device = KGSL_DEVICE(adreno_dev); struct gmu_device *gmu = KGSL_GMU_DEVICE(device); + if (!gmu_core_isenabled(device)) + return 0; + for (i = 0; i < ARRAY_SIZE(counts); i++) { if (!adreno_dev->gpmu_throttle_counters[i]) counts[i] = 0; -- GitLab From 0b0a93d8eb2bf0c956924fec51c51b33bf4380e9 Mon Sep 17 00:00:00 2001 From: "Thomas (Wonyoung) Yun" Date: Mon, 1 Apr 2019 11:22:33 -0400 Subject: [PATCH 0722/1121] ARM: dts: msm: Add GPU frequency @500Mhz to NOMINAL Add the GPU frequency to LEVEL_NOM Change-Id: I6769e131e40e06cf07e4009cf003f791c3faa340 Signed-off-by: Thomas (Wonyoung) Yun --- arch/arm64/boot/dts/qcom/sa8155-v2.dtsi | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sa8155-v2.dtsi b/arch/arm64/boot/dts/qcom/sa8155-v2.dtsi index a98d52061524..b43385b399fb 100644 --- a/arch/arm64/boot/dts/qcom/sa8155-v2.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8155-v2.dtsi @@ -48,6 +48,11 @@ opp-microvolt = ; }; + opp-500000000 { + opp-hz = /bits/ 64 <500000000>; + opp-microvolt = ; + }; + opp-427000000 { opp-hz = /bits/ 64 <427000000>; opp-microvolt = ; @@ -101,30 +106,38 @@ qcom,gpu-pwrlevel@3 { reg = <3>; + qcom,gpu-freq = <500000000>; + qcom,bus-freq = <7>; + qcom,bus-min = <6>; + qcom,bus-max = <11>; + }; + + qcom,gpu-pwrlevel@4 { + reg = <4>; qcom,gpu-freq = <427000000>; qcom,bus-freq = <6>; qcom,bus-min = <5>; qcom,bus-max = <9>; }; - qcom,gpu-pwrlevel@4 { - reg = <4>; + qcom,gpu-pwrlevel@5 { + reg = <5>; qcom,gpu-freq = <345000000>; qcom,bus-freq = <3>; qcom,bus-min = <3>; qcom,bus-max = <8>; }; - qcom,gpu-pwrlevel@5 { - reg = <5>; + qcom,gpu-pwrlevel@6 { + reg = <6>; qcom,gpu-freq = <257000000>; qcom,bus-freq = <2>; qcom,bus-min = <1>; qcom,bus-max = <8>; }; - qcom,gpu-pwrlevel@6 { - reg = <6>; + qcom,gpu-pwrlevel@7 { + reg = <7>; qcom,gpu-freq = <0>; qcom,bus-freq = <0>; qcom,bus-min = <0>; -- GitLab From a4cc2897651d95abc6477e7431793f9c5eabf431 Mon Sep 17 00:00:00 2001 From: Archit Saxena Date: Tue, 14 May 2019 15:14:17 +0530 Subject: [PATCH 0723/1121] ARM: dts: msm: Support 1.4 GHz frequency level for QCS405 Add 1.4 GHz frequency level on qcs405. Change-Id: Ic757ea7e9af2408520ea3dde86238f27ef8e2100 Signed-off-by: Archit Saxena --- arch/arm64/boot/dts/qcom/qcs405.dtsi | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/qcs405.dtsi b/arch/arm64/boot/dts/qcom/qcs405.dtsi index 47fdcb141b61..a8639eb4ec0c 100644 --- a/arch/arm64/boot/dts/qcom/qcs405.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs405.dtsi @@ -1354,7 +1354,8 @@ qcom,cpufreq-table = < 1094400 >, - < 1248000 >; + < 1248000 >, + < 1401600 >; }; ddr_bw_opp_table: ddr-bw-opp-table { @@ -1395,7 +1396,8 @@ qcom,target-dev = <&cpu0_cpu_ddr_latfloor>; qcom,core-dev-table = < 1094400 MHZ_TO_MBPS( 297, 8) >, - < 1248000 MHZ_TO_MBPS( 597, 8) >; + < 1248000 MHZ_TO_MBPS( 597, 8) >, + < 1401600 MHZ_TO_MBPS( 710, 8) >; }; emac_hw: qcom,emac@07A80000 { -- GitLab From 9c88718c45723f973feae0267cbf3f5da1837d07 Mon Sep 17 00:00:00 2001 From: Prakruthi Deepak Heragu Date: Wed, 19 Jun 2019 11:50:09 -0700 Subject: [PATCH 0724/1121] AndroidKernel: Building dtb.img to support header version 2 The dtb.img is made by concatenating all the compiled dtbs after the kernel is compiled. This dtb.img is then added to be a part of the boot.img. Change-Id: I7667d1c3118962bbc709a362a2b9a2b6419dede4 Signed-off-by: Prakruthi Deepak Heragu --- AndroidKernel.mk | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/AndroidKernel.mk b/AndroidKernel.mk index 47e11eb5f71d..e17150c54e53 100644 --- a/AndroidKernel.mk +++ b/AndroidKernel.mk @@ -6,6 +6,11 @@ ifeq ($(KERNEL_TARGET),) INSTALLED_KERNEL_TARGET := $(PRODUCT_OUT)/kernel endif +ifneq ($(TARGET_KERNEL_APPEND_DTB), true) +$(info Using DTB Image) +INSTALLED_DTBIMAGE_TARGET := $(PRODUCT_OUT)/dtb.img +endif + TARGET_KERNEL_MAKE_ENV := $(strip $(TARGET_KERNEL_MAKE_ENV)) ifeq ($(TARGET_KERNEL_MAKE_ENV),) KERNEL_MAKE_ENV := @@ -187,6 +192,10 @@ $(KERNEL_HEADERS_INSTALL): $(KERNEL_OUT) echo $(KERNEL_CONFIG_OVERRIDE) >> $(KERNEL_OUT)/.config; \ $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) oldconfig; fi +# Creating a dtb.img once the kernel is compiled if TARGET_KERNEL_APPEND_DTB is set to be false +$(INSTALLED_DTBIMAGE_TARGET): $(TARGET_PREBUILT_INT_KERNEL) + cat $(KERNEL_OUT)/arch/$(KERNEL_ARCH)/boot/dts/vendor/qcom/*.dtb > $@ + .PHONY: kerneltags kerneltags: $(KERNEL_OUT) $(KERNEL_CONFIG) $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) tags -- GitLab From 140a829428757d273575e13168f75e86e056806b Mon Sep 17 00:00:00 2001 From: Sujeev Dias Date: Wed, 30 Jan 2019 10:38:52 -0800 Subject: [PATCH 0725/1121] mhi: core: calculate times based on given timer frequencies Query timer frequencies for host and device and calculate time based on them. CRs-Fixed: 2377061 Change-Id: I8dba580505870f82bb6e2529d1e01c85c4aafd29 Acked-by: Bhaumik Vasav Bhatt Signed-off-by: Sujeev Dias --- drivers/bus/mhi/core/mhi_internal.h | 7 +++++-- drivers/bus/mhi/core/mhi_main.c | 3 ++- include/linux/mhi.h | 2 ++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/bus/mhi/core/mhi_internal.h b/drivers/bus/mhi/core/mhi_internal.h index c888aaa58064..3ae36ac333f4 100644 --- a/drivers/bus/mhi/core/mhi_internal.h +++ b/drivers/bus/mhi/core/mhi_internal.h @@ -234,8 +234,11 @@ extern struct bus_type mhi_bus_type; #define SOC_HW_VERSION_MINOR_VER_BMSK (0x000000FF) #define SOC_HW_VERSION_MINOR_VER_SHFT (0) -/* convert ticks to micro seconds by dividing by 19.2 */ -#define TIME_TICKS_TO_US(x) (div_u64((x) * 10, 192)) +/* timesync time calculations */ +#define LOCAL_TICKS_TO_US(x) (div_u64((x) * 100ULL, \ + div_u64(mhi_cntrl->local_timer_freq, 10000ULL))) +#define REMOTE_TICKS_TO_US(x) (div_u64((x) * 100ULL, \ + div_u64(mhi_cntrl->remote_timer_freq, 10000ULL))) struct mhi_event_ctxt { u32 reserved : 8; diff --git a/drivers/bus/mhi/core/mhi_main.c b/drivers/bus/mhi/core/mhi_main.c index a97259118412..7859ef5749b8 100644 --- a/drivers/bus/mhi/core/mhi_main.c +++ b/drivers/bus/mhi/core/mhi_main.c @@ -717,7 +717,8 @@ static ssize_t time_us_show(struct device *dev, } return scnprintf(buf, PAGE_SIZE, "local: %llu remote: %llu (us)\n", - TIME_TICKS_TO_US(t_host), TIME_TICKS_TO_US(t_device)); + LOCAL_TICKS_TO_US(t_host), + REMOTE_TICKS_TO_US(t_device)); } static DEVICE_ATTR_RO(time_us); diff --git a/include/linux/mhi.h b/include/linux/mhi.h index fd9a331240d4..94b6f4f99883 100644 --- a/include/linux/mhi.h +++ b/include/linux/mhi.h @@ -312,6 +312,8 @@ struct mhi_controller { /* supports time sync feature */ struct mhi_timesync *mhi_tsync; struct mhi_device *tsync_dev; + u64 local_timer_freq; + u64 remote_timer_freq; /* kernel log level */ enum MHI_DEBUG_LEVEL klog_lvl; -- GitLab From a91cb0726961110e13de298f3c77b59afefb2947 Mon Sep 17 00:00:00 2001 From: David Dai Date: Thu, 27 Jun 2019 11:35:26 -0700 Subject: [PATCH 0726/1121] ARM: dts: msm: add proxy bandwidth vote for sm8150 Add 3G proxy bandwidth vote for SM8150 to support continuous splash display usecase. Change-Id: I0592878b9f4a94221dafb0250b124831d78451c0 Signed-off-by: David Dai --- arch/arm64/boot/dts/qcom/sm8150.dtsi | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi index 1bc585cf954d..35857496dfd0 100644 --- a/arch/arm64/boot/dts/qcom/sm8150.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi @@ -1378,14 +1378,20 @@ compatible = "qcom,bus-proxy-client"; qcom,msm-bus,name = "bus-proxy-client"; qcom,msm-bus,num-cases = <2>; - qcom,msm-bus,num-paths = <3>; + qcom,msm-bus,num-paths = <5>; qcom,msm-bus,vectors-KBps = , , , + , + , , , - ; + , + , + ; status = "ok"; }; -- GitLab From a2fed4441067a2c43bb4b2e8eb4e815ca0048b2f Mon Sep 17 00:00:00 2001 From: Sean Tranchetti Date: Fri, 28 Jun 2019 17:12:00 -0600 Subject: [PATCH 0727/1121] net: qualcomm: rmnet: lock descriptor pool In CPU hotplug scenarios, it is possible for the descriptor pool to be accessed by multiple cores at the same time, leading to race conditions where data can be maniuplated at the same time. This can leave the list in an invalid state, leading to errors later in processing. Change-Id: Id7652c47abf80f73f36a5bf89136f0e695887be1 Signed-off-by: Sean Tranchetti --- .../ethernet/qualcomm/rmnet/rmnet_config.h | 3 +- .../qualcomm/rmnet/rmnet_descriptor.c | 39 +++++++++---------- .../qualcomm/rmnet/rmnet_descriptor.h | 12 ++---- 3 files changed, 24 insertions(+), 30 deletions(-) diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h index c7a2e8a0f4d3..ebfc2081e3d3 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h @@ -81,7 +81,8 @@ struct rmnet_port { struct rmnet_port_priv_stats stats; int dl_marker_flush; - struct rmnet_descriptor *rmnet_desc; + /* Descriptor pool */ + spinlock_t desc_pool_lock; struct rmnet_frag_descriptor_pool *frag_desc_pool; }; diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c index 00516925c8a6..b2aa3edf42a4 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c @@ -43,6 +43,7 @@ rmnet_get_frag_descriptor(struct rmnet_port *port) struct rmnet_frag_descriptor_pool *pool = port->frag_desc_pool; struct rmnet_frag_descriptor *frag_desc; + spin_lock(&port->desc_pool_lock); if (!list_empty(&pool->free_list)) { frag_desc = list_first_entry(&pool->free_list, struct rmnet_frag_descriptor, @@ -51,13 +52,15 @@ rmnet_get_frag_descriptor(struct rmnet_port *port) } else { frag_desc = kzalloc(sizeof(*frag_desc), GFP_ATOMIC); if (!frag_desc) - return NULL; + goto out; INIT_LIST_HEAD(&frag_desc->list); INIT_LIST_HEAD(&frag_desc->sub_frags); pool->pool_size++; } +out: + spin_unlock(&port->desc_pool_lock); return frag_desc; } EXPORT_SYMBOL(rmnet_get_frag_descriptor); @@ -73,12 +76,14 @@ void rmnet_recycle_frag_descriptor(struct rmnet_frag_descriptor *frag_desc, memset(frag_desc, 0, sizeof(*frag_desc)); INIT_LIST_HEAD(&frag_desc->list); INIT_LIST_HEAD(&frag_desc->sub_frags); + spin_lock(&port->desc_pool_lock); list_add_tail(&frag_desc->list, &pool->free_list); + spin_unlock(&port->desc_pool_lock); } EXPORT_SYMBOL(rmnet_recycle_frag_descriptor); -void rmnet_descriptor_add_frag(struct rmnet_port *port, struct page *p, - u32 page_offset, u32 len) +void rmnet_descriptor_add_frag(struct rmnet_port *port, struct list_head *list, + struct page *p, u32 page_offset, u32 len) { struct rmnet_frag_descriptor *frag_desc; @@ -87,8 +92,7 @@ void rmnet_descriptor_add_frag(struct rmnet_port *port, struct page *p, return; rmnet_frag_fill(frag_desc, p, page_offset, len); - list_add_tail(&frag_desc->list, &port->rmnet_desc->frags); - port->rmnet_desc->nr_frags++; + list_add_tail(&frag_desc->list, list); } EXPORT_SYMBOL(rmnet_descriptor_add_frag); @@ -318,7 +322,8 @@ int rmnet_frag_flow_command(struct rmnet_map_header *qmap, } EXPORT_SYMBOL(rmnet_frag_flow_command); -void rmnet_frag_deaggregate(skb_frag_t *frag, struct rmnet_port *port) +void rmnet_frag_deaggregate(skb_frag_t *frag, struct rmnet_port *port, + struct list_head *list) { struct rmnet_map_header *maph; u8 *data = skb_frag_address(frag); @@ -360,7 +365,7 @@ void rmnet_frag_deaggregate(skb_frag_t *frag, struct rmnet_port *port) if ((int)skb_frag_size(frag) - (int)packet_len < 0) return; - rmnet_descriptor_add_frag(port, skb_frag_page(frag), + rmnet_descriptor_add_frag(port, list, skb_frag_page(frag), frag->page_offset + offset, packet_len); @@ -1004,6 +1009,7 @@ void rmnet_frag_ingress_handler(struct sk_buff *skb, struct rmnet_port *port) { rmnet_perf_chain_hook_t rmnet_perf_opt_chain_end; + LIST_HEAD(desc_list); /* Deaggregation and freeing of HW originating * buffers is done within here @@ -1011,19 +1017,18 @@ void rmnet_frag_ingress_handler(struct sk_buff *skb, while (skb) { struct sk_buff *skb_frag; - rmnet_frag_deaggregate(skb_shinfo(skb)->frags, port); - if (port->rmnet_desc->nr_frags) { + rmnet_frag_deaggregate(skb_shinfo(skb)->frags, port, + &desc_list); + if (!list_empty(&desc_list)) { struct rmnet_frag_descriptor *frag_desc, *tmp; - list_for_each_entry_safe(frag_desc, tmp, - &port->rmnet_desc->frags, + list_for_each_entry_safe(frag_desc, tmp, &desc_list, list) { list_del_init(&frag_desc->list); __rmnet_frag_ingress_handler(frag_desc, port); } } - port->rmnet_desc->nr_frags = 0; skb_frag = skb_shinfo(skb)->frag_list; skb_shinfo(skb)->frag_list = NULL; consume_skb(skb); @@ -1050,22 +1055,14 @@ void rmnet_descriptor_deinit(struct rmnet_port *port) } kfree(pool); - kfree(port->rmnet_desc); } int rmnet_descriptor_init(struct rmnet_port *port) { - struct rmnet_descriptor *rmnet_desc; struct rmnet_frag_descriptor_pool *pool; int i; - rmnet_desc = kzalloc(sizeof(*rmnet_desc), GFP_ATOMIC); - if (!rmnet_desc) - return -ENOMEM; - - INIT_LIST_HEAD(&rmnet_desc->frags); - port->rmnet_desc = rmnet_desc; - + spin_lock_init(&port->desc_pool_lock); pool = kzalloc(sizeof(*pool), GFP_ATOMIC); if (!pool) return -ENOMEM; diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.h b/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.h index da4192320921..0b0489dde732 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.h +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.h @@ -52,18 +52,13 @@ struct rmnet_frag_descriptor { reserved:3; }; -struct rmnet_descriptor { - struct list_head frags; - u8 nr_frags; -}; - /* Descriptor management */ struct rmnet_frag_descriptor * rmnet_get_frag_descriptor(struct rmnet_port *port); void rmnet_recycle_frag_descriptor(struct rmnet_frag_descriptor *frag_desc, struct rmnet_port *port); -void rmnet_descriptor_add_frag(struct rmnet_port *port, struct page *p, - u32 page_offset, u32 len); +void rmnet_descriptor_add_frag(struct rmnet_port *port, struct list_head *list, + struct page *p, u32 page_offset, u32 len); int rmnet_frag_ipv6_skip_exthdr(struct rmnet_frag_descriptor *frag_desc, int start, u8 *nexthdrp, __be16 *fragp); @@ -73,7 +68,8 @@ int rmnet_frag_flow_command(struct rmnet_map_header *qmap, struct rmnet_port *port, u16 pkt_len); /* Ingress data handlers */ -void rmnet_frag_deaggregate(skb_frag_t *frag, struct rmnet_port *port); +void rmnet_frag_deaggregate(skb_frag_t *frag, struct rmnet_port *port, + struct list_head *list); void rmnet_frag_deliver(struct rmnet_frag_descriptor *frag_desc, struct rmnet_port *port); int rmnet_frag_process_next_hdr_packet(struct rmnet_frag_descriptor *frag_desc, -- GitLab From 0d04de565004f43240532a5d5564bfdd26834fe7 Mon Sep 17 00:00:00 2001 From: Mayank Rana Date: Fri, 28 Jun 2019 16:30:04 -0700 Subject: [PATCH 0728/1121] f_gsi: Increase MBIM IN aggregation to 31KB This change increases MBIM IN aggregation and related TRB buffer size from 16KB to 31KB. With this aggregation change, DL throughput is increased form 4.2 Gbps to 4.7 Gbps. Also reduced OUT buffer size from 31KB to 16 KB (i.e. as equal to size of OUT aggregation). Change-Id: Ida6444536f27f385034fefc71e663d7b7ce5626f Signed-off-by: Mayank Rana --- drivers/usb/gadget/function/f_gsi.c | 2 +- drivers/usb/gadget/function/f_gsi.h | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/function/f_gsi.c b/drivers/usb/gadget/function/f_gsi.c index eea1bd5d20f8..b7569bdfa89a 100644 --- a/drivers/usb/gadget/function/f_gsi.c +++ b/drivers/usb/gadget/function/f_gsi.c @@ -3211,7 +3211,7 @@ static int gsi_bind(struct usb_configuration *c, struct usb_function *f) gsi->d_port.in_aggr_size = GSI_IN_MBIM_AGGR_SIZE; info.in_req_buf_len = GSI_IN_MBIM_AGGR_SIZE; info.in_req_num_buf = GSI_NUM_IN_BUFFERS; - gsi->d_port.out_aggr_size = GSI_OUT_AGGR_SIZE; + gsi->d_port.out_aggr_size = GSI_OUT_MBIM_AGGR_SIZE; info.out_req_buf_len = GSI_OUT_MBIM_BUF_LEN; info.out_req_num_buf = GSI_NUM_OUT_BUFFERS; info.notify_buf_len = sizeof(struct usb_cdc_notification); diff --git a/drivers/usb/gadget/function/f_gsi.h b/drivers/usb/gadget/function/f_gsi.h index cfb55662ec21..5fff57dc9d76 100644 --- a/drivers/usb/gadget/function/f_gsi.h +++ b/drivers/usb/gadget/function/f_gsi.h @@ -53,8 +53,9 @@ #define GSI_OUT_AGGR_SIZE 24576 #define GSI_IN_RNDIS_AGGR_SIZE 16384 -#define GSI_IN_MBIM_AGGR_SIZE 16384 +#define GSI_IN_MBIM_AGGR_SIZE 31744 #define GSI_IN_RMNET_AGGR_SIZE 16384 +#define GSI_OUT_MBIM_AGGR_SIZE 16384 #define GSI_ECM_AGGR_SIZE 2048 #define GSI_OUT_MBIM_BUF_LEN 16384 @@ -771,7 +772,8 @@ static struct usb_gadget_strings *rndis_gsi_strings[] = { }; /* mbim device descriptors */ -#define MBIM_NTB_DEFAULT_IN_SIZE (0x4000) +#define MBIM_NTB_DEFAULT_IN_SIZE GSI_IN_MBIM_AGGR_SIZE +#define MBIM_NTB_DEFAULT_OUT_SIZE GSI_OUT_MBIM_AGGR_SIZE static struct usb_cdc_ncm_ntb_parameters mbim_gsi_ntb_parameters = { .wLength = sizeof(mbim_gsi_ntb_parameters), @@ -781,7 +783,7 @@ static struct usb_cdc_ncm_ntb_parameters mbim_gsi_ntb_parameters = { .wNdpInPayloadRemainder = cpu_to_le16(0), .wNdpInAlignment = cpu_to_le16(4), - .dwNtbOutMaxSize = cpu_to_le32(0x4000), + .dwNtbOutMaxSize = cpu_to_le32(MBIM_NTB_DEFAULT_OUT_SIZE), .wNdpOutDivisor = cpu_to_le16(4), .wNdpOutPayloadRemainder = cpu_to_le16(0), .wNdpOutAlignment = cpu_to_le16(4), -- GitLab From 6836c3649cce881b5979b9cda5b3615155fecaf1 Mon Sep 17 00:00:00 2001 From: Subbaraman Narayanamurthy Date: Fri, 28 Jun 2019 18:38:02 -0700 Subject: [PATCH 0729/1121] defconfig: sm8150: Enable QPNP_PBS driver Enable QPNP_PBS driver to trigger PBS sequence for some PMIC specific configuration on PM8150B that is used on SM8150 platforms. Change-Id: Ib7a7853b8aeaba8b3663bc8f5f92f2367b577172 Signed-off-by: Subbaraman Narayanamurthy --- arch/arm64/configs/vendor/sm8150-perf_defconfig | 1 + arch/arm64/configs/vendor/sm8150_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm64/configs/vendor/sm8150-perf_defconfig b/arch/arm64/configs/vendor/sm8150-perf_defconfig index ff178c26a817..4f3731b94aa9 100644 --- a/arch/arm64/configs/vendor/sm8150-perf_defconfig +++ b/arch/arm64/configs/vendor/sm8150-perf_defconfig @@ -562,6 +562,7 @@ CONFIG_QCOM_MEMORY_DUMP_V2=y CONFIG_QCOM_WATCHDOG_V2=y CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y CONFIG_QCOM_SMP2P=y +CONFIG_QPNP_PBS=y CONFIG_MSM_SERVICE_LOCATOR=y CONFIG_MSM_SERVICE_NOTIFIER=y CONFIG_MSM_SUBSYSTEM_RESTART=y diff --git a/arch/arm64/configs/vendor/sm8150_defconfig b/arch/arm64/configs/vendor/sm8150_defconfig index 026aa27ae87c..81b1f2b6e005 100644 --- a/arch/arm64/configs/vendor/sm8150_defconfig +++ b/arch/arm64/configs/vendor/sm8150_defconfig @@ -587,6 +587,7 @@ CONFIG_QCOM_WATCHDOG_V2=y CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y CONFIG_QCOM_WDOG_IPI_ENABLE=y CONFIG_QCOM_SMP2P=y +CONFIG_QPNP_PBS=y CONFIG_MSM_SERVICE_LOCATOR=y CONFIG_MSM_SERVICE_NOTIFIER=y CONFIG_MSM_SUBSYSTEM_RESTART=y -- GitLab From d4af177eda41d88166abd2f7b09e413490eb4a6d Mon Sep 17 00:00:00 2001 From: Subbaraman Narayanamurthy Date: Fri, 28 Jun 2019 18:41:13 -0700 Subject: [PATCH 0730/1121] dt-bindings: qpnp-fg-gen4: add support for PBS configuration Add support to obtain PBS handle so that PBS trigger can be made to do certain configurations. Change-Id: Id2d8eb032650be5f04c7abe602a145347c904282 Signed-off-by: Subbaraman Narayanamurthy --- .../devicetree/bindings/power/supply/qcom/qpnp-fg-gen4.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen4.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen4.txt index fadf4793cc5c..167edfef140c 100644 --- a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen4.txt +++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen4.txt @@ -29,6 +29,12 @@ First Level Node - FG Gen4 device Definition: Should specify the phandle of PMIC revid module. This is used to identify the PMIC subtype. +- qcom,pmic-pbs + Usage: optional + Value type: + Definition: Should specify the phandle of PMIC PBS module. This is + used to trigger PBS for certain configurations. + - #thermal-sensor-cells: Should be 0. See thermal.txt for the description. - nvmem-names: -- GitLab From 4e3443470d7657ade827d075eb47afd8d3f1aa4c Mon Sep 17 00:00:00 2001 From: Subbaraman Narayanamurthy Date: Tue, 25 Jun 2019 11:07:00 -0700 Subject: [PATCH 0731/1121] power: qpnp-fg-gen4: add support for calibration configuration Based on the hardware recommendation, add support for configuring calibration level based on POWER_SUPPLY_PROP_CALIBRATE property. Since this requires PBS trigger, add support to obtain PBS handle to do the configuration. Change-Id: If3ceb9a7ec3b4474f0db917d7c824a268411e91d Signed-off-by: Subbaraman Narayanamurthy --- drivers/power/supply/qcom/qpnp-fg-gen4.c | 73 ++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/drivers/power/supply/qcom/qpnp-fg-gen4.c b/drivers/power/supply/qcom/qpnp-fg-gen4.c index 5a0d4bd96359..a1f11bc1eba4 100644 --- a/drivers/power/supply/qcom/qpnp-fg-gen4.c +++ b/drivers/power/supply/qcom/qpnp-fg-gen4.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include "fg-core.h" @@ -255,6 +256,7 @@ struct fg_gen4_chip { struct cycle_counter *counter; struct cap_learning *cl; struct ttf *ttf; + struct device_node *pbs_dev; struct nvmem_device *fg_nvmem; struct votable *delta_esr_irq_en_votable; struct votable *pl_disable_votable; @@ -289,6 +291,7 @@ struct fg_gen4_chip { int vbatt_res; int scale_timer; int current_now; + int calib_level; bool first_profile_load; bool ki_coeff_dischg_en; bool slope_limit_en; @@ -1026,6 +1029,59 @@ static int fg_gen4_get_prop_soc_scale(struct fg_gen4_chip *chip) return rc; } +#define SDAM1_MEM_127_REG 0xB0BF +static int fg_gen4_set_calibrate_level(struct fg_gen4_chip *chip, int val) +{ + struct fg_dev *fg = &chip->fg; + int rc; + u8 buf; + + if (!chip->pbs_dev) + return -ENODEV; + + if (val < 0 || val > 0x83) { + pr_err("Incorrect calibration level %d\n", val); + return -EINVAL; + } + + if (val == chip->calib_level) + return 0; + + buf = (u8)val; + rc = fg_write(fg, SDAM1_MEM_127_REG, &buf, 1); + if (rc < 0) { + pr_err("Error in writing to 0xB0BF, rc=%d\n", rc); + return rc; + } + + buf = 0x1; + rc = qpnp_pbs_trigger_event(chip->pbs_dev, buf); + if (rc < 0) { + pr_err("Error in triggering PBS rc=%d\n", rc); + return rc; + } + + rc = fg_read(fg, SDAM1_MEM_127_REG, &buf, 1); + if (rc < 0) { + pr_err("Error in reading from 0xB0BF, rc=%d\n", rc); + return rc; + } + + if (buf) { + pr_err("Incorrect return value: %x\n", buf); + return -EINVAL; + } + + if (is_parallel_charger_available(fg)) { + cancel_work_sync(&chip->pl_current_en_work); + schedule_work(&chip->pl_current_en_work); + } + + chip->calib_level = val; + fg_dbg(fg, FG_POWER_SUPPLY, "Set calib_level to %x\n", val); + return 0; +} + /* ALG callback functions below */ static int fg_gen4_get_ttf_param(void *data, enum ttf_param param, int *val) @@ -4225,6 +4281,9 @@ static int fg_psy_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_POWER_AVG: rc = fg_gen4_get_power(chip, &pval->intval, true); break; + case POWER_SUPPLY_PROP_CALIBRATE: + pval->intval = chip->calib_level; + break; default: pr_err("unsupported property %d\n", psp); rc = -EINVAL; @@ -4314,6 +4373,9 @@ static int fg_psy_set_property(struct power_supply *psy, chip->batt_age_level = pval->intval; schedule_delayed_work(&fg->profile_load_work, 0); break; + case POWER_SUPPLY_PROP_CALIBRATE: + rc = fg_gen4_set_calibrate_level(chip, pval->intval); + break; default: break; } @@ -4333,6 +4395,7 @@ static int fg_property_is_writeable(struct power_supply *psy, case POWER_SUPPLY_PROP_SOH: case POWER_SUPPLY_PROP_CLEAR_SOH: case POWER_SUPPLY_PROP_BATT_AGE_LEVEL: + case POWER_SUPPLY_PROP_CALIBRATE: return 1; default: break; @@ -4377,6 +4440,7 @@ static enum power_supply_property fg_psy_props[] = { POWER_SUPPLY_PROP_POWER_NOW, POWER_SUPPLY_PROP_POWER_AVG, POWER_SUPPLY_PROP_SCALE_MODE_EN, + POWER_SUPPLY_PROP_CALIBRATE, }; static const struct power_supply_desc fg_psy_desc = { @@ -5313,6 +5377,14 @@ static int fg_gen4_parse_dt(struct fg_gen4_chip *chip) return -EINVAL; } + if (of_find_property(node, "qcom,pmic-pbs", NULL)) { + chip->pbs_dev = of_parse_phandle(node, "qcom,pmic-pbs", 0); + if (!chip->pbs_dev) { + pr_err("Missing qcom,pmic-pbs property\n"); + return -ENODEV; + } + } + rc = fg_gen4_parse_nvmem_dt(chip); if (rc < 0) return rc; @@ -5628,6 +5700,7 @@ static int fg_gen4_probe(struct platform_device *pdev) chip->ki_coeff_full_soc[0] = -EINVAL; chip->ki_coeff_full_soc[1] = -EINVAL; chip->esr_soh_cycle_count = -EINVAL; + chip->calib_level = -EINVAL; fg->regmap = dev_get_regmap(fg->dev->parent, NULL); if (!fg->regmap) { dev_err(fg->dev, "Parent regmap is unavailable\n"); -- GitLab From fef5e365b721e6d77e7e80ef0f5ad2d1593b9f72 Mon Sep 17 00:00:00 2001 From: Mohammed Javid Date: Mon, 29 Apr 2019 18:15:07 +0530 Subject: [PATCH 0732/1121] msm: ipa: QMI update for firwall config QMI struct update to support firewall config. Change-Id: I55f80d24670ec3062bd8d83834f2b302177119c5 Signed-off-by: Mohammed Javid --- .../platform/msm/ipa/ipa_v3/ipa_qmi_service.c | 18 ++++++++-- .../platform/msm/ipa/ipa_v3/ipa_qmi_service.h | 3 ++ .../msm/ipa/ipa_v3/ipa_qmi_service_v01.c | 2 +- drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c | 35 +++++++++++++++++++ include/uapi/linux/msm_ipa.h | 2 ++ 5 files changed, 56 insertions(+), 4 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c index a8b530c77642..60da89daf619 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c @@ -1335,13 +1335,25 @@ int ipa3_qmi_filter_notify_send( return -EINVAL; } + if (req->rule_id_ex_len == 0) { + IPAWANDBG(" delete UL filter rule for pipe %d\n", + req->source_pipe_index); + } else if (req->rule_id_ex_len > QMI_IPA_MAX_FILTERS_EX2_V01) { + IPAWANERR(" UL filter rule for pipe %d exceed max (%u)\n", + req->source_pipe_index, + req->rule_id_ex_len); + return -EINVAL; + } + if (req->install_status != IPA_QMI_RESULT_SUCCESS_V01) { IPAWANERR(" UL filter rule for pipe %d install_status = %d\n", req->source_pipe_index, req->install_status); return -EINVAL; - } else if (req->rule_id_valid != 1) { - IPAWANERR(" UL filter rule for pipe %d rule_id_valid = %d\n", - req->source_pipe_index, req->rule_id_valid); + } else if ((req->rule_id_valid != 1) && + (req->rule_id_ex_valid != 1)) { + IPAWANERR(" UL filter rule for pipe %d rule_id_valid = %d/%d\n", + req->source_pipe_index, req->rule_id_valid, + req->rule_id_ex_valid); return -EINVAL; } else if (req->source_pipe_index >= ipa3_ctx->ipa_num_pipes) { IPAWANDBG( diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.h b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.h index e94f6e1968a9..a0f3ea37306c 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.h @@ -116,6 +116,9 @@ struct ipa3_qmi_context { int num_ipa_offload_connection; struct ipa_offload_connection_val ipa_offload_cache[QMI_IPA_MAX_FILTERS_V01]; + uint8_t ul_firewall_indices_list_valid; + uint32_t ul_firewall_indices_list_len; + uint32_t ul_firewall_indices_list[QMI_IPA_MAX_FILTERS_V01]; }; struct ipa3_rmnet_mux_val { diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service_v01.c b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service_v01.c index 6d79e4c36c9d..e760d16b0e38 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service_v01.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service_v01.c @@ -2304,7 +2304,7 @@ struct qmi_elem_info ipa3_fltr_installed_notif_req_msg_data_v01_ei[] = { { .data_type = QMI_DATA_LEN, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(uint32_t), .is_array = NO_ARRAY, .tlv_type = 0x19, .offset = offsetof( diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c index 566b62017893..d3f42a9194dd 100644 --- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c @@ -691,6 +691,41 @@ int ipa3_copy_ul_filter_rule_to_ipa(struct ipa_install_fltr_rule_req_msg_v01 } } } + + if (rule_req->ul_firewall_indices_list_valid) { + IPAWANDBG("Receive ul_firewall_indices_list_len = (%d)", + rule_req->ul_firewall_indices_list_len); + + if (rule_req->ul_firewall_indices_list_len > + rmnet_ipa3_ctx->num_q6_rules) { + IPAWANERR("UL rule indices are not valid: (%d/%d)\n", + rule_req->xlat_filter_indices_list_len, + rmnet_ipa3_ctx->num_q6_rules); + goto failure; + } + + ipa3_qmi_ctx->ul_firewall_indices_list_valid = 1; + ipa3_qmi_ctx->ul_firewall_indices_list_len = + rule_req->ul_firewall_indices_list_len; + + for (i = 0; i < rule_req->ul_firewall_indices_list_len; i++) { + ipa3_qmi_ctx->ul_firewall_indices_list[i] = + rule_req->ul_firewall_indices_list[i]; + } + + for (i = 0; i < rule_req->ul_firewall_indices_list_len; i++) { + if (rule_req->ul_firewall_indices_list[i] + >= rmnet_ipa3_ctx->num_q6_rules) { + IPAWANERR("UL rule idx is wrong: %d\n", + rule_req->ul_firewall_indices_list[i]); + goto failure; + } else { + ipa3_qmi_ctx->q6_ul_filter_rule + [rule_req->ul_firewall_indices_list[i]] + .replicate_needed = 1; + } + } + } goto success; failure: diff --git a/include/uapi/linux/msm_ipa.h b/include/uapi/linux/msm_ipa.h index 568ecb0bea07..3c5560c78e83 100644 --- a/include/uapi/linux/msm_ipa.h +++ b/include/uapi/linux/msm_ipa.h @@ -1962,6 +1962,8 @@ struct ipa_ioc_ext_intf_prop { uint8_t is_xlat_rule; uint32_t rule_id; uint8_t is_rule_hashable; +#define IPA_V6_UL_WL_FIREWALL_HANDLE + uint8_t replicate_needed; }; /** -- GitLab From dabaa7749c893751778a1f1e0103217243602c18 Mon Sep 17 00:00:00 2001 From: Ashay Jaiswal Date: Sun, 30 Jun 2019 11:32:34 +0530 Subject: [PATCH 0733/1121] power: battery: fix usage of un-initialized variable in FCC stepper Update FCC stepper calculations to use effective result of MAIN_FCC for calculation instead of un-initialized variable. Change-Id: If64f6598e9cce74bb105e1951c39563804d45c14 Signed-off-by: Ashay Jaiswal --- drivers/power/supply/qcom/battery.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/power/supply/qcom/battery.c b/drivers/power/supply/qcom/battery.c index e786e27bb02a..93c9f520a0db 100644 --- a/drivers/power/supply/qcom/battery.c +++ b/drivers/power/supply/qcom/battery.c @@ -561,23 +561,21 @@ static void get_main_fcc_config(struct pl_data *chip, int *total_fcc) static void get_fcc_stepper_params(struct pl_data *chip, int main_fcc_ua, int parallel_fcc_ua) { - union power_supply_propval pval = {0, }; - /* Read current FCC of main charger */ chip->main_fcc_ua = get_effective_result(chip->fcc_main_votable); - chip->main_step_fcc_dir = (main_fcc_ua > pval.intval) ? + chip->main_step_fcc_dir = (main_fcc_ua > chip->main_fcc_ua) ? STEP_UP : STEP_DOWN; - chip->main_step_fcc_count = abs((main_fcc_ua - pval.intval) / + chip->main_step_fcc_count = abs((main_fcc_ua - chip->main_fcc_ua) / + FCC_STEP_SIZE_UA); + chip->main_step_fcc_residual = abs((main_fcc_ua - chip->main_fcc_ua) % FCC_STEP_SIZE_UA); - chip->main_step_fcc_residual = (main_fcc_ua - pval.intval) % - FCC_STEP_SIZE_UA; chip->parallel_step_fcc_dir = (parallel_fcc_ua > chip->slave_fcc_ua) ? STEP_UP : STEP_DOWN; chip->parallel_step_fcc_count = abs((parallel_fcc_ua - chip->slave_fcc_ua) / FCC_STEP_SIZE_UA); - chip->parallel_step_fcc_residual = (parallel_fcc_ua - - chip->slave_fcc_ua) % FCC_STEP_SIZE_UA; + chip->parallel_step_fcc_residual = abs((parallel_fcc_ua - + chip->slave_fcc_ua)) % FCC_STEP_SIZE_UA; if (chip->parallel_step_fcc_count || chip->parallel_step_fcc_residual || chip->main_step_fcc_count || chip->main_step_fcc_residual) -- GitLab From 218076b3428f828e4578f276a7a903f93bff0157 Mon Sep 17 00:00:00 2001 From: Anirudh Ghayal Date: Mon, 1 Jul 2019 10:02:08 +0530 Subject: [PATCH 0734/1121] dt-bindings: qpnp-qg: Add property for minimum sleep time Add a DT property so specify the minimum sleep time to allow an SOC jump. Change-Id: I8018f8033d05273320fd92cc7d21fcdce0885dfd Signed-off-by: Anirudh Ghayal --- .../devicetree/bindings/power/supply/qcom/qpnp-qg.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-qg.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-qg.txt index e81bdbde95f9..65e0b3bc2364 100644 --- a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-qg.txt +++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-qg.txt @@ -342,6 +342,12 @@ First Level Node - QGAUGE device Value type: Definition: Boolean property to use S7 for PON OCV. +- qcom,min-sleep-time-secs + Usage: optional + Value type: + Definition: The minimum sleep time in secs to allow a SOC + jump if there has been a GOOD_OCV. + ========================================================== Second Level Nodes - Peripherals managed by QGAUGE driver ========================================================== -- GitLab From 7b39d5a7692152d953ff24be9c862e8453075a74 Mon Sep 17 00:00:00 2001 From: Anirudh Ghayal Date: Mon, 1 Jul 2019 10:03:44 +0530 Subject: [PATCH 0735/1121] power: qpnp-qg: Allow SOC jump during resume If a GOOD_OCV is generated during sleep, allow the SOC to jump to the new value if the device is in sleep for a longer period. This is to avoid a quick drop in SOC (due to scaling) on resume. Change-Id: Ib4f4d5d166093298599c84459d3bd47695742e67 Signed-off-by: Anirudh Ghayal --- drivers/power/supply/qcom/qg-core.h | 2 ++ drivers/power/supply/qcom/qpnp-qg.c | 29 +++++++++++++++++++++++------ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/drivers/power/supply/qcom/qg-core.h b/drivers/power/supply/qcom/qg-core.h index ec35ded03e4d..e8c8bf226636 100644 --- a/drivers/power/supply/qcom/qg-core.h +++ b/drivers/power/supply/qcom/qg-core.h @@ -57,6 +57,7 @@ struct qg_dt { int esr_disable_soc; int esr_min_ibat_ua; int shutdown_soc_threshold; + int min_sleep_time_secs; bool hold_soc_while_full; bool linearize_soc; bool cl_disable; @@ -142,6 +143,7 @@ struct qpnp_qg { ktime_t last_user_update_time; ktime_t last_fifo_update_time; unsigned long last_maint_soc_update_time; + unsigned long suspend_time; struct iio_channel *batt_therm_chan; struct iio_channel *batt_id_chan; diff --git a/drivers/power/supply/qcom/qpnp-qg.c b/drivers/power/supply/qcom/qpnp-qg.c index 98d43b33cf95..02ac28dcc999 100644 --- a/drivers/power/supply/qcom/qpnp-qg.c +++ b/drivers/power/supply/qcom/qpnp-qg.c @@ -3360,6 +3360,7 @@ static int qg_alg_init(struct qpnp_qg *chip) #define DEFAULT_ESR_QUAL_VBAT_UV 7000 #define DEFAULT_ESR_DISABLE_SOC 1000 #define ESR_CHG_MIN_IBAT_UA (-450000) +#define DEFAULT_SLEEP_TIME_SECS 1800 /* 30 mins */ static int qg_parse_dt(struct qpnp_qg *chip) { int rc = 0; @@ -3600,6 +3601,12 @@ static int qg_parse_dt(struct qpnp_qg *chip) chip->dt.use_s7_ocv = of_property_read_bool(node, "qcom,qg-use-s7-ocv"); + rc = of_property_read_u32(node, "qcom,min-sleep-time-secs", &temp); + if (rc < 0) + chip->dt.min_sleep_time_secs = DEFAULT_SLEEP_TIME_SECS; + else + chip->dt.min_sleep_time_secs = temp; + /* Capacity learning params*/ if (!chip->dt.cl_disable) { chip->dt.cl_feedback_on = of_property_read_bool(node, @@ -3740,9 +3747,12 @@ static int process_suspend(struct qpnp_qg *chip) chip->suspend_data = true; } - qg_dbg(chip, QG_DEBUG_PM, "FIFO rt_length=%d sleep_fifo_length=%d default_s2_count=%d suspend_data=%d\n", + get_rtc_time(&chip->suspend_time); + + qg_dbg(chip, QG_DEBUG_PM, "FIFO rt_length=%d sleep_fifo_length=%d default_s2_count=%d suspend_data=%d time=%d\n", fifo_rt_length, sleep_fifo_length, - chip->dt.s2_fifo_length, chip->suspend_data); + chip->dt.s2_fifo_length, chip->suspend_data, + chip->suspend_time); return rc; } @@ -3752,12 +3762,15 @@ static int process_resume(struct qpnp_qg *chip) u8 status2 = 0, rt_status = 0; u32 ocv_uv = 0, ocv_raw = 0; int rc; - unsigned long rtc_sec = 0; + unsigned long rtc_sec = 0, sleep_time_secs = 0; /* skip if profile is not loaded */ if (!chip->profile_loaded) return 0; + get_rtc_time(&rtc_sec); + sleep_time_secs = rtc_sec - chip->suspend_time; + rc = qg_read(chip, chip->qg_base + QG_STATUS2_REG, &status2, 1); if (rc < 0) { pr_err("Failed to read status2 register, rc=%d\n", rc); @@ -3773,12 +3786,15 @@ static int process_resume(struct qpnp_qg *chip) /* Clear suspend data as there has been a GOOD OCV */ memset(&chip->kdata, 0, sizeof(chip->kdata)); - get_rtc_time(&rtc_sec); chip->kdata.fifo_time = (u32)rtc_sec; chip->kdata.param[QG_GOOD_OCV_UV].data = ocv_uv; chip->kdata.param[QG_GOOD_OCV_UV].valid = true; chip->suspend_data = false; + /* allow SOC jump if we have slept longer */ + if (sleep_time_secs >= chip->dt.min_sleep_time_secs) + chip->force_soc = true; + qg_dbg(chip, QG_DEBUG_PM, "GOOD OCV @ resume good_ocv=%d uV\n", ocv_uv); } @@ -3791,9 +3807,10 @@ static int process_resume(struct qpnp_qg *chip) } rt_status &= FIFO_UPDATE_DONE_INT_LAT_STS_BIT; - qg_dbg(chip, QG_DEBUG_PM, "FIFO_DONE_STS=%d suspend_data=%d good_ocv=%d\n", + qg_dbg(chip, QG_DEBUG_PM, "FIFO_DONE_STS=%d suspend_data=%d good_ocv=%d sleep_time=%d secs\n", !!rt_status, chip->suspend_data, - chip->kdata.param[QG_GOOD_OCV_UV].valid); + chip->kdata.param[QG_GOOD_OCV_UV].valid, + sleep_time_secs); /* * If this is not a wakeup from FIFO-done, * process the data immediately if - we have data from -- GitLab From 1b518cc6b890a7adf1d9b99d0c708d83c5e31972 Mon Sep 17 00:00:00 2001 From: Mukesh Kumar Savaliya Date: Sat, 1 Jun 2019 22:33:26 +0530 Subject: [PATCH 0736/1121] serial: msm_geni_serial: Make sure to have buffer for stop rx This patch creates RX buffer required to handle EOT event as part of stop rx operation. In some rare scenario it may happen that stop rx may not find the DMA buffer if there is some unexpected sequence gets executed for any reason. Change-Id: Iaf74170ca71b4247b46af2e69a8a19ccf4166cdf Signed-off-by: Mukesh Kumar Savaliya --- drivers/tty/serial/msm_geni_serial.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/msm_geni_serial.c b/drivers/tty/serial/msm_geni_serial.c index a47f873c2659..b145d43c5b74 100644 --- a/drivers/tty/serial/msm_geni_serial.c +++ b/drivers/tty/serial/msm_geni_serial.c @@ -1023,8 +1023,21 @@ static void start_rx_sequencer(struct uart_port *uport) u32 geni_se_param = UART_PARAM_RFR_OPEN; geni_status = geni_read_reg_nolog(uport->membase, SE_GENI_STATUS); - if (geni_status & S_GENI_CMD_ACTIVE) + if (geni_status & S_GENI_CMD_ACTIVE) { + if (port->xfer_mode == SE_DMA && !port->rx_dma) { + IPC_LOG_MSG(port->ipc_log_misc, + "%s: GENI: 0x%x\n", __func__, geni_status); + ret = geni_se_rx_dma_prep(port->wrapper_dev, + uport->membase, port->rx_buf, DMA_RX_BUF_SIZE, + &port->rx_dma); + if (ret) { + IPC_LOG_MSG(port->ipc_log_misc, + "%s: RX buff Fail %d\n", __func__, ret); + goto exit_start_rx_sequencer; + } + } msm_geni_serial_stop_rx(uport); + } /* Start RX with the RFR_OPEN to keep RFR in always ready state */ geni_setup_s_cmd(uport->membase, UART_START_READ, geni_se_param); -- GitLab From c8f9898628e927158f50261610967576c7aa1099 Mon Sep 17 00:00:00 2001 From: Naman Padhiar Date: Mon, 3 Jun 2019 15:13:30 +0530 Subject: [PATCH 0737/1121] icnss: Synchronize idle shutdown and restart If WLAN interface is not brought up for certain amount of time after it is created, idle shutdown will happen to power off WLAN device. Idle restart will happen to power up WLAN device if WLAN is needed by user again. Add the support in platform driver. Change-Id: I63e85c7de20536fc4146e05146e72537095025e5 Signed-off-by: Naman Padhiar --- drivers/soc/qcom/icnss.c | 103 +++++++++++++++++++++++++++++++ drivers/soc/qcom/icnss_private.h | 3 + include/soc/qcom/icnss.h | 4 ++ 3 files changed, 110 insertions(+) diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c index 2cb1599e29dc..c4957fe6066c 100644 --- a/drivers/soc/qcom/icnss.c +++ b/drivers/soc/qcom/icnss.c @@ -302,6 +302,10 @@ static char *icnss_driver_event_to_str(enum icnss_driver_event_type type) return "PD_SERVICE_DOWN"; case ICNSS_DRIVER_EVENT_FW_EARLY_CRASH_IND: return "FW_EARLY_CRASH_IND"; + case ICNSS_DRIVER_EVENT_IDLE_SHUTDOWN: + return "IDLE_SHUTDOWN"; + case ICNSS_DRIVER_EVENT_IDLE_RESTART: + return "IDLE_RESTART"; case ICNSS_DRIVER_EVENT_MAX: return "EVENT_MAX"; } @@ -1127,6 +1131,7 @@ static int icnss_pd_restart_complete(struct icnss_priv *priv) icnss_call_driver_shutdown(priv); clear_bit(ICNSS_PDR, &priv->state); + clear_bit(ICNSS_MODEM_CRASHED, &priv->state); clear_bit(ICNSS_REJUVENATE, &priv->state); clear_bit(ICNSS_PD_RESTART, &priv->state); priv->early_crash_ind = false; @@ -1405,6 +1410,51 @@ static int icnss_driver_event_early_crash_ind(struct icnss_priv *priv, return ret; } +static int icnss_driver_event_idle_shutdown(void *data) +{ + int ret = 0; + + if (!penv->ops || !penv->ops->idle_shutdown) + return 0; + + if (test_bit(ICNSS_MODEM_CRASHED, &penv->state) || + test_bit(ICNSS_PDR, &penv->state) || + test_bit(ICNSS_REJUVENATE, &penv->state)) { + icnss_pr_err("SSR/PDR is already in-progress during idle shutdown callback\n"); + ret = -EBUSY; + } else { + icnss_pr_dbg("Calling driver idle shutdown, state: 0x%lx\n", + penv->state); + icnss_block_shutdown(true); + ret = penv->ops->idle_shutdown(&penv->pdev->dev); + icnss_block_shutdown(false); + } + + return ret; +} + +static int icnss_driver_event_idle_restart(void *data) +{ + int ret = 0; + + if (!penv->ops || !penv->ops->idle_restart) + return 0; + + if (test_bit(ICNSS_MODEM_CRASHED, &penv->state) || + test_bit(ICNSS_PDR, &penv->state) || + test_bit(ICNSS_REJUVENATE, &penv->state)) { + icnss_pr_err("SSR/PDR is already in-progress during idle restart callback\n"); + ret = -EBUSY; + } else { + icnss_pr_dbg("Calling driver idle restart, state: 0x%lx\n", + penv->state); + icnss_block_shutdown(true); + ret = penv->ops->idle_restart(&penv->pdev->dev); + icnss_block_shutdown(false); + } + + return ret; +} static void icnss_driver_event_work(struct work_struct *work) { @@ -1451,6 +1501,12 @@ static void icnss_driver_event_work(struct work_struct *work) ret = icnss_driver_event_early_crash_ind(penv, event->data); break; + case ICNSS_DRIVER_EVENT_IDLE_SHUTDOWN: + ret = icnss_driver_event_idle_shutdown(event->data); + break; + case ICNSS_DRIVER_EVENT_IDLE_RESTART: + ret = icnss_driver_event_idle_restart(event->data); + break; default: icnss_pr_err("Invalid Event type: %d", event->type); kfree(event); @@ -1525,6 +1581,9 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb, priv->is_ssr = true; + if (notif->crashed) + set_bit(ICNSS_MODEM_CRASHED, &priv->state); + if (code == SUBSYS_BEFORE_SHUTDOWN && !notif->crashed && atomic_read(&priv->is_shutdown)) { atomic_set(&priv->is_shutdown, false); @@ -2514,6 +2573,48 @@ int icnss_trigger_recovery(struct device *dev) } EXPORT_SYMBOL(icnss_trigger_recovery); +int icnss_idle_shutdown(struct device *dev) +{ + struct icnss_priv *priv = dev_get_drvdata(dev); + + if (!priv) { + icnss_pr_err("Invalid drvdata: dev %pK", dev); + return -EINVAL; + } + + if (test_bit(ICNSS_MODEM_CRASHED, &priv->state) || + test_bit(ICNSS_PDR, &priv->state) || + test_bit(ICNSS_REJUVENATE, &penv->state)) { + icnss_pr_err("SSR/PDR is already in-progress during idle shutdown\n"); + return -EBUSY; + } + + return icnss_driver_event_post(ICNSS_DRIVER_EVENT_IDLE_SHUTDOWN, + ICNSS_EVENT_SYNC_UNINTERRUPTIBLE, NULL); +} +EXPORT_SYMBOL(icnss_idle_shutdown); + +int icnss_idle_restart(struct device *dev) +{ + struct icnss_priv *priv = dev_get_drvdata(dev); + + if (!priv) { + icnss_pr_err("Invalid drvdata: dev %pK", dev); + return -EINVAL; + } + + if (test_bit(ICNSS_MODEM_CRASHED, &priv->state) || + test_bit(ICNSS_PDR, &priv->state) || + test_bit(ICNSS_REJUVENATE, &penv->state)) { + icnss_pr_err("SSR/PDR is already in-progress during idle restart\n"); + return -EBUSY; + } + + return icnss_driver_event_post(ICNSS_DRIVER_EVENT_IDLE_RESTART, + ICNSS_EVENT_SYNC_UNINTERRUPTIBLE, NULL); +} +EXPORT_SYMBOL(icnss_idle_restart); + static int icnss_smmu_init(struct icnss_priv *priv) { @@ -3018,6 +3119,8 @@ static int icnss_stats_show_state(struct seq_file *s, struct icnss_priv *priv) case ICNSS_ESOC_OFF: seq_puts(s, "ESOC_OFF"); continue; + case ICNSS_MODEM_CRASHED: + seq_puts(s, "MODEM CRASHED"); } seq_printf(s, "UNKNOWN-%d", i); diff --git a/drivers/soc/qcom/icnss_private.h b/drivers/soc/qcom/icnss_private.h index dc2c0812eea4..5edd8d789554 100644 --- a/drivers/soc/qcom/icnss_private.h +++ b/drivers/soc/qcom/icnss_private.h @@ -120,6 +120,8 @@ enum icnss_driver_event_type { ICNSS_DRIVER_EVENT_UNREGISTER_DRIVER, ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN, ICNSS_DRIVER_EVENT_FW_EARLY_CRASH_IND, + ICNSS_DRIVER_EVENT_IDLE_SHUTDOWN, + ICNSS_DRIVER_EVENT_IDLE_RESTART, ICNSS_DRIVER_EVENT_MAX, }; @@ -165,6 +167,7 @@ enum icnss_driver_state { ICNSS_PDR, ICNSS_CLK_UP, ICNSS_ESOC_OFF, + ICNSS_MODEM_CRASHED, }; struct ce_irq_list { diff --git a/include/soc/qcom/icnss.h b/include/soc/qcom/icnss.h index 0717cd12dfde..54f2a51123e6 100644 --- a/include/soc/qcom/icnss.h +++ b/include/soc/qcom/icnss.h @@ -50,6 +50,8 @@ struct icnss_driver_ops { int (*suspend_noirq)(struct device *dev); int (*resume_noirq)(struct device *dev); int (*uevent)(struct device *dev, struct icnss_uevent_data *uevent); + int (*idle_shutdown)(struct device *dev); + int (*idle_restart)(struct device *dev); }; @@ -146,4 +148,6 @@ extern bool icnss_is_rejuvenate(void); extern int icnss_trigger_recovery(struct device *dev); extern void icnss_block_shutdown(bool status); extern bool icnss_is_pdr(void); +extern int icnss_idle_restart(struct device *dev); +extern int icnss_idle_shutdown(struct device *dev); #endif /* _ICNSS_WLAN_H_ */ -- GitLab From d4982419a66bc560405d98837bc10f7935d5a026 Mon Sep 17 00:00:00 2001 From: Anirudh Ghayal Date: Mon, 1 Jul 2019 11:37:33 +0530 Subject: [PATCH 0738/1121] dt-bindings: qpnp-qg: Add property to specify system minimum voltage Minimum system voltage is used for calculating the average and instantaneous power. Change-Id: I8018f8033d05273320fd92cc7d21fcdce0885dfa Signed-off-by: Anirudh Ghayal --- .../devicetree/bindings/power/supply/qcom/qpnp-qg.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-qg.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-qg.txt index 65e0b3bc2364..d754b0b6e027 100644 --- a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-qg.txt +++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-qg.txt @@ -348,6 +348,15 @@ First Level Node - QGAUGE device Definition: The minimum sleep time in secs to allow a SOC jump if there has been a GOOD_OCV. +- qcom,qg-sys-min-voltage + Usage: optional + Value type: + Definition: The voltage threshold (in mV) which describes the system + minimum voltage as per the hardware recommendation. This + is not used for any configuration but only for calculating + the available power. If this property is not specified, + then the default value used is 2800 mV. + ========================================================== Second Level Nodes - Peripherals managed by QGAUGE driver ========================================================== -- GitLab From 814f1cb508ce223d1cf9ab14b61e293b7fbb3d34 Mon Sep 17 00:00:00 2001 From: Hareesh Gundu Date: Wed, 26 Jun 2019 14:46:36 +0530 Subject: [PATCH 0739/1121] ARM: dts: msm: Add GPU properties for atoll Atoll inherits all the sdmmagpie GPU properties Like GPU clocks, registers, interrupts, bus, freq plan, SMMU properties, and GPU power levels. Add GPU properties for atoll to support graphics. Change-Id: I8236c4051c8020f74903a0fa685729ce5317b04a Signed-off-by: Hareesh Gundu --- arch/arm64/boot/dts/qcom/atoll.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index 120b81650db5..05d65a20d964 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -1912,6 +1912,11 @@ #include "atoll-ion.dtsi" #include "msm-arm-smmu-sdmatoll.dtsi" #include "atoll-qupv3.dtsi" +#include "sdmmagpie-gpu.dtsi" + +&msm_gpu { + /delete-property/qcom,gpu-speed-bin; +}; &ufs_phy_gdsc { status = "ok"; -- GitLab From 273e840ee5513d3f0776639a91baade6cc158531 Mon Sep 17 00:00:00 2001 From: Raghavendra Kakarla Date: Mon, 1 Jul 2019 14:39:27 +0530 Subject: [PATCH 0740/1121] ARM: dts: msm: Add QMP debugfs client on atoll The QMP debugfs client uses the QMP mailbox driver to communicate with the Always On processor. Change-Id: I8f4f2d3ca9b459e52a6e93a6104bc23f5e156b99 Signed-off-by: Raghavendra Kakarla --- arch/arm64/boot/dts/qcom/atoll.dtsi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index 120b81650db5..d496f03f65cd 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -744,6 +744,12 @@ reg-names = "pshold-base", "tcsr-boot-misc-detect"; }; + aop-msg-client { + compatible = "qcom,debugfs-qmp-client"; + mboxes = <&qmp_aop 0>; + mbox-names = "aop"; + }; + qcom,msm-rtb { compatible = "qcom,msm-rtb"; qcom,rtb-size = <0x100000>; -- GitLab From d8fc5e41d05ddf52823427f3891f0ad3e91933cc Mon Sep 17 00:00:00 2001 From: Anirudh Ghayal Date: Mon, 1 Jul 2019 11:39:13 +0530 Subject: [PATCH 0741/1121] power: qpnp-qg: Add support to display available power Add support to show the available power from battery parameters through POWER_SUPPLY_PROP_POWER_NOW, POWER_SUPPLY_PROP_POWER_AVG properties. Change-Id: I8018f8033d05273320fd92cc7d21fcdce0885dfb Signed-off-by: Anirudh Ghayal --- drivers/power/supply/qcom/qg-core.h | 1 + drivers/power/supply/qcom/qpnp-qg.c | 63 +++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/drivers/power/supply/qcom/qg-core.h b/drivers/power/supply/qcom/qg-core.h index e8c8bf226636..2d4ff77044ab 100644 --- a/drivers/power/supply/qcom/qg-core.h +++ b/drivers/power/supply/qcom/qg-core.h @@ -58,6 +58,7 @@ struct qg_dt { int esr_min_ibat_ua; int shutdown_soc_threshold; int min_sleep_time_secs; + int sys_min_volt_mv; bool hold_soc_while_full; bool linearize_soc; bool cl_disable; diff --git a/drivers/power/supply/qcom/qpnp-qg.c b/drivers/power/supply/qcom/qpnp-qg.c index 02ac28dcc999..81e70b0250df 100644 --- a/drivers/power/supply/qcom/qpnp-qg.c +++ b/drivers/power/supply/qcom/qpnp-qg.c @@ -1579,6 +1579,54 @@ static int qg_get_charge_counter(struct qpnp_qg *chip, int *charge_counter) return 0; } +static int qg_get_power(struct qpnp_qg *chip, int *val, bool average) +{ + int rc, v_min, v_ocv, rbatt = 0, esr = 0; + s64 power; + + if (is_debug_batt_id(chip)) { + *val = -EINVAL; + return 0; + } + + v_min = chip->dt.sys_min_volt_mv * 1000; + + rc = qg_sdam_read(SDAM_OCV_UV, &v_ocv); + if (rc < 0) { + pr_err("Failed to read OCV rc=%d\n", rc); + return rc; + } + + rc = qg_sdam_read(SDAM_RBAT_MOHM, &rbatt); + if (rc < 0) { + pr_err("Failed to read T_RBAT rc=%d\n", rc); + return rc; + } + + rbatt *= 1000; /* uohms */ + esr = chip->esr_last * 1000; + + if (rbatt <= 0 || esr <= 0) { + pr_debug("Invalid rbatt/esr rbatt=%d esr=%d\n", rbatt, esr); + *val = -EINVAL; + return 0; + } + + power = (s64)v_min * (v_ocv - v_min); + + if (average) + power = div_s64(power, rbatt); + else + power = div_s64(power, esr); + + *val = power; + + qg_dbg(chip, QG_DEBUG_STATUS, "v_min=%d v_ocv=%d rbatt=%d esr=%d power=%lld\n", + v_min, v_ocv, rbatt, esr, power); + + return 0; +} + static int qg_get_ttf_param(void *data, enum ttf_param param, int *val) { union power_supply_propval prop = {0, }; @@ -1909,6 +1957,12 @@ static int qg_psy_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_VOLTAGE_AVG: rc = qg_get_vbat_avg(chip, &pval->intval); break; + case POWER_SUPPLY_PROP_POWER_NOW: + rc = qg_get_power(chip, &pval->intval, false); + break; + case POWER_SUPPLY_PROP_POWER_AVG: + rc = qg_get_power(chip, &pval->intval, true); + break; default: pr_debug("Unsupported property %d\n", psp); break; @@ -1964,6 +2018,8 @@ static enum power_supply_property qg_psy_props[] = { POWER_SUPPLY_PROP_FG_RESET, POWER_SUPPLY_PROP_CC_SOC, POWER_SUPPLY_PROP_VOLTAGE_AVG, + POWER_SUPPLY_PROP_POWER_AVG, + POWER_SUPPLY_PROP_POWER_NOW, }; static const struct power_supply_desc qg_psy_desc = { @@ -3361,6 +3417,7 @@ static int qg_alg_init(struct qpnp_qg *chip) #define DEFAULT_ESR_DISABLE_SOC 1000 #define ESR_CHG_MIN_IBAT_UA (-450000) #define DEFAULT_SLEEP_TIME_SECS 1800 /* 30 mins */ +#define DEFAULT_SYS_MIN_VOLT_MV 2800 static int qg_parse_dt(struct qpnp_qg *chip) { int rc = 0; @@ -3597,6 +3654,12 @@ static int qg_parse_dt(struct qpnp_qg *chip) else chip->dt.shutdown_soc_threshold = temp; + rc = of_property_read_u32(node, "qcom,qg-sys-min-voltage", &temp); + if (rc < 0) + chip->dt.sys_min_volt_mv = DEFAULT_SYS_MIN_VOLT_MV; + else + chip->dt.sys_min_volt_mv = temp; + chip->dt.qg_ext_sense = of_property_read_bool(node, "qcom,qg-ext-sns"); chip->dt.use_s7_ocv = of_property_read_bool(node, "qcom,qg-use-s7-ocv"); -- GitLab From 35e0d2edead91028550869023aa0dee96ea29b5e Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Mon, 1 Jul 2019 14:03:33 +0530 Subject: [PATCH 0742/1121] Documentation: Add DT bindings on atoll Add DT binding for video encoders and decoders on atoll. Change-Id: I0259b59ecd4dd595907675e158897020fcc43cb0 Signed-off-by: Dikshita Agarwal --- Documentation/devicetree/bindings/media/video/msm-vidc.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/media/video/msm-vidc.txt b/Documentation/devicetree/bindings/media/video/msm-vidc.txt index 08af0e2d8ff4..d613450cdc59 100644 --- a/Documentation/devicetree/bindings/media/video/msm-vidc.txt +++ b/Documentation/devicetree/bindings/media/video/msm-vidc.txt @@ -13,6 +13,7 @@ Required properties: - "qcom,trinket-vidc" : Invokes driver specific data for trinket. - "qcom,sdm845-vidc" : Invokes driver specific data for SDM845. - "qcom,sdm670-vidc" : Invokes driver specific data for SDM670. + - "qcom,atoll-vidc" : Invokes driver specific data for atoll. Optional properties: - reg : offset and length of the register set for the device. -- GitLab From 311a92a36d1f28c51ed57ee3ba7903044582c75a Mon Sep 17 00:00:00 2001 From: Mohammed Siddiq Date: Mon, 1 Jul 2019 15:04:58 +0530 Subject: [PATCH 0743/1121] icnss: Reduce the shutdown timeout from 50sec to 15sec Sub-system shutdown timeout is 20 seconds. In wlan platform driver, modem block shutdown timeout should be less than sub-system timeout. Hence, change block shutdown timeout to 15 seconds. Change-Id: I936e0c462858727b86b35b924dd124a5d1434780 Signed-off-by: Mohammed Siddiq --- drivers/soc/qcom/icnss.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c index 2cb1599e29dc..92569ffe3159 100644 --- a/drivers/soc/qcom/icnss.c +++ b/drivers/soc/qcom/icnss.c @@ -73,7 +73,7 @@ #define SUBSYS_INTERNAL_MODEM_NAME "modem" #define SUBSYS_EXTERNAL_MODEM_NAME "esoc0" -#define PROBE_TIMEOUT 5000 +#define PROBE_TIMEOUT 15000 #define FW_READY_TIMEOUT 50000 static struct icnss_priv *penv; @@ -1534,8 +1534,8 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb, if (code == SUBSYS_BEFORE_SHUTDOWN && !notif->crashed && test_bit(ICNSS_BLOCK_SHUTDOWN, &priv->state)) { if (!wait_for_completion_timeout(&priv->unblock_shutdown, - PROBE_TIMEOUT)) - icnss_pr_err("wlan driver probe timeout\n"); + msecs_to_jiffies(PROBE_TIMEOUT))) + icnss_pr_err("modem block shutdown timeout\n"); } if (code == SUBSYS_BEFORE_SHUTDOWN && !notif->crashed) { -- GitLab From cc5e68daf9262461c1e6ad06b36b1d3978ce59bd Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Fri, 14 Jun 2019 12:52:33 +0530 Subject: [PATCH 0744/1121] msm: vidc: Check image encode capabilities For heic/hevc image session, check respective capabilities to allow and reject. Change-Id: If3a296d984eb3e0f1f90faaa6f6b0be8a5f21f0d Signed-off-by: Manikanta Kanamarlapudi --- drivers/media/platform/msm/vidc/msm_venc.c | 1 + .../media/platform/msm/vidc/msm_vidc_common.c | 64 +++++++++++++++++++ .../platform/msm/vidc/msm_vidc_internal.h | 12 ++++ .../platform/msm/vidc/msm_vidc_platform.c | 22 +++++++ 4 files changed, 99 insertions(+) diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c index 3282b57ed847..e92e3d206cf6 100644 --- a/drivers/media/platform/msm/vidc/msm_venc.c +++ b/drivers/media/platform/msm/vidc/msm_venc.c @@ -1606,6 +1606,7 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL, temp_ctrl->val); pdata = &profile_level; + inst->profile = profile_level.profile; break; case V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL: temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE); diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c index 405d62fedc8f..afc274c610c2 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_common.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c @@ -5647,6 +5647,65 @@ int msm_vidc_check_scaling_supported(struct msm_vidc_inst *inst) return 0; } +static bool is_image_session(struct msm_vidc_inst *inst) +{ + if (inst->session_type == MSM_VIDC_ENCODER && + get_hal_codec(inst->fmts[CAPTURE_PORT].fourcc) == + HAL_VIDEO_CODEC_HEVC) + return (inst->profile == HAL_HEVC_PROFILE_MAIN_STILL_PIC || + inst->grid_enable); + else + return false; +} + +static int msm_vidc_check_image_session_capabilities(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct msm_vidc_image_capability *capability = NULL; + + u32 output_height = ALIGN(inst->prop.height[CAPTURE_PORT], 512); + u32 output_width = ALIGN(inst->prop.width[CAPTURE_PORT], 512); + + if (inst->grid_enable) + capability = inst->core->platform_data->heic_image_capability; + else + capability = inst->core->platform_data->hevc_image_capability; + + if (!capability) + return -EINVAL; + + if (output_width < capability->width.min || + output_height < capability->height.min) { + dprintk(VIDC_ERR, + "HEIC Unsupported WxH = (%u)x(%u), min supported is - (%u)x(%u)\n", + output_width, + output_height, + capability->width.min, + capability->height.min); + rc = -ENOTSUPP; + } + if (!rc && (output_width > capability->width.max || + output_height > capability->height.max)) { + dprintk(VIDC_ERR, + "HEIC Unsupported WxH = (%u)x(%u), max supported is - (%u)x(%u)\n", + output_width, + output_height, + capability->width.max, + capability->height.max); + rc = -ENOTSUPP; + } + if (!rc && output_height * output_width > + capability->width.max * capability->height.max) { + dprintk(VIDC_ERR, + "HEIC Unsupported WxH = (%u)x(%u), max supported is - (%u)x(%u)\n", + output_width, output_height, + capability->width.max, capability->height.max); + rc = -ENOTSUPP; + } + + return rc; +} + int msm_vidc_check_session_supported(struct msm_vidc_inst *inst) { struct msm_vidc_capability *capability; @@ -5692,6 +5751,11 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst) rc = -ENOTSUPP; } + if (is_image_session(inst)) { + rc = msm_vidc_check_image_session_capabilities(inst); + return rc; + } + output_height = ALIGN(inst->prop.height[CAPTURE_PORT], 16); output_width = ALIGN(inst->prop.width[CAPTURE_PORT], 16); diff --git a/drivers/media/platform/msm/vidc/msm_vidc_internal.h b/drivers/media/platform/msm/vidc/msm_vidc_internal.h index cc681d81656c..b9cda3e94ec8 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_internal.h +++ b/drivers/media/platform/msm/vidc/msm_vidc_internal.h @@ -232,6 +232,16 @@ struct msm_vidc_efuse_data { enum efuse_purpose purpose; }; +struct msm_vidc_capability_range { + u32 min; + u32 max; +}; + +struct msm_vidc_image_capability { + struct msm_vidc_capability_range width; + struct msm_vidc_capability_range height; +}; + enum vpu_version { VPU_VERSION_4 = 1, VPU_VERSION_5, @@ -253,6 +263,8 @@ struct msm_vidc_platform_data { unsigned int efuse_data_length; struct msm_vidc_ubwc_config *ubwc_config; unsigned int ubwc_config_length; + struct msm_vidc_image_capability *heic_image_capability; + struct msm_vidc_image_capability *hevc_image_capability; unsigned int sku_version; uint32_t vpu_ver; }; diff --git a/drivers/media/platform/msm/vidc/msm_vidc_platform.c b/drivers/media/platform/msm/vidc/msm_vidc_platform.c index e4ab7e6a1e93..ca0d912348cd 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_platform.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_platform.c @@ -674,6 +674,14 @@ static struct msm_vidc_ubwc_config trinket_ubwc_data[] = { UBWC_CONFIG(0, 1, 0, 0, 0, 64, 0, 0), }; +static struct msm_vidc_image_capability default_heic_image_capability = { + {512, 8192}, {512, 8192} +}; + +static struct msm_vidc_image_capability default_hevc_image_capability = { + {512, 512}, {512, 512} +}; + static struct msm_vidc_platform_data default_data = { .codec_data = default_codec_data, .codec_data_length = ARRAY_SIZE(default_codec_data), @@ -686,6 +694,8 @@ static struct msm_vidc_platform_data default_data = { .csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff, .efuse_data = NULL, .efuse_data_length = 0, + .heic_image_capability = &default_heic_image_capability, + .hevc_image_capability = &default_hevc_image_capability, .sku_version = 0, .vpu_ver = VPU_VERSION_5, }; @@ -702,6 +712,8 @@ static struct msm_vidc_platform_data sm6150_data = { .csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff, .efuse_data = NULL, .efuse_data_length = 0, + .heic_image_capability = NULL, + .hevc_image_capability = NULL, .sku_version = 0, .vpu_ver = VPU_VERSION_4, }; @@ -718,6 +730,8 @@ static struct msm_vidc_platform_data trinket_data = { .csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff, .efuse_data = NULL, .efuse_data_length = 0, + .heic_image_capability = &default_heic_image_capability, + .hevc_image_capability = &default_hevc_image_capability, .sku_version = 0, .vpu_ver = VPU_VERSION_4, }; @@ -734,6 +748,8 @@ static struct msm_vidc_platform_data sm8150_data = { .csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff, .efuse_data = NULL, .efuse_data_length = 0, + .heic_image_capability = &default_heic_image_capability, + .hevc_image_capability = &default_hevc_image_capability, .sku_version = 0, .vpu_ver = VPU_VERSION_5, }; @@ -750,6 +766,8 @@ static struct msm_vidc_platform_data sdmmagpie_data = { .csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff, .efuse_data = sdmmagpie_efuse_data, .efuse_data_length = ARRAY_SIZE(sdmmagpie_efuse_data), + .heic_image_capability = &default_heic_image_capability, + .hevc_image_capability = &default_hevc_image_capability, .sku_version = 0, .vpu_ver = VPU_VERSION_5, }; @@ -766,6 +784,8 @@ static struct msm_vidc_platform_data sdm845_data = { .csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff, .efuse_data = NULL, .efuse_data_length = 0, + .heic_image_capability = NULL, + .hevc_image_capability = NULL, .sku_version = 0, .vpu_ver = VPU_VERSION_4, }; @@ -782,6 +802,8 @@ static struct msm_vidc_platform_data sdm670_data = { .csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff, .efuse_data = sdm670_efuse_data, .efuse_data_length = ARRAY_SIZE(sdm670_efuse_data), + .heic_image_capability = NULL, + .hevc_image_capability = NULL, .sku_version = 0, .vpu_ver = VPU_VERSION_4, }; -- GitLab From 9bf4b4a10c24eba4b495fc7968329e7b171b1c4c Mon Sep 17 00:00:00 2001 From: Sujeev Dias Date: Fri, 17 May 2019 18:41:17 -0700 Subject: [PATCH 0745/1121] mhi: cntrl: qcom: set device timer frequency for timesync calculations Set local and device timer frequencies for timesync calculations. CRs-Fixed: 2377061 Change-Id: Ie5346b517bc69bd0bf15ab65567470dd17f9efbe Acked-by: Bhaumik Vasav Bhatt Signed-off-by: Sujeev Dias --- drivers/bus/mhi/controllers/mhi_qcom.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/bus/mhi/controllers/mhi_qcom.c b/drivers/bus/mhi/controllers/mhi_qcom.c index 00c8b264377c..58b319ffc5ef 100644 --- a/drivers/bus/mhi/controllers/mhi_qcom.c +++ b/drivers/bus/mhi/controllers/mhi_qcom.c @@ -700,6 +700,8 @@ static struct mhi_controller *mhi_register_controller(struct pci_dev *pci_dev) mhi_cntrl->lpm_disable = mhi_lpm_disable; mhi_cntrl->lpm_enable = mhi_lpm_enable; mhi_cntrl->time_get = mhi_time_get; + mhi_cntrl->remote_timer_freq = 19200000; + mhi_cntrl->local_timer_freq = 19200000; ret = of_register_mhi_controller(mhi_cntrl); if (ret) -- GitLab From 39f0b2bac1920339a83776319b431b4150dfa9d8 Mon Sep 17 00:00:00 2001 From: Depeng Shao Date: Wed, 29 May 2019 20:58:27 +0800 Subject: [PATCH 0746/1121] msm: camera: reqmgr: Add initial sync support Do the initial sync by SOF timestamp, if the gap between the initial SOF of link and the last SOF of sync link is less than half of frame druation, CRM should abandon this frame since this frame should sync with next frame of sync link. Change-Id: I204e3ed49bcf4ac7424aaf5109ad5ce3bc3a2789 Signed-off-by: Depeng Shao --- .../msm/camera/cam_isp/cam_isp_context.c | 6 ++ .../msm/camera/cam_req_mgr/cam_req_mgr_core.c | 93 ++++++++++++++++++- .../msm/camera/cam_req_mgr/cam_req_mgr_core.h | 10 +- .../cam_req_mgr/cam_req_mgr_interface.h | 4 +- 4 files changed, 107 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c index 3f6fa82adbbb..afb02bd80ab7 100644 --- a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c +++ b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c @@ -703,6 +703,7 @@ static int __cam_isp_ctx_notify_sof_in_activated_state( notify.dev_hdl = ctx->dev_hdl; notify.frame_id = ctx_isp->frame_id; notify.trigger = CAM_TRIGGER_POINT_SOF; + notify.sof_timestamp_val = ctx_isp->sof_timestamp_val; ctx->ctx_crm_intf->notify_trigger(¬ify); CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld ctx %u", @@ -1335,6 +1336,7 @@ static int __cam_isp_ctx_fs2_sof_in_sof_state( notify.dev_hdl = ctx->dev_hdl; notify.frame_id = ctx_isp->frame_id; notify.trigger = CAM_TRIGGER_POINT_SOF; + notify.sof_timestamp_val = ctx_isp->sof_timestamp_val; ctx->ctx_crm_intf->notify_trigger(¬ify); CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld", @@ -1512,6 +1514,7 @@ static int __cam_isp_ctx_fs2_reg_upd_in_applied_state( notify.dev_hdl = ctx->dev_hdl; notify.frame_id = ctx_isp->frame_id; notify.trigger = CAM_TRIGGER_POINT_SOF; + notify.sof_timestamp_val = ctx_isp->sof_timestamp_val; ctx->ctx_crm_intf->notify_trigger(¬ify); CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld", @@ -2100,6 +2103,7 @@ static int __cam_isp_ctx_rdi_only_sof_in_top_state( notify.dev_hdl = ctx->dev_hdl; notify.frame_id = ctx_isp->frame_id; notify.trigger = CAM_TRIGGER_POINT_SOF; + notify.sof_timestamp_val = ctx_isp->sof_timestamp_val; ctx->ctx_crm_intf->notify_trigger(¬ify); CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld", @@ -2291,6 +2295,7 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_state( notify.dev_hdl = ctx->dev_hdl; notify.frame_id = ctx_isp->frame_id; notify.trigger = CAM_TRIGGER_POINT_SOF; + notify.sof_timestamp_val = ctx_isp->sof_timestamp_val; ctx->ctx_crm_intf->notify_trigger(¬ify); CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld", @@ -2361,6 +2366,7 @@ static int __cam_isp_ctx_rdi_only_reg_upd_in_bubble_applied_state( notify.dev_hdl = ctx->dev_hdl; notify.frame_id = ctx_isp->frame_id; notify.trigger = CAM_TRIGGER_POINT_SOF; + notify.sof_timestamp_val = ctx_isp->sof_timestamp_val; ctx->ctx_crm_intf->notify_trigger(¬ify); CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld", diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c index 9d176678d9de..cde0d8faae16 100644 --- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c +++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c @@ -48,6 +48,9 @@ void cam_req_mgr_core_link_reset(struct cam_req_mgr_core_link *link) link->last_flush_id = 0; link->initial_sync_req = -1; link->in_msync_mode = false; + link->initial_skip = true; + link->sof_timestamp = 0; + link->prev_sof_timestamp = 0; } void cam_req_mgr_handle_core_shutdown(void) @@ -609,6 +612,19 @@ static int __cam_req_mgr_check_link_is_ready(struct cam_req_mgr_core_link *link, traverse_data.validate_only = validate_only; traverse_data.open_req_cnt = link->open_req_cnt; + /* + * Some no-sync mode requests are processed after link config, + * then process the sync mode requests after no-sync mode requests + * are handled, the initial_skip should be false when processing + * the sync mode requests. + */ + if (link->initial_skip) { + CAM_DBG(CAM_CRM, + "Set initial_skip to false for link %x", + link->link_hdl); + link->initial_skip = false; + } + /* * Traverse through all pd tables, if result is success, * apply the settings @@ -897,6 +913,7 @@ static int __cam_req_mgr_check_sync_req_is_ready( int64_t req_id = 0; int sync_slot_idx = 0, sync_rd_idx = 0, rc = 0; int32_t sync_num_slots = 0; + uint64_t sync_frame_duration = 0; bool ready = true, sync_ready = true; if (!link->sync_link) { @@ -912,6 +929,57 @@ static int __cam_req_mgr_check_sync_req_is_ready( "link_hdl %x req %lld frame_skip_flag %d ", link->link_hdl, req_id, link->sync_link_sof_skip); + if (sync_link->initial_skip) { + link->initial_skip = false; + __cam_req_mgr_inject_delay(link->req.l_tbl, slot->idx); + CAM_DBG(CAM_CRM, + "sync link %x not streamed on", + sync_link->link_hdl); + return -EAGAIN; + } + + if (sync_link->prev_sof_timestamp) + sync_frame_duration = sync_link->sof_timestamp + - sync_link->prev_sof_timestamp; + else + sync_frame_duration = DEFAULT_FRAME_DURATION; + + CAM_DBG(CAM_CRM, + "sync link %x last frame_duration is %d ns", + sync_link->link_hdl, sync_frame_duration); + + if (link->initial_skip) { + link->initial_skip = false; + + if (link->sof_timestamp > sync_link->sof_timestamp && + sync_link->sof_timestamp > 0 && + link->sof_timestamp - sync_link->sof_timestamp < + sync_frame_duration / 2) { + /* + * If this frame sync with the previous frame of sync + * link, then we need to skip this frame, since the + * previous frame of sync link is also skipped. + */ + __cam_req_mgr_inject_delay(link->req.l_tbl, slot->idx); + CAM_DBG(CAM_CRM, + "This frame sync with previous sync_link %x frame", + sync_link->link_hdl); + return -EAGAIN; + } else if (link->sof_timestamp <= sync_link->sof_timestamp) { + /* + * Sometimes, link receives the SOF event is eariler + * than sync link in IFE CSID side, but link's SOF + * event is processed later than sync link's, then + * we need to skip this SOF event since the sync + * link's SOF event is also skipped. + */ + __cam_req_mgr_inject_delay(link->req.l_tbl, slot->idx); + CAM_DBG(CAM_CRM, + "The previous frame of sync link is skipped"); + return -EAGAIN; + } + } + if (sync_link->sync_link_sof_skip) { CAM_DBG(CAM_REQ, "No req applied on corresponding SOF on sync link: %x", @@ -1011,10 +1079,11 @@ static int __cam_req_mgr_check_sync_req_is_ready( * */ static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link, - uint32_t trigger) + struct cam_req_mgr_trigger_notify *trigger_data) { int rc = 0, idx, last_app_idx; int reset_step = 0; + uint32_t trigger = trigger_data->trigger; struct cam_req_mgr_slot *slot = NULL; struct cam_req_mgr_req_queue *in_q; struct cam_req_mgr_core_session *session; @@ -1052,6 +1121,13 @@ static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link, } if (trigger == CAM_TRIGGER_POINT_SOF) { + /* + * Update the timestamp in session lock protection + * to avoid timing issue. + */ + link->prev_sof_timestamp = link->sof_timestamp; + link->sof_timestamp = trigger_data->sof_timestamp_val; + if (link->trigger_mask) { CAM_ERR_RATE_LIMIT(CAM_CRM, "Applying for last EOF fails"); @@ -2141,7 +2217,7 @@ static int cam_req_mgr_process_trigger(void *priv, void *data) __cam_req_mgr_inc_idx(&in_q->rd_idx, 1, in_q->num_slots); } - rc = __cam_req_mgr_process_req(link, trigger_data->trigger); + rc = __cam_req_mgr_process_req(link, trigger_data); release_lock: mutex_unlock(&link->req.lock); @@ -2372,6 +2448,7 @@ static int cam_req_mgr_cb_notify_trigger( notify_trigger->link_hdl = trigger_data->link_hdl; notify_trigger->dev_hdl = trigger_data->dev_hdl; notify_trigger->trigger = trigger_data->trigger; + notify_trigger->sof_timestamp_val = trigger_data->sof_timestamp_val; task->process_cb = &cam_req_mgr_process_trigger; rc = cam_req_mgr_workq_enqueue_task(task, link, CRM_TASK_PRIORITY_0); @@ -3125,8 +3202,6 @@ int cam_req_mgr_sync_config( link1->is_master = false; link2->is_master = false; - link1->initial_skip = false; - link2->initial_skip = false; link1->in_msync_mode = false; link2->in_msync_mode = false; @@ -3137,6 +3212,16 @@ int cam_req_mgr_sync_config( link1->sync_link = link2; link2->sync_link = link1; __cam_req_mgr_set_master_link(link1, link2); + } else { + /* + * Reset below info after the mode is configured + * to NO-SYNC mode since they may be overridden + * if the sync config is invoked after SOF comes. + */ + link1->initial_skip = true; + link2->initial_skip = true; + link1->sof_timestamp = 0; + link2->sof_timestamp = 0; } cam_session->sync_mode = sync_info->sync_mode; diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.h b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.h index 7bd04c137ed9..bcaf4da387b3 100644 --- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.h +++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.h @@ -32,6 +32,9 @@ #define MAX_SYNC_COUNT 65535 +/* Default frame rate is 30 */ +#define DEFAULT_FRAME_DURATION 33333333 + #define SYNC_LINK_SOF_CNT_MAX_LMT 1 #define MAXIMUM_LINKS_PER_SESSION 4 @@ -321,7 +324,10 @@ struct cam_req_mgr_connected_device { * master-slave sync * @in_msync_mode : Flag to determine if a link is in master-slave mode * @initial_sync_req : The initial req which is required to sync with the - * other link + * other link, it means current hasn't receive any + * stream after streamon if it is true + * @sof_timestamp_value : SOF timestamp value + * @prev_sof_timestamp : Previous SOF timestamp value */ struct cam_req_mgr_core_link { int32_t link_hdl; @@ -348,6 +354,8 @@ struct cam_req_mgr_core_link { bool initial_skip; bool in_msync_mode; int64_t initial_sync_req; + uint64_t sof_timestamp; + uint64_t prev_sof_timestamp; }; /** diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_interface.h b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_interface.h index 409e74961b45..934bc76014a5 100644 --- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_interface.h +++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_interface.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -201,12 +201,14 @@ enum cam_req_mgr_link_evt_type { * @frame_id : frame id for internal tracking * @trigger : trigger point of this notification, CRM will send apply * only to the devices which subscribe to this point. + * @sof_timestamp_val: Captured time stamp value at sof hw event */ struct cam_req_mgr_trigger_notify { int32_t link_hdl; int32_t dev_hdl; int64_t frame_id; uint32_t trigger; + uint64_t sof_timestamp_val; }; /** -- GitLab From 7065a2f8eb04b6d01831b38b8371c49cea9eed3a Mon Sep 17 00:00:00 2001 From: Depeng Shao Date: Mon, 3 Jun 2019 19:54:41 +0800 Subject: [PATCH 0747/1121] msm: camera: reqmgr: Verify the req of two links The req of two links should be same if current frame sync with previous frame of sync link, CRM can do self-correction based on this condition. Change-Id: Idb208958a850ec1fe12f12443e7ecc2e126970d8 Signed-off-by: Depeng Shao --- .../msm/camera/cam_req_mgr/cam_req_mgr_core.c | 76 +++++++++++++++++-- 1 file changed, 71 insertions(+), 5 deletions(-) diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c index cde0d8faae16..d4a76622caec 100644 --- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c +++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c @@ -910,7 +910,8 @@ static int __cam_req_mgr_check_sync_req_is_ready( struct cam_req_mgr_slot *slot) { struct cam_req_mgr_core_link *sync_link = NULL; - int64_t req_id = 0; + struct cam_req_mgr_slot *sync_rd_slot = NULL; + int64_t req_id = 0, sync_req_id = 0; int sync_slot_idx = 0, sync_rd_idx = 0, rc = 0; int32_t sync_num_slots = 0; uint64_t sync_frame_duration = 0; @@ -924,6 +925,9 @@ static int __cam_req_mgr_check_sync_req_is_ready( sync_link = link->sync_link; req_id = slot->req_id; sync_num_slots = sync_link->req.in_q->num_slots; + sync_rd_idx = sync_link->req.in_q->rd_idx; + sync_rd_slot = &sync_link->req.in_q->slot[sync_rd_idx]; + sync_req_id = sync_rd_slot->req_id; CAM_DBG(CAM_REQ, "link_hdl %x req %lld frame_skip_flag %d ", @@ -945,7 +949,7 @@ static int __cam_req_mgr_check_sync_req_is_ready( sync_frame_duration = DEFAULT_FRAME_DURATION; CAM_DBG(CAM_CRM, - "sync link %x last frame_duration is %d ns", + "sync link %x last frame duration is %d ns", sync_link->link_hdl, sync_frame_duration); if (link->initial_skip) { @@ -1005,12 +1009,11 @@ static int __cam_req_mgr_check_sync_req_is_ready( sync_ready = false; } - sync_rd_idx = sync_link->req.in_q->rd_idx; if ((sync_link->req.in_q->slot[sync_slot_idx].status != CRM_SLOT_STATUS_REQ_APPLIED) && (((sync_slot_idx - sync_rd_idx + sync_num_slots) % sync_num_slots) >= 1) && - (sync_link->req.in_q->slot[sync_rd_idx].status != + (sync_rd_slot->status != CRM_SLOT_STATUS_REQ_APPLIED)) { CAM_DBG(CAM_CRM, "Req: %lld [other link] not next req to be applied on link: %x", @@ -1043,7 +1046,15 @@ static int __cam_req_mgr_check_sync_req_is_ready( CAM_DBG(CAM_CRM, "Req: %lld ready %d sync_ready %d, ignore sync link next SOF", req_id, ready, sync_ready); - link->sync_link_sof_skip = true; + + /* + * Only skip the frames if current frame sync with + * next frame of sync link. + */ + if (link->sof_timestamp - sync_link->sof_timestamp > + sync_frame_duration / 2) + link->sync_link_sof_skip = true; + return -EINVAL; } else if (ready == false) { CAM_DBG(CAM_CRM, @@ -1052,6 +1063,61 @@ static int __cam_req_mgr_check_sync_req_is_ready( return -EINVAL; } + /* + * Do the self-correction when the frames are sync, + * we consider that the frames are synced if the + * difference of two SOF timestamp less than + * (sync_frame_duration / 5). + */ + if ((link->sof_timestamp > sync_link->sof_timestamp) && + (sync_link->sof_timestamp > 0) && + (link->sof_timestamp - sync_link->sof_timestamp < + sync_frame_duration / 5) && + (sync_rd_slot->sync_mode == CAM_REQ_MGR_SYNC_MODE_SYNC)) { + + /* + * This means current frame should sync with next + * frame of sync link, then the request id of in + * rd slot of two links should be same. + */ + CAM_DBG(CAM_CRM, + "link %x req_id %lld, sync_link %x req_id %lld", + link->link_hdl, req_id, + sync_link->link_hdl, sync_req_id); + + if (req_id > sync_req_id) { + CAM_DBG(CAM_CRM, + "link %x too quickly, skip this frame", + link->link_hdl); + return -EAGAIN; + } else if (req_id < sync_req_id) { + CAM_DBG(CAM_CRM, + "sync link %x too quickly, skip next frame of sync link", + sync_link->link_hdl); + link->sync_link_sof_skip = true; + } + } else if ((sync_link->sof_timestamp > 0) && + (link->sof_timestamp < sync_link->sof_timestamp) && + (sync_link->sof_timestamp - link->sof_timestamp < + sync_frame_duration / 5) && + (sync_rd_slot->sync_mode == CAM_REQ_MGR_SYNC_MODE_SYNC)) { + + /* + * There is a timing issue once enter this condition, + * it means link receives the SOF event earlier than + * sync link in IFE CSID side, but the process in CRM + * is sync_link earlier than link, then previous SOF + * event of sync link is skipped, so we also need to + * skip this SOF event. + */ + if (req_id >= sync_req_id) { + CAM_DBG(CAM_CRM, + "Timing issue, the sof event of link %x is delayed", + link->link_hdl); + return -EAGAIN; + } + } + CAM_DBG(CAM_REQ, "Req: %lld ready to apply on link: %x [validation successful]", req_id, link->link_hdl); -- GitLab From f308c564b6ab3db2aeb5e78d92db30a7b6a4302f Mon Sep 17 00:00:00 2001 From: Jishnu Prakash Date: Sun, 23 Jun 2019 18:35:00 +0530 Subject: [PATCH 0748/1121] thermal: adc-tm: Add suspend_noirq support for ADC_TM ADC_TM driver can sleep before the notifications are sent to clients on threshold violation interrupts during suspend path. Flush workqueues for ADC_TM when device suspends to send all pending notifications. Change-Id: I368764725557524c556accd4966231a93943921f Signed-off-by: Jishnu Prakash --- drivers/thermal/qcom/adc-tm.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/thermal/qcom/adc-tm.c b/drivers/thermal/qcom/adc-tm.c index 730f7122ac56..3cefd0a68dde 100644 --- a/drivers/thermal/qcom/adc-tm.c +++ b/drivers/thermal/qcom/adc-tm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -424,10 +424,30 @@ static int adc_tm_remove(struct platform_device *pdev) return 0; } +static int adc_tm_suspend_noirq(struct device *dev) +{ + struct adc_tm_chip *adc_tm = dev_get_drvdata(dev); + int i = 0; + + while (i < adc_tm->dt_channels) { + if (adc_tm->sensor[i].req_wq) { + pr_debug("flushing queue for sensor %d\n", i); + flush_workqueue(adc_tm->sensor[i].req_wq); + } + i++; + } + return 0; +} + +static const struct dev_pm_ops adc_tm_pm_ops = { + .suspend_noirq = adc_tm_suspend_noirq, +}; + static struct platform_driver adc_tm_driver = { .driver = { .name = "qcom,adc-tm", .of_match_table = adc_tm_match_table, + .pm = &adc_tm_pm_ops, }, .probe = adc_tm_probe, .remove = adc_tm_remove, -- GitLab From 58a1490ed387fbb02029d0e426517c136a200db3 Mon Sep 17 00:00:00 2001 From: Jishnu Prakash Date: Tue, 2 Jul 2019 15:09:57 +0530 Subject: [PATCH 0749/1121] ARM: dts: msm: Fix ADC compilation error for atoll Fix the ADC compilation error by adding the ADC header file in the target specific file. While at it, remove the polling delay for tof_therm to avoid the periodic system wakeups. Change-Id: I8c5020fe4412a63c27808dd0280d09ac8d003fd3 Signed-off-by: Jishnu Prakash --- arch/arm64/boot/dts/qcom/atoll-idp.dtsi | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/atoll-idp.dtsi b/arch/arm64/boot/dts/qcom/atoll-idp.dtsi index 5a4b76171bcc..a9c5ba4e4177 100644 --- a/arch/arm64/boot/dts/qcom/atoll-idp.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll-idp.dtsi @@ -10,6 +10,8 @@ * GNU General Public License for more details. */ +#include + &soc { }; @@ -90,7 +92,7 @@ tof-therm { polling-delay-passive = <0>; - polling-delay = <5000>; + polling-delay = <0>; thermal-governor = "user_space"; thermal-sensors = <&pm6150l_adc_tm_iio ADC_GPIO3_PU2>; wake-capable-sensor; -- GitLab From 331ddccf489aacaf1f73b63bda467721eb586816 Mon Sep 17 00:00:00 2001 From: Mohammed Nayeem Ur Rahman Date: Thu, 27 Jun 2019 19:16:49 +0530 Subject: [PATCH 0750/1121] ARM: dts: msm: update atoll DT entries for fastRPC usecases Add CDSP loader DT entry to load CDSP image, add adsprpc mem region DT entry for remote heap usecase, configure SMMU context banks for fastRPC sessions. Change-Id: I012f9339103c39ac09be0b86e644391288f1f618 Acked-by: Krishnaiah Tadakamalla Signed-off-by: Mohammed Nayeem Ur Rahman --- arch/arm64/boot/dts/qcom/atoll.dtsi | 113 ++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index e42d12a897ac..b44004251cd6 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -583,6 +583,14 @@ size = <0 0x8c00000>; }; + adsp_mem: adsp_region { + compatible = "shared-dma-pool"; + alloc-ranges = <0x0 0x00000000 0x0 0xffffffff>; + reusable; + alignment = <0x0 0x400000>; + size = <0x0 0x800000>; + }; + /* global autoconfigured region for contiguous allocations */ linux,cma { compatible = "shared-dma-pool"; @@ -885,6 +893,111 @@ mbox-names = "cdsp-pil"; }; + qcom,msm-cdsp-loader { + compatible = "qcom,cdsp-loader"; + qcom,proc-img-to-load = "cdsp"; + }; + + qcom,msm-adsprpc-mem { + compatible = "qcom,msm-adsprpc-mem-region"; + memory-region = <&adsp_mem>; + restrict-access; + }; + + qcom,msm_fastrpc { + compatible = "qcom,msm-fastrpc-compute"; + qcom,rpc-latency-us = <611>; + qcom,adsp-remoteheap-vmid = <22 37>; + qcom,fastrpc-adsp-audio-pdr; + qcom,fastrpc-adsp-sensors-pdr; + + qcom,msm_fastrpc_compute_cb1 { + compatible = "qcom,msm-fastrpc-compute-cb"; + label = "cdsprpc-smd"; + iommus = <&apps_smmu 0x1401 0x20>; + dma-coherent; + }; + + qcom,msm_fastrpc_compute_cb2 { + compatible = "qcom,msm-fastrpc-compute-cb"; + label = "cdsprpc-smd"; + iommus = <&apps_smmu 0x1402 0x20>; + dma-coherent; + }; + + qcom,msm_fastrpc_compute_cb3 { + compatible = "qcom,msm-fastrpc-compute-cb"; + label = "cdsprpc-smd"; + iommus = <&apps_smmu 0x1403 0x20>; + dma-coherent; + }; + + qcom,msm_fastrpc_compute_cb4 { + compatible = "qcom,msm-fastrpc-compute-cb"; + label = "cdsprpc-smd"; + iommus = <&apps_smmu 0x1404 0x20>; + dma-coherent; + }; + + qcom,msm_fastrpc_compute_cb5 { + compatible = "qcom,msm-fastrpc-compute-cb"; + label = "cdsprpc-smd"; + iommus = <&apps_smmu 0x1405 0x20>; + dma-coherent; + }; + + qcom,msm_fastrpc_compute_cb6 { + compatible = "qcom,msm-fastrpc-compute-cb"; + label = "cdsprpc-smd"; + iommus = <&apps_smmu 0x1406 0x20>; + dma-coherent; + }; + + qcom,msm_fastrpc_compute_cb7 { + compatible = "qcom,msm-fastrpc-compute-cb"; + label = "cdsprpc-smd"; + iommus = <&apps_smmu 0x1407 0x20>; + dma-coherent; + }; + + qcom,msm_fastrpc_compute_cb8 { + compatible = "qcom,msm-fastrpc-compute-cb"; + label = "cdsprpc-smd"; + iommus = <&apps_smmu 0x1408 0x20>; + dma-coherent; + }; + + qcom,msm_fastrpc_compute_cb9 { + compatible = "qcom,msm-fastrpc-compute-cb"; + label = "cdsprpc-smd"; + qcom,secure-context-bank; + iommus = <&apps_smmu 0x1409 0x20>; + dma-coherent; + }; + + qcom,msm_fastrpc_compute_cb10 { + compatible = "qcom,msm-fastrpc-compute-cb"; + label = "adsprpc-smd"; + iommus = <&apps_smmu 0x1003 0x0>; + dma-coherent; + }; + + qcom,msm_fastrpc_compute_cb11 { + compatible = "qcom,msm-fastrpc-compute-cb"; + label = "adsprpc-smd"; + iommus = <&apps_smmu 0x1004 0x0>; + dma-coherent; + }; + + qcom,msm_fastrpc_compute_cb12 { + compatible = "qcom,msm-fastrpc-compute-cb"; + label = "adsprpc-smd"; + iommus = <&apps_smmu 0x1005 0x0>; + shared-cb = <5>; + dma-coherent; + }; + }; + qcom,lpass@62400000 { compatible = "qcom,pil-tz-generic"; reg = <0x62400000 0x00100>; -- GitLab From c61d011520028f616e16057134c44ad5be3c70ac Mon Sep 17 00:00:00 2001 From: Maria Yu Date: Thu, 27 Jun 2019 14:43:16 +0800 Subject: [PATCH 0751/1121] sched: core: Clear walt rq request in cpu starting Clear walt rq request in cpu starting. Change-Id: Id3004337f3924984b8b812151a6ba01c6f1c013e Signed-off-by: Maria Yu --- kernel/sched/core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 6f82ff44881d..91b80307795c 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -6256,6 +6256,7 @@ int sched_cpu_starting(unsigned int cpu) { set_cpu_rq_start_time(cpu); sched_rq_cpu_starting(cpu); + clear_walt_request(cpu); return 0; } -- GitLab From 07e7e2c2cc32c7d1699e85bc6a5af5f2e4d9b9a6 Mon Sep 17 00:00:00 2001 From: Maria Yu Date: Wed, 3 Apr 2019 18:26:21 +0800 Subject: [PATCH 0752/1121] sched/fair: Avoid cpu idle to deep sleep when have active balance Avoid cpu idle to deep sleep when have active balance task to be coming. Change-Id: Ie1c0f7fe0ff3da38d0a8f5ebe974080a52b7e6f4 Signed-off-by: Maria Yu --- kernel/sched/fair.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 344908a8fdf8..31e67d999d3e 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -11162,6 +11162,7 @@ static int load_balance(int this_cpu, struct rq *this_rq, busiest->active_balance = 1; busiest->push_cpu = this_cpu; active_balance = 1; + mark_reserved(this_cpu); } raw_spin_unlock_irqrestore(&busiest->lock, flags); @@ -11546,6 +11547,7 @@ static int active_load_balance_cpu_stop(void *data) busiest_rq->active_balance = 0; push_task = busiest_rq->push_task; target_cpu = busiest_rq->push_cpu; + clear_reserved(target_cpu); if (push_task) busiest_rq->push_task = NULL; @@ -11556,7 +11558,6 @@ static int active_load_balance_cpu_stop(void *data) if (push_task_detached) attach_one_task(target_rq, push_task); put_task_struct(push_task); - clear_reserved(target_cpu); } if (p) -- GitLab From c04a6b619361cd477f47c3f61d8704c061bdaf9a Mon Sep 17 00:00:00 2001 From: Yuanfang Zhang Date: Wed, 19 Jun 2019 13:12:20 +0800 Subject: [PATCH 0753/1121] Coresight: byte-cntr: Don't read byte-cntr when etr is diasbled Tmc etr buffer will be read when cat /dev/byte-cntr. If tmc etr is disabled, the buffer will be released. So exit byte-cntr-read when etr is disabled. Change-Id: Ia7037362dd973895f3b095a2ffbbab83570fb57e Signed-off-by: Yuanfang Zhang --- .../hwtracing/coresight/coresight-byte-cntr.c | 36 +++++++++++++------ 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-byte-cntr.c b/drivers/hwtracing/coresight/coresight-byte-cntr.c index 1a4c74191789..ecf92b7756b0 100644 --- a/drivers/hwtracing/coresight/coresight-byte-cntr.c +++ b/drivers/hwtracing/coresight/coresight-byte-cntr.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -143,13 +143,15 @@ static ssize_t tmc_etr_byte_cntr_read(struct file *fp, char __user *data, { struct byte_cntr *byte_cntr_data = fp->private_data; char *bufp; - + int ret = 0; if (!data) return -EINVAL; mutex_lock(&byte_cntr_data->byte_cntr_lock); - if (!byte_cntr_data->read_active) + if (!byte_cntr_data->read_active) { + ret = -EINVAL; goto err0; + } bufp = (char *)(tmcdrvdata->buf + *ppos); @@ -157,11 +159,15 @@ static ssize_t tmc_etr_byte_cntr_read(struct file *fp, char __user *data, if (!atomic_read(&byte_cntr_data->irq_cnt)) { mutex_unlock(&byte_cntr_data->byte_cntr_lock); if (wait_event_interruptible(byte_cntr_data->wq, - atomic_read(&byte_cntr_data->irq_cnt) > 0)) + atomic_read(&byte_cntr_data->irq_cnt) > 0 + || !byte_cntr_data->enable)) return -ERESTARTSYS; mutex_lock(&byte_cntr_data->byte_cntr_lock); - if (!byte_cntr_data->read_active) + if (!byte_cntr_data->read_active) { + ret = -EINVAL; goto err0; + } + } if (tmcdrvdata->memtype == TMC_ETR_MEM_TYPE_CONTIG) @@ -183,8 +189,10 @@ static ssize_t tmc_etr_byte_cntr_read(struct file *fp, char __user *data, byte_cntr_data->block_size, 1, &len, &bufp); - if (!len) + if (!len) { + ret = -EINVAL; goto err0; + } } else { if (tmcdrvdata->memtype == TMC_ETR_MEM_TYPE_CONTIG) tmc_etr_read_bytes(byte_cntr_data, ppos, @@ -208,9 +216,14 @@ static ssize_t tmc_etr_byte_cntr_read(struct file *fp, char __user *data, *ppos = 0; else *ppos += len; + + goto out; + err0: mutex_unlock(&byte_cntr_data->byte_cntr_lock); - + return ret; +out: + mutex_unlock(&byte_cntr_data->byte_cntr_lock); return len; } @@ -221,7 +234,8 @@ void tmc_etr_byte_cntr_start(struct byte_cntr *byte_cntr_data) mutex_lock(&byte_cntr_data->byte_cntr_lock); - if (byte_cntr_data->block_size == 0) { + if (byte_cntr_data->block_size == 0 + || byte_cntr_data->read_active) { mutex_unlock(&byte_cntr_data->byte_cntr_lock); return; } @@ -239,6 +253,8 @@ void tmc_etr_byte_cntr_stop(struct byte_cntr *byte_cntr_data) mutex_lock(&byte_cntr_data->byte_cntr_lock); byte_cntr_data->enable = false; + byte_cntr_data->read_active = false; + wake_up(&byte_cntr_data->wq); coresight_csr_set_byte_cntr(byte_cntr_data->csr, 0); mutex_unlock(&byte_cntr_data->byte_cntr_lock); @@ -266,7 +282,7 @@ static int tmc_etr_byte_cntr_open(struct inode *in, struct file *fp) mutex_lock(&byte_cntr_data->byte_cntr_lock); - if (!tmcdrvdata->enable || !byte_cntr_data->block_size) { + if (!byte_cntr_data->enable || !byte_cntr_data->block_size) { mutex_unlock(&byte_cntr_data->byte_cntr_lock); return -EINVAL; } @@ -279,10 +295,8 @@ static int tmc_etr_byte_cntr_open(struct inode *in, struct file *fp) fp->private_data = byte_cntr_data; nonseekable_open(in, fp); - byte_cntr_data->enable = true; byte_cntr_data->read_active = true; mutex_unlock(&byte_cntr_data->byte_cntr_lock); - return 0; } -- GitLab From 324ae1f3f174d2a10276c75e5af3e862442240a8 Mon Sep 17 00:00:00 2001 From: Kaushal Kumar Date: Tue, 2 Jul 2019 18:21:48 +0530 Subject: [PATCH 0754/1121] defconfig: msm: disable PM_AUTOSLEEP for sm8150, sa8155, trinket Disable PM_AUTOSLEEP for sm8150, sa8155 and trinket targets to align them with android base config. Change-Id: Iba3e3d6c6bec89d818bbbe5f3d84ec7ac57d3f52 Signed-off-by: Kaushal Kumar --- arch/arm64/configs/vendor/sa8155-perf_defconfig | 1 - arch/arm64/configs/vendor/sa8155_defconfig | 1 - arch/arm64/configs/vendor/sm8150-perf_defconfig | 1 - arch/arm64/configs/vendor/sm8150_defconfig | 1 - arch/arm64/configs/vendor/trinket-perf_defconfig | 1 - arch/arm64/configs/vendor/trinket_defconfig | 1 - 6 files changed, 6 deletions(-) diff --git a/arch/arm64/configs/vendor/sa8155-perf_defconfig b/arch/arm64/configs/vendor/sa8155-perf_defconfig index ab10045c4e48..071c6c943d4f 100644 --- a/arch/arm64/configs/vendor/sa8155-perf_defconfig +++ b/arch/arm64/configs/vendor/sa8155-perf_defconfig @@ -79,7 +79,6 @@ CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y CONFIG_BUILD_ARM64_UNCOMPRESSED_KERNEL=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_COMPAT=y -CONFIG_PM_AUTOSLEEP=y CONFIG_PM_WAKELOCKS=y CONFIG_PM_WAKELOCKS_LIMIT=0 # CONFIG_PM_WAKELOCKS_GC is not set diff --git a/arch/arm64/configs/vendor/sa8155_defconfig b/arch/arm64/configs/vendor/sa8155_defconfig index 2c4bc5524158..8215ca010e84 100644 --- a/arch/arm64/configs/vendor/sa8155_defconfig +++ b/arch/arm64/configs/vendor/sa8155_defconfig @@ -87,7 +87,6 @@ CONFIG_BUILD_ARM64_UNCOMPRESSED_KERNEL=y CONFIG_COMPAT=y CONFIG_HIBERNATION=y CONFIG_PM_STD_PARTITION="/dev/sda7" -CONFIG_PM_AUTOSLEEP=y CONFIG_PM_WAKELOCKS=y CONFIG_PM_WAKELOCKS_LIMIT=0 # CONFIG_PM_WAKELOCKS_GC is not set diff --git a/arch/arm64/configs/vendor/sm8150-perf_defconfig b/arch/arm64/configs/vendor/sm8150-perf_defconfig index 21918d41533f..70976f73a38f 100644 --- a/arch/arm64/configs/vendor/sm8150-perf_defconfig +++ b/arch/arm64/configs/vendor/sm8150-perf_defconfig @@ -85,7 +85,6 @@ CONFIG_BUILD_ARM64_UNCOMPRESSED_KERNEL=y CONFIG_KRYO_PMU_WORKAROUND=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_COMPAT=y -CONFIG_PM_AUTOSLEEP=y CONFIG_PM_WAKELOCKS=y CONFIG_PM_WAKELOCKS_LIMIT=0 # CONFIG_PM_WAKELOCKS_GC is not set diff --git a/arch/arm64/configs/vendor/sm8150_defconfig b/arch/arm64/configs/vendor/sm8150_defconfig index 44bd6ad2404c..73a9c5d9c311 100644 --- a/arch/arm64/configs/vendor/sm8150_defconfig +++ b/arch/arm64/configs/vendor/sm8150_defconfig @@ -91,7 +91,6 @@ CONFIG_BUILD_ARM64_UNCOMPRESSED_KERNEL=y CONFIG_KRYO_PMU_WORKAROUND=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_COMPAT=y -CONFIG_PM_AUTOSLEEP=y CONFIG_PM_WAKELOCKS=y CONFIG_PM_WAKELOCKS_LIMIT=0 # CONFIG_PM_WAKELOCKS_GC is not set diff --git a/arch/arm64/configs/vendor/trinket-perf_defconfig b/arch/arm64/configs/vendor/trinket-perf_defconfig index da204a4f283b..cadaf213e19a 100644 --- a/arch/arm64/configs/vendor/trinket-perf_defconfig +++ b/arch/arm64/configs/vendor/trinket-perf_defconfig @@ -82,7 +82,6 @@ CONFIG_RANDOMIZE_BASE=y CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_COMPAT=y -CONFIG_PM_AUTOSLEEP=y CONFIG_PM_WAKELOCKS=y CONFIG_PM_WAKELOCKS_LIMIT=0 # CONFIG_PM_WAKELOCKS_GC is not set diff --git a/arch/arm64/configs/vendor/trinket_defconfig b/arch/arm64/configs/vendor/trinket_defconfig index 7a14f8209f92..bb367d4d0959 100644 --- a/arch/arm64/configs/vendor/trinket_defconfig +++ b/arch/arm64/configs/vendor/trinket_defconfig @@ -88,7 +88,6 @@ CONFIG_RANDOMIZE_BASE=y CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_COMPAT=y -CONFIG_PM_AUTOSLEEP=y CONFIG_PM_WAKELOCKS=y CONFIG_PM_WAKELOCKS_LIMIT=0 # CONFIG_PM_WAKELOCKS_GC is not set -- GitLab From 3f26e3414fe72613eb558d200934dc9a5d165d3d Mon Sep 17 00:00:00 2001 From: Manoj Prabhu B Date: Tue, 2 Jul 2019 12:54:02 +0530 Subject: [PATCH 0755/1121] diag: Switch to correct logging mode after mdlog exit Mdlog in multimode when exits is not switching to required USB or PCIE mode. Adding missing check handles switching to proper logging mode when mdlog exits. Change-Id: I7c7bc23c463cc809765b4774fa5147c7245d8c50 Signed-off-by: Manoj Prabhu B --- drivers/char/diag/diagchar_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c index 5428ad8c1c00..5c63ba2749ee 100644 --- a/drivers/char/diag/diagchar_core.c +++ b/drivers/char/diag/diagchar_core.c @@ -1615,7 +1615,8 @@ static int diag_md_session_check(int proc, int curr_mode, int req_mode, *change_mode = 1; return 0; } else if ((req_mode == DIAG_USB_MODE || req_mode == DIAG_PCIE_MODE) - && curr_mode == DIAG_MEMORY_DEVICE_MODE) { + && (curr_mode == DIAG_MEMORY_DEVICE_MODE || + curr_mode == DIAG_MULTI_MODE)) { mutex_lock(&driver->md_session_lock); if (driver->md_session_mode[proc] == DIAG_MD_NONE && driver->md_session_mask[proc] == 0 && -- GitLab From 639cbe86715f3b6d1239223e759ad8c83f95f877 Mon Sep 17 00:00:00 2001 From: Rajesh Kemisetti Date: Tue, 2 Jul 2019 20:10:34 +0530 Subject: [PATCH 0756/1121] msm: kgsl: Correctly update script size for MVC registers Update crash dumper script size correctly for MVC sub-block select register so as to avoid out of bound access if any. Change-Id: I82c4f1ef5f9b8e929ea7d217f6682f96899424bb Signed-off-by: Rajesh Kemisetti --- drivers/gpu/msm/adreno_a6xx_snapshot.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/msm/adreno_a6xx_snapshot.c b/drivers/gpu/msm/adreno_a6xx_snapshot.c index 2a75c75492d8..472c933aecb1 100644 --- a/drivers/gpu/msm/adreno_a6xx_snapshot.c +++ b/drivers/gpu/msm/adreno_a6xx_snapshot.c @@ -1856,6 +1856,10 @@ void a6xx_crashdump_init(struct adreno_device *adreno_dev) for (i = 0; i < ARRAY_SIZE(a6xx_clusters); i++) { struct a6xx_cluster_registers *cluster = &a6xx_clusters[i]; + /* 16 bytes if cluster sel exists */ + if (cluster->sel) + script_size += 16; + for (j = 0; j < A6XX_NUM_CTXTS; j++) { /* 16 bytes for programming the aperture */ -- GitLab From 7f34cbab70f377c94756ada4def371e69623bbaf Mon Sep 17 00:00:00 2001 From: "Jinesh K. Jayakumar" Date: Fri, 21 Jun 2019 08:50:20 -0400 Subject: [PATCH 0757/1121] msm: ipa: Add support for crashdump in IPA offload sub-system Enable support in IPA offload sub-system to call into network and offload drivers to collect device registers during a kernel panic. Change-Id: I35b1b84d29716f78f19606a3603447df1cfd0c6b Signed-off-by: Jinesh K. Jayakumar --- .../msm/ipa/ipa_v3/ethernet/ipa_eth.c | 35 +++++++++++++++++++ .../msm/ipa/ipa_v3/ethernet/ipa_eth_i.h | 4 +++ .../msm/ipa/ipa_v3/ethernet/ipa_eth_net.c | 10 ++++++ .../msm/ipa/ipa_v3/ethernet/ipa_eth_offload.c | 10 ++++++ include/linux/ipa_eth.h | 25 ++++++++++++- 5 files changed, 83 insertions(+), 1 deletion(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth.c b/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth.c index 0405b09a24ba..91c8222eefce 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth.c +++ b/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth.c @@ -1014,11 +1014,41 @@ static void ipa_eth_ipc_log_cleanup(void) } } +static int ipa_eth_panic_save_device(struct ipa_eth_device *eth_dev) +{ + ipa_eth_net_save_regs(eth_dev); + ipa_eth_offload_save_regs(eth_dev); + + return 0; +} + +static int ipa_eth_panic_notifier(struct notifier_block *nb, + unsigned long event, void *ptr) +{ + struct ipa_eth_device *eth_dev; + + mutex_lock(&ipa_eth_devices_lock); + + list_for_each_entry(eth_dev, &ipa_eth_devices, device_list) + ipa_eth_panic_save_device(eth_dev); + + mutex_unlock(&ipa_eth_devices_lock); + + return NOTIFY_DONE; +} + +static struct notifier_block ipa_eth_panic_nb = { + .notifier_call = ipa_eth_panic_notifier, +}; + int ipa_eth_init(void) { int rc; unsigned int wq_flags = WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_FREEZABLE; + (void) atomic_notifier_chain_register( + &panic_notifier_list, &ipa_eth_panic_nb); + rc = ipa_eth_ipc_log_init(); if (rc) { ipa_eth_err("Failed to initialize IPC logging"); @@ -1087,6 +1117,8 @@ int ipa_eth_init(void) err_dbgfs: ipa_eth_ipc_log_cleanup(); err_ipclog: + (void) atomic_notifier_chain_unregister( + &panic_notifier_list, &ipa_eth_panic_nb); return rc; } @@ -1107,4 +1139,7 @@ void ipa_eth_exit(void) ipa_eth_debugfs_cleanup(); ipa_eth_ipc_log_cleanup(); + + (void) atomic_notifier_chain_unregister( + &panic_notifier_list, &ipa_eth_panic_nb); } diff --git a/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_i.h b/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_i.h index 1c63fc92e4d2..9b7212bd726c 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_i.h @@ -146,9 +146,13 @@ int ipa_eth_offload_deinit(struct ipa_eth_device *eth_dev); int ipa_eth_offload_start(struct ipa_eth_device *eth_dev); int ipa_eth_offload_stop(struct ipa_eth_device *eth_dev); +int ipa_eth_offload_save_regs(struct ipa_eth_device *eth_dev); + int ipa_eth_net_open_device(struct ipa_eth_device *eth_dev); void ipa_eth_net_close_device(struct ipa_eth_device *eth_dev); +int ipa_eth_net_save_regs(struct ipa_eth_device *eth_dev); + int ipa_eth_ep_init_headers(struct ipa_eth_device *eth_dev); int ipa_eth_ep_register_interface(struct ipa_eth_device *eth_dev); int ipa_eth_ep_unregister_interface(struct ipa_eth_device *eth_dev); diff --git a/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_net.c b/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_net.c index 1e993936abe9..1c4b502f9442 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_net.c +++ b/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_net.c @@ -1058,3 +1058,13 @@ struct ipa_eth_resource *ipa_eth_net_ch_to_cb_mem( return cb_mem; } EXPORT_SYMBOL(ipa_eth_net_ch_to_cb_mem); + +int ipa_eth_net_save_regs(struct ipa_eth_device *eth_dev) +{ + struct ipa_eth_net_driver *nd = eth_dev->nd; + + if (nd && nd->ops->save_regs) + return ipa_eth_nd_op(eth_dev, save_regs, eth_dev, NULL, NULL); + + return 0; +} diff --git a/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_offload.c b/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_offload.c index faebc82bf256..89acc788609c 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_offload.c +++ b/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_offload.c @@ -212,6 +212,16 @@ void ipa_eth_offload_unregister_driver(struct ipa_eth_offload_driver *od) mutex_unlock(&ipa_eth_offload_drivers_lock); } +int ipa_eth_offload_save_regs(struct ipa_eth_device *eth_dev) +{ + struct ipa_eth_offload_driver *od = eth_dev->od; + + if (od && od->ops->save_regs) + return eth_dev->od->ops->save_regs(eth_dev, NULL, NULL); + + return 0; +} + int ipa_eth_offload_modinit(struct dentry *dbgfs_root) { int rc; diff --git a/include/linux/ipa_eth.h b/include/linux/ipa_eth.h index 15fcf3d3f6d4..04eed6ad4236 100644 --- a/include/linux/ipa_eth.h +++ b/include/linux/ipa_eth.h @@ -38,9 +38,10 @@ * defined via struct ipa_eth_dma_allocator interface * - probe() and remove() offload bus ops are replaced by pair() * and unpair() callbacks respectively + * 3 - Added .save_regs() callback for network and offload drivers */ -#define IPA_ETH_API_VER 2 +#define IPA_ETH_API_VER 3 /** * enum ipa_eth_dev_features - Features supported by an ethernet device or @@ -687,6 +688,17 @@ struct ipa_eth_net_ops { */ int (*transmit_skb)(struct ipa_eth_device *eth_dev, struct sk_buff *skb); + + /** + * .save_regs() - Save registers for debugging + * @eth_dev: Offloaded device + * @regs: if not NULL, write saved data address to the given pointer + * @size: if not NULL, write the size of saved data to the given pointer + * + * Return: 0 on success, errno otherwise. + */ + int (*save_regs)(struct ipa_eth_device *eth_dev, + void **regs, size_t *size); }; /** @@ -877,6 +889,17 @@ struct ipa_eth_offload_ops { * Return: 0 on success, negative errno otherwise */ int (*clear_stats)(struct ipa_eth_device *eth_dev); + + /** + * .save_regs() - Save registers for debugging + * @eth_dev: Offloaded device + * @regs: if not NULL, write saved data address to the given pointer + * @size: if not NULL, write the size of saved data to the given pointer + * + * Return: 0 on success, errno otherwise. + */ + int (*save_regs)(struct ipa_eth_device *eth_dev, + void **regs, size_t *size); }; /** -- GitLab From 166b4faf381ccb69037a92b9b896778ca46285d7 Mon Sep 17 00:00:00 2001 From: Sujeev Dias Date: Thu, 16 May 2019 16:35:46 -0700 Subject: [PATCH 0758/1121] mhi: core: add time synchronized logs support Whenever important events such as state changes occur on device, it can help in debug to compare device timestamps and co-relate those with host-side processing. Add support to log remote time for these important events from MHI core layer. CRs-Fixed: 2377061 Change-Id: Ieffd28e8049266e05a6c7397238083f02b2c095f Acked-by: Bhaumik Vasav Bhatt Signed-off-by: Sujeev Dias --- drivers/bus/mhi/core/mhi_internal.h | 10 ++++++++++ drivers/bus/mhi/core/mhi_pm.c | 3 +++ include/linux/mhi.h | 1 + 3 files changed, 14 insertions(+) diff --git a/drivers/bus/mhi/core/mhi_internal.h b/drivers/bus/mhi/core/mhi_internal.h index 3ae36ac333f4..3c61ac56e557 100644 --- a/drivers/bus/mhi/core/mhi_internal.h +++ b/drivers/bus/mhi/core/mhi_internal.h @@ -762,6 +762,16 @@ void mhi_destroy_timesync(struct mhi_controller *mhi_cntrl); int mhi_create_vote_sysfs(struct mhi_controller *mhi_cntrl); void mhi_destroy_vote_sysfs(struct mhi_controller *mhi_cntrl); +/* timesync log support */ +static inline void mhi_timesync_log(struct mhi_controller *mhi_cntrl) +{ + struct mhi_timesync *mhi_tsync = mhi_cntrl->mhi_tsync; + + if (mhi_tsync && mhi_cntrl->tsync_log) + mhi_cntrl->tsync_log(mhi_cntrl, + readq_no_log(mhi_tsync->time_reg)); +} + /* memory allocation methods */ static inline void *mhi_alloc_coherent(struct mhi_controller *mhi_cntrl, size_t size, diff --git a/drivers/bus/mhi/core/mhi_pm.c b/drivers/bus/mhi/core/mhi_pm.c index 846910a15428..35dd3e213b6e 100644 --- a/drivers/bus/mhi/core/mhi_pm.c +++ b/drivers/bus/mhi/core/mhi_pm.c @@ -145,6 +145,9 @@ enum MHI_PM_STATE __must_check mhi_tryset_pm_state( MHI_VERB("Transition to pm state from:%s to:%s\n", to_mhi_pm_state_str(cur_state), to_mhi_pm_state_str(state)); + if (MHI_REG_ACCESS_VALID(cur_state) || MHI_REG_ACCESS_VALID(state)) + mhi_timesync_log(mhi_cntrl); + mhi_cntrl->pm_state = state; return mhi_cntrl->pm_state; } diff --git a/include/linux/mhi.h b/include/linux/mhi.h index 94b6f4f99883..7ac0ed9f9c20 100644 --- a/include/linux/mhi.h +++ b/include/linux/mhi.h @@ -301,6 +301,7 @@ struct mhi_controller { struct mhi_buf_info *buf); void (*unmap_single)(struct mhi_controller *mhi_cntrl, struct mhi_buf_info *buf); + void (*tsync_log)(struct mhi_controller *mhi_cntrl, u64 remote_time); /* channel to control DTR messaging */ struct mhi_device *dtr_dev; -- GitLab From 76cfefd09706a9524546278f4937091b44442e6e Mon Sep 17 00:00:00 2001 From: Sujeev Dias Date: Tue, 11 Jun 2019 20:47:08 -0700 Subject: [PATCH 0759/1121] mhi: core: skip MHI state SYS_ERR handling if RDDM is supported Controllers that support RDDM mode does not handle optional SYS_ERR to RDDM transition well. Instead of handling SYS_ERR transition, jump straight to ramdump transfer by programming RXVEC registers during boot. CRs-Fixed: 2459474 Change-Id: If39989520b161bc073a552cd4bf048283cf1d8e4 Signed-off-by: Sujeev Dias --- drivers/bus/mhi/core/mhi_boot.c | 111 +++++++--------------------- drivers/bus/mhi/core/mhi_init.c | 3 + drivers/bus/mhi/core/mhi_internal.h | 2 + drivers/bus/mhi/core/mhi_main.c | 20 ++++- drivers/bus/mhi/core/mhi_pm.c | 13 +++- 5 files changed, 59 insertions(+), 90 deletions(-) diff --git a/drivers/bus/mhi/core/mhi_boot.c b/drivers/bus/mhi/core/mhi_boot.c index 74fca23a627e..6f4c24f659ca 100644 --- a/drivers/bus/mhi/core/mhi_boot.c +++ b/drivers/bus/mhi/core/mhi_boot.c @@ -27,12 +27,14 @@ #include "mhi_internal.h" -/* setup rddm vector table for rddm transfer */ -static void mhi_rddm_prepare(struct mhi_controller *mhi_cntrl, +/* setup rddm vector table for rddm transfer and program rxvec */ +void mhi_rddm_prepare(struct mhi_controller *mhi_cntrl, struct image_info *img_info) { struct mhi_buf *mhi_buf = img_info->mhi_buf; struct bhi_vec_entry *bhi_vec = img_info->bhi_vec; + void __iomem *base = mhi_cntrl->bhie; + u32 sequence_id; int i = 0; for (i = 0; i < img_info->entries - 1; i++, mhi_buf++, bhi_vec++) { @@ -41,17 +43,35 @@ static void mhi_rddm_prepare(struct mhi_controller *mhi_cntrl, bhi_vec->dma_addr = mhi_buf->dma_addr; bhi_vec->size = mhi_buf->len; } + + MHI_LOG("BHIe programming for RDDM\n"); + + mhi_write_reg(mhi_cntrl, base, BHIE_RXVECADDR_HIGH_OFFS, + upper_32_bits(mhi_buf->dma_addr)); + + mhi_write_reg(mhi_cntrl, base, BHIE_RXVECADDR_LOW_OFFS, + lower_32_bits(mhi_buf->dma_addr)); + + mhi_write_reg(mhi_cntrl, base, BHIE_RXVECSIZE_OFFS, mhi_buf->len); + sequence_id = prandom_u32() & BHIE_RXVECSTATUS_SEQNUM_BMSK; + + if (unlikely(!sequence_id)) + sequence_id = 1; + + mhi_write_reg_field(mhi_cntrl, base, BHIE_RXVECDB_OFFS, + BHIE_RXVECDB_SEQNUM_BMSK, BHIE_RXVECDB_SEQNUM_SHFT, + sequence_id); + + MHI_LOG("address:%pad len:0x%lx sequence:%u\n", + &mhi_buf->dma_addr, mhi_buf->len, sequence_id); } /* collect rddm during kernel panic */ static int __mhi_download_rddm_in_panic(struct mhi_controller *mhi_cntrl) { int ret; - struct mhi_buf *mhi_buf; - u32 sequence_id; u32 rx_status; enum mhi_ee ee; - struct image_info *rddm_image = mhi_cntrl->rddm_image; const u32 delayus = 2000; u32 retry = (mhi_cntrl->timeout_ms * 1000) / delayus; const u32 rddm_timeout_us = 200000; @@ -77,29 +97,6 @@ static int __mhi_download_rddm_in_panic(struct mhi_controller *mhi_cntrl) /* update should take the effect immediately */ smp_wmb(); - /* setup the RX vector table */ - mhi_rddm_prepare(mhi_cntrl, rddm_image); - mhi_buf = &rddm_image->mhi_buf[rddm_image->entries - 1]; - - MHI_LOG("Starting BHIe programming for RDDM\n"); - - mhi_write_reg(mhi_cntrl, base, BHIE_RXVECADDR_HIGH_OFFS, - upper_32_bits(mhi_buf->dma_addr)); - - mhi_write_reg(mhi_cntrl, base, BHIE_RXVECADDR_LOW_OFFS, - lower_32_bits(mhi_buf->dma_addr)); - - mhi_write_reg(mhi_cntrl, base, BHIE_RXVECSIZE_OFFS, mhi_buf->len); - sequence_id = prandom_u32() & BHIE_RXVECSTATUS_SEQNUM_BMSK; - - if (unlikely(!sequence_id)) - sequence_id = 1; - - - mhi_write_reg_field(mhi_cntrl, base, BHIE_RXVECDB_OFFS, - BHIE_RXVECDB_SEQNUM_BMSK, BHIE_RXVECDB_SEQNUM_SHFT, - sequence_id); - /* * Make sure device is not already in RDDM. * In case device asserts and a kernel panic follows, device will @@ -166,70 +163,15 @@ static int __mhi_download_rddm_in_panic(struct mhi_controller *mhi_cntrl) int mhi_download_rddm_img(struct mhi_controller *mhi_cntrl, bool in_panic) { void __iomem *base = mhi_cntrl->bhie; - rwlock_t *pm_lock = &mhi_cntrl->pm_lock; - struct image_info *rddm_image = mhi_cntrl->rddm_image; - struct mhi_buf *mhi_buf; - int ret; u32 rx_status; - u32 sequence_id; - - if (!rddm_image) - return -ENOMEM; if (in_panic) return __mhi_download_rddm_in_panic(mhi_cntrl); - MHI_LOG("Waiting for device to enter RDDM state from EE:%s\n", - TO_MHI_EXEC_STR(mhi_cntrl->ee)); - - ret = wait_event_timeout(mhi_cntrl->state_event, - mhi_cntrl->ee == MHI_EE_RDDM || - MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state), - msecs_to_jiffies(mhi_cntrl->timeout_ms)); - - if (!ret || MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) { - MHI_ERR("MHI is not in valid state, pm_state:%s ee:%s\n", - to_mhi_pm_state_str(mhi_cntrl->pm_state), - TO_MHI_EXEC_STR(mhi_cntrl->ee)); - return -EIO; - } - - mhi_rddm_prepare(mhi_cntrl, mhi_cntrl->rddm_image); - - /* vector table is the last entry */ - mhi_buf = &rddm_image->mhi_buf[rddm_image->entries - 1]; - - read_lock_bh(pm_lock); - if (!MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) { - read_unlock_bh(pm_lock); - return -EIO; - } - - MHI_LOG("Starting BHIe Programming for RDDM\n"); - - mhi_write_reg(mhi_cntrl, base, BHIE_RXVECADDR_HIGH_OFFS, - upper_32_bits(mhi_buf->dma_addr)); - - mhi_write_reg(mhi_cntrl, base, BHIE_RXVECADDR_LOW_OFFS, - lower_32_bits(mhi_buf->dma_addr)); - - mhi_write_reg(mhi_cntrl, base, BHIE_RXVECSIZE_OFFS, mhi_buf->len); - - sequence_id = prandom_u32() & BHIE_RXVECSTATUS_SEQNUM_BMSK; - mhi_write_reg_field(mhi_cntrl, base, BHIE_RXVECDB_OFFS, - BHIE_RXVECDB_SEQNUM_BMSK, BHIE_RXVECDB_SEQNUM_SHFT, - sequence_id); - read_unlock_bh(pm_lock); - - MHI_LOG("Upper:0x%x Lower:0x%x len:0x%lx sequence:%u\n", - upper_32_bits(mhi_buf->dma_addr), - lower_32_bits(mhi_buf->dma_addr), - mhi_buf->len, sequence_id); MHI_LOG("Waiting for image download completion\n"); /* waiting for image download completion */ wait_event_timeout(mhi_cntrl->state_event, - MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state) || mhi_read_reg_field(mhi_cntrl, base, BHIE_RXVECSTATUS_OFFS, BHIE_RXVECSTATUS_STATUS_BMSK, @@ -237,9 +179,6 @@ int mhi_download_rddm_img(struct mhi_controller *mhi_cntrl, bool in_panic) &rx_status) || rx_status, msecs_to_jiffies(mhi_cntrl->timeout_ms)); - if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) - return -EIO; - return (rx_status == BHIE_RXVECSTATUS_STATUS_XFER_COMPL) ? 0 : -EIO; } EXPORT_SYMBOL(mhi_download_rddm_img); diff --git a/drivers/bus/mhi/core/mhi_init.c b/drivers/bus/mhi/core/mhi_init.c index 57dd599f6e90..d070c5c773d8 100644 --- a/drivers/bus/mhi/core/mhi_init.c +++ b/drivers/bus/mhi/core/mhi_init.c @@ -1427,6 +1427,9 @@ int mhi_prepare_for_power_up(struct mhi_controller *mhi_cntrl) memset_io(mhi_cntrl->bhie + BHIE_RXVECADDR_LOW_OFFS, 0, BHIE_RXVECSTATUS_OFFS - BHIE_RXVECADDR_LOW_OFFS + 4); + + if (mhi_cntrl->rddm_image) + mhi_rddm_prepare(mhi_cntrl, mhi_cntrl->rddm_image); } mhi_cntrl->pre_init = true; diff --git a/drivers/bus/mhi/core/mhi_internal.h b/drivers/bus/mhi/core/mhi_internal.h index 3c61ac56e557..887f93e410ea 100644 --- a/drivers/bus/mhi/core/mhi_internal.h +++ b/drivers/bus/mhi/core/mhi_internal.h @@ -826,6 +826,8 @@ void mhi_deinit_dev_ctxt(struct mhi_controller *mhi_cntrl); int mhi_init_irq_setup(struct mhi_controller *mhi_cntrl); void mhi_deinit_free_irq(struct mhi_controller *mhi_cntrl); int mhi_dtr_init(void); +void mhi_rddm_prepare(struct mhi_controller *mhi_cntrl, + struct image_info *img_info); /* isr handlers */ irqreturn_t mhi_msi_handlr(int irq_number, void *dev); diff --git a/drivers/bus/mhi/core/mhi_main.c b/drivers/bus/mhi/core/mhi_main.c index 7859ef5749b8..1e786e97c5d3 100644 --- a/drivers/bus/mhi/core/mhi_main.c +++ b/drivers/bus/mhi/core/mhi_main.c @@ -1467,15 +1467,17 @@ irqreturn_t mhi_intvec_threaded_handlr(int irq_number, void *dev) struct mhi_controller *mhi_cntrl = dev; enum mhi_dev_state state = MHI_STATE_MAX; enum MHI_PM_STATE pm_state = 0; - enum mhi_ee ee; + enum mhi_ee ee = 0; MHI_VERB("Enter\n"); write_lock_irq(&mhi_cntrl->pm_lock); if (MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) { state = mhi_get_mhi_state(mhi_cntrl); - ee = mhi_get_exec_env(mhi_cntrl); - MHI_LOG("device ee:%s dev_state:%s\n", TO_MHI_EXEC_STR(ee), + ee = mhi_cntrl->ee; + mhi_cntrl->ee = mhi_get_exec_env(mhi_cntrl); + MHI_LOG("device ee:%s dev_state:%s\n", + TO_MHI_EXEC_STR(mhi_cntrl->ee), TO_MHI_STATE_STR(state)); } @@ -1485,6 +1487,17 @@ irqreturn_t mhi_intvec_threaded_handlr(int irq_number, void *dev) MHI_PM_SYS_ERR_DETECT); } write_unlock_irq(&mhi_cntrl->pm_lock); + + /* if device in rddm don't bother processing sys error */ + if (mhi_cntrl->ee == MHI_EE_RDDM) { + if (mhi_cntrl->ee != ee) { + mhi_cntrl->status_cb(mhi_cntrl, mhi_cntrl->priv_data, + MHI_CB_EE_RDDM); + wake_up_all(&mhi_cntrl->state_event); + } + goto exit_intvec; + } + if (pm_state == MHI_PM_SYS_ERR_DETECT) { wake_up_all(&mhi_cntrl->state_event); @@ -1496,6 +1509,7 @@ irqreturn_t mhi_intvec_threaded_handlr(int irq_number, void *dev) schedule_work(&mhi_cntrl->syserr_worker); } +exit_intvec: MHI_VERB("Exit\n"); return IRQ_HANDLED; diff --git a/drivers/bus/mhi/core/mhi_pm.c b/drivers/bus/mhi/core/mhi_pm.c index 35dd3e213b6e..fb7118cd6799 100644 --- a/drivers/bus/mhi/core/mhi_pm.c +++ b/drivers/bus/mhi/core/mhi_pm.c @@ -529,9 +529,20 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl, to_mhi_pm_state_str(transition_state)); /* We must notify MHI control driver so it can clean up first */ - if (transition_state == MHI_PM_SYS_ERR_PROCESS) + if (transition_state == MHI_PM_SYS_ERR_PROCESS) { + /* + * if controller support rddm, we do not process + * sys error state, instead we will jump directly + * to rddm state + */ + if (mhi_cntrl->rddm_image) { + MHI_LOG( + "Controller Support RDDM, skipping SYS_ERR_PROCESS\n"); + return; + } mhi_cntrl->status_cb(mhi_cntrl, mhi_cntrl->priv_data, MHI_CB_SYS_ERROR); + } mutex_lock(&mhi_cntrl->pm_mutex); write_lock_irq(&mhi_cntrl->pm_lock); -- GitLab From 8d8e470d0db8fd7cbe8660ed702d04dcdde57025 Mon Sep 17 00:00:00 2001 From: Sujeev Dias Date: Tue, 11 Jun 2019 21:19:25 -0700 Subject: [PATCH 0760/1121] mhi: core: do not trigger sys_error if controller already entered RDDM EE Triggering SYS ERROR while controller in RDDM EE has undefined behavior. Return immediately if controller already in RDDM EE. CRs-Fixed: 2459474 Change-Id: I9a84313633098e39c67b1459de6cc1bfd8f0248d Signed-off-by: Sujeev Dias --- drivers/bus/mhi/core/mhi_pm.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/bus/mhi/core/mhi_pm.c b/drivers/bus/mhi/core/mhi_pm.c index fb7118cd6799..b8eb3dfbaf07 100644 --- a/drivers/bus/mhi/core/mhi_pm.c +++ b/drivers/bus/mhi/core/mhi_pm.c @@ -1413,6 +1413,10 @@ int mhi_force_rddm_mode(struct mhi_controller *mhi_cntrl) to_mhi_pm_state_str(mhi_cntrl->pm_state), TO_MHI_EXEC_STR(mhi_cntrl->ee)); + /* device already in rddm */ + if (mhi_cntrl->ee == MHI_EE_RDDM) + return 0; + MHI_LOG("Triggering SYS_ERR to force rddm state\n"); mhi_set_mhi_state(mhi_cntrl, MHI_STATE_SYS_ERR); -- GitLab From 1e602cdd1fa99f1d7a1818d5340b575ae2a9a8e5 Mon Sep 17 00:00:00 2001 From: Sujeev Dias Date: Fri, 12 Apr 2019 16:58:59 -0700 Subject: [PATCH 0761/1121] mhi: core: notify mission mode transition to control driver MHI control driver require notification from core layer soon as device enter mission mode transition. CRs-Fixed: 2457211 Change-Id: Ifbfc60164ffd52290e23b395ea6aa590ec19f26a Signed-off-by: Sujeev Dias --- drivers/bus/mhi/core/mhi_pm.c | 26 ++++++++++++++------------ include/linux/mhi.h | 2 ++ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/drivers/bus/mhi/core/mhi_pm.c b/drivers/bus/mhi/core/mhi_pm.c index b8eb3dfbaf07..f56f8d205e67 100644 --- a/drivers/bus/mhi/core/mhi_pm.c +++ b/drivers/bus/mhi/core/mhi_pm.c @@ -445,27 +445,31 @@ static int mhi_pm_mission_mode_transition(struct mhi_controller *mhi_cntrl) MHI_LOG("Processing Mission Mode Transition\n"); - /* force MHI to be in M0 state before continuing */ - ret = __mhi_device_get_sync(mhi_cntrl); - if (ret) - return ret; - - ret = -EIO; - write_lock_irq(&mhi_cntrl->pm_lock); if (MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) mhi_cntrl->ee = mhi_get_exec_env(mhi_cntrl); write_unlock_irq(&mhi_cntrl->pm_lock); - read_lock_bh(&mhi_cntrl->pm_lock); if (!MHI_IN_MISSION_MODE(mhi_cntrl->ee)) - goto error_mission_mode; + return -EIO; wake_up_all(&mhi_cntrl->state_event); + mhi_cntrl->status_cb(mhi_cntrl, mhi_cntrl->priv_data, + MHI_CB_EE_MISSION_MODE); + + /* force MHI to be in M0 state before continuing */ + ret = __mhi_device_get_sync(mhi_cntrl); + if (ret) + return ret; + + read_lock_bh(&mhi_cntrl->pm_lock); + /* add elements to all HW event rings */ - if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) + if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) { + ret = -EIO; goto error_mission_mode; + } mhi_event = mhi_cntrl->mhi_event; for (i = 0; i < mhi_cntrl->total_ev_rings; i++, mhi_event++) { @@ -499,8 +503,6 @@ static int mhi_pm_mission_mode_transition(struct mhi_controller *mhi_cntrl) /* setup sysfs nodes for userspace votes */ mhi_create_vote_sysfs(mhi_cntrl); - ret = 0; - read_lock_bh(&mhi_cntrl->pm_lock); error_mission_mode: diff --git a/include/linux/mhi.h b/include/linux/mhi.h index 7ac0ed9f9c20..ebda4aa4568f 100644 --- a/include/linux/mhi.h +++ b/include/linux/mhi.h @@ -28,6 +28,7 @@ struct mhi_buf_info; * @MHI_CB_LPM_ENTER: MHI host entered low power mode * @MHI_CB_LPM_EXIT: MHI host about to exit low power mode * @MHI_CB_EE_RDDM: MHI device entered RDDM execution enviornment + * @MHI_CB_EE_MISSION_MODE: MHI device entered Mission Mode ee * @MHI_CB_SYS_ERROR: MHI device enter error state (may recover) * @MHI_CB_FATAL_ERROR: MHI device entered fatal error * @MHI_CB_BW_REQ: Received a bandwidth switch request from device @@ -38,6 +39,7 @@ enum MHI_CB { MHI_CB_LPM_ENTER, MHI_CB_LPM_EXIT, MHI_CB_EE_RDDM, + MHI_CB_EE_MISSION_MODE, MHI_CB_SYS_ERROR, MHI_CB_FATAL_ERROR, MHI_CB_BW_REQ, -- GitLab From 2d30ac5c7501e5d5fd15f6b206b2079dfacdb2dc Mon Sep 17 00:00:00 2001 From: Sujeev Dias Date: Mon, 20 May 2019 20:18:35 -0700 Subject: [PATCH 0762/1121] mhi: cntrl: qcom: add usage of system pm state notifications ESOC power off notifications can be received during any stage of system suspend/resume. Avoid these race conditions by aborting system suspend and waiting for system resume to complete to process ESOC power off. CRs-Fixed: 2429838 Change-Id: Ie79b0e007b628f8740e581e9a6776b1e581259f5 Acked-by: Bhaumik Vasav Bhatt Signed-off-by: Sujeev Dias --- drivers/bus/mhi/controllers/mhi_arch_qcom.c | 45 +++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/drivers/bus/mhi/controllers/mhi_arch_qcom.c b/drivers/bus/mhi/controllers/mhi_arch_qcom.c index 362635464f07..19745752654a 100644 --- a/drivers/bus/mhi/controllers/mhi_arch_qcom.c +++ b/drivers/bus/mhi/controllers/mhi_arch_qcom.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "mhi_qcom.h" @@ -41,6 +42,8 @@ struct arch_info { struct mhi_device *boot_dev; struct mhi_link_info current_link_info; struct work_struct bw_scale_work; + struct notifier_block pm_notifier; + struct completion pm_completion; }; /* ipc log markings */ @@ -59,6 +62,25 @@ enum MHI_DEBUG_LEVEL mhi_ipc_log_lvl = MHI_MSG_LVL_ERROR; #endif +static int mhi_arch_pm_notifier(struct notifier_block *nb, + unsigned long event, void *unused) +{ + struct arch_info *arch_info = + container_of(nb, struct arch_info, pm_notifier); + + switch (event) { + case PM_SUSPEND_PREPARE: + reinit_completion(&arch_info->pm_completion); + break; + + case PM_POST_SUSPEND: + complete_all(&arch_info->pm_completion); + break; + } + + return NOTIFY_DONE; +} + static int mhi_arch_set_bus_request(struct mhi_controller *mhi_cntrl, int index) { struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl); @@ -174,6 +196,15 @@ static void mhi_arch_esoc_ops_power_off(void *priv, unsigned int flags) mhi_dev->powered_on = false; mutex_unlock(&mhi_cntrl->pm_mutex); + /* + * Abort system suspend if system is preparing to go to suspend + * by grabbing wake source. + * If system is suspended, wait for pm notifier callback to notify + * that resume has occurred with PM_POST_SUSPEND event. + */ + pm_stay_awake(&mhi_cntrl->mhi_dev->dev); + wait_for_completion(&arch_info->pm_completion); + MHI_LOG("Triggering shutdown process\n"); mhi_power_down(mhi_cntrl, !mdm_state); @@ -186,6 +217,8 @@ static void mhi_arch_esoc_ops_power_off(void *priv, unsigned int flags) mhi_arch_iommu_deinit(mhi_cntrl); mhi_arch_pcie_deinit(mhi_cntrl); + + pm_relax(&mhi_cntrl->mhi_dev->dev); } static void mhi_bl_dl_cb(struct mhi_device *mhi_device, @@ -417,6 +450,18 @@ int mhi_arch_pcie_init(struct mhi_controller *mhi_cntrl) if (ret) MHI_LOG("Failed to reg. for link up notification\n"); + init_completion(&arch_info->pm_completion); + + /* register PM notifier to get post resume events */ + arch_info->pm_notifier.notifier_call = mhi_arch_pm_notifier; + register_pm_notifier(&arch_info->pm_notifier); + + /* + * Mark as completed at initial boot-up to allow ESOC power on + * callback to proceed if system has not gone to suspend + */ + complete_all(&arch_info->pm_completion); + arch_info->esoc_client = devm_register_esoc_client( &mhi_dev->pci_dev->dev, "mdm"); if (IS_ERR_OR_NULL(arch_info->esoc_client)) { -- GitLab From 4cadc271d5175cfe62014e0c12d3d2a3839b5406 Mon Sep 17 00:00:00 2001 From: Skylar Chang Date: Mon, 10 Jun 2019 18:06:04 -0700 Subject: [PATCH 0763/1121] msm: ipa3: vote turbo when tethering on Change the modem vote for pm_client as the highest when usb-tethering is on and vote back to low power mode when usb-tethering off. Change-Id: I3e51dc34cea5c97a7f901d9981f908e35b8b0fb2 Signed-off-by: Skylar Chang --- drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c | 33 ++++++++++++------- drivers/platform/msm/ipa/ipa_v3/teth_bridge.c | 6 ++-- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c index 566b62017893..07b4442bc156 100644 --- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c @@ -2169,16 +2169,33 @@ static int rmnet_ipa_send_coalesce_notification(uint8_t qmap_id, int ipa3_wwan_set_modem_state(struct wan_ioctl_notify_wan_state *state) { + uint32_t bw_mbps = 0; + int ret = 0; + if (!state) return -EINVAL; if (!ipa_pm_is_used()) return 0; - if (state->up) - return ipa_pm_activate_sync(rmnet_ipa3_ctx->q6_teth_pm_hdl); - else - return ipa_pm_deactivate_sync(rmnet_ipa3_ctx->q6_teth_pm_hdl); + if (state->up) { + bw_mbps = 5200; + ret = ipa3_vote_for_bus_bw(&bw_mbps); + if (ret) { + IPAERR("Failed to vote for bus BW (%u)\n", bw_mbps); + return ret; + } + ret = ipa_pm_activate_sync(rmnet_ipa3_ctx->q6_teth_pm_hdl); + } else { + bw_mbps = 0; + ret = ipa3_vote_for_bus_bw(&bw_mbps); + if (ret) { + IPAERR("Failed to vote for bus BW (%u)\n", bw_mbps); + return ret; + } + ret = ipa_pm_deactivate_sync(rmnet_ipa3_ctx->q6_teth_pm_hdl); + } + return ret; } /** @@ -2227,18 +2244,10 @@ int ipa3_wwan_set_modem_perf_profile(int throughput) { struct ipa_rm_perf_profile profile; int ret; - int tether_bridge_handle = 0; IPAWANDBG("throughput: %d\n", throughput); if (ipa3_ctx->use_ipa_pm) { - /* query rmnet-tethering handle */ - tether_bridge_handle = ipa3_teth_bridge_get_pm_hdl(); - if (tether_bridge_handle > 0) { - /* only update with valid handle*/ - ret = ipa_pm_set_throughput(tether_bridge_handle, - throughput); - } /* for TETH MODEM on softap/rndis */ ret = ipa_pm_set_throughput(rmnet_ipa3_ctx->q6_teth_pm_hdl, throughput); diff --git a/drivers/platform/msm/ipa/ipa_v3/teth_bridge.c b/drivers/platform/msm/ipa/ipa_v3/teth_bridge.c index 71482e4eeac7..bac75e2dba71 100644 --- a/drivers/platform/msm/ipa/ipa_v3/teth_bridge.c +++ b/drivers/platform/msm/ipa/ipa_v3/teth_bridge.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -191,7 +191,9 @@ int ipa3_teth_bridge_connect(struct teth_bridge_connect_params *connect_params) TETH_ERR("fail to register with PM %d\n", res); return res; } - + /* vote for turbo */ + res = ipa_pm_set_throughput(ipa3_teth_ctx->modem_pm_hdl, + 5200); res = ipa_pm_activate_sync(ipa3_teth_ctx->modem_pm_hdl); goto bail; } -- GitLab From c21c32473e8daad1dba4eb5d217db60585f5b951 Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Tue, 25 Jun 2019 14:55:10 -0700 Subject: [PATCH 0764/1121] ARM: dts: msm: Add labels to PIL entries for sdmshrike Provide labels for PIL entries on the sdmshrike target. Add a node to invoke the SSC sensors driver. Change-Id: Ib39f4e03afdde92e5f3e3c73949ffb76c496e7f3 Signed-off-by: Anant Goel --- arch/arm64/boot/dts/qcom/sdmshrike.dtsi | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdmshrike.dtsi b/arch/arm64/boot/dts/qcom/sdmshrike.dtsi index 10adcd5b3833..06bafeb94260 100644 --- a/arch/arm64/boot/dts/qcom/sdmshrike.dtsi +++ b/arch/arm64/boot/dts/qcom/sdmshrike.dtsi @@ -1154,7 +1154,7 @@ 0x4400 2>; }; - apr_tal_rpmsg { + qcom,apr_tal_rpmsg { qcom,glink-channels = "apr_audio_svc"; qcom,intents = <0x200 20>; }; @@ -1489,7 +1489,7 @@ qcom,client-id = <0x00000001>; }; - qcom,lpass@17300000 { + pil_lpass: qcom,lpass@17300000 { compatible = "qcom,pil-tz-generic"; reg = <0x17300000 0x00100>; @@ -1573,7 +1573,7 @@ mbox-names = "slpi-pil"; }; - qcom,spss@1880000 { + pil_spss: qcom,spss@1880000 { compatible = "qcom,pil-tz-generic"; reg = <0x188101c 0x4>, <0x1881024 0x4>, @@ -1606,7 +1606,7 @@ mbox-names = "spss-pil"; }; - qcom,npu@0x9800000 { + pil_npu: qcom,npu@0x9800000 { compatible = "qcom,pil-tz-generic"; reg = <0x9800000 0x800000>; @@ -1617,7 +1617,7 @@ memory-region = <&pil_npu_mem>; }; - qcom,turing@8300000 { + pil_turing: qcom,turing@8300000 { compatible = "qcom,pil-tz-generic"; reg = <0x8300000 0x100000>; @@ -1666,7 +1666,7 @@ mbox-names = "cdsp-pil"; }; - qcom,venus@aae0000 { + pil_venus: qcom,venus@aae0000 { compatible = "qcom,pil-tz-generic"; reg = <0xaae0000 0x4000>; @@ -1695,6 +1695,12 @@ memory-region = <&pil_video_mem>; }; + ssc_sensors: qcom,msm-ssc-sensors { + compatible = "qcom,msm-ssc-sensors"; + qcom,firmware-name = "slpi"; + status = "disabled"; + }; + wdog: qcom,wdt@17c10000 { compatible = "qcom,msm-watchdog"; reg = <0x17c10000 0x1000>; -- GitLab From 7782f2cee0eaa232e24fa62585d7f4b3fc2d289c Mon Sep 17 00:00:00 2001 From: Aditya Mathur Date: Wed, 26 Jun 2019 16:12:26 -0700 Subject: [PATCH 0765/1121] ARM: dts: msm: Add support for SA515M CCARD boards Initial changes for SA515M CCARD boards. Change-Id: Idb421d101c1cb3a24b64f2293e973aafce7d1c75 Signed-off-by: Aditya Mathur --- .../devicetree/bindings/arm/msm/msm.txt | 1 + arch/arm64/boot/dts/qcom/Makefile | 5 +- .../boot/dts/qcom/sa515m-ccard-pcie-ep.dts | 46 +++++++ .../boot/dts/qcom/sa515m-ccard-usb-ep.dts | 22 ++++ arch/arm64/boot/dts/qcom/sa515m-ccard.dts | 22 ++++ arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi | 121 ++++++++++++++++++ 6 files changed, 216 insertions(+), 1 deletion(-) create mode 100644 arch/arm64/boot/dts/qcom/sa515m-ccard-pcie-ep.dts create mode 100644 arch/arm64/boot/dts/qcom/sa515m-ccard-usb-ep.dts create mode 100644 arch/arm64/boot/dts/qcom/sa515m-ccard.dts create mode 100644 arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi diff --git a/Documentation/devicetree/bindings/arm/msm/msm.txt b/Documentation/devicetree/bindings/arm/msm/msm.txt index 85f746cee2c2..ed31d3edb60c 100644 --- a/Documentation/devicetree/bindings/arm/msm/msm.txt +++ b/Documentation/devicetree/bindings/arm/msm/msm.txt @@ -209,6 +209,7 @@ compatible = "qcom,sa8155p-adp-alcor" compatible = "qcom,sdxprairie-rumi" compatible = "qcom,sdxprairie-mtp" compatible = "qcom,sdxprairie-cdp" +compatible = "qcom,sa515m-ccard" compatible = "qcom,sdmmagpie-rumi" compatible = "qcom,sdmmagpie-idp" compatible = "qcom,sdmmagpie-atp" diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index 14be137d0cab..d31d7aa4926e 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -267,7 +267,10 @@ dtb-$(CONFIG_ARCH_SDXPRAIRIE) += sdxprairie-rumi.dtb \ sdxprairie-mtp-aqc.dtb \ sdxprairie-dsda-mtp.dtb \ sdxprairie-v2-cdp.dtb \ - sdxprairie-v2-mtp.dtb + sdxprairie-v2-mtp.dtb \ + sa515m-ccard.dtb \ + sa515m-ccard-pcie-ep.dtb \ + sa515m-ccard-usb-ep.dtb ifeq ($(CONFIG_ARM64),y) always := $(dtb-y) diff --git a/arch/arm64/boot/dts/qcom/sa515m-ccard-pcie-ep.dts b/arch/arm64/boot/dts/qcom/sa515m-ccard-pcie-ep.dts new file mode 100644 index 000000000000..7bd092eebb5c --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sa515m-ccard-pcie-ep.dts @@ -0,0 +1,46 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "sa515m-ccard.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. SA515M CCARD PCIE-EP"; + compatible = "qcom,sa515m-ccard", + "qcom,sdxprairie", "qcom,ccard"; + qcom,board-id = <25 1>, <25 0x101>; +}; + +&restart_pshold { + qcom,force-warm-reboot; +}; + +&cnss_qca6390 { + status = "disabled"; +}; + +&ipa_hw { + qcom,use-ipa-in-mhi-mode; +}; + +&pcie0 { + status = "disabled"; +}; + +&pcie_ep { + status = "ok"; +}; + +&mhi_device { + status = "ok"; +}; diff --git a/arch/arm64/boot/dts/qcom/sa515m-ccard-usb-ep.dts b/arch/arm64/boot/dts/qcom/sa515m-ccard-usb-ep.dts new file mode 100644 index 000000000000..14c0248a591e --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sa515m-ccard-usb-ep.dts @@ -0,0 +1,22 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "sa515m-ccard.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. SA515M CCARD USB-EP"; + compatible = "qcom,sa515m-ccard", + "qcom,sdxprairie", "qcom,ccard"; + qcom,board-id = <25 2>, <25 0x102>; +}; diff --git a/arch/arm64/boot/dts/qcom/sa515m-ccard.dts b/arch/arm64/boot/dts/qcom/sa515m-ccard.dts new file mode 100644 index 000000000000..1fc00a911c00 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sa515m-ccard.dts @@ -0,0 +1,22 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "sa515m-ccard.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. SA515M CCARD"; + compatible = "qcom,sa515m-ccard", + "qcom,sdxprairie", "qcom,ccard"; + qcom,board-id = <25 0>, <25 0x100>; +}; diff --git a/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi b/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi new file mode 100644 index 000000000000..3033eba9f683 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi @@ -0,0 +1,121 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "sdxprairie.dtsi" +#include "sdxprairie-mtp.dtsi" + +&soc { + /delete-node/ qcom,battery-data; + + codec_vreg: regulator-codec-tlv320aic3x { + compatible = "regulator-fixed"; + regulator-name = "codec_vreg"; + startup-delay-us = <100>; + gpio = <&tlmm 23 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; +}; + +/* delete pm8150b nodes */ +&thermal_zones { + /delete-node/ pm8150b-wp-therm; + /delete-node/ pm8150b_tz; + /delete-node/ pm8150b-ibat-lvl0; + /delete-node/ pm8150b-ibat-lvl1; + /delete-node/ pm8150b-vbat-lvl0; + /delete-node/ pm8150b-vbat-lvl1; + /delete-node/ pm8150b-vbat-lvl2; + /delete-node/ soc; +}; + +&usb { + extcon = <&vbus_detect>; +}; + +&spmi_bus { + /delete-node/ qpnp,fg; + /delete-node/ bcl@1d00; + /delete-node/ qcom,usb-pdphy@1700; + /delete-node/ qcom,qpnp-smb5; + /delete-node/ adc_tm@3500; + /delete-node/ vadc@3100; + /delete-node/ qcom,pm8150b@2; + /delete-node/ qcom,pm8150b@3; +}; + +&qnand_1 { + status = "ok"; +}; + +&blsp1_uart2b_hs { + status = "okay"; +}; + +&blsp1_uart4a_hs { + status = "okay"; +}; + +&vbus_detect { + status = "okay"; +}; + +&snd_934x { + status = "disabled"; +}; + +&wcd9xxx_intc { + status = "disabled"; +}; + +&clock_audio_up { + status = "disabled"; +}; + +&wcd_rst_gpio { + status = "disabled"; +}; + + +&wcd934x_cdc { + status = "disabled"; +}; + +&spi_2 { + status = "okay"; + + can-controller@0 { + compatible = "qcom,nxp,mpc5746c"; + reg = <0>; + interrupt-parent = <&tlmm>; + interrupts = <88 0>; + spi-max-frequency = <5000000>; + qcom,clk-freq-mhz = <40000000>; + qcom,max-can-channels = <1>; + qcom,bits-per-word = <8>; + qcom,support-can-fd; + }; +}; + +&i2c_3 { + tlv320aic3x_codec: tlv320aic3x@18 { + compatible = "ti,tlv320aic3x"; + reg = <0x18>; + gpio-reset = <&tlmm 92 0>; + reset-inverted; + AVDD-supply = <&codec_vreg>; + IOVDD-supply = <&codec_vreg>; + }; +}; + +&i2c_4 { + status = "okay"; +}; -- GitLab From 41e8a9519b5a841d3bd4bd5512b313a919051bd1 Mon Sep 17 00:00:00 2001 From: Pavankumar Kondeti Date: Wed, 3 Jul 2019 09:15:58 +0530 Subject: [PATCH 0766/1121] cpufreq: schedutil: Fix for limits update with fast switch enabled When the policy limits are applied with fast switch enabled, the policy->cur is not updated. This can result in incorrect calculation of the average capacity and any subsequent limit updates. Update cpufreq_policy_apply_limits_fast() API to return a non-zero value when the frequency is updated. Make use of this return value and update policy->cur. While at it, print cpu_frequency trace point, when frequency is changed due to change in limits. Change-Id: I51732fa061aac11231d1f18ca70f31f252f0a0dd Signed-off-by: Pavankumar Kondeti --- include/linux/cpufreq.h | 12 ++++++++---- kernel/sched/cpufreq_schedutil.c | 9 ++++++++- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 829b7a9613c4..ed0ff1538049 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -541,13 +541,17 @@ static inline void cpufreq_policy_apply_limits(struct cpufreq_policy *policy) __cpufreq_driver_target(policy, policy->min, CPUFREQ_RELATION_L); } -static inline void cpufreq_policy_apply_limits_fast(struct cpufreq_policy - *policy) +static inline unsigned int +cpufreq_policy_apply_limits_fast(struct cpufreq_policy *policy) { + unsigned int ret = 0; + if (policy->max < policy->cur) - cpufreq_driver_fast_switch(policy, policy->max); + ret = cpufreq_driver_fast_switch(policy, policy->max); else if (policy->min > policy->cur) - cpufreq_driver_fast_switch(policy, policy->min); + ret = cpufreq_driver_fast_switch(policy, policy->min); + + return ret; } /* Governor attribute set */ diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c index c57673e5152c..f8231399358f 100644 --- a/kernel/sched/cpufreq_schedutil.c +++ b/kernel/sched/cpufreq_schedutil.c @@ -1067,6 +1067,8 @@ static void sugov_limits(struct cpufreq_policy *policy) { struct sugov_policy *sg_policy = policy->governor_data; unsigned long flags; + unsigned int ret; + int cpu; if (!policy->fast_switch_enabled) { mutex_lock(&sg_policy->work_lock); @@ -1080,7 +1082,12 @@ static void sugov_limits(struct cpufreq_policy *policy) raw_spin_lock_irqsave(&sg_policy->update_lock, flags); sugov_track_cycles(sg_policy, sg_policy->policy->cur, ktime_get_ns()); - cpufreq_policy_apply_limits_fast(policy); + ret = cpufreq_policy_apply_limits_fast(policy); + if (ret && policy->cur != ret) { + policy->cur = ret; + for_each_cpu(cpu, policy->cpus) + trace_cpu_frequency(ret, cpu); + } raw_spin_unlock_irqrestore(&sg_policy->update_lock, flags); } -- GitLab From d1e016256bb9e7ea5e1dcba4ec497c1bb87f2fde Mon Sep 17 00:00:00 2001 From: Naresh Munagala Date: Tue, 11 Jun 2019 16:24:25 +0530 Subject: [PATCH 0767/1121] ARM: dts: msm: enable SiRF GNSS Driver and hsuart1 DTS Entries to enable SiRF GNSS Driver and hsuart1 serial port. Change-Id: Iecca398c4af4a7f1e1cab5a273586e2eb03ce722 Signed-off-by: Naresh Munagala --- arch/arm64/boot/dts/qcom/sa6155-adp-air.dtsi | 11 ++++ arch/arm64/boot/dts/qcom/sm6150-pinctrl.dtsi | 57 ++++++++++++++++++++ arch/arm64/boot/dts/qcom/sm6150-qupv3.dtsi | 17 ++++++ arch/arm64/boot/dts/qcom/sm6150.dtsi | 1 + 4 files changed, 86 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sa6155-adp-air.dtsi b/arch/arm64/boot/dts/qcom/sa6155-adp-air.dtsi index a7a4d95902b6..61a1491c3e6e 100644 --- a/arch/arm64/boot/dts/qcom/sa6155-adp-air.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155-adp-air.dtsi @@ -43,6 +43,13 @@ }; }; + ss5_pwr_ctrl0 { + compatible = "gnss_sirf"; + pinctrl-0 = <&ss5_pwr_ctrl_rst_on>; + ssVreset-gpio = <&tlmm 87 1>; + ssVonoff-gpio = <&tlmm 18 1>; + }; + hsi2s: qcom,hsi2s { compatible = "qcom,hsi2s"; number-of-interfaces = <2>; @@ -251,6 +258,10 @@ status = "ok"; }; +&qupv3_se4_2uart { + status = "ok"; +}; + &qupv3_se7_4uart { status = "ok"; }; diff --git a/arch/arm64/boot/dts/qcom/sm6150-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sm6150-pinctrl.dtsi index b8d91f451eaf..df5960c939e9 100644 --- a/arch/arm64/boot/dts/qcom/sm6150-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/sm6150-pinctrl.dtsi @@ -260,6 +260,36 @@ }; }; + ss5_pwr_ctrl_pins: ss5_pwr_ctrl_pins { + ss5_pwr_ctrl_rst_on: ss5_pwr_ctrl_rst_on { + mux { + pins = "gpio87", "gpio18"; + function = "gpio"; + }; + + config { + pins = "gpio87", "gpio18"; + drive-strength = <16>; /* 16 mA */ + bias-pull-up; + output-high; + }; + }; + + ss5_pwr_ctrl_rst_off: ss5_pwr_ctrl_off { + mux { + pins = "gpio87", "gpio18"; + function = "gpio"; + }; + + config { + pins = "gpio87", "gpio18"; + drive-strength = <16>; /* 16 mA */ + bias-pull-up; + output-high; + }; + }; + }; + /* QUPv3_1 North instances */ /* SE 4 pin mappings */ qupv3_se4_i2c_pins: qupv3_se4_i2c_pins { @@ -321,6 +351,33 @@ }; }; }; + qupv3_se4_2uart_pins: qupv3_se4_2uart_pins { + qupv3_se4_2uart_active: qupv3_se4_2uart_active { + mux { + pins = "gpio22", "gpio23"; + function = "qup10"; + }; + + config { + pins = "gpio22", "gpio23"; + drive-strength = <16>; + bias-disable; + }; + }; + + qupv3_se4_2uart_sleep: qupv3_se4_2uart_sleep { + mux { + pins = "gpio22", "gpio23"; + function = "gpio"; + }; + + config { + pins = "gpio22", "gpio23"; + drive-strength = <16>; + bias-disable; + }; + }; + }; /* SE 5 pin mappings */ qupv3_se5_i2c_pins: qupv3_se5_i2c_pins { diff --git a/arch/arm64/boot/dts/qcom/sm6150-qupv3.dtsi b/arch/arm64/boot/dts/qcom/sm6150-qupv3.dtsi index ce13188e5a98..cc6dd19ab227 100644 --- a/arch/arm64/boot/dts/qcom/sm6150-qupv3.dtsi +++ b/arch/arm64/boot/dts/qcom/sm6150-qupv3.dtsi @@ -154,6 +154,23 @@ }; }; + /* GNSS UART Instance for CDP/MTP platform */ + qupv3_se4_2uart: qcom,qup_uart@0xa80000 { + compatible = "qcom,msm-geni-serial-hs"; + reg = <0xa80000 0x4000>; + reg-names = "se_phys"; + clock-names = "se-clk", "m-ahb", "s-ahb"; + clocks = <&clock_gcc GCC_QUPV3_WRAP1_S0_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_1_M_AHB_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_1_S_AHB_CLK>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&qupv3_se4_2uart_active>; + pinctrl-1 = <&qupv3_se4_2uart_sleep>; + interrupts = ; + qcom,wrapper-core = <&qupv3_1>; + status = "disabled"; + }; + /* I2C */ qupv3_se4_i2c: i2c@a80000 { compatible = "qcom,i2c-geni"; diff --git a/arch/arm64/boot/dts/qcom/sm6150.dtsi b/arch/arm64/boot/dts/qcom/sm6150.dtsi index a0405ea1b29a..bef0d618e3d1 100644 --- a/arch/arm64/boot/dts/qcom/sm6150.dtsi +++ b/arch/arm64/boot/dts/qcom/sm6150.dtsi @@ -46,6 +46,7 @@ i2c1 = &qupv3_se1_i2c; i2c2 = &qupv3_se3_i2c; hsuart0 = &qupv3_se7_4uart; + hsuart1 = &qupv3_se4_2uart; swr0 = &swr0; swr1 = &swr1; swr2 = &swr2; -- GitLab From 8eb5df7461f67fb178239d69a0905ef7bff32310 Mon Sep 17 00:00:00 2001 From: Naresh Munagala Date: Wed, 3 Jul 2019 12:08:58 +0530 Subject: [PATCH 0768/1121] defconfig: sa6155: Enable CONFIG_GNSS_SIRF Enable CONFIG_GNSS_SIRF for SiRF GNSS Driver. Change-Id: I3252213e6f64943e26353d31a01339db29043617 Signed-off-by: Naresh Munagala --- arch/arm64/configs/vendor/sdmsteppe-auto_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/vendor/sdmsteppe-auto_defconfig b/arch/arm64/configs/vendor/sdmsteppe-auto_defconfig index ec93b2066a87..1ddb89cc282f 100644 --- a/arch/arm64/configs/vendor/sdmsteppe-auto_defconfig +++ b/arch/arm64/configs/vendor/sdmsteppe-auto_defconfig @@ -377,6 +377,7 @@ CONFIG_PINCTRL_SDMMAGPIE=y CONFIG_PINCTRL_SM6150=y CONFIG_PINCTRL_SLPI=y CONFIG_GPIO_SYSFS=y +CONFIG_GNSS_SIRF=y CONFIG_POWER_RESET_QCOM=y CONFIG_QCOM_DLOAD_MODE=y CONFIG_POWER_RESET_XGENE=y -- GitLab From c8bbb1e3a59cb5cde2da79a8db638691b70535d7 Mon Sep 17 00:00:00 2001 From: Kaushal Kumar Date: Wed, 3 Jul 2019 14:41:03 +0530 Subject: [PATCH 0769/1121] defconfig: msm: enable CONFIG_USB_RTL8152 for sm8150, sa8155, trinket Enable config for Realtek RTL8152/RTL8153 based USB Ethernet Adapters for sm8150, sa8155 and trinket targets. This is to align them with android base config. Change-Id: I8b0e14054188b31378426cb814d3f5e8f2230044 Signed-off-by: Kaushal Kumar --- arch/arm64/configs/vendor/sa8155-perf_defconfig | 1 + arch/arm64/configs/vendor/sa8155_defconfig | 1 + arch/arm64/configs/vendor/sm8150-perf_defconfig | 1 + arch/arm64/configs/vendor/sm8150_defconfig | 1 + arch/arm64/configs/vendor/trinket-perf_defconfig | 1 + arch/arm64/configs/vendor/trinket_defconfig | 1 + 6 files changed, 6 insertions(+) diff --git a/arch/arm64/configs/vendor/sa8155-perf_defconfig b/arch/arm64/configs/vendor/sa8155-perf_defconfig index ab10045c4e48..9e0c891637c4 100644 --- a/arch/arm64/configs/vendor/sa8155-perf_defconfig +++ b/arch/arm64/configs/vendor/sa8155-perf_defconfig @@ -300,6 +300,7 @@ CONFIG_PPPOLAC=y CONFIG_PPPOPNS=y CONFIG_PPP_ASYNC=y CONFIG_PPP_SYNC_TTY=y +CONFIG_USB_RTL8152=y CONFIG_USB_USBNET=y CONFIG_WIL6210=m CONFIG_WCNSS_MEM_PRE_ALLOC=y diff --git a/arch/arm64/configs/vendor/sa8155_defconfig b/arch/arm64/configs/vendor/sa8155_defconfig index 2c4bc5524158..9fffaa06618f 100644 --- a/arch/arm64/configs/vendor/sa8155_defconfig +++ b/arch/arm64/configs/vendor/sa8155_defconfig @@ -313,6 +313,7 @@ CONFIG_PPPOLAC=y CONFIG_PPPOPNS=y CONFIG_PPP_ASYNC=y CONFIG_PPP_SYNC_TTY=y +CONFIG_USB_RTL8152=y CONFIG_USB_USBNET=y CONFIG_WIL6210=m CONFIG_WCNSS_MEM_PRE_ALLOC=y diff --git a/arch/arm64/configs/vendor/sm8150-perf_defconfig b/arch/arm64/configs/vendor/sm8150-perf_defconfig index 21918d41533f..260b74316e13 100644 --- a/arch/arm64/configs/vendor/sm8150-perf_defconfig +++ b/arch/arm64/configs/vendor/sm8150-perf_defconfig @@ -311,6 +311,7 @@ CONFIG_PPPOLAC=y CONFIG_PPPOPNS=y CONFIG_PPP_ASYNC=y CONFIG_PPP_SYNC_TTY=y +CONFIG_USB_RTL8152=y CONFIG_USB_LAN78XX=y CONFIG_USB_USBNET=y CONFIG_WIL6210=m diff --git a/arch/arm64/configs/vendor/sm8150_defconfig b/arch/arm64/configs/vendor/sm8150_defconfig index 44bd6ad2404c..7f44078a72d9 100644 --- a/arch/arm64/configs/vendor/sm8150_defconfig +++ b/arch/arm64/configs/vendor/sm8150_defconfig @@ -322,6 +322,7 @@ CONFIG_PPPOLAC=y CONFIG_PPPOPNS=y CONFIG_PPP_ASYNC=y CONFIG_PPP_SYNC_TTY=y +CONFIG_USB_RTL8152=y CONFIG_USB_LAN78XX=y CONFIG_USB_USBNET=y CONFIG_WIL6210=m diff --git a/arch/arm64/configs/vendor/trinket-perf_defconfig b/arch/arm64/configs/vendor/trinket-perf_defconfig index da204a4f283b..e0b979dd063f 100644 --- a/arch/arm64/configs/vendor/trinket-perf_defconfig +++ b/arch/arm64/configs/vendor/trinket-perf_defconfig @@ -302,6 +302,7 @@ CONFIG_PPPOLAC=y CONFIG_PPPOPNS=y CONFIG_PPP_ASYNC=y CONFIG_PPP_SYNC_TTY=y +CONFIG_USB_RTL8152=y CONFIG_USB_USBNET=y CONFIG_WIL6210=m CONFIG_WCNSS_MEM_PRE_ALLOC=y diff --git a/arch/arm64/configs/vendor/trinket_defconfig b/arch/arm64/configs/vendor/trinket_defconfig index 7a14f8209f92..0d9cc2f33b39 100644 --- a/arch/arm64/configs/vendor/trinket_defconfig +++ b/arch/arm64/configs/vendor/trinket_defconfig @@ -313,6 +313,7 @@ CONFIG_PPPOLAC=y CONFIG_PPPOPNS=y CONFIG_PPP_ASYNC=y CONFIG_PPP_SYNC_TTY=y +CONFIG_USB_RTL8152=y CONFIG_USB_USBNET=y CONFIG_WIL6210=m CONFIG_WCNSS_MEM_PRE_ALLOC=y -- GitLab From 216ae5275e283ecde73c193aef044b2c6f65837a Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Tue, 25 Jun 2019 15:14:41 -0700 Subject: [PATCH 0770/1121] ARM: dts: msm: Add QSEECOM, SMC, and RNG nodes to sdmshrike Provide entries to invoke the QSEECOM, smcinvoke, and rng drivers for the sdmshrike target. Change-Id: I88afa9f631fe6e037d2b4c6b4a28a98ba5cc9f52 Signed-off-by: Anant Goel --- arch/arm64/boot/dts/qcom/sdmshrike.dtsi | 43 +++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdmshrike.dtsi b/arch/arm64/boot/dts/qcom/sdmshrike.dtsi index 8f3fcd23991e..1eece9526f7c 100644 --- a/arch/arm64/boot/dts/qcom/sdmshrike.dtsi +++ b/arch/arm64/boot/dts/qcom/sdmshrike.dtsi @@ -2050,6 +2050,49 @@ compatible = "qcom,system-pm"; mboxes = <&apps_rsc 0>; }; + + qcom_seecom: qseecom@87900000 { + compatible = "qcom,qseecom"; + reg = <0x87900000 0x2200000>; + reg-names = "secapp-region"; + memory-region = <&qseecom_mem>; + qcom,hlos-num-ce-hw-instances = <1>; + qcom,hlos-ce-hw-instance = <0>; + qcom,qsee-ce-hw-instance = <0>; + qcom,disk-encrypt-pipe-pair = <2>; + qcom,support-fde; + qcom,no-clock-support; + qcom,fde-key-size; + qcom,appsbl-qseecom-support; + qcom,commonlib64-loaded-by-uefi; + qcom,qsee-reentrancy-support = <2>; + }; + + qcom_smcinvoke: smcinvoke@87900000 { + compatible = "qcom,smcinvoke"; + reg = <0x87900000 0x2200000>; + reg-names = "secapp-region"; + }; + + qcom_rng: qrng@793000 { + compatible = "qcom,msm-rng"; + reg = <0x793000 0x1000>; + qcom,msm-rng-iface-clk; + qcom,no-qrng-config; + qcom,msm-bus,name = "msm-rng-noc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <1 618 0 0>, /* No vote */ + <1 618 0 300000>; /* 75 MHz */ + clocks = <&clock_gcc GCC_PRNG_AHB_CLK>; + clock-names = "iface_clk"; + }; + + qcom_msmhdcp: qcom,msm_hdcp { + compatible = "qcom,msm-hdcp"; + }; + mem_dump { compatible = "qcom,mem-dump"; memory-region = <&dump_mem>; -- GitLab From cdc00261b03e7bf88bd791a4889e18fd5b5e2069 Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Fri, 26 Apr 2019 13:32:44 -0700 Subject: [PATCH 0771/1121] ARM: dts: msm: Add bluetooth pin definition for sdmshrike Provide device tree entry for bluetooth pin definition needed by sdmshrike. Change-Id: I8c43dcc18da955ded0a238932e7593ee8dd2aa1c Signed-off-by: Anant Goel --- arch/arm64/boot/dts/qcom/sdmshrike-pinctrl.dtsi | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdmshrike-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sdmshrike-pinctrl.dtsi index 45c80e413d5e..a90667d2aa7d 100644 --- a/arch/arm64/boot/dts/qcom/sdmshrike-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/sdmshrike-pinctrl.dtsi @@ -2868,6 +2868,19 @@ }; }; + bt_en_active: bt_en_active { + mux { + pins = "gpio172"; + function = "gpio"; + }; + + config { + pins = "gpio172"; + drive-strength = <2>; + bias-pull-down; + }; + }; + /* SE0 pin mappings */ qupv3_se0_i2c_pins: qupv3_se0_i2c_pins { qupv3_se0_i2c_active: qupv3_se0_i2c_active { -- GitLab From 95f04359ab22c8888b60b267e43601901e4941f2 Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Fri, 17 May 2019 14:08:59 -0700 Subject: [PATCH 0772/1121] drivers: msm: pinctrl: Add custom TLMM direct connect list feature support Add support for enabling a feature where a user can provide a custom list of TLMM GPIOs associated with hardware IRQs for direct connect interrupt support. This feature is needed because the TLMM GPIO direct connect interrupt list is fixed per target which is restrictive for a usecase where a custom list of direct connect interrupts for GPIOs is needed. Change-Id: I9b4eb8005a7c0230940a59337352bb3eaaa51ceb Signed-off-by: Anant Goel --- .../bindings/pinctrl/qcom,sm8150-pinctrl | 7 +++ drivers/pinctrl/qcom/pinctrl-sm8150.c | 54 ++++++++++++++++++- 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm8150-pinctrl b/Documentation/devicetree/bindings/pinctrl/qcom,sm8150-pinctrl index 64fef96c75d6..71ceabd31110 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sm8150-pinctrl +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm8150-pinctrl @@ -47,6 +47,13 @@ SM8150 platform. Definition: must be 2. Specifying the pin number and flags, as defined in +- dirconn-list: + Usage: optional + Value type: + Definition: a 3-tuple list which contains mapping of GPIO pin to + hardware IRQ, and a boolean for enabling the TLMM direct + connect interrupt for the pin. + Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for a general description of GPIO and interrupt bindings. diff --git a/drivers/pinctrl/qcom/pinctrl-sm8150.c b/drivers/pinctrl/qcom/pinctrl-sm8150.c index ccd7091a0657..c0a853d7b511 100644 --- a/drivers/pinctrl/qcom/pinctrl-sm8150.c +++ b/drivers/pinctrl/qcom/pinctrl-sm8150.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1939,7 +1939,7 @@ static struct msm_dir_conn sm8150_dir_conn[] = { {-1, 209}, }; -static const struct msm_pinctrl_soc_data sm8150_pinctrl = { +static struct msm_pinctrl_soc_data sm8150_pinctrl = { .pins = sm8150_pins, .npins = ARRAY_SIZE(sm8150_pins), .functions = sm8150_functions, @@ -1952,8 +1952,58 @@ static const struct msm_pinctrl_soc_data sm8150_pinctrl = { .dir_conn_irq_base = 216, }; +static int sm8150_pinctrl_dir_conn_probe(struct platform_device *pdev) +{ + const __be32 *prop; + struct msm_dir_conn *dir_conn_list; + uint32_t dir_conn_length, iterator = 0; + int i, length, *dir_conn_entries, num_dir_conns; + + prop = of_get_property(pdev->dev.of_node, "dirconn-list", + &length); + + dir_conn_length = length / sizeof(u32); + + dir_conn_entries = devm_kzalloc(&pdev->dev, + dir_conn_length*sizeof(uint32_t), GFP_KERNEL); + if (!dir_conn_entries) + return -ENOMEM; + + for (i = 0; i < dir_conn_length; i++) + dir_conn_entries[i] = be32_to_cpu(prop[i]); + + num_dir_conns = (dir_conn_length / 3); + + dir_conn_list = devm_kzalloc(&pdev->dev, + num_dir_conns * sizeof(*dir_conn_list), GFP_KERNEL); + if (!dir_conn_list) + return -ENOMEM; + + for (i = 0; i < num_dir_conns; i++) { + dir_conn_list[i].gpio = dir_conn_entries[iterator++]; + dir_conn_list[i].hwirq = dir_conn_entries[iterator++]; + dir_conn_list[i].tlmm_dc = dir_conn_entries[iterator++]; + } + + sm8150_pinctrl.dir_conn = dir_conn_list; + sm8150_pinctrl.n_dir_conns = num_dir_conns; + + return 0; +} + static int sm8150_pinctrl_probe(struct platform_device *pdev) { + int len, ret; + + if (of_find_property(pdev->dev.of_node, "dirconn-list", &len)) { + ret = sm8150_pinctrl_dir_conn_probe(pdev); + if (ret) { + dev_err(&pdev->dev, + "Unable to parse TLMM direct connects\n"); + return ret; + } + } + return msm_pinctrl_probe(pdev, &sm8150_pinctrl); } -- GitLab From 84c5576cc6164515b6dd78efad928491bcf76057 Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Fri, 17 May 2019 15:18:42 -0700 Subject: [PATCH 0773/1121] ARM: dts: msm: Add TLMM GPIOs for direct connect support on SA8155 VM Provide the TLMM GPIO direct connect list for SA8155 VM. These GPIOs are required by drivers for end to end functionality. Change-Id: I2cd8e2e9a508918fd24eca21a56e816fbdafbf99 Signed-off-by: Anant Goel --- arch/arm64/boot/dts/qcom/sa8155-vm.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi b/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi index be8537c57965..2b18f9aa9242 100644 --- a/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi @@ -491,6 +491,10 @@ #include "sa8155-vm-pcie.dtsi" #include "sa8155-vm-mhi.dtsi" +&tlmm { + dirconn-list = <37 216 1>; +}; + &qupv3_se13_4uart { status = "ok"; }; -- GitLab From de081f83f5e46b04eb26b01268cbd10a953e5e01 Mon Sep 17 00:00:00 2001 From: Vijayakumar Badiger Date: Wed, 3 Jul 2019 12:07:05 -0700 Subject: [PATCH 0774/1121] defconfig: msm: Enable DM_VERITY_FEC support Add forward error correction config for supporting device mapper functionality. Change-Id: I9d207bf91e219bd32e360d8b16767ee98caff7a3 Signed-off-by: Vijayakumar Badiger --- arch/arm64/configs/vendor/sdmshrike-perf_defconfig | 1 + arch/arm64/configs/vendor/sdmshrike_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm64/configs/vendor/sdmshrike-perf_defconfig b/arch/arm64/configs/vendor/sdmshrike-perf_defconfig index d2b5346cb894..df3b04bcccb7 100644 --- a/arch/arm64/configs/vendor/sdmshrike-perf_defconfig +++ b/arch/arm64/configs/vendor/sdmshrike-perf_defconfig @@ -270,6 +270,7 @@ CONFIG_MD=y CONFIG_BLK_DEV_DM=y CONFIG_DM_UEVENT=y CONFIG_DM_VERITY=y +CONFIG_DM_VERITY_FEC=y CONFIG_NETDEVICES=y CONFIG_BONDING=y CONFIG_DUMMY=y diff --git a/arch/arm64/configs/vendor/sdmshrike_defconfig b/arch/arm64/configs/vendor/sdmshrike_defconfig index e0cdaf032fc9..415ff0c6156e 100644 --- a/arch/arm64/configs/vendor/sdmshrike_defconfig +++ b/arch/arm64/configs/vendor/sdmshrike_defconfig @@ -283,6 +283,7 @@ CONFIG_MD=y CONFIG_BLK_DEV_DM=y CONFIG_DM_UEVENT=y CONFIG_DM_VERITY=y +CONFIG_DM_VERITY_FEC=y CONFIG_NETDEVICES=y CONFIG_BONDING=y CONFIG_DUMMY=y -- GitLab From d1baaa5f8d4d569cd3c095c75abc506b74955560 Mon Sep 17 00:00:00 2001 From: Ashok Vuyyuru Date: Sun, 16 Jun 2019 23:24:37 +0530 Subject: [PATCH 0775/1121] msm: ipa4: increase event channel ref count for non-coalescing pipe While configuring coalescing pipe channel increasing event channel reference count causing the null pointer dereference during WAN consumer pipe configuration. Added changes to increase event channel ref count only for non-coalescing pipe. Change-Id: I1f29e636b85296115a0cbe145c5239ae2969f41e Signed-off-by: Ashok Vuyyuru --- drivers/platform/msm/gsi/gsi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/platform/msm/gsi/gsi.c b/drivers/platform/msm/gsi/gsi.c index ddafc10cb6ed..0a3af89be687 100644 --- a/drivers/platform/msm/gsi/gsi.c +++ b/drivers/platform/msm/gsi/gsi.c @@ -2395,7 +2395,8 @@ int gsi_alloc_channel(struct gsi_chan_props *props, unsigned long dev_hdl, if (erindex < GSI_EVT_RING_MAX) { ctx->evtr = &gsi_ctx->evtr[erindex]; - atomic_inc(&ctx->evtr->chan_ref_cnt); + if (props->prot != GSI_CHAN_PROT_GCI) + atomic_inc(&ctx->evtr->chan_ref_cnt); if (props->prot != GSI_CHAN_PROT_GCI && ctx->evtr->props.exclusive && atomic_read(&ctx->evtr->chan_ref_cnt) == 1) -- GitLab From 9ac315ee6d5204b833e0d16d2ebd4e6e6dab7e9c Mon Sep 17 00:00:00 2001 From: Ashok Vuyyuru Date: Thu, 20 Jun 2019 20:44:39 +0530 Subject: [PATCH 0776/1121] msm: ipa4: Fix to configure pending packelist WAN consumer pipe When coalescing pipe and WAN consumer pipe are configuring case pending list pointer was not initlizing causing null pointer deference. Add changes to initialize pending packet list for WAN consumer pipe. Change-Id: I8daa75522be7f6a1fa5eb60e025992539be4b124 Signed-off-by: Ashok Vuyyuru --- drivers/platform/msm/ipa/ipa_v3/ipa_dp.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c index 040a15f3b1be..dd0b96d51dac 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c @@ -1216,7 +1216,7 @@ static int ipa_setup_coal_def_pipe(struct ipa_sys_connect_params *sys_in, { struct ipa3_ep_context *ep; int result = -EINVAL; - int ipa_ep_idx; + int ipa_ep_idx, i; ipa_ep_idx = ipa3_get_ep_mapping(sys_in->client); @@ -1300,6 +1300,9 @@ static int ipa_setup_coal_def_pipe(struct ipa_sys_connect_params *sys_in, ep->sys->repl = ep_coalescing->sys->repl; ipa3_replenish_rx_cache(ep->sys); + for (i = 0; i < GSI_VEID_MAX; i++) + INIT_LIST_HEAD(&ep->sys->pending_pkts[i]); + ipa3_ctx->skip_ep_cfg_shadow[ipa_ep_idx] = ep->skip_ep_cfg; result = ipa3_enable_data_path(ipa_ep_idx); -- GitLab From d852427d28cf91685d63e7669e9e5b5776d4d847 Mon Sep 17 00:00:00 2001 From: Ashok Vuyyuru Date: Thu, 20 Jun 2019 20:55:18 +0530 Subject: [PATCH 0777/1121] msm: ipa4: GCI protocal channel update polling mode for dependent channels Both coalescing and WAN consumer pipes are sharing the same event channel, while configuring the polling or interrupt mode for GCI protocal channel update the WAN consumer channel polling mode also. Change-Id: Idf8fb40aba354f6eaf320303880d6cb64e9ed51a Signed-off-by: Ashok Vuyyuru --- drivers/platform/msm/gsi/gsi.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/platform/msm/gsi/gsi.c b/drivers/platform/msm/gsi/gsi.c index ddafc10cb6ed..5282a47cd615 100644 --- a/drivers/platform/msm/gsi/gsi.c +++ b/drivers/platform/msm/gsi/gsi.c @@ -3693,6 +3693,8 @@ int gsi_config_channel_mode(unsigned long chan_hdl, enum gsi_chan_mode mode) gsi_writel(1 << ctx->evtr->id, gsi_ctx->base + GSI_EE_n_CNTXT_SRC_IEOB_IRQ_CLR_OFFS(gsi_ctx->per.ee)); atomic_set(&ctx->poll_mode, mode); + if (ctx->props.prot == GSI_CHAN_PROT_GCI) + atomic_set(&ctx->evtr->chan->poll_mode, mode); GSIDBG("set gsi_ctx evtr_id %d to %d mode\n", ctx->evtr->id, mode); ctx->stats.callback_to_poll++; @@ -3701,6 +3703,8 @@ int gsi_config_channel_mode(unsigned long chan_hdl, enum gsi_chan_mode mode) if (curr == GSI_CHAN_MODE_POLL && mode == GSI_CHAN_MODE_CALLBACK) { atomic_set(&ctx->poll_mode, mode); + if (ctx->props.prot == GSI_CHAN_PROT_GCI) + atomic_set(&ctx->evtr->chan->poll_mode, mode); __gsi_config_ieob_irq(gsi_ctx->per.ee, 1 << ctx->evtr->id, ~0); GSIDBG("set gsi_ctx evtr_id %d to %d mode\n", ctx->evtr->id, mode); -- GitLab From 5843503f00f53c02614f6ef057469de6f797d7b6 Mon Sep 17 00:00:00 2001 From: Bojun Pan Date: Mon, 1 Jul 2019 13:30:22 -0700 Subject: [PATCH 0778/1121] msm: IPA: enable uC debug stats for gsi on IPA4.1 APQ Enable uC debug stats for gsi offloading protocols on IPA4.1 APQ platform. Change-Id: I3de6bb29286a725304f4771f9bc6955281821f85 Signed-off-by: Bojun Pan --- drivers/platform/msm/ipa/ipa_v3/ipa_client.c | 4 +++- drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c | 24 ++++++++++++++----- drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c | 12 +++++++--- drivers/platform/msm/ipa/ipa_v3/ipa_utils.c | 4 +++- drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c | 12 +++++++--- 5 files changed, 42 insertions(+), 14 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c index 515b2903c3f7..8496e360302a 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c @@ -272,7 +272,9 @@ static void ipa3_start_gsi_debug_monitor(u32 clnt_hdl) client_type = ipa3_get_client_mapping(clnt_hdl); /* start uC gsi dbg stats monitor */ - if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5) { + if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5 || + (ipa3_ctx->ipa_hw_type == IPA_HW_v4_1 && + ipa3_ctx->platform_type == IPA_PLAT_TYPE_APQ)) { switch (client_type) { case IPA_CLIENT_MHI_PRIME_TETH_PROD: gsi_info = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_MHIP]; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c index ded52a01e5ff..81f1ff4a72b6 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c @@ -1988,7 +1988,9 @@ static ssize_t ipa3_read_wdi_gsi_stats(struct file *file, int nbytes; int cnt = 0; - if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_5) { + if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_5 + && (ipa3_ctx->ipa_hw_type != IPA_HW_v4_1 + || ipa3_ctx->platform_type != IPA_PLAT_TYPE_APQ)) { nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN, "This feature only support on IPA4.5+\n"); cnt += nbytes; @@ -2036,7 +2038,9 @@ static ssize_t ipa3_read_wdi3_gsi_stats(struct file *file, int nbytes; int cnt = 0; - if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_5) { + if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_5 + && (ipa3_ctx->ipa_hw_type != IPA_HW_v4_1 + || ipa3_ctx->platform_type != IPA_PLAT_TYPE_APQ)) { nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN, "This feature only support on IPA4.5+\n"); cnt += nbytes; @@ -2083,7 +2087,9 @@ static ssize_t ipa3_read_11ad_gsi_stats(struct file *file, int nbytes; int cnt = 0; - if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_5) { + if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_5 + && (ipa3_ctx->ipa_hw_type != IPA_HW_v4_1 + || ipa3_ctx->platform_type != IPA_PLAT_TYPE_APQ)) { nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN, "This feature only support on IPA4.5+\n"); cnt += nbytes; @@ -2100,7 +2106,9 @@ static ssize_t ipa3_read_aqc_gsi_stats(struct file *file, int nbytes; int cnt = 0; - if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_5) { + if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_5 + && (ipa3_ctx->ipa_hw_type != IPA_HW_v4_1 + || ipa3_ctx->platform_type != IPA_PLAT_TYPE_APQ)) { nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN, "This feature only support on IPA4.5+\n"); cnt += nbytes; @@ -2118,7 +2126,9 @@ static ssize_t ipa3_read_mhip_gsi_stats(struct file *file, int nbytes; int cnt = 0; - if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_5) { + if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_5 + && (ipa3_ctx->ipa_hw_type != IPA_HW_v4_1 + || ipa3_ctx->platform_type != IPA_PLAT_TYPE_APQ)) { nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN, "This feature only support on IPA4.5+\n"); cnt += nbytes; @@ -2190,7 +2200,9 @@ static ssize_t ipa3_read_usb_gsi_stats(struct file *file, int nbytes; int cnt = 0; - if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_5) { + if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_5 + && (ipa3_ctx->ipa_hw_type != IPA_HW_v4_1 + || ipa3_ctx->platform_type != IPA_PLAT_TYPE_APQ)) { nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN, "This feature only support on IPA4.5+\n"); cnt += nbytes; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c index 7cef724ba88f..4e44e94e4ac0 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c @@ -2097,7 +2097,9 @@ int ipa3_disconnect_gsi_wdi_pipe(u32 clnt_hdl) ipa3_ctx->uc_wdi_ctx.stats_notify = NULL; else IPADBG("uc_wdi_ctx.stats_notify already null\n"); - if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5) + if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5 || + (ipa3_ctx->ipa_hw_type == IPA_HW_v4_1 && + ipa3_ctx->platform_type == IPA_PLAT_TYPE_APQ)) ipa3_uc_debug_stats_dealloc(IPA_HW_PROTOCOL_WDI); IPADBG("client (ep: %d) disconnected\n", clnt_hdl); @@ -2478,7 +2480,9 @@ int ipa3_resume_gsi_wdi_pipe(u32 clnt_hdl) } pcmd_t = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_WDI]; /* start uC gsi dbg stats monitor */ - if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5) { + if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5 || + (ipa3_ctx->ipa_hw_type == IPA_HW_v4_1 && + ipa3_ctx->platform_type == IPA_PLAT_TYPE_APQ)) { if (IPA_CLIENT_IS_PROD(ep->client)) { pcmd_t->ch_id_info[0].ch_id = ep->gsi_chan_hdl; @@ -2654,7 +2658,9 @@ int ipa3_suspend_gsi_wdi_pipe(u32 clnt_hdl) } pcmd_t = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_WDI]; /* stop uC gsi dbg stats monitor */ - if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5) { + if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5 || + (ipa3_ctx->ipa_hw_type == IPA_HW_v4_1 && + ipa3_ctx->platform_type == IPA_PLAT_TYPE_APQ)) { if (IPA_CLIENT_IS_PROD(ep->client)) { pcmd_t->ch_id_info[0].ch_id = 0xff; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c index ac754b13db58..b335a4412905 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c @@ -7153,7 +7153,9 @@ static int __ipa3_stop_gsi_channel(u32 clnt_hdl) memset(&mem, 0, sizeof(mem)); /* stop uC gsi dbg stats monitor */ - if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5) { + if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5 || + (ipa3_ctx->ipa_hw_type == IPA_HW_v4_1 && + ipa3_ctx->platform_type == IPA_PLAT_TYPE_APQ)) { switch (client_type) { case IPA_CLIENT_MHI_PRIME_TETH_PROD: gsi_info = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_MHIP]; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c b/drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c index f5aa6698df80..bea91b734aae 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c @@ -698,7 +698,9 @@ int ipa3_disconn_wdi3_pipes(int ipa_ep_idx_tx, int ipa_ep_idx_rx) goto exit; } - if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5) + if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5 || + (ipa3_ctx->ipa_hw_type == IPA_HW_v4_1 && + ipa3_ctx->platform_type == IPA_PLAT_TYPE_APQ)) ipa3_uc_debug_stats_dealloc(IPA_HW_PROTOCOL_WDI3); ipa3_delete_dflt_flt_rules(ipa_ep_idx_rx); memset(ep_rx, 0, sizeof(struct ipa3_ep_context)); @@ -745,7 +747,9 @@ int ipa3_enable_wdi3_pipes(int ipa_ep_idx_tx, int ipa_ep_idx_rx) goto exit; } /* start uC gsi dbg stats monitor */ - if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5) { + if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5 || + (ipa3_ctx->ipa_hw_type == IPA_HW_v4_1 && + ipa3_ctx->platform_type == IPA_PLAT_TYPE_APQ)) { ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_WDI3].ch_id_info[0].ch_id = ep_rx->gsi_chan_hdl; ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_WDI3].ch_id_info[0].dir @@ -852,7 +856,9 @@ int ipa3_disable_wdi3_pipes(int ipa_ep_idx_tx, int ipa_ep_idx_rx) goto fail; } /* stop uC gsi dbg stats monitor */ - if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5) { + if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5 || + (ipa3_ctx->ipa_hw_type == IPA_HW_v4_1 && + ipa3_ctx->platform_type == IPA_PLAT_TYPE_APQ)) { ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_WDI3].ch_id_info[0].ch_id = 0xff; ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_WDI3].ch_id_info[0].dir -- GitLab From 1627132970751b135db02dc209ac74a534e56c6b Mon Sep 17 00:00:00 2001 From: Sujeev Dias Date: Mon, 6 May 2019 12:05:47 -0700 Subject: [PATCH 0779/1121] mhi: cntrl: qcom: bring MHI out of suspend prior to MHI shutdown During MHI shutdown, MHI host would issue an MHI reset to controller. Therefore, if power-off occurs while MHI is in a suspended state, MHI resume needs to occur first. CRs-Fixed: 2446191 Change-Id: Iadd354cf51daabffad35555c43297e6ced4b177a Acked-by: Bhaumik Vasav Bhatt Signed-off-by: Sujeev Dias --- drivers/bus/mhi/controllers/mhi_arch_qcom.c | 23 ++++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/bus/mhi/controllers/mhi_arch_qcom.c b/drivers/bus/mhi/controllers/mhi_arch_qcom.c index 19745752654a..ef335537f3c1 100644 --- a/drivers/bus/mhi/controllers/mhi_arch_qcom.c +++ b/drivers/bus/mhi/controllers/mhi_arch_qcom.c @@ -184,26 +184,33 @@ static void mhi_arch_esoc_ops_power_off(void *priv, unsigned int flags) struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl); bool mdm_state = (flags & ESOC_HOOK_MDM_CRASH); struct arch_info *arch_info = mhi_dev->arch_info; + struct pci_dev *pci_dev = mhi_dev->pci_dev; MHI_LOG("Enter: mdm_crashed:%d\n", mdm_state); + /* + * Abort system suspend if system is preparing to go to suspend + * by grabbing wake source. + * If system is suspended, wait for pm notifier callback to notify + * that resume has occurred with PM_POST_SUSPEND event. + */ + pm_stay_awake(&mhi_cntrl->mhi_dev->dev); + wait_for_completion(&arch_info->pm_completion); + + /* if link is in drv suspend, wake it up */ + pm_runtime_get_sync(&pci_dev->dev); + mutex_lock(&mhi_cntrl->pm_mutex); if (!mhi_dev->powered_on) { MHI_LOG("Not in active state\n"); mutex_unlock(&mhi_cntrl->pm_mutex); + pm_runtime_put_noidle(&pci_dev->dev); return; } mhi_dev->powered_on = false; mutex_unlock(&mhi_cntrl->pm_mutex); - /* - * Abort system suspend if system is preparing to go to suspend - * by grabbing wake source. - * If system is suspended, wait for pm notifier callback to notify - * that resume has occurred with PM_POST_SUSPEND event. - */ - pm_stay_awake(&mhi_cntrl->mhi_dev->dev); - wait_for_completion(&arch_info->pm_completion); + pm_runtime_put_noidle(&pci_dev->dev); MHI_LOG("Triggering shutdown process\n"); mhi_power_down(mhi_cntrl, !mdm_state); -- GitLab From fa66312f765973e928ad66e610680a4522435bb7 Mon Sep 17 00:00:00 2001 From: Sujeev Dias Date: Wed, 8 May 2019 14:35:44 -0700 Subject: [PATCH 0780/1121] mhi: cntrl: qcom: reset suspend state to active in suspend error cases Make sure MHI suspend state correctly reflect when returning from run time and system suspend. CRs-Fixed: 2451030 Change-Id: Iaf48d5f9f5e18c7de0b0bb9be04a22b8bcc7ac63 Acked-by: Bhaumik Vasav Bhatt Signed-off-by: Sujeev Dias --- drivers/bus/mhi/controllers/mhi_qcom.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/bus/mhi/controllers/mhi_qcom.c b/drivers/bus/mhi/controllers/mhi_qcom.c index 58b319ffc5ef..8ce69ce2e72a 100644 --- a/drivers/bus/mhi/controllers/mhi_qcom.c +++ b/drivers/bus/mhi/controllers/mhi_qcom.c @@ -217,6 +217,7 @@ static int mhi_runtime_suspend(struct device *dev) if (ret) { MHI_LOG("Abort due to ret:%d\n", ret); + mhi_dev->suspend_mode = MHI_ACTIVE_STATE; goto exit_runtime_suspend; } -- GitLab From 07b8393eed22e982badea42aea69c0be13211261 Mon Sep 17 00:00:00 2001 From: Sujeev Dias Date: Fri, 12 Apr 2019 17:39:38 -0700 Subject: [PATCH 0781/1121] mhi: cntrl: qcom: force a suspend during boot Soon as device transition to mission mode force a PCIe link suspend and a resume so device can update PCIe phy sequence. CRs-Fixed: 2457211 Change-Id: Ic9de5f69c425f7a1a5b8a931930882a9da80c2ad Signed-off-by: Sujeev Dias --- drivers/bus/mhi/controllers/mhi_arch_qcom.c | 3 -- drivers/bus/mhi/controllers/mhi_qcom.c | 53 +++++++++++++++++++++ 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/drivers/bus/mhi/controllers/mhi_arch_qcom.c b/drivers/bus/mhi/controllers/mhi_arch_qcom.c index ef335537f3c1..c2d5e157b010 100644 --- a/drivers/bus/mhi/controllers/mhi_arch_qcom.c +++ b/drivers/bus/mhi/controllers/mhi_arch_qcom.c @@ -281,9 +281,6 @@ static void mhi_boot_monitor(void *data, async_cookie_t cookie) if (boot_dev) mhi_unprepare_from_transfer(boot_dev); - /* enable link inactivity timer to start auto suspend */ - msm_pcie_l1ss_timeout_enable(mhi_dev->pci_dev); - pm_runtime_allow(&mhi_dev->pci_dev->dev); } } diff --git a/drivers/bus/mhi/controllers/mhi_qcom.c b/drivers/bus/mhi/controllers/mhi_qcom.c index 8ce69ce2e72a..fd08c6cbf937 100644 --- a/drivers/bus/mhi/controllers/mhi_qcom.c +++ b/drivers/bus/mhi/controllers/mhi_qcom.c @@ -376,6 +376,47 @@ int mhi_system_suspend(struct device *dev) return ret; } +static int mhi_force_suspend(struct mhi_controller *mhi_cntrl) +{ + int ret = -EIO; + const u32 delayms = 100; + struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl); + int itr = DIV_ROUND_UP(mhi_cntrl->timeout_ms, delayms); + + MHI_LOG("Entered\n"); + + mutex_lock(&mhi_cntrl->pm_mutex); + + for (; itr; itr--) { + /* + * This function get called soon as device entered mission mode + * so most of the channels are still in disabled state. However, + * sbl channels are active and clients could be trying to close + * channels while we trying to suspend the link. So, we need to + * re-try if MHI is busy + */ + ret = mhi_pm_suspend(mhi_cntrl); + if (!ret || ret != -EBUSY) + break; + + MHI_LOG("MHI busy, sleeping and retry\n"); + msleep(delayms); + } + + if (ret) + goto exit_force_suspend; + + mhi_dev->suspend_mode = MHI_DEFAULT_SUSPEND; + ret = mhi_arch_link_suspend(mhi_cntrl); + +exit_force_suspend: + MHI_LOG("Force suspend ret with %d\n", ret); + + mutex_unlock(&mhi_cntrl->pm_mutex); + + return ret; +} + /* checks if link is down */ static int mhi_link_status(struct mhi_controller *mhi_cntrl, void *priv) { @@ -545,6 +586,7 @@ static void mhi_status_cb(struct mhi_controller *mhi_cntrl, { struct mhi_dev *mhi_dev = priv; struct device *dev = &mhi_dev->pci_dev->dev; + int ret; switch (reason) { case MHI_CB_IDLE: @@ -556,6 +598,17 @@ static void mhi_status_cb(struct mhi_controller *mhi_cntrl, if (mhi_dev->bw_scale) mhi_dev->bw_scale(mhi_cntrl, mhi_dev); break; + case MHI_CB_EE_MISSION_MODE: + /* + * we need to force a suspend so device can switch to + * mission mode pcie phy settings. + */ + pm_runtime_get(dev); + ret = mhi_force_suspend(mhi_cntrl); + if (!ret) + mhi_runtime_resume(dev); + pm_runtime_put(dev); + break; default: MHI_ERR("Unhandled cb:0x%x\n", reason); } -- GitLab From ef1260fb4c12af35962f490600d9bd7b01be0193 Mon Sep 17 00:00:00 2001 From: Sujeev Dias Date: Thu, 30 May 2019 13:16:16 -0700 Subject: [PATCH 0782/1121] mhi: core: add support for early error notifications Some MHI based devices transfer time sensitive data and require early termination of active transfers even before MHI teardown happens. This change immediately transitions MHI into an error state and notify such devices. CRs-Fixed: 2459916 Change-Id: Ic647bd34e01f39389f3eda0f8a0dc096190fe39b Signed-off-by: Sujeev Dias --- drivers/bus/mhi/core/mhi_internal.h | 1 + drivers/bus/mhi/core/mhi_main.c | 23 ++++++++++++++++++++++ drivers/bus/mhi/core/mhi_pm.c | 30 +++++++++++++++++++++++++++++ include/linux/mhi.h | 11 +++++++++++ 4 files changed, 65 insertions(+) diff --git a/drivers/bus/mhi/core/mhi_internal.h b/drivers/bus/mhi/core/mhi_internal.h index 887f93e410ea..8853ba4a97c4 100644 --- a/drivers/bus/mhi/core/mhi_internal.h +++ b/drivers/bus/mhi/core/mhi_internal.h @@ -761,6 +761,7 @@ int mhi_create_timesync_sysfs(struct mhi_controller *mhi_cntrl); void mhi_destroy_timesync(struct mhi_controller *mhi_cntrl); int mhi_create_vote_sysfs(struct mhi_controller *mhi_cntrl); void mhi_destroy_vote_sysfs(struct mhi_controller *mhi_cntrl); +int mhi_early_notify_device(struct device *dev, void *data); /* timesync log support */ static inline void mhi_timesync_log(struct mhi_controller *mhi_cntrl) diff --git a/drivers/bus/mhi/core/mhi_main.c b/drivers/bus/mhi/core/mhi_main.c index 1e786e97c5d3..52df21b68e9f 100644 --- a/drivers/bus/mhi/core/mhi_main.c +++ b/drivers/bus/mhi/core/mhi_main.c @@ -646,6 +646,22 @@ int mhi_destroy_device(struct device *dev, void *data) return 0; } +int mhi_early_notify_device(struct device *dev, void *data) +{ + struct mhi_device *mhi_dev = to_mhi_device(dev); + struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; + + /* skip early notification */ + if (!mhi_dev->early_notif) + return 0; + + MHI_LOG("Early notification for dev:%s\n", mhi_dev->chan_name); + + mhi_notify(mhi_dev, MHI_CB_FATAL_ERROR); + + return 0; +} + void mhi_notify(struct mhi_device *mhi_dev, enum MHI_CB cb_reason) { struct mhi_driver *mhi_drv; @@ -856,6 +872,13 @@ void mhi_create_devices(struct mhi_controller *mhi_cntrl) /* add if there is a matching DT node */ mhi_assign_of_node(mhi_cntrl, mhi_dev); + /* + * if set, these device should get a early notification during + * early notification state + */ + mhi_dev->early_notif = + of_property_read_bool(mhi_dev->dev.of_node, + "mhi,early-notify"); /* init wake source */ if (mhi_dev->dl_chan && mhi_dev->dl_chan->wake_capable) device_init_wakeup(&mhi_dev->dev, true); diff --git a/drivers/bus/mhi/core/mhi_pm.c b/drivers/bus/mhi/core/mhi_pm.c index f56f8d205e67..7ebd6b209d04 100644 --- a/drivers/bus/mhi/core/mhi_pm.c +++ b/drivers/bus/mhi/core/mhi_pm.c @@ -893,6 +893,36 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl) } EXPORT_SYMBOL(mhi_async_power_up); +/* Transition MHI into error state and notify critical clients */ +void mhi_control_error(struct mhi_controller *mhi_cntrl) +{ + enum MHI_PM_STATE cur_state; + + MHI_LOG("Enter with pm_state:%s MHI_STATE:%s\n", + to_mhi_pm_state_str(mhi_cntrl->pm_state), + TO_MHI_STATE_STR(mhi_cntrl->dev_state)); + + write_lock_irq(&mhi_cntrl->pm_lock); + cur_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_LD_ERR_FATAL_DETECT); + write_unlock_irq(&mhi_cntrl->pm_lock); + + if (cur_state != MHI_PM_LD_ERR_FATAL_DETECT) { + MHI_ERR("Failed to transition to state:%s from:%s\n", + to_mhi_pm_state_str(MHI_PM_LD_ERR_FATAL_DETECT), + to_mhi_pm_state_str(cur_state)); + goto exit_control_error; + } + + /* start notifying all clients who request early notification */ + device_for_each_child(mhi_cntrl->dev, NULL, mhi_early_notify_device); + +exit_control_error: + MHI_LOG("Exit with pm_state:%s MHI_STATE:%s\n", + to_mhi_pm_state_str(mhi_cntrl->pm_state), + TO_MHI_STATE_STR(mhi_cntrl->dev_state)); +} +EXPORT_SYMBOL(mhi_control_error); + void mhi_power_down(struct mhi_controller *mhi_cntrl, bool graceful) { enum MHI_PM_STATE cur_state; diff --git a/include/linux/mhi.h b/include/linux/mhi.h index ebda4aa4568f..76db830c5de3 100644 --- a/include/linux/mhi.h +++ b/include/linux/mhi.h @@ -338,6 +338,8 @@ struct mhi_controller { * @ul_chan_id: MHI channel id for UL transfer * @dl_chan_id: MHI channel id for DL transfer * @tiocm: Device current terminal settings + * @early_notif: This device needs an early notification in case of error + * with external modem. * @dev_vote: Keep external device in active state * @bus_vote: Keep physical bus (pci, spi) in active state * @priv: Driver private data @@ -354,6 +356,7 @@ struct mhi_device { int ul_event_id; int dl_event_id; u32 tiocm; + bool early_notif; const struct mhi_device_id *id; const char *chan_name; struct mhi_controller *mhi_cntrl; @@ -705,6 +708,14 @@ static inline bool mhi_is_active(struct mhi_device *mhi_dev) mhi_cntrl->dev_state <= MHI_STATE_M3_FAST); } +/** + * mhi_control_error - MHI controller went into unrecoverable error state. + * Will transition MHI into Linkdown state. Do not call from atomic + * context. + * @mhi_cntrl: MHI controller + */ +void mhi_control_error(struct mhi_controller *mhi_cntrl); + /** * mhi_debug_reg_dump - dump MHI registers for debug purpose * @mhi_cntrl: MHI controller -- GitLab From d1e7b91a71d31ff599ccb63931902a4570a8ffa2 Mon Sep 17 00:00:00 2001 From: Sujeev Dias Date: Mon, 6 May 2019 17:47:11 -0700 Subject: [PATCH 0783/1121] mhi: cntrl: qcom: timesync IPC log buffer support Add a separate IPC log buffer for time synchronized logs to log local and remote timestamps and aid in debug. CRs-Fixed: 2377061 Change-Id: Ia8ddab5dc53cc03e98014330fc360014e14be2f9 Acked-by: Bhaumik Vasav Bhatt Signed-off-by: Sujeev Dias --- drivers/bus/mhi/controllers/mhi_arch_qcom.c | 24 +++++++++++++++++++++ drivers/bus/mhi/controllers/mhi_qcom.h | 8 +++++++ 2 files changed, 32 insertions(+) diff --git a/drivers/bus/mhi/controllers/mhi_arch_qcom.c b/drivers/bus/mhi/controllers/mhi_arch_qcom.c index c2d5e157b010..800bfc0a11a7 100644 --- a/drivers/bus/mhi/controllers/mhi_arch_qcom.c +++ b/drivers/bus/mhi/controllers/mhi_arch_qcom.c @@ -39,6 +39,7 @@ struct arch_info { struct dma_iommu_mapping *mapping; async_cookie_t cookie; void *boot_ipc_log; + void *tsync_ipc_log; struct mhi_device *boot_dev; struct mhi_link_info current_link_info; struct work_struct bw_scale_work; @@ -50,6 +51,8 @@ struct arch_info { #define DLOG "Dev->Host: " #define HLOG "Host: " +#define MHI_TSYNC_LOG_PAGES (10) + #ifdef CONFIG_MHI_DEBUG #define MHI_IPC_LOG_PAGES (100) @@ -81,6 +84,19 @@ static int mhi_arch_pm_notifier(struct notifier_block *nb, return NOTIFY_DONE; } +static void mhi_arch_timesync_log(struct mhi_controller *mhi_cntrl, + u64 remote_time) +{ + struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl); + struct arch_info *arch_info = mhi_dev->arch_info; + + if (remote_time != U64_MAX) + ipc_log_string(arch_info->tsync_ipc_log, "%6u.%06lu 0x%llx", + REMOTE_TICKS_TO_SEC(remote_time), + REMOTE_TIME_REMAINDER_US(remote_time), + remote_time); +} + static int mhi_arch_set_bus_request(struct mhi_controller *mhi_cntrl, int index) { struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl); @@ -431,6 +447,14 @@ int mhi_arch_pcie_init(struct mhi_controller *mhi_cntrl) node, 0); mhi_cntrl->log_lvl = mhi_ipc_log_lvl; + snprintf(node, sizeof(node), "mhi_tsync_%04x_%02u.%02u.%02u", + mhi_cntrl->dev_id, mhi_cntrl->domain, mhi_cntrl->bus, + mhi_cntrl->slot); + arch_info->tsync_ipc_log = ipc_log_context_create( + MHI_TSYNC_LOG_PAGES, node, 0); + if (arch_info->tsync_ipc_log) + mhi_cntrl->tsync_log = mhi_arch_timesync_log; + /* register for bus scale if defined */ arch_info->msm_bus_pdata = msm_bus_cl_get_pdata_from_dev( &mhi_dev->pci_dev->dev); diff --git a/drivers/bus/mhi/controllers/mhi_qcom.h b/drivers/bus/mhi/controllers/mhi_qcom.h index 4b0cbfff3901..91396c4aac08 100644 --- a/drivers/bus/mhi/controllers/mhi_qcom.h +++ b/drivers/bus/mhi/controllers/mhi_qcom.h @@ -26,6 +26,14 @@ #define MHI_RPM_SUSPEND_TMR_MS (250) #define MHI_PCI_BAR_NUM (0) +/* timesync time calculations */ +#define REMOTE_TICKS_TO_US(x) (div_u64((x) * 100ULL, \ + div_u64(mhi_cntrl->remote_timer_freq, 10000ULL))) +#define REMOTE_TICKS_TO_SEC(x) (div_u64((x), \ + mhi_cntrl->remote_timer_freq)) +#define REMOTE_TIME_REMAINDER_US(x) (REMOTE_TICKS_TO_US((x)) % \ + (REMOTE_TICKS_TO_SEC((x)) * 1000000ULL)) + extern const char * const mhi_ee_str[MHI_EE_MAX]; #define TO_MHI_EXEC_STR(ee) (ee >= MHI_EE_MAX ? "INVALID_EE" : mhi_ee_str[ee]) -- GitLab From f4bc18cfcad442833cf208e1d515defb83ca5052 Mon Sep 17 00:00:00 2001 From: Sujeev Dias Date: Thu, 30 May 2019 14:40:35 -0700 Subject: [PATCH 0784/1121] mhi: cntrl: qcom: register for early error fatal notification Register for early error fatal notification from esoc so we can transition MHI into error state sooner. CRs-Fixed: 2459916 Change-Id: I56bd66fa35c32cb36451bf50b9f644340b7d8d8d Signed-off-by: Sujeev Dias --- drivers/bus/mhi/controllers/mhi_arch_qcom.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/bus/mhi/controllers/mhi_arch_qcom.c b/drivers/bus/mhi/controllers/mhi_arch_qcom.c index 800bfc0a11a7..56708218081e 100644 --- a/drivers/bus/mhi/controllers/mhi_arch_qcom.c +++ b/drivers/bus/mhi/controllers/mhi_arch_qcom.c @@ -244,6 +244,18 @@ static void mhi_arch_esoc_ops_power_off(void *priv, unsigned int flags) pm_relax(&mhi_cntrl->mhi_dev->dev); } +static void mhi_arch_esoc_ops_mdm_error(void *priv) +{ + struct mhi_controller *mhi_cntrl = priv; + + MHI_LOG("Enter: mdm asserted\n"); + + /* transition MHI state into error state */ + mhi_control_error(mhi_cntrl); + + MHI_LOG("Exit\n"); +} + static void mhi_bl_dl_cb(struct mhi_device *mhi_device, struct mhi_result *mhi_result) { @@ -505,6 +517,8 @@ int mhi_arch_pcie_init(struct mhi_controller *mhi_cntrl) mhi_arch_esoc_ops_power_on; esoc_ops->esoc_link_power_off = mhi_arch_esoc_ops_power_off; + esoc_ops->esoc_link_mdm_crash = + mhi_arch_esoc_ops_mdm_error; ret = esoc_register_client_hook(arch_info->esoc_client, esoc_ops); -- GitLab From 0eae1c563c87605bb2f58614f678b3588fbaee2d Mon Sep 17 00:00:00 2001 From: Vijayakumar Badiger Date: Wed, 3 Jul 2019 11:18:55 -0700 Subject: [PATCH 0785/1121] ARM: dts: msm: Add overlay DT nodes for sdmshrike Add the overlay dtb node for the sdmshrike. Change-Id: Ie4b00ebb8ed6b77c003a9eaf5a5bc6ff0d347944 Signed-off-by: Vijayakumar Badiger --- .../dts/qcom/sa8195p-adp-star-overlay.dts | 23 +++++++++++++++++++ arch/arm64/boot/dts/qcom/sdmshrike.dtsi | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 arch/arm64/boot/dts/qcom/sa8195p-adp-star-overlay.dts diff --git a/arch/arm64/boot/dts/qcom/sa8195p-adp-star-overlay.dts b/arch/arm64/boot/dts/qcom/sa8195p-adp-star-overlay.dts new file mode 100644 index 000000000000..d7752bd2ecec --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sa8195p-adp-star-overlay.dts @@ -0,0 +1,23 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; +/plugin/; + +#include "sa8195p-adp-star.dtsi" + +/ { + model = "ADP-STAR"; + compatible = "qcom,sa8195p-adp-star", "qcom,sa8195p", + "qcom,adp-star"; + qcom,board-id = <25 0>; +}; diff --git a/arch/arm64/boot/dts/qcom/sdmshrike.dtsi b/arch/arm64/boot/dts/qcom/sdmshrike.dtsi index 8f3fcd23991e..459f39250432 100644 --- a/arch/arm64/boot/dts/qcom/sdmshrike.dtsi +++ b/arch/arm64/boot/dts/qcom/sdmshrike.dtsi @@ -411,7 +411,7 @@ dev = "/dev/block/platform/soc/8804000.sdhci/by-name/vendor"; type = "ext4"; mnt_flags = "ro,barrier=1,discard"; - fsmgr_flags = "wait,slotselect"; + fsmgr_flags = "wait,slotselect,avb"; status = "ok"; }; }; -- GitLab From 317d58ec6456198233ae96122b6e6f79a785740e Mon Sep 17 00:00:00 2001 From: Ashay Jaiswal Date: Thu, 27 Jun 2019 00:36:34 +0530 Subject: [PATCH 0786/1121] power: smb1390: fix NULL pointer de-reference in resume path Add checks before accessing/de-referencing the pointers. While at it, add a separate "is_writeable" callback for the slave SMB1390. Change-Id: I397f31b526e8d168a7c4bd2831c6dc5fe2fcc83e Signed-off-by: Ashay Jaiswal --- .../power/supply/qcom/smb1390-charger-psy.c | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/power/supply/qcom/smb1390-charger-psy.c b/drivers/power/supply/qcom/smb1390-charger-psy.c index c14f975c68a0..d583ce66694c 100644 --- a/drivers/power/supply/qcom/smb1390-charger-psy.c +++ b/drivers/power/supply/qcom/smb1390-charger-psy.c @@ -1730,6 +1730,12 @@ static enum power_supply_property smb1390_cp_slave_props[] = { POWER_SUPPLY_PROP_CURRENT_CAPABILITY, }; +static int smb1390_slave_prop_is_writeable(struct power_supply *psy, + enum power_supply_property prop) +{ + return 0; +} + static int smb1390_cp_slave_get_prop(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val) @@ -1788,7 +1794,7 @@ static const struct power_supply_desc cps_psy_desc = { .num_properties = ARRAY_SIZE(smb1390_cp_slave_props), .get_property = smb1390_cp_slave_get_prop, .set_property = smb1390_cp_slave_set_prop, - .property_is_writeable = smb1390_prop_is_writeable, + .property_is_writeable = smb1390_slave_prop_is_writeable, }; static int smb1390_init_cps_psy(struct smb1390 *chip) @@ -1930,8 +1936,17 @@ static int smb1390_resume(struct device *dev) struct smb1390 *chip = dev_get_drvdata(dev); chip->suspended = false; - rerun_election(chip->ilim_votable); - rerun_election(chip->disable_votable); + + /* ILIM rerun is applicable for both master and slave */ + if (!chip->ilim_votable) + chip->ilim_votable = find_votable("CP_ILIM"); + + if (chip->ilim_votable) + rerun_election(chip->ilim_votable); + + /* Run disable votable for master only */ + if (chip->cp_role == CP_MASTER) + rerun_election(chip->disable_votable); return 0; } -- GitLab From 25b489cddb08a13c04f4efbf700e3c7a4baeb6dc Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Wed, 13 Mar 2019 23:19:39 +0530 Subject: [PATCH 0787/1121] ARM: dts: qcom: enable mi2s gpios dynamically in qcs405 Enable GPIOs for MI2S during usecase setup. Change-Id: Id4bdb1d2b44c1e7f932883dbcec5005d1378cf98 Signed-off-by: Mangesh Kunchamwar --- .../dts/qcom/qcs405-csra1-audio-overlay.dtsi | 29 +++++++++++--- .../dts/qcom/qcs405-csra6-audio-overlay.dtsi | 35 +++++++++++++---- .../dts/qcom/qcs405-csra8-audio-overlay.dtsi | 38 ++++++++++++++----- 3 files changed, 79 insertions(+), 23 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/qcs405-csra1-audio-overlay.dtsi b/arch/arm64/boot/dts/qcom/qcs405-csra1-audio-overlay.dtsi index 742270e49394..408285b6c756 100644 --- a/arch/arm64/boot/dts/qcom/qcs405-csra1-audio-overlay.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs405-csra1-audio-overlay.dtsi @@ -43,6 +43,26 @@ pinctrl-1 = <&cdc_dmic67_clk_sleep &cdc_dmic67_data_sleep>; qcom,lpi-gpios; }; + + pri_mi2s_gpios: pri_mi2s_pinctrl { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&pri_mi2s_sck_active &pri_mi2s_ws_active + &pri_mi2s_sd0_active>; + pinctrl-1 = <&pri_mi2s_sck_sleep &pri_mi2s_ws_sleep + &pri_mi2s_sd0_sleep>; + }; + + sec_mi2s_gpios: sec_mi2s_pinctrl { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&sec_mi2s_sck_active &sec_mi2s_ws_active + &sec_mi2s_sd0_active &sec_mi2s_sd1_active + &sec_mi2s_sd2_active &sec_mi2s_sd3_active>; + pinctrl-1 = <&sec_mi2s_sck_sleep &sec_mi2s_ws_sleep + &sec_mi2s_sd0_sleep &sec_mi2s_sd1_sleep + &sec_mi2s_sd2_sleep &sec_mi2s_sd3_sleep>; + }; }; &q6core { @@ -68,6 +88,8 @@ qcom,cdc-dmic23-gpios = <&cdc_dmic23_gpios>; qcom,cdc-dmic45-gpios = <&cdc_dmic45_gpios>; qcom,cdc-dmic67-gpios = <&cdc_dmic67_gpios>; + qcom,pri-mi2s-gpios = <&pri_mi2s_gpios>; + qcom,sec-mi2s-gpios = <&sec_mi2s_gpios>; qcom,audio-routing = "RX_BIAS", "MCLK", "lineout booster", "LINEOUT1", @@ -98,12 +120,7 @@ "VA MIC BIAS1", "Digital Mic7", "CSRA_12 IN", "PRI_MI2S_RX"; pinctrl-names = "default"; - pinctrl-0 = <&spdifrx_opt_default - &pri_mi2s_sck_active &pri_mi2s_ws_active - &pri_mi2s_sd0_active - &sec_mi2s_sck_active &sec_mi2s_ws_active - &sec_mi2s_sd0_active &sec_mi2s_sd1_active - &sec_mi2s_sd2_active &sec_mi2s_sd3_active>; + pinctrl-0 = <&spdifrx_opt_default>; }; &dai_mi2s0 { diff --git a/arch/arm64/boot/dts/qcom/qcs405-csra6-audio-overlay.dtsi b/arch/arm64/boot/dts/qcom/qcs405-csra6-audio-overlay.dtsi index 2818f5f0b17d..44b10697db35 100644 --- a/arch/arm64/boot/dts/qcom/qcs405-csra6-audio-overlay.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs405-csra6-audio-overlay.dtsi @@ -43,6 +43,30 @@ pinctrl-1 = <&cdc_dmic67_clk_sleep &cdc_dmic67_data_sleep>; qcom,lpi-gpios; }; + + pri_mi2s_gpios: pri_mi2s_pinctrl { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&pri_mi2s_sck_active &pri_mi2s_ws_active + &pri_mi2s_sd0_active &pri_mi2s_sd1_active + &pri_mi2s_sd2_active &pri_mi2s_sd3_active + &pri_mi2s_sd4_active &pri_mi2s_sd5_active>; + pinctrl-1 = <&pri_mi2s_sck_sleep &pri_mi2s_ws_sleep + &pri_mi2s_sd0_sleep &pri_mi2s_sd1_sleep + &pri_mi2s_sd2_sleep &pri_mi2s_sd3_sleep + &pri_mi2s_sd4_sleep &pri_mi2s_sd5_sleep>; + }; + + sec_mi2s_gpios: sec_mi2s_pinctrl { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&sec_mi2s_sck_active &sec_mi2s_ws_active + &sec_mi2s_sd0_active &sec_mi2s_sd1_active + &sec_mi2s_sd2_active &sec_mi2s_sd3_active>; + pinctrl-1 = <&sec_mi2s_sck_sleep &sec_mi2s_ws_sleep + &sec_mi2s_sd0_sleep &sec_mi2s_sd1_sleep + &sec_mi2s_sd2_sleep &sec_mi2s_sd3_sleep>; + }; }; &q6core { @@ -71,6 +95,8 @@ qcom,cdc-dmic23-gpios = <&cdc_dmic23_gpios>; qcom,cdc-dmic45-gpios = <&cdc_dmic45_gpios>; qcom,cdc-dmic67-gpios = <&cdc_dmic67_gpios>; + qcom,pri-mi2s-gpios = <&pri_mi2s_gpios>; + qcom,sec-mi2s-gpios = <&sec_mi2s_gpios>; qcom,audio-routing = "RX_BIAS", "MCLK", "lineout booster", "LINEOUT1", @@ -106,14 +132,7 @@ "CSRA_9A IN", "PRI_MI2S_RX", "CSRA_BC IN", "PRI_MI2S_RX"; pinctrl-names = "default"; - pinctrl-0 = <&spdifrx_opt_default - &pri_mi2s_sck_active &pri_mi2s_ws_active - &pri_mi2s_sd0_active &pri_mi2s_sd1_active - &pri_mi2s_sd2_active &pri_mi2s_sd3_active - &pri_mi2s_sd4_active &pri_mi2s_sd5_active - &sec_mi2s_sck_active &sec_mi2s_ws_active - &sec_mi2s_sd0_active &sec_mi2s_sd1_active - &sec_mi2s_sd2_active &sec_mi2s_sd3_active>; + pinctrl-0 = <&spdifrx_opt_default>; }; &dai_mi2s0 { diff --git a/arch/arm64/boot/dts/qcom/qcs405-csra8-audio-overlay.dtsi b/arch/arm64/boot/dts/qcom/qcs405-csra8-audio-overlay.dtsi index 1e753a38e799..1138390a012c 100644 --- a/arch/arm64/boot/dts/qcom/qcs405-csra8-audio-overlay.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs405-csra8-audio-overlay.dtsi @@ -43,6 +43,32 @@ pinctrl-1 = <&cdc_dmic67_clk_sleep &cdc_dmic67_data_sleep>; qcom,lpi-gpios; }; + + pri_mi2s_gpios: pri_mi2s_pinctrl { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&pri_mi2s_sck_active &pri_mi2s_ws_active + &pri_mi2s_sd0_active &pri_mi2s_sd1_active + &pri_mi2s_sd2_active &pri_mi2s_sd3_active + &pri_mi2s_sd4_active &pri_mi2s_sd5_active + &pri_mi2s_sd6_active &pri_mi2s_sd7_active>; + pinctrl-1 = <&pri_mi2s_sck_sleep &pri_mi2s_ws_sleep + &pri_mi2s_sd0_sleep &pri_mi2s_sd1_sleep + &pri_mi2s_sd2_sleep &pri_mi2s_sd3_sleep + &pri_mi2s_sd4_sleep &pri_mi2s_sd5_sleep + &pri_mi2s_sd6_sleep &pri_mi2s_sd7_sleep>; + }; + + sec_mi2s_gpios: sec_mi2s_pinctrl { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&sec_mi2s_sck_active &sec_mi2s_ws_active + &sec_mi2s_sd0_active &sec_mi2s_sd1_active + &sec_mi2s_sd2_active &sec_mi2s_sd3_active>; + pinctrl-1 = <&sec_mi2s_sck_sleep &sec_mi2s_ws_sleep + &sec_mi2s_sd0_sleep &sec_mi2s_sd1_sleep + &sec_mi2s_sd2_sleep &sec_mi2s_sd3_sleep>; + }; }; &q6core { @@ -72,6 +98,8 @@ qcom,cdc-dmic23-gpios = <&cdc_dmic23_gpios>; qcom,cdc-dmic45-gpios = <&cdc_dmic45_gpios>; qcom,cdc-dmic67-gpios = <&cdc_dmic67_gpios>; + qcom,pri-mi2s-gpios = <&pri_mi2s_gpios>; + qcom,sec-mi2s-gpios = <&sec_mi2s_gpios>; qcom,audio-routing = "RX_BIAS", "MCLK", "lineout booster", "LINEOUT1", @@ -109,15 +137,7 @@ "CSRA_DE IN", "PRI_MI2S_RX", "CSRA_F0 IN", "PRI_MI2S_RX"; pinctrl-names = "default"; - pinctrl-0 = <&spdifrx_opt_default - &pri_mi2s_sck_active &pri_mi2s_ws_active - &pri_mi2s_sd0_active &pri_mi2s_sd1_active - &pri_mi2s_sd2_active &pri_mi2s_sd3_active - &pri_mi2s_sd4_active &pri_mi2s_sd5_active - &pri_mi2s_sd6_active &pri_mi2s_sd7_active - &sec_mi2s_sck_active &sec_mi2s_ws_active - &sec_mi2s_sd0_active &sec_mi2s_sd1_active - &sec_mi2s_sd2_active &sec_mi2s_sd3_active>; + pinctrl-0 = <&spdifrx_opt_default>; }; &dai_mi2s0 { -- GitLab From 153a487ad5abc8bdf44a496199cf3ba02ad32c11 Mon Sep 17 00:00:00 2001 From: Yue Ma Date: Fri, 28 Jun 2019 14:35:23 -0700 Subject: [PATCH 0788/1121] cnss2: Use uninterruptible wait for idle shutdown/restart work Idle shutdown/restart work can be terminated by a signal from freezing user space which may cause unexpected behavior. Use uninterruptible wait for idle shutdown/restart work to avoid such case. Change-Id: Ic96a5ecc711d5d70bf81edf12b46b0d560bf7ad3 Signed-off-by: Yue Ma --- drivers/net/wireless/cnss2/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/cnss2/main.c b/drivers/net/wireless/cnss2/main.c index a1221dee7a24..aa5a561684d9 100644 --- a/drivers/net/wireless/cnss2/main.c +++ b/drivers/net/wireless/cnss2/main.c @@ -660,7 +660,7 @@ int cnss_idle_restart(struct device *dev) ret = cnss_driver_event_post(plat_priv, CNSS_DRIVER_EVENT_IDLE_RESTART, - CNSS_EVENT_SYNC, NULL); + CNSS_EVENT_SYNC_UNINTERRUPTIBLE, NULL); if (ret) goto out; @@ -714,7 +714,7 @@ int cnss_idle_shutdown(struct device *dev) skip_wait: return cnss_driver_event_post(plat_priv, CNSS_DRIVER_EVENT_IDLE_SHUTDOWN, - CNSS_EVENT_SYNC, NULL); + CNSS_EVENT_SYNC_UNINTERRUPTIBLE, NULL); } EXPORT_SYMBOL(cnss_idle_shutdown); -- GitLab From 9f461afe10dad1c89e033051f83a6e95aa1db0a6 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Fri, 19 Apr 2019 18:05:34 +0530 Subject: [PATCH 0789/1121] ARM: dts: qcom: Enable display driver node for trinket tasha and qrd DT change to enable display port driver for trinket tasha and qrd Change-Id: Ic750c926dda1788bbc1075d187cf87c9338d7f15 Signed-off-by: Vatsal Bucha --- arch/arm64/boot/dts/qcom/trinket-qrd.dtsi | 5 +++-- arch/arm64/boot/dts/qcom/trinket-tasha-codec.dtsi | 9 +++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/trinket-qrd.dtsi b/arch/arm64/boot/dts/qcom/trinket-qrd.dtsi index 84f5f479c6e8..6a4eecf616a3 100644 --- a/arch/arm64/boot/dts/qcom/trinket-qrd.dtsi +++ b/arch/arm64/boot/dts/qcom/trinket-qrd.dtsi @@ -368,8 +368,9 @@ qcom,wsa-aux-dev-prefix = "SpkrLeft", "SpkrLeft"; qcom,msm-mbhc-hphl-swh = <1>; qcom,msm-mbhc-gnd-swh = <1>; - asoc-codec = <&stub_codec>, <&bolero>; - asoc-codec-names = "msm-stub-codec.1", "bolero_codec"; + asoc-codec = <&stub_codec>, <&bolero>, <&ext_disp_audio_codec>; + asoc-codec-names = "msm-stub-codec.1", "bolero_codec", + "msm-ext-disp-audio-codec-rx"; qcom,codec-max-aux-devs = <1>; qcom,codec-aux-devs = <&wcd937x_codec>; qcom,msm_audio_ssr_devs = <&audio_apr>, <&q6core>, diff --git a/arch/arm64/boot/dts/qcom/trinket-tasha-codec.dtsi b/arch/arm64/boot/dts/qcom/trinket-tasha-codec.dtsi index 0276333f392d..94c4bba291fb 100644 --- a/arch/arm64/boot/dts/qcom/trinket-tasha-codec.dtsi +++ b/arch/arm64/boot/dts/qcom/trinket-tasha-codec.dtsi @@ -39,7 +39,7 @@ "msm-pcm-routing", "msm-compr-dsp", "msm-pcm-dsp-noirq", "msm-cpe-lsm", "msm-cpe-lsm.3"; - asoc-cpu = <&dai_mi2s0>, <&dai_mi2s1>, + asoc-cpu = <&dai_dp>, <&dai_mi2s0>, <&dai_mi2s1>, <&dai_mi2s2>, <&dai_mi2s3>, <&dai_mi2s4>, <&dai_pri_auxpcm>, <&dai_sec_auxpcm>, <&dai_tert_auxpcm>, <&dai_quat_auxpcm>, @@ -59,7 +59,8 @@ <&dai_tert_tdm_rx_0>, <&dai_tert_tdm_tx_0>, <&dai_quat_tdm_rx_0>, <&dai_quat_tdm_tx_0>, <&dai_quin_tdm_rx_0>, <&dai_quin_tdm_tx_0>; - asoc-cpu-names = "msm-dai-q6-mi2s.0", "msm-dai-q6-mi2s.1", + asoc-cpu-names = "msm-dai-q6-dp.24608", + "msm-dai-q6-mi2s.0", "msm-dai-q6-mi2s.1", "msm-dai-q6-mi2s.2", "msm-dai-q6-mi2s.3", "msm-dai-q6-mi2s.4", "msm-dai-q6-auxpcm.1", "msm-dai-q6-auxpcm.2", @@ -117,8 +118,8 @@ qcom,msm-mbhc-hphl-swh = <1>; qcom,msm-mbhc-gnd-swh = <1>; qcom,msm-mclk-freq = <9600000>; - asoc-codec = <&stub_codec>; - asoc-codec-names = "msm-stub-codec.1"; + asoc-codec = <&stub_codec>, <&ext_disp_audio_codec>; + asoc-codec-names = "msm-stub-codec.1", "msm-ext-disp-audio-codec-rx"; qcom,wsa-max-devs = <2>; qcom,wsa-devs = <&wsa881x_70212>, <&wsa881x_70211>, <&wsa881x_70214>, <&wsa881x_70213>; -- GitLab From 52677f542b9601227c2c0ddd73cf20dffa97f5d2 Mon Sep 17 00:00:00 2001 From: Zhiqiang Tu Date: Thu, 4 Jul 2019 16:22:55 +0800 Subject: [PATCH 0790/1121] ARM: dts: msm: Change irq number of virtio clock Change irq number of virtio clocks since there is conflict with smmu. Change-Id: Ia4ccc22707140228ebb3a959f52f36c2bd5af665 Signed-off-by: Zhiqiang Tu --- arch/arm64/boot/dts/qcom/sa8155-vm.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi b/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi index 2b18f9aa9242..7adb434d99ee 100644 --- a/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi @@ -32,7 +32,7 @@ clock_virt: qcom,virtio-gcc { compatible = "virtio,mmio"; reg = <0x1c200000 0x1000>; - interrupts = <0 100 0>; + interrupts = <0 48 0>; #clock-cells = <1>; #reset-cells = <1>; }; @@ -40,7 +40,7 @@ clock_virt_scc: qcom,virtio-scc { compatible = "virtio,mmio"; reg = <0x1c300000 0x1000>; - interrupts = <0 101 0>; + interrupts = <0 49 0>; #clock-cells = <1>; #reset-cells = <1>; }; -- GitLab From 5790a4904d29150735cef38d9be7a30fd53fcce7 Mon Sep 17 00:00:00 2001 From: Alok Pandey Date: Tue, 18 Jun 2019 23:59:42 +0530 Subject: [PATCH 0791/1121] msm: camera: isp: notify boot time stamp with precision This change makes boot time stamp independent of any delay caused due to irq or tasklet scheduling. Change-Id: I640c5a9c657c46c40e808b2c067546b4fd09ae8b Signed-off-by: Alok Pandey --- .../msm/camera/cam_isp/cam_isp_context.c | 32 +++++++--- .../msm/camera/cam_isp/cam_isp_context.h | 4 ++ .../cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c | 63 +++++++++---------- .../isp_hw/ife_csid_hw/cam_ife_csid_core.c | 16 ++++- .../isp_hw/ife_csid_hw/cam_ife_csid_core.h | 2 + 5 files changed, 74 insertions(+), 43 deletions(-) diff --git a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c index 3f6fa82adbbb..81addc8feac8 100644 --- a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c +++ b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c @@ -571,21 +571,24 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state( static void __cam_isp_ctx_send_sof_boot_timestamp( struct cam_isp_context *ctx_isp, uint64_t request_id, - uint32_t sof_event_status) + uint32_t sof_event_status, uint64_t delta_ts) { struct cam_req_mgr_message req_msg; req_msg.session_hdl = ctx_isp->base->session_hdl; req_msg.u.frame_msg.frame_id = ctx_isp->frame_id; req_msg.u.frame_msg.request_id = request_id; - req_msg.u.frame_msg.timestamp = ctx_isp->boot_timestamp; req_msg.u.frame_msg.link_hdl = ctx_isp->base->link_hdl; req_msg.u.frame_msg.sof_status = sof_event_status; + req_msg.u.frame_msg.timestamp = ctx_isp->prev_boot_timestamp + delta_ts; + CAM_DBG(CAM_ISP, - "request id:%lld frame number:%lld boot time stamp:0x%llx", - request_id, ctx_isp->frame_id, - ctx_isp->boot_timestamp); + "req id:%lld frame num:%lld bt_ts:0x%llx pre_bt_ts:0x%llx diff:0x%llx", + request_id, ctx_isp->frame_id, + ctx_isp->boot_timestamp, ctx_isp->prev_boot_timestamp, + delta_ts); + if (cam_req_mgr_notify_message(&req_msg, V4L_EVENT_CAM_REQ_MGR_SOF_BOOT_TS, @@ -593,6 +596,8 @@ static void __cam_isp_ctx_send_sof_boot_timestamp( CAM_ERR(CAM_ISP, "Error in notifying the boot time for req id:%lld", request_id); + + ctx_isp->prev_boot_timestamp = req_msg.u.frame_msg.timestamp; } @@ -601,6 +606,7 @@ static void __cam_isp_ctx_send_sof_timestamp( uint32_t sof_event_status) { struct cam_req_mgr_message req_msg; + uint64_t delta_ts; req_msg.session_hdl = ctx_isp->base->session_hdl; req_msg.u.frame_msg.frame_id = ctx_isp->frame_id; @@ -610,9 +616,9 @@ static void __cam_isp_ctx_send_sof_timestamp( req_msg.u.frame_msg.sof_status = sof_event_status; CAM_DBG(CAM_ISP, - "request id:%lld frame number:%lld SOF time stamp:0x%llx", + "request id:%lld frame number:%lld SOF time stamp:0x%llx, Prev SOF time:0x%llx", request_id, ctx_isp->frame_id, - ctx_isp->sof_timestamp_val); + ctx_isp->sof_timestamp_val, ctx_isp->prev_sof_timestamp_val); CAM_DBG(CAM_ISP, "sof status:%d", sof_event_status); if (cam_req_mgr_notify_message(&req_msg, @@ -620,9 +626,17 @@ static void __cam_isp_ctx_send_sof_timestamp( CAM_ERR(CAM_ISP, "Error in notifying the sof time for req id:%lld", request_id); + delta_ts = ctx_isp->sof_timestamp_val - + ctx_isp->prev_sof_timestamp_val; __cam_isp_ctx_send_sof_boot_timestamp(ctx_isp, - request_id, sof_event_status); + request_id, sof_event_status, + (ctx_isp->prev_sof_timestamp_val == 0) ? + ctx_isp->boot_timestamp : + delta_ts); + + ctx_isp->prev_sof_timestamp_val = + ctx_isp->sof_timestamp_val; } @@ -3383,6 +3397,8 @@ static int __cam_isp_ctx_stop_dev_in_activated_unlock( ctx_isp->req_info.last_applied_time_stamp = 0; ctx_isp->req_info.last_bufdone_time_stamp = 0; ctx_isp->req_info.last_reported_id_time_stamp = 0; + ctx_isp->prev_sof_timestamp_val = 0; + ctx_isp->prev_boot_timestamp = 0; atomic_set(&ctx_isp->process_bubble, 0); diff --git a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h index bec84a85391c..a4f4e5ae0ee9 100644 --- a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h +++ b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h @@ -165,7 +165,9 @@ struct cam_isp_context_req_id_info { * @req_isp: ISP private request object storage * @hw_ctx: HW object returned by the acquire device command * @sof_timestamp_val: Captured time stamp value at sof hw event + * @prev_sof_timestamp_val Holds last notified sof time stamp * @boot_timestamp: Boot time stamp for a given req_id + * @prev_boot_timestamp Holds last notified boot time stamp * @active_req_cnt: Counter for the active request * @subscribe_event: The irq event mask that CRM subscribes to, IFE * will invoke CRM cb at those event. @@ -194,7 +196,9 @@ struct cam_isp_context { void *hw_ctx; uint64_t sof_timestamp_val; + uint64_t prev_sof_timestamp_val; uint64_t boot_timestamp; + uint64_t prev_boot_timestamp; int32_t active_req_cnt; uint32_t subscribe_event; atomic64_t state_monitor_head; diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c index 3d394c69368f..1479941a272e 100644 --- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c @@ -4261,45 +4261,44 @@ static int cam_ife_mgr_cmd_get_sof_timestamp( struct cam_hw_intf *hw_intf; struct cam_csid_get_time_stamp_args csid_get_time; - list_for_each_entry(hw_mgr_res, &ife_ctx->res_list_ife_csid, list) { - for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { - if (!hw_mgr_res->hw_res[i]) - continue; + hw_mgr_res = list_first_entry(&ife_ctx->res_list_ife_csid, + struct cam_ife_hw_mgr_res, list); + for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { + if (!hw_mgr_res->hw_res[i]) + continue; + /* + * Get the SOF time stamp from left resource only. + * Left resource is master for dual vfe case and + * Rdi only context case left resource only hold + * the RDI resource + */ + + hw_intf = hw_mgr_res->hw_res[i]->hw_intf; + if (hw_intf->hw_ops.process_cmd) { /* - * Get the SOF time stamp from left resource only. - * Left resource is master for dual vfe case and - * Rdi only context case left resource only hold - * the RDI resource + * Single VFE case, Get the time stamp from + * available one csid hw in the context + * Dual VFE case, get the time stamp from + * master(left) would be sufficient */ - hw_intf = hw_mgr_res->hw_res[i]->hw_intf; - if (hw_intf->hw_ops.process_cmd) { - /* - * Single VFE case, Get the time stamp from - * available one csid hw in the context - * Dual VFE case, get the time stamp from - * master(left) would be sufficient - */ - - csid_get_time.node_res = - hw_mgr_res->hw_res[i]; - rc = hw_intf->hw_ops.process_cmd( - hw_intf->hw_priv, - CAM_IFE_CSID_CMD_GET_TIME_STAMP, - &csid_get_time, - sizeof( - struct cam_csid_get_time_stamp_args)); - if (!rc && (i == CAM_ISP_HW_SPLIT_LEFT)) { - *time_stamp = - csid_get_time.time_stamp_val; - *boot_time_stamp = - csid_get_time.boot_timestamp; - } + csid_get_time.node_res = + hw_mgr_res->hw_res[i]; + rc = hw_intf->hw_ops.process_cmd( + hw_intf->hw_priv, + CAM_IFE_CSID_CMD_GET_TIME_STAMP, + &csid_get_time, + sizeof( + struct cam_csid_get_time_stamp_args)); + if (!rc && (i == CAM_ISP_HW_SPLIT_LEFT)) { + *time_stamp = + csid_get_time.time_stamp_val; + *boot_time_stamp = + csid_get_time.boot_timestamp; } } } - if (rc) CAM_ERR(CAM_ISP, "Getting sof time stamp failed"); diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c index f4b91a4d844a..15d720a086a6 100644 --- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c +++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c @@ -467,6 +467,7 @@ static int cam_ife_csid_global_reset(struct cam_ife_csid_hw *csid_hw) CAM_ERR(CAM_ISP, "CSID:%d IRQ value after reset rc = %d", csid_hw->hw_intf->hw_idx, val); csid_hw->error_irq_count = 0; + csid_hw->first_sof_ts = 0; for (i = 0 ; i < CAM_IFE_PIX_PATH_RES_MAX; i++) csid_hw->res_sof_cnt[i] = 0; @@ -1168,6 +1169,7 @@ static int cam_ife_csid_disable_hw(struct cam_ife_csid_hw *csid_hw) csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN; csid_hw->error_irq_count = 0; + csid_hw->first_sof_ts = 0; return rc; } @@ -2455,9 +2457,16 @@ static int cam_ife_csid_get_time_stamp( CAM_IFE_CSID_QTIMER_MUL_FACTOR, CAM_IFE_CSID_QTIMER_DIV_FACTOR); - get_monotonic_boottime64(&ts); - time_stamp->boot_timestamp = (uint64_t)((ts.tv_sec * 1000000000) + - ts.tv_nsec); + if (!csid_hw->first_sof_ts) { + get_monotonic_boottime64(&ts); + time_stamp->boot_timestamp = + (uint64_t)((ts.tv_sec * 1000000000) + + ts.tv_nsec); + CAM_DBG(CAM_ISP, "timestamp:%lld", + time_stamp->boot_timestamp); + csid_hw->first_sof_ts = 1; + } else + time_stamp->boot_timestamp = 0; return 0; } @@ -3739,6 +3748,7 @@ int cam_ife_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf, ife_csid_hw->csid_debug = 0; ife_csid_hw->error_irq_count = 0; + ife_csid_hw->first_sof_ts = 0; return 0; err: diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h index 600deb245f32..9b4d5c3d6add 100644 --- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h +++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h @@ -480,6 +480,7 @@ struct cam_ife_csid_path_cfg { * @init_frame_drop Initial frame drop number * @res_sof_cnt path resource sof count value. it used for initial * frame drop + * @first_sof_ts flag to mark the first sof has been registered * */ struct cam_ife_csid_hw { @@ -511,6 +512,7 @@ struct cam_ife_csid_hw { uint32_t dual_usage; uint32_t init_frame_drop; uint32_t res_sof_cnt[CAM_IFE_PIX_PATH_RES_MAX]; + uint32_t first_sof_ts; }; int cam_ife_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf, -- GitLab From c98acfd7b5480ade687fa1940cb33ca7ef9806cd Mon Sep 17 00:00:00 2001 From: Sunil Paidimarri Date: Thu, 4 Jul 2019 04:16:49 -0700 Subject: [PATCH 0792/1121] ARM: dts: msm: update the phy interrupt in sdxprairie On sdxprairie phy interrupt is connected to gpio90, update the dtsi accordingly. Change-Id: I3bd307c2c2e70a5e26900d773d0a49ad7b144b54 Signed-off-by: Sunil Paidimarri --- arch/arm64/boot/dts/qcom/sdxprairie.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sdxprairie.dtsi b/arch/arm64/boot/dts/qcom/sdxprairie.dtsi index f232aff1f166..670eb35e660b 100644 --- a/arch/arm64/boot/dts/qcom/sdxprairie.dtsi +++ b/arch/arm64/boot/dts/qcom/sdxprairie.dtsi @@ -1461,7 +1461,7 @@ 0x0007c 0x4e /* PORT0_STATUS */ 0x00094 0x4e /* PORT6_STATUS */ >; - qcom,link-intr-gpio = <84>; + qcom,link-intr-gpio = <90>; qcom,switch-cpu-bmp = <0x01>; /* cpu port bitmap */ qcom,switch-lan-bmp = <0x3e>; /* lan port bitmap */ qcom,switch-wan-bmp = <0x0>; /* wan port bitmap */ -- GitLab From 72893a4ba26b5c9b465ac9cfad83e28b2e7a44aa Mon Sep 17 00:00:00 2001 From: Rama Krishna Phani A Date: Mon, 3 Jun 2019 19:41:33 +0530 Subject: [PATCH 0793/1121] ARM: dts: msm: add initial MHI devicetree node for QCS405 Add initial devicetree node to support MHI based devices over PCIe on QCS405. Change-Id: I609a4d22303db37555f0ad323649516ac823160a Signed-off-by: Rama Krishna Phani A --- arch/arm64/boot/dts/qcom/qcs405-mhi.dtsi | 716 ++++++++++++++++++++++ arch/arm64/boot/dts/qcom/qcs405-pcie.dtsi | 7 + arch/arm64/boot/dts/qcom/qcs405.dtsi | 8 + 3 files changed, 731 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/qcs405-mhi.dtsi diff --git a/arch/arm64/boot/dts/qcom/qcs405-mhi.dtsi b/arch/arm64/boot/dts/qcom/qcs405-mhi.dtsi new file mode 100644 index 000000000000..12ba814820f3 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs405-mhi.dtsi @@ -0,0 +1,716 @@ +/* + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&pcie_rc0 { + reg = <0 0 0 0 0>; + + mhi_0: qcom,mhi@0 { + reg = <0 0 0 0 0 >; + + pci-ids = "17cb:0304"; + + /* controller specific configuration */ + qcom,smmu-cfg = <0x0>; + qcom,msm-bus,name = "mhi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <45 512 0 0>, + <45 512 1200000000 650000000>; + + /* mhi bus specific settings */ + mhi,max-channels = <110>; + mhi,timeout = <2000>; + + mhi_channels { + #address-cells = <1>; + #size-cells = <0>; + mhi_chan@0 { + reg = <0>; + label = "LOOPBACK"; + mhi,num-elements = <64>; + mhi,event-ring = <2>; + mhi,chan-dir = <1>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x4>; + }; + + mhi_chan@1 { + reg = <1>; + label = "LOOPBACK"; + mhi,num-elements = <64>; + mhi,event-ring = <2>; + mhi,chan-dir = <2>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x4>; + }; + + mhi_chan@4 { + reg = <4>; + label = "DIAG"; + mhi,num-elements = <64>; + mhi,event-ring = <1>; + mhi,chan-dir = <1>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x4>; + }; + + mhi_chan@5 { + reg = <5>; + label = "DIAG"; + mhi,num-elements = <64>; + mhi,event-ring = <3>; + mhi,chan-dir = <2>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x4>; + }; + + mhi_chan@14 { + reg = <14>; + label = "QMI0"; + mhi,num-elements = <64>; + mhi,event-ring = <1>; + mhi,chan-dir = <1>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x4>; + }; + + mhi_chan@15 { + reg = <15>; + label = "QMI0"; + mhi,num-elements = <64>; + mhi,event-ring = <2>; + mhi,chan-dir = <2>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x4>; + }; + + mhi_chan@16 { + reg = <16>; + label = "QMI1"; + mhi,num-elements = <64>; + mhi,event-ring = <3>; + mhi,chan-dir = <1>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x4>; + }; + + mhi_chan@17 { + reg = <17>; + label = "QMI1"; + mhi,num-elements = <64>; + mhi,event-ring = <3>; + mhi,chan-dir = <2>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x4>; + }; + + mhi_chan@20 { + reg = <20>; + label = "IPCR"; + mhi,num-elements = <64>; + mhi,event-ring = <2>; + mhi,chan-dir = <1>; + mhi,data-type = <1>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x4>; + mhi,auto-start; + }; + + mhi_chan@21 { + reg = <21>; + label = "IPCR"; + mhi,num-elements = <64>; + mhi,event-ring = <2>; + mhi,chan-dir = <2>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x4>; + mhi,auto-queue; + mhi,auto-start; + }; + + mhi_chan@32 { + reg = <32>; + label = "DUN"; + mhi,num-elements = <64>; + mhi,event-ring = <3>; + mhi,chan-dir = <1>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x4>; + }; + + mhi_chan@33 { + reg = <33>; + label = "DUN"; + mhi,num-elements = <64>; + mhi,event-ring = <3>; + mhi,chan-dir = <2>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x4>; + }; + + mhi_chan@46 { + reg = <46>; + label = "IP_SW_0"; + mhi,num-elements = <512>; + mhi,event-ring = <4>; + mhi,chan-dir = <1>; + mhi,data-type = <1>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x4>; + }; + + mhi_chan@47 { + reg = <47>; + label = "IP_SW_0"; + mhi,num-elements = <512>; + mhi,event-ring = <5>; + mhi,chan-dir = <2>; + mhi,data-type = <4>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x4>; + }; + + mhi_chan@100 { + reg = <100>; + label = "IP_HW0"; + mhi,num-elements = <512>; + mhi,event-ring = <6>; + mhi,chan-dir = <1>; + mhi,data-type = <1>; + mhi,doorbell-mode = <3>; + mhi,ee = <0x4>; + mhi,db-mode-switch; + }; + + mhi_chan@101 { + reg = <101>; + label = "IP_HW0"; + mhi,num-elements = <512>; + mhi,event-ring = <7>; + mhi,chan-dir = <2>; + mhi,data-type = <4>; + mhi,doorbell-mode = <3>; + mhi,ee = <0x4>; + }; + + mhi_chan@105 { + reg = <105>; + label = "IP_HW1"; + mhi,num-elements = <512>; + mhi,event-ring = <8>; + mhi,chan-dir = <1>; + mhi,data-type = <1>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x4>; + }; + + mhi_chan@106 { + reg = <106>; + label = "IP_HW1"; + mhi,num-elements = <512>; + mhi,event-ring = <9>; + mhi,chan-dir = <2>; + mhi,data-type = <4>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x4>; + }; + }; + + mhi_events { + mhi_event@0 { + mhi,num-elements = <32>; + mhi,intmod = <1>; + mhi,msi = <1>; + mhi,priority = <1>; + mhi,brstmode = <2>; + mhi,data-type = <1>; + }; + + mhi_event@1 { + mhi,num-elements = <256>; + mhi,intmod = <1>; + mhi,msi = <2>; + mhi,priority = <1>; + mhi,brstmode = <2>; + }; + + mhi_event@2 { + mhi,num-elements = <256>; + mhi,intmod = <1>; + mhi,msi = <3>; + mhi,priority = <1>; + mhi,brstmode = <2>; + }; + + mhi_event@3 { + mhi,num-elements = <256>; + mhi,intmod = <1>; + mhi,msi = <4>; + mhi,priority = <1>; + mhi,brstmode = <2>; + }; + + mhi_event@4 { + mhi,num-elements = <1024>; + mhi,intmod = <5>; + mhi,msi = <5>; + mhi,chan = <46>; + mhi,priority = <1>; + mhi,brstmode = <2>; + }; + + mhi_event@5 { + mhi,num-elements = <1024>; + mhi,intmod = <5>; + mhi,msi = <6>; + mhi,chan = <47>; + mhi,priority = <1>; + mhi,brstmode = <2>; + mhi,client-manage; + }; + + mhi_event@6 { + mhi,num-elements = <1024>; + mhi,intmod = <5>; + mhi,msi = <5>; + mhi,chan = <100>; + mhi,priority = <1>; + mhi,brstmode = <3>; + mhi,hw-ev; + }; + + mhi_event@7 { + mhi,num-elements = <1024>; + mhi,intmod = <5>; + mhi,msi = <6>; + mhi,chan = <101>; + mhi,priority = <1>; + mhi,brstmode = <3>; + mhi,hw-ev; + mhi,client-manage; + }; + + mhi_event@8 { + mhi,num-elements = <1024>; + mhi,intmod = <0>; + mhi,msi = <7>; + mhi,chan = <105>; + mhi,priority = <1>; + mhi,brstmode = <2>; + mhi,hw-ev; + }; + + mhi_event@9 { + mhi,num-elements = <1024>; + mhi,intmod = <0>; + mhi,msi = <8>; + mhi,chan = <106>; + mhi,priority = <1>; + mhi,brstmode = <2>; + mhi,hw-ev; + mhi,client-manage; + }; + }; + + mhi_devices { + #address-cells = <1>; + #size-cells = <0>; + mhi_netdev_0: mhi_rmnet@0 { + reg = <0x0>; + mhi,chan = "IP_HW0"; + mhi,interface-name = "rmnet_mhi"; + mhi,mru = <0x8000>; + mhi,disable-chain-skb; + }; + + mhi_netdev_1: mhi_rmnet@1 { + reg = <0x1>; + mhi,chan = "IP_HW1"; + mhi,interface-name = "rmnet_mhi"; + mhi,mru = <0x8000>; + mhi,disable-chain-skb; + }; + + mhi_netdev_2: mhi_rmnet@2 { + reg = <0x2>; + mhi,chan = "IP_SW_0"; + mhi,interface-name = "mhi_swip"; + mhi,mru = <0x4000>; + mhi,ethernet-interface; + mhi,disable-chain-skb; + }; + }; + }; + + mhi_1: qcom,mhi@1 { + reg = <0 0 0 0 0 >; + + pci-ids = "17cb:0306"; + + /* controller specific configuration */ + qcom,smmu-cfg = <0x0>; + qcom,msm-bus,name = "mhi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <45 512 0 0>, + <45 512 1200000000 650000000>; + + /* mhi bus specific settings */ + mhi,max-channels = <110>; + mhi,timeout = <2000>; + + mhi_channels { + #address-cells = <1>; + #size-cells = <0>; + mhi_chan@0 { + reg = <0>; + label = "LOOPBACK"; + mhi,num-elements = <64>; + mhi,event-ring = <2>; + mhi,chan-dir = <1>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x4>; + }; + + mhi_chan@1 { + reg = <1>; + label = "LOOPBACK"; + mhi,num-elements = <64>; + mhi,event-ring = <2>; + mhi,chan-dir = <2>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x4>; + }; + + mhi_chan@4 { + reg = <4>; + label = "DIAG"; + mhi,num-elements = <64>; + mhi,event-ring = <1>; + mhi,chan-dir = <1>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x4>; + }; + + mhi_chan@5 { + reg = <5>; + label = "DIAG"; + mhi,num-elements = <64>; + mhi,event-ring = <3>; + mhi,chan-dir = <2>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x4>; + }; + + mhi_chan@14 { + reg = <14>; + label = "QMI0"; + mhi,num-elements = <64>; + mhi,event-ring = <1>; + mhi,chan-dir = <1>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x4>; + }; + + mhi_chan@15 { + reg = <15>; + label = "QMI0"; + mhi,num-elements = <64>; + mhi,event-ring = <2>; + mhi,chan-dir = <2>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x4>; + }; + + mhi_chan@16 { + reg = <16>; + label = "QMI1"; + mhi,num-elements = <64>; + mhi,event-ring = <3>; + mhi,chan-dir = <1>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x4>; + }; + + mhi_chan@17 { + reg = <17>; + label = "QMI1"; + mhi,num-elements = <64>; + mhi,event-ring = <3>; + mhi,chan-dir = <2>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x4>; + }; + + mhi_chan@20 { + reg = <20>; + label = "IPCR"; + mhi,num-elements = <64>; + mhi,event-ring = <2>; + mhi,chan-dir = <1>; + mhi,data-type = <1>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x4>; + mhi,auto-start; + }; + + mhi_chan@21 { + reg = <21>; + label = "IPCR"; + mhi,num-elements = <64>; + mhi,event-ring = <2>; + mhi,chan-dir = <2>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x4>; + mhi,auto-queue; + mhi,auto-start; + }; + + mhi_chan@32 { + reg = <32>; + label = "DUN"; + mhi,num-elements = <64>; + mhi,event-ring = <3>; + mhi,chan-dir = <1>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x4>; + }; + + mhi_chan@33 { + reg = <33>; + label = "DUN"; + mhi,num-elements = <64>; + mhi,event-ring = <3>; + mhi,chan-dir = <2>; + mhi,data-type = <0>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x4>; + }; + + mhi_chan@46 { + reg = <46>; + label = "IP_SW_0"; + mhi,num-elements = <512>; + mhi,event-ring = <4>; + mhi,chan-dir = <1>; + mhi,data-type = <1>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x4>; + }; + + mhi_chan@47 { + reg = <47>; + label = "IP_SW_0"; + mhi,num-elements = <512>; + mhi,event-ring = <5>; + mhi,chan-dir = <2>; + mhi,data-type = <4>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x4>; + }; + + mhi_chan@100 { + reg = <100>; + label = "IP_HW0"; + mhi,num-elements = <512>; + mhi,event-ring = <6>; + mhi,chan-dir = <1>; + mhi,data-type = <1>; + mhi,doorbell-mode = <3>; + mhi,ee = <0x4>; + mhi,db-mode-switch; + }; + + mhi_chan@101 { + reg = <101>; + label = "IP_HW0"; + mhi,num-elements = <512>; + mhi,event-ring = <7>; + mhi,chan-dir = <2>; + mhi,data-type = <4>; + mhi,doorbell-mode = <3>; + mhi,ee = <0x4>; + }; + + mhi_chan@105 { + reg = <105>; + label = "IP_HW1"; + mhi,num-elements = <512>; + mhi,event-ring = <8>; + mhi,chan-dir = <1>; + mhi,data-type = <1>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x4>; + }; + + mhi_chan@106 { + reg = <106>; + label = "IP_HW1"; + mhi,num-elements = <512>; + mhi,event-ring = <9>; + mhi,chan-dir = <2>; + mhi,data-type = <4>; + mhi,doorbell-mode = <2>; + mhi,ee = <0x4>; + }; + }; + + mhi_events { + mhi_event@0 { + mhi,num-elements = <32>; + mhi,intmod = <1>; + mhi,msi = <1>; + mhi,priority = <1>; + mhi,brstmode = <2>; + mhi,data-type = <1>; + }; + + mhi_event@1 { + mhi,num-elements = <256>; + mhi,intmod = <1>; + mhi,msi = <2>; + mhi,priority = <1>; + mhi,brstmode = <2>; + }; + + mhi_event@2 { + mhi,num-elements = <256>; + mhi,intmod = <1>; + mhi,msi = <3>; + mhi,priority = <1>; + mhi,brstmode = <2>; + }; + + mhi_event@3 { + mhi,num-elements = <256>; + mhi,intmod = <1>; + mhi,msi = <4>; + mhi,priority = <1>; + mhi,brstmode = <2>; + }; + + mhi_event@4 { + mhi,num-elements = <1024>; + mhi,intmod = <5>; + mhi,msi = <5>; + mhi,chan = <46>; + mhi,priority = <1>; + mhi,brstmode = <2>; + }; + + mhi_event@5 { + mhi,num-elements = <1024>; + mhi,intmod = <5>; + mhi,msi = <6>; + mhi,chan = <47>; + mhi,priority = <1>; + mhi,brstmode = <2>; + mhi,client-manage; + }; + + mhi_event@6 { + mhi,num-elements = <1024>; + mhi,intmod = <5>; + mhi,msi = <5>; + mhi,chan = <100>; + mhi,priority = <1>; + mhi,brstmode = <3>; + mhi,hw-ev; + }; + + mhi_event@7 { + mhi,num-elements = <1024>; + mhi,intmod = <5>; + mhi,msi = <6>; + mhi,chan = <101>; + mhi,priority = <1>; + mhi,brstmode = <3>; + mhi,hw-ev; + mhi,client-manage; + }; + + mhi_event@8 { + mhi,num-elements = <1024>; + mhi,intmod = <0>; + mhi,msi = <7>; + mhi,chan = <105>; + mhi,priority = <1>; + mhi,brstmode = <2>; + mhi,hw-ev; + }; + + mhi_event@9 { + mhi,num-elements = <1024>; + mhi,intmod = <0>; + mhi,msi = <8>; + mhi,chan = <106>; + mhi,priority = <1>; + mhi,brstmode = <2>; + mhi,hw-ev; + mhi,client-manage; + }; + }; + + mhi_devices { + #address-cells = <1>; + #size-cells = <0>; + mhi_netdev_3: mhi_rmnet@0 { + reg = <0x0>; + mhi,chan = "IP_HW0"; + mhi,interface-name = "rmnet_mhi"; + mhi,mru = <0x8000>; + mhi,disable-chain-skb; + }; + + mhi_netdev_4: mhi_rmnet@1 { + reg = <0x1>; + mhi,chan = "IP_HW1"; + mhi,interface-name = "rmnet_mhi"; + mhi,mru = <0x8000>; + mhi,disable-chain-skb; + }; + + mhi_netdev_5: mhi_rmnet@2 { + reg = <0x2>; + mhi,chan = "IP_SW_0"; + mhi,interface-name = "mhi_swip"; + mhi,mru = <0x4000>; + mhi,ethernet-interface; + mhi,disable-chain-skb; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/qcs405-pcie.dtsi b/arch/arm64/boot/dts/qcom/qcs405-pcie.dtsi index bda2e511a766..dfd3ebedc0a2 100644 --- a/arch/arm64/boot/dts/qcom/qcs405-pcie.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs405-pcie.dtsi @@ -115,6 +115,13 @@ clock-output-names = "pcie_0_pipe_clk"; resets = <&clock_gcc GCC_PCIEPHY_0_PHY_BCR>; reset-names = "pcie_0_phy_reset"; + + pcie_rc0: pcie_rc0 { + #address-cells = <5>; + #size-cells = <0>; + reg = <0 0 0 0 0>; + pci-ids = "17cb:1000"; + }; }; pcie0_msi: qcom,pcie0_msi@a0000000 { diff --git a/arch/arm64/boot/dts/qcom/qcs405.dtsi b/arch/arm64/boot/dts/qcom/qcs405.dtsi index a8639eb4ec0c..d9187013e918 100644 --- a/arch/arm64/boot/dts/qcom/qcs405.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs405.dtsi @@ -139,6 +139,13 @@ sdhc2 = &sdhc_2; /* SDC2 SD Card slot */ qpic_nand1 = &qnand_1; pci-domain0 = &pcie0; /* PCIe0 domain */ + mhi0 = &mhi_0; + mhi_netdev0 = &mhi_netdev_0; + mhi_netdev1 = &mhi_netdev_1; + mhi_netdev2 = &mhi_netdev_2; + mhi_netdev3 = &mhi_netdev_3; + mhi_netdev4 = &mhi_netdev_4; + mhi_netdev5 = &mhi_netdev_5; }; soc: soc { }; @@ -1536,6 +1543,7 @@ #include "qcs405-coresight.dtsi" #include "qcs405-usb.dtsi" #include "qcs405-pcie.dtsi" +#include "qcs405-mhi.dtsi" &i2c_5 { smb1351_otg_supply: smb1351-charger@55 { -- GitLab From b8579e135e2ef0adae7d6cd5b52b0e3d2305746f Mon Sep 17 00:00:00 2001 From: Pradeep P V K Date: Thu, 20 Jun 2019 19:26:13 +0530 Subject: [PATCH 0794/1121] ARM: dts: msm: Supply dll-hsr settings for sdhc on sdxprairie Supply dll-hsr setiings for SD card on sdxprairie. Change-Id: Id5277b3e218386dd93ae27bb18d3da9fe245bdc6 Signed-off-by: Pradeep P V K --- arch/arm64/boot/dts/qcom/sdxprairie.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdxprairie.dtsi b/arch/arm64/boot/dts/qcom/sdxprairie.dtsi index f232aff1f166..d3a292b39ce2 100644 --- a/arch/arm64/boot/dts/qcom/sdxprairie.dtsi +++ b/arch/arm64/boot/dts/qcom/sdxprairie.dtsi @@ -1349,6 +1349,10 @@ qcom,restore-after-cx-collapse; + /* DLL HSR settings. Refer go/hsr - DLL settings */ + qcom,dll-hsr-list = <0x0007642c 0xa800 0x10 + 0x2c010800 0x80040868>; + status = "disabled"; }; -- GitLab From 11245d7e5154f00e5bd3d56f2b7c2adfae95586f Mon Sep 17 00:00:00 2001 From: "Thomas (Wonyoung) Yun" Date: Thu, 20 Jun 2019 15:22:48 -0400 Subject: [PATCH 0795/1121] msm: kgsl: Program sub-cache ID for SC8180 Require to program GBIF_SCACHE_CNTL1 register for gpu SCID. Change-Id: Ic61f34d49103be7a297a1870e0bf372aa888860a Signed-off-by: Thomas (Wonyoung) Yun --- drivers/gpu/msm/adreno_a6xx.c | 6 +++--- drivers/gpu/msm/kgsl_iommu.c | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/msm/adreno_a6xx.c b/drivers/gpu/msm/adreno_a6xx.c index 0ec46c177efb..d8efd3e4f9f0 100644 --- a/drivers/gpu/msm/adreno_a6xx.c +++ b/drivers/gpu/msm/adreno_a6xx.c @@ -1628,7 +1628,7 @@ static void a6xx_llc_configure_gpu_scid(struct adreno_device *adreno_dev) | gpu_scid; if (adreno_is_a640(adreno_dev) || adreno_is_a612(adreno_dev) || - adreno_is_a610(adreno_dev)) { + adreno_is_a610(adreno_dev) || adreno_is_a680(adreno_dev)) { kgsl_regrmw(KGSL_DEVICE(adreno_dev), A6XX_GBIF_SCACHE_CNTL1, A6XX_GPU_LLC_SCID_MASK, gpu_cntl1_val); } else { @@ -1651,7 +1651,7 @@ static void a6xx_llc_configure_gpuhtw_scid(struct adreno_device *adreno_dev) * XBL image. */ if (adreno_is_a640(adreno_dev) || adreno_is_a612(adreno_dev) || - adreno_is_a610(adreno_dev)) + adreno_is_a610(adreno_dev) || adreno_is_a680(adreno_dev)) return; gpuhtw_scid = adreno_llc_get_scid(adreno_dev->gpuhtw_llc_slice); @@ -1673,7 +1673,7 @@ static void a6xx_llc_enable_overrides(struct adreno_device *adreno_dev) * Attributes are used as configured through SMMU pagetable entries. */ if (adreno_is_a640(adreno_dev) || adreno_is_a612(adreno_dev) || - adreno_is_a610(adreno_dev)) + adreno_is_a610(adreno_dev) || adreno_is_a680(adreno_dev)) return; /* diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c index af617e70f1f1..6a387eca1d3c 100644 --- a/drivers/gpu/msm/kgsl_iommu.c +++ b/drivers/gpu/msm/kgsl_iommu.c @@ -1192,7 +1192,8 @@ void _enable_gpuhtw_llc(struct kgsl_mmu *mmu, struct kgsl_iommu_pt *iommu_pt) return; /* Domain attribute to enable system cache for GPU pagetable walks */ - if (adreno_is_a640(adreno_dev) || adreno_is_a612(adreno_dev)) + if (adreno_is_a640(adreno_dev) || adreno_is_a612(adreno_dev) || + adreno_is_a680(adreno_dev)) ret = iommu_domain_set_attr(iommu_pt->domain, DOMAIN_ATTR_USE_LLC_NWA, &gpuhtw_llc_enable); else -- GitLab From 309c4081b2da47e4fc0e5990deddab01f13985fc Mon Sep 17 00:00:00 2001 From: Sriharsha Allenki Date: Fri, 5 Jul 2019 10:23:02 +0530 Subject: [PATCH 0796/1121] ARM: dts: msm: Add parameter override for SDXPRAIRIE Add parameter override sequence to override the default X1 parameter to 0x43 to improve the eye diagram of High speed compliance results. Change-Id: Idffed587fd15cd20fc1f408028aa7742050fc85a Signed-off-by: Sriharsha Allenki --- arch/arm64/boot/dts/qcom/sdxprairie-usb.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/qcom/sdxprairie-usb.dtsi b/arch/arm64/boot/dts/qcom/sdxprairie-usb.dtsi index 5ba14bdda6b0..83d05b8dc091 100644 --- a/arch/arm64/boot/dts/qcom/sdxprairie-usb.dtsi +++ b/arch/arm64/boot/dts/qcom/sdxprairie-usb.dtsi @@ -145,6 +145,7 @@ resets = <&clock_gcc GCC_QUSB2PHY_BCR>; reset-names = "phy_reset"; + qcom,param-override-seq = <0x43 0x70>; qcom,no-rext-present; }; -- GitLab From b07be3d6ddaf0c66cf23f2c864c2377a5634f238 Mon Sep 17 00:00:00 2001 From: jiad Date: Fri, 5 Jul 2019 17:03:59 +0800 Subject: [PATCH 0797/1121] cnss2: set iova_start and iova_stop to 0 Set iova_start and iova_stop to 0 when SMMU S1 is not enabled. Change-Id: I37fe32db5bed8b741c0ba2f2657ae6b13d9c0f12 Signed-off-by: jiad --- drivers/net/wireless/cnss2/pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/cnss2/pci.c b/drivers/net/wireless/cnss2/pci.c index bba2189d01a7..193dd20c036d 100644 --- a/drivers/net/wireless/cnss2/pci.c +++ b/drivers/net/wireless/cnss2/pci.c @@ -2714,8 +2714,8 @@ static int cnss_pci_register_mhi(struct cnss_pci_data *pci_priv) mhi_ctrl->iova_stop = pci_priv->smmu_iova_start + pci_priv->smmu_iova_len; } else { - mhi_ctrl->iova_start = memblock_start_of_DRAM(); - mhi_ctrl->iova_stop = memblock_end_of_DRAM(); + mhi_ctrl->iova_start = 0; + mhi_ctrl->iova_stop = 0; } mhi_ctrl->link_status = cnss_mhi_link_status; -- GitLab From ddf032eac1571c1b88a2360aa0d4510422309b8c Mon Sep 17 00:00:00 2001 From: Shravan Nevatia Date: Fri, 21 Jun 2019 18:08:26 +0530 Subject: [PATCH 0798/1121] msm: camera: csiphy: Support multiple data rates in CSIPHY for sm6150 Dynamically set the csiphy settings using CDR mask registers for multiple data rates. Change-Id: I39ff8099468bb308f109c02115a93006fae93ab3 Signed-off-by: Shravan Nevatia --- .../cam_csiphy/cam_csiphy_soc.c | 5 ++-- .../cam_csiphy/include/cam_csiphy_1_2_hwreg.h | 2 +- .../cam_csiphy/include/cam_csiphy_2_0_hwreg.h | 28 +++++++++++++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c index 0bf5aac2f090..416cb2a9fa96 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c @@ -272,7 +272,7 @@ int32_t cam_csiphy_parse_dt_info(struct platform_device *pdev, csiphy_dev->hw_version = CSIPHY_VERSION_V12; csiphy_dev->clk_lane = 0; csiphy_dev->ctrl_reg->data_rates_settings_table = - &data_rate_delta_table; + &data_rate_delta_table_1_2; } else if (of_device_is_compatible(soc_info->dev->of_node, "qcom,csiphy-v2.0")) { csiphy_dev->ctrl_reg->csiphy_2ph_reg = csiphy_2ph_v2_0_reg; @@ -288,7 +288,8 @@ int32_t cam_csiphy_parse_dt_info(struct platform_device *pdev, csiphy_dev->hw_version = CSIPHY_VERSION_V20; csiphy_dev->is_csiphy_3phase_hw = CSI_3PHASE_HW; csiphy_dev->clk_lane = 0; - csiphy_dev->ctrl_reg->data_rates_settings_table = NULL; + csiphy_dev->ctrl_reg->data_rates_settings_table = + &data_rate_delta_table_2_0; } else { CAM_ERR(CAM_CSIPHY, "invalid hw version : 0x%x", csiphy_dev->hw_version); diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h index edde07091d9e..ac113d613fce 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h @@ -430,7 +430,7 @@ csiphy_reg_t csiphy_3ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { }, }; -struct data_rate_settings_t data_rate_delta_table = { +struct data_rate_settings_t data_rate_delta_table_1_2 = { .num_data_rate_settings = 3, .data_rate_settings = { { diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_2_0_hwreg.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_2_0_hwreg.h index b7345d4abeeb..e64a5da74260 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_2_0_hwreg.h +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_2_0_hwreg.h @@ -297,4 +297,32 @@ struct csiphy_reg_t csiphy_3ph_v2_0_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { }, }; +struct data_rate_settings_t data_rate_delta_table_2_0 = { + .num_data_rate_settings = 2, + .data_rate_settings = { + { + // data rate <= 2 Gsps + // max bandwidth = 2 * 2.28 * (10**3) Mbps + .bandwidth = 4560000000, + .data_rate_reg_array_size = 3, + .csiphy_data_rate_regs = { + {0x0164, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0364, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0564, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS} + } + }, + { + // 2 Gsps <= data rate <= 2.5 Gsps + // max bandwidth = 2.5 * 2.28 * (10**3) Mbps + .bandwidth = 5700000000, + .data_rate_reg_array_size = 3, + .csiphy_data_rate_regs = { + {0x0164, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0364, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0564, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS} + } + } + } +}; + #endif /* _CAM_CSIPHY_2_0_HWREG_H_ */ -- GitLab From e56c3232fb5efc330dfed830f7d305b0996b7e8d Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Mon, 1 Jul 2019 17:09:33 +0530 Subject: [PATCH 0799/1121] ARM: dts: msm: Add video device node for atoll Add video device node for atoll. Change-Id: I5880b9cf81ed3115cc551b93321f40485105b73d Signed-off-by: Dikshita Agarwal --- arch/arm64/boot/dts/qcom/atoll-vidc.dtsi | 106 +++++++++++++++++++++++ arch/arm64/boot/dts/qcom/atoll.dtsi | 1 + 2 files changed, 107 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/atoll-vidc.dtsi diff --git a/arch/arm64/boot/dts/qcom/atoll-vidc.dtsi b/arch/arm64/boot/dts/qcom/atoll-vidc.dtsi new file mode 100644 index 000000000000..24e21d0080ca --- /dev/null +++ b/arch/arm64/boot/dts/qcom/atoll-vidc.dtsi @@ -0,0 +1,106 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include + +&soc { + msm_vidc: qcom,vidc@aa00000 { + compatible = "qcom,msm-vidc", "qcom,atoll"; + status = "ok"; + reg = <0xaa00000 0x200000>; + interrupts = ; + + /* Supply */ + venus-supply = <&venus_gdsc>; + venus-core0-supply = <&vcodec0_gdsc>; + + /* Clocks */ + clock-names = "core_clk", "iface_clk", "bus_clk", + "core0_clk", "core0_bus_clk"; + clocks = <&clock_videocc VIDEO_CC_VENUS_CTL_CORE_CLK>, + <&clock_videocc VIDEO_CC_VENUS_AHB_CLK>, + <&clock_videocc VIDEO_CC_VENUS_CTL_AXI_CLK>, + <&clock_videocc VIDEO_CC_VCODEC0_CORE_CLK>, + <&clock_videocc VIDEO_CC_VCODEC0_AXI_CLK>; + qcom,proxy-clock-names = "core_clk", "iface_clk", + "bus_clk", "core0_clk", "core0_bus_clk"; + qcom,clock-configs = <0x1 0x0 0x0 0x1 0x0>; + qcom,allowed-clock-rates = <150000000 270000000 340000000 + 434000000>; + + /* Buses */ + bus_cnoc { + compatible = "qcom,msm-vidc,bus"; + label = "cnoc"; + qcom,bus-master = ; + qcom,bus-slave = ; + qcom,bus-governor = "performance"; + qcom,bus-range-kbps = <1000 1000>; + }; + + venus_bus_ddr { + compatible = "qcom,msm-vidc,bus"; + label = "venus-ddr"; + qcom,bus-master = ; + qcom,bus-slave = ; + qcom,bus-governor = "vidc-ar50-ddr"; + qcom,bus-range-kbps = <1000 2128000>; + }; + arm9_bus_ddr { + compatible = "qcom,msm-vidc,bus"; + label = "venus-arm9-ddr"; + qcom,bus-master = ; + qcom,bus-slave = ; + qcom,bus-governor = "performance"; + qcom,bus-range-kbps = <1000 1000>; + }; + + /* MMUs */ + non_secure_cb { + compatible = "qcom,msm-vidc,context-bank"; + label = "venus_ns"; + iommus = <&apps_smmu 0xC00 0x60>; + buffer-types = <0xfff>; + virtual-addr-pool = <0x70800000 0x6f800000>; + }; + + secure_bitstream_cb { + compatible = "qcom,msm-vidc,context-bank"; + label = "venus_sec_bitstream"; + iommus = <&apps_smmu 0xC21 0x4>; + buffer-types = <0x241>; + virtual-addr-pool = <0x4b000000 0x25800000>; + qcom,secure-context-bank; + }; + + secure_pixel_cb { + compatible = "qcom,msm-vidc,context-bank"; + label = "venus_sec_pixel"; + iommus = <&apps_smmu 0xC23 0x0>; + buffer-types = <0x106>; + virtual-addr-pool = <0x25800000 0x25800000>; + qcom,secure-context-bank; + }; + + secure_non_pixel_cb { + compatible = "qcom,msm-vidc,context-bank"; + label = "venus_sec_non_pixel"; + iommus = <&apps_smmu 0xC04 0x60>; + buffer-types = <0x480>; + virtual-addr-pool = <0x1000000 0x24800000>; + qcom,secure-context-bank; + }; + }; +}; + diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index 0ce872bc2d72..d5f6fafd7ed2 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -2134,6 +2134,7 @@ #include "atoll-coresight.dtsi" #include "atoll-stub-regulator.dtsi" #include "atoll-usb.dtsi" +#include "atoll-vidc.dtsi" &pm6150_vadc { pinctrl-names = "default"; -- GitLab From 71c8a6805ab623e47f773940d2b42484b6b609cf Mon Sep 17 00:00:00 2001 From: Prakasha Nayak Date: Fri, 5 Jul 2019 17:10:19 +0530 Subject: [PATCH 0800/1121] msm: camera: Print mem handle index and io config index Print index to check if mem handles are released or not for ife, jpeg, icp drivers. Change-Id: I6d09b9aef3c2ac24adfe151260a43ba9b2c6d647 Signed-off-by: Prakasha Nayak --- .../msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c | 7 ++++++- .../msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c | 6 +++++- .../platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c | 7 ++++++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c index 51422dac5725..370768a0609d 100644 --- a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c +++ b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c @@ -4081,8 +4081,13 @@ static void cam_icp_mgr_print_io_bufs(struct cam_packet *packet, for (i = 0; i < packet->num_io_configs; i++) { for (j = 0; j < CAM_PACKET_MAX_PLANES; j++) { - if (!io_cfg[i].mem_handle[j]) + if (!io_cfg[i].mem_handle[j]) { + CAM_ERR(CAM_ICP, + "Mem Handle %d is NULL for %d io config", + j, i); break; + } + if (GET_FD_FROM_HANDLE(io_cfg[i].mem_handle[j]) == GET_FD_FROM_HANDLE(pf_buf_info)) { diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c index 3d394c69368f..7ff9add26a7f 100644 --- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c @@ -4097,8 +4097,12 @@ static void cam_ife_mgr_print_io_bufs(struct cam_packet *packet, for (i = 0; i < packet->num_io_configs; i++) { for (j = 0; j < CAM_PACKET_MAX_PLANES; j++) { - if (!io_cfg[i].mem_handle[j]) + if (!io_cfg[i].mem_handle[j]) { + CAM_ERR(CAM_ISP, + "Mem Handle %d is NULL for %d io config", + j, i); break; + } if (pf_buf_info && GET_FD_FROM_HANDLE(io_cfg[i].mem_handle[j]) == diff --git a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c index 9ea8e3f5b7d1..696566d6a37a 100644 --- a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c +++ b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c @@ -647,8 +647,13 @@ static void cam_jpeg_mgr_print_io_bufs(struct cam_packet *packet, for (i = 0; i < packet->num_io_configs; i++) { for (j = 0; j < CAM_PACKET_MAX_PLANES; j++) { - if (!io_cfg[i].mem_handle[j]) + if (!io_cfg[i].mem_handle[j]) { + CAM_ERR(CAM_JPEG, + "Mem Handle %d is NULL for %d io config", + j, i); break; + } + if (GET_FD_FROM_HANDLE(io_cfg[i].mem_handle[j]) == GET_FD_FROM_HANDLE(pf_buf_info)) { -- GitLab From 9fcd72d5ccdcf788c789d9588640d438ddf1eaa5 Mon Sep 17 00:00:00 2001 From: Ramachandran Venkataramani Date: Tue, 9 Jul 2019 10:57:03 -0700 Subject: [PATCH 0801/1121] ARM: dts: qcom: Remove vidc DT file for sdmshrike Remove the include for vidc device tree to fix compilation errors for sdmshrike target. Change-Id: Ibc43ada95260cf1b40a6f88ba5ed51a254007ba1 Signed-off-by: Ramachandran Venkataramani --- arch/arm64/boot/dts/qcom/sdmshrike.dtsi | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sdmshrike.dtsi b/arch/arm64/boot/dts/qcom/sdmshrike.dtsi index 396fb8ec49ae..7b6158372845 100644 --- a/arch/arm64/boot/dts/qcom/sdmshrike.dtsi +++ b/arch/arm64/boot/dts/qcom/sdmshrike.dtsi @@ -2358,7 +2358,6 @@ #include "sdmshrike-usb.dtsi" #include "sdmshrike-qupv3.dtsi" #include "sm8150-audio.dtsi" -#include "sm8150-vidc.dtsi" #include "sm8150-pm.dtsi" #include "sdmshrike-gpu.dtsi" #include "sdmshrike-thermal.dtsi" -- GitLab From 873d038fd753823fe210891533ceee6fc004d616 Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Mon, 8 Jul 2019 14:27:42 -0700 Subject: [PATCH 0802/1121] usb: f_gsi: Fix error handling path in ipa_connect_channels Commit 7674e8f6a77e ("usb: f_gsi: Don't enable IPA data path if connect channel fails") added error handling path and IN and out endpoints. For DPL out ep and out request are NULL. In case ipa_connect_channels returns error for DPL usb_gsi_ep_op() is de-referencing NULL pointer. Add NULL check for out ep in error handling path. Change-Id: Ia2db2ed840a4ab9032366042f00a1a9ac086d91f Signed-off-by: Hemant Kumar --- drivers/usb/gadget/function/f_gsi.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/function/f_gsi.c b/drivers/usb/gadget/function/f_gsi.c index b7569bdfa89a..fd7005e82876 100644 --- a/drivers/usb/gadget/function/f_gsi.c +++ b/drivers/usb/gadget/function/f_gsi.c @@ -737,11 +737,13 @@ static int ipa_connect_channels(struct gsi_data_port *d_port) return ret; end_xfer_ep_out: - usb_gsi_ep_op(d_port->out_ep, NULL, - GSI_EP_OP_ENDXFER); + if (d_port->out_ep) + usb_gsi_ep_op(d_port->out_ep, NULL, + GSI_EP_OP_ENDXFER); free_trb_ep_out: - usb_gsi_ep_op(d_port->out_ep, &d_port->out_request, - GSI_EP_OP_FREE_TRBS); + if (d_port->out_ep) + usb_gsi_ep_op(d_port->out_ep, &d_port->out_request, + GSI_EP_OP_FREE_TRBS); end_xfer_ep_in: usb_gsi_ep_op(d_port->in_ep, NULL, GSI_EP_OP_ENDXFER); -- GitLab From 384621f685f6b57db7e5c3e670afba142eda8c4b Mon Sep 17 00:00:00 2001 From: hangtian Date: Wed, 10 Jul 2019 14:52:14 +0800 Subject: [PATCH 0803/1121] mmc: core: Do not set host->card to NULL if oldcard is not released When card initiated mmc_power_restore_host() which triggers 2nd time mmc_sdio_init_card(), we free the new allocated card and keep oldcard, so we cannot set host->card to NULL if we still have oldcard. Change-Id: I50cf6b543244fe929bc08da64571b7ccfd734f77 CRs-Fixed: 2487134 Signed-off-by: hangtian --- drivers/mmc/core/bus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index b0986b6aa31b..aca68f0d011e 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c @@ -282,7 +282,7 @@ static void mmc_release_card(struct device *dev) kfree(card->info); kfree(card); - if (host) + if (host && card == host->card) host->card = NULL; } -- GitLab From 57a7b626334c9b2d45a0f3b681f49ea4cdd9d08b Mon Sep 17 00:00:00 2001 From: hangtian Date: Wed, 10 Jul 2019 15:43:11 +0800 Subject: [PATCH 0804/1121] Bluetooth: Fix compile issue when both CONFIG_CNSS and CONFIG_ICNSS enabled Fix compile issue when both CONFIG_CNSS and CONFIG_ICNSS enabled platform. Change-Id: I453bfec2de816dc9d504a1f07e144a00a80abcdc CRs-Fixed: 2487176 Signed-off-by: hangtian --- drivers/bluetooth/bluetooth-power.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/bluetooth/bluetooth-power.c b/drivers/bluetooth/bluetooth-power.c index 18195b4f5833..b7774077d03e 100644 --- a/drivers/bluetooth/bluetooth-power.c +++ b/drivers/bluetooth/bluetooth-power.c @@ -28,7 +28,7 @@ #include #include -#if defined(CONFIG_CNSS) +#if defined(CONFIG_CNSS) && !defined(CONFIG_ICNSS) #include #endif @@ -338,7 +338,7 @@ static const struct rfkill_ops bluetooth_power_rfkill_ops = { .set_block = bluetooth_toggle_radio, }; -#if defined(CONFIG_CNSS) +#if defined(CONFIG_CNSS) && !defined(CONFIG_ICNSS) static ssize_t enable_extldo(struct device *dev, struct device_attribute *attr, char *buf) { -- GitLab From 5795307bdf9ece323e018baebe3661a2ce1e2a18 Mon Sep 17 00:00:00 2001 From: hangtian Date: Wed, 10 Jul 2019 16:15:15 +0800 Subject: [PATCH 0805/1121] defconfig: qcs405: Enable cnss_sdio driver for Tufello Enable cnss_sdio driver for Tufello. Change-Id: I0a0d2f9abb4e37404c7a956715af7f0f98c364b5 CRs-Fixed: 2487189 Signed-off-by: hangtian --- arch/arm64/configs/vendor/qcs405-perf_defconfig | 3 +++ arch/arm64/configs/vendor/qcs405_defconfig | 3 +++ 2 files changed, 6 insertions(+) diff --git a/arch/arm64/configs/vendor/qcs405-perf_defconfig b/arch/arm64/configs/vendor/qcs405-perf_defconfig index 8c759619f54a..04875dad4815 100644 --- a/arch/arm64/configs/vendor/qcs405-perf_defconfig +++ b/arch/arm64/configs/vendor/qcs405-perf_defconfig @@ -269,6 +269,9 @@ CONFIG_ATH10K_DEBUG=y CONFIG_ATH10K_DEBUGFS=y CONFIG_WCNSS_MEM_PRE_ALLOC=y CONFIG_CLD_LL_CORE=y +CONFIG_CNSS=y +CONFIG_CNSS_SDIO=y +CONFIG_CLD_HL_SDIO_CORE=y CONFIG_INPUT_EVDEV=y CONFIG_INPUT_EVBUG=m CONFIG_INPUT_KEYRESET=y diff --git a/arch/arm64/configs/vendor/qcs405_defconfig b/arch/arm64/configs/vendor/qcs405_defconfig index 6f32a26228a8..937eedd79780 100644 --- a/arch/arm64/configs/vendor/qcs405_defconfig +++ b/arch/arm64/configs/vendor/qcs405_defconfig @@ -275,6 +275,9 @@ CONFIG_ATH10K_DEBUG=y CONFIG_ATH10K_DEBUGFS=y CONFIG_WCNSS_MEM_PRE_ALLOC=y CONFIG_CLD_LL_CORE=y +CONFIG_CNSS=y +CONFIG_CNSS_SDIO=y +CONFIG_CLD_HL_SDIO_CORE=y CONFIG_INPUT_EVDEV=y CONFIG_INPUT_EVBUG=m CONFIG_INPUT_KEYRESET=y -- GitLab From ae16da658afbf86526b83b494326db1859d56fbe Mon Sep 17 00:00:00 2001 From: Ramachandran Venkataramani Date: Wed, 10 Jul 2019 06:19:47 -0700 Subject: [PATCH 0806/1121] ARM: dts: qcom: Add CPU and cluster cost for sdmshrike Add the CPU and clusters costs for all cpus on sdmshrike. Change-Id: Id74ad926e10bfe32ef00840d52297d0e495fdc5d Signed-off-by: Ramachandran Venkataramani --- arch/arm64/boot/dts/qcom/sdmshrike.dtsi | 130 ++++++++++++++++++++++++ 1 file changed, 130 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdmshrike.dtsi b/arch/arm64/boot/dts/qcom/sdmshrike.dtsi index 396fb8ec49ae..07c81b12646e 100644 --- a/arch/arm64/boot/dts/qcom/sdmshrike.dtsi +++ b/arch/arm64/boot/dts/qcom/sdmshrike.dtsi @@ -56,8 +56,10 @@ compatible = "arm,armv8"; reg = <0x0 0x0>; enable-method = "psci"; + capacity-dmips-mhz = <1024>; cache-size = <0x8000>; next-level-cache = <&L2_0>; + sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>; qcom,lmh-dcvs = <&lmh_dcvs0>; #cooling-cells = <2>; L2_0: l2-cache { @@ -89,8 +91,10 @@ compatible = "arm,armv8"; reg = <0x0 0x100>; enable-method = "psci"; + capacity-dmips-mhz = <1024>; cache-size = <0x8000>; next-level-cache = <&L2_1>; + sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>; qcom,lmh-dcvs = <&lmh_dcvs0>; #cooling-cells = <2>; L2_1: l2-cache { @@ -116,8 +120,10 @@ compatible = "arm,armv8"; reg = <0x0 0x200>; enable-method = "psci"; + capacity-dmips-mhz = <1024>; cache-size = <0x8000>; next-level-cache = <&L2_2>; + sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>; qcom,lmh-dcvs = <&lmh_dcvs0>; #cooling-cells = <2>; L2_2: l2-cache { @@ -143,8 +149,10 @@ compatible = "arm,armv8"; reg = <0x0 0x300>; enable-method = "psci"; + capacity-dmips-mhz = <1024>; cache-size = <0x8000>; next-level-cache = <&L2_3>; + sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>; qcom,lmh-dcvs = <&lmh_dcvs0>; #cooling-cells = <2>; L2_3: l2-cache { @@ -170,8 +178,10 @@ compatible = "arm,armv8"; reg = <0x0 0x400>; enable-method = "psci"; + capacity-dmips-mhz = <1740>; cache-size = <0x20000>; next-level-cache = <&L2_4>; + sched-energy-costs = <&CPU_COST_1 &CLUSTER_COST_1>; qcom,lmh-dcvs = <&lmh_dcvs1>; #cooling-cells = <2>; L2_4: l2-cache { @@ -197,8 +207,10 @@ compatible = "arm,armv8"; reg = <0x0 0x500>; enable-method = "psci"; + capacity-dmips-mhz = <1740>; cache-size = <0x20000>; next-level-cache = <&L2_5>; + sched-energy-costs = <&CPU_COST_1 &CLUSTER_COST_1>; qcom,lmh-dcvs = <&lmh_dcvs1>; #cooling-cells = <2>; L2_5: l2-cache { @@ -224,8 +236,10 @@ compatible = "arm,armv8"; reg = <0x0 0x600>; enable-method = "psci"; + capacity-dmips-mhz = <1740>; cache-size = <0x20000>; next-level-cache = <&L2_6>; + sched-energy-costs = <&CPU_COST_1 &CLUSTER_COST_1>; qcom,lmh-dcvs = <&lmh_dcvs1>; #cooling-cells = <2>; L2_6: l2-cache { @@ -251,8 +265,10 @@ compatible = "arm,armv8"; reg = <0x0 0x700>; enable-method = "psci"; + capacity-dmips-mhz = <1740>; cache-size = <0x20000>; next-level-cache = <&L2_7>; + sched-energy-costs = <&CPU_COST_1 &CLUSTER_COST_1>; qcom,lmh-dcvs = <&lmh_dcvs1>; #cooling-cells = <2>; L2_7: l2-cache { @@ -317,6 +333,120 @@ }; }; + energy_costs: energy-costs { + compatible = "sched-energy"; + + CPU_COST_0: core-cost0 { + busy-cost-data = < + 300000 24 + 403200 25 + 499200 27 + 576000 29 + 672000 33 + 768000 37 + 844800 42 + 940800 47 + 1036800 54 + 1113600 59 + 1209600 66 + 1305600 73 + 1382400 79 + 1478400 88 + 1555200 96 + 1632000 105 + 1708800 115 + 1785600 128 + >; + idle-cost-data = < + 18 14 12 + >; + }; + + CPU_COST_1: core-cost1 { + busy-cost-data = < + 825600 227 + 940800 262 + 1056000 302 + 1171200 348 + 1286400 398 + 1401600 451 + 1497600 498 + 1612800 556 + 1708800 606 + 1804800 655 + 1920000 716 + 2016000 766 + 2131200 826 + 2227200 878 + 2323200 933 + 2419200 992 + 2534400 1075 + 2649600 1179 + 2745600 1288 + 2841600 1427 + 2956800 1670 + >; + idle-cost-data = < + 110 90 70 + >; + }; + + CLUSTER_COST_0: cluster-cost0 { + busy-cost-data = < + 300000 3 + 403200 4 + 499200 4 + 576000 4 + 672000 5 + 768000 5 + 844800 6 + 940800 7 + 1036800 8 + 1113600 9 + 1209600 10 + 1305600 11 + 1382400 12 + 1478400 13 + 1555200 14 + 1632000 15 + 1708800 16 + 1785600 17 + >; + idle-cost-data = < + 3 2 1 + >; + }; + + CLUSTER_COST_1: cluster-cost1 { + busy-cost-data = < + 825600 30 + 940800 33 + 1056000 36 + 1171200 39 + 1286400 42 + 1401600 46 + 1497600 49 + 1612800 55 + 1708800 67 + 1804800 77 + 1920000 87 + 2016000 100 + 2131200 110 + 2227200 120 + 2323200 128 + 2419200 135 + 2534400 140 + 2649600 147 + 2745600 160 + 2841600 180 + 2956800 197 + >; + idle-cost-data = < + 3 2 1 + >; + }; + }; /* energy-costs */ + cpuss_dump { compatible = "qcom,cpuss-dump"; -- GitLab From 4277aebeff91be9904202a94737793527e8dbc9b Mon Sep 17 00:00:00 2001 From: Jay Jayanna Date: Tue, 9 Jul 2019 16:37:51 -0700 Subject: [PATCH 0807/1121] net: qrtr: Free skb if qrtr_node_lookup fails during qrtr_fwd_pkt While forwarding a packet, if the node lookup fails, qrtr_fwd_pkt returns without freeing the socket buffer. This results in memory leak. Make sure this memory is freed to prevent this memory leak. Change-Id: Ia17ceaaa8da7ec7b08ea0982928502c52316e8c0 Signed-off-by: Jay Jayanna --- net/qrtr/qrtr.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c index 2d940d7a2d75..76a1a750f0e2 100644 --- a/net/qrtr/qrtr.c +++ b/net/qrtr/qrtr.c @@ -870,8 +870,10 @@ static void qrtr_fwd_pkt(struct sk_buff *skb, struct qrtr_cb *cb) struct qrtr_node *node; node = qrtr_node_lookup(cb->dst_node); - if (!node) + if (!node) { + kfree_skb(skb); return; + } qrtr_node_enqueue(node, skb, cb->type, &from, &to, 0); qrtr_node_release(node); -- GitLab From a554838a9b55a9aaf876290258201b48b24f016d Mon Sep 17 00:00:00 2001 From: Subash Abhinov Kasiviswanathan Date: Thu, 4 Jul 2019 13:34:40 -0700 Subject: [PATCH 0808/1121] soc: qcom: wda: Disable powersave work on deinitialization A delayed powersave work may not be cancelled if it re-arms itself. This could lead to invalid memory access after the work is destroyed. This change prevents the powersave work from re-queueing during deinitialization process. Change-Id: Ib5257c05e10e2e12c64ec28043ad0664574ccf97 Acked-by: Weiyi Chen Signed-off-by: Subash Abhinov Kasiviswanathan --- drivers/soc/qcom/qmi_rmnet.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/drivers/soc/qcom/qmi_rmnet.c b/drivers/soc/qcom/qmi_rmnet.c index f387d6214571..4b35f8dfe3d5 100644 --- a/drivers/soc/qcom/qmi_rmnet.c +++ b/drivers/soc/qcom/qmi_rmnet.c @@ -759,6 +759,7 @@ EXPORT_SYMBOL(qmi_rmnet_qos_exit); #ifdef CONFIG_QCOM_QMI_POWER_COLLAPSE static struct workqueue_struct *rmnet_ps_wq; static struct rmnet_powersave_work *rmnet_work; +static bool rmnet_work_quit; static LIST_HEAD(ps_list); struct rmnet_powersave_work { @@ -841,9 +842,10 @@ EXPORT_SYMBOL(qmi_rmnet_set_powersave_mode); static void qmi_rmnet_work_restart(void *port) { - if (!rmnet_ps_wq || !rmnet_work) - return; - queue_delayed_work(rmnet_ps_wq, &rmnet_work->work, NO_DELAY); + rcu_read_lock(); + if (!rmnet_work_quit) + queue_delayed_work(rmnet_ps_wq, &rmnet_work->work, NO_DELAY); + rcu_read_unlock(); } static void qmi_rmnet_check_stats(struct work_struct *work) @@ -870,13 +872,9 @@ static void qmi_rmnet_check_stats(struct work_struct *work) qmi->ps_ignore_grant = false; /* Register to get QMI DFC and DL marker */ - if (qmi_rmnet_set_powersave_mode(real_work->port, 0) < 0) { - /* If this failed need to retry quickly */ - queue_delayed_work(rmnet_ps_wq, - &real_work->work, HZ / 50); - return; + if (qmi_rmnet_set_powersave_mode(real_work->port, 0) < 0) + goto end; - } qmi->ps_enabled = false; /* Do a query when coming out of powersave */ @@ -906,11 +904,9 @@ static void qmi_rmnet_check_stats(struct work_struct *work) goto end; /* Deregister to suppress QMI DFC and DL marker */ - if (qmi_rmnet_set_powersave_mode(real_work->port, 1) < 0) { - queue_delayed_work(rmnet_ps_wq, - &real_work->work, PS_INTERVAL); - return; - } + if (qmi_rmnet_set_powersave_mode(real_work->port, 1) < 0) + goto end; + qmi->ps_enabled = true; /* Ignore grant after going into powersave */ @@ -928,7 +924,10 @@ static void qmi_rmnet_check_stats(struct work_struct *work) return; } end: - queue_delayed_work(rmnet_ps_wq, &real_work->work, PS_INTERVAL); + rcu_read_lock(); + if (!rmnet_work_quit) + queue_delayed_work(rmnet_ps_wq, &real_work->work, PS_INTERVAL); + rcu_read_unlock(); } static void qmi_rmnet_work_set_active(void *port, int status) @@ -964,6 +963,7 @@ void qmi_rmnet_work_init(void *port) rmnet_get_packets(rmnet_work->port, &rmnet_work->old_rx_pkts, &rmnet_work->old_tx_pkts); + rmnet_work_quit = false; qmi_rmnet_work_set_active(rmnet_work->port, 1); queue_delayed_work(rmnet_ps_wq, &rmnet_work->work, PS_INTERVAL); } @@ -986,6 +986,10 @@ void qmi_rmnet_work_exit(void *port) { if (!rmnet_ps_wq || !rmnet_work) return; + + rmnet_work_quit = true; + synchronize_rcu(); + cancel_delayed_work_sync(&rmnet_work->work); destroy_workqueue(rmnet_ps_wq); qmi_rmnet_work_set_active(port, 0); -- GitLab From c3dee4c25e9d91be43cbe2aa6fa7bdd0cd8d86ee Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Tue, 9 Jul 2019 14:34:45 -0700 Subject: [PATCH 0809/1121] ARM: dts: msm: Update entries for serial engine instances Update the base address for serial engine instance 15 to the address specified by the hardware spec. Update the wrapper node for serial engine instance 13 to use the correct serial engine wrapper node. Change-Id: I88264487bbfc361d8ed4b4c689347d5ecab3f538 Signed-off-by: Anant Goel --- arch/arm64/boot/dts/qcom/sa8155-vm-qupv3.dtsi | 6 +++--- arch/arm64/boot/dts/qcom/sdmshrike-qupv3.dtsi | 6 +++--- arch/arm64/boot/dts/qcom/sm8150-qupv3.dtsi | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sa8155-vm-qupv3.dtsi b/arch/arm64/boot/dts/qcom/sa8155-vm-qupv3.dtsi index aa8957d93480..dd9bc5819ec8 100644 --- a/arch/arm64/boot/dts/qcom/sa8155-vm-qupv3.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8155-vm-qupv3.dtsi @@ -599,7 +599,7 @@ pinctrl-1 = <&qupv3_se13_spi_sleep>; interrupts = ; spi-max-frequency = <50000000>; - qcom,wrapper-core = <&qupv3_1>; + qcom,wrapper-core = <&qupv3_2>; status = "disabled"; }; @@ -740,11 +740,11 @@ status = "disabled"; }; - qupv3_se15_spi: spi@c90000 { + qupv3_se15_spi: spi@c94000 { compatible = "qcom,spi-geni"; #address-cells = <1>; #size-cells = <0>; - reg = <0xc90000 0x4000>; + reg = <0xc94000 0x4000>; reg-names = "se_phys"; clock-names = "se-clk", "m-ahb", "s-ahb"; clocks = <&clock_virt GCC_QUPV3_WRAP2_S5_CLK>, diff --git a/arch/arm64/boot/dts/qcom/sdmshrike-qupv3.dtsi b/arch/arm64/boot/dts/qcom/sdmshrike-qupv3.dtsi index 220cce9f632a..b26cb64f139f 100644 --- a/arch/arm64/boot/dts/qcom/sdmshrike-qupv3.dtsi +++ b/arch/arm64/boot/dts/qcom/sdmshrike-qupv3.dtsi @@ -605,7 +605,7 @@ pinctrl-1 = <&qupv3_se13_spi_sleep>; interrupts = ; spi-max-frequency = <50000000>; - qcom,wrapper-core = <&qupv3_1>; + qcom,wrapper-core = <&qupv3_2>; status = "disabled"; }; @@ -769,11 +769,11 @@ status = "disabled"; }; - qupv3_se15_spi: spi@c90000 { + qupv3_se15_spi: spi@c94000 { compatible = "qcom,spi-geni"; #address-cells = <1>; #size-cells = <0>; - reg = <0xc90000 0x4000>; + reg = <0xc94000 0x4000>; reg-names = "se_phys"; clock-names = "se-clk", "m-ahb", "s-ahb"; clocks = <&clock_gcc GCC_QUPV3_WRAP2_S5_CLK>, diff --git a/arch/arm64/boot/dts/qcom/sm8150-qupv3.dtsi b/arch/arm64/boot/dts/qcom/sm8150-qupv3.dtsi index c7e8ad0a23e9..aa109f9a7f94 100644 --- a/arch/arm64/boot/dts/qcom/sm8150-qupv3.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150-qupv3.dtsi @@ -681,7 +681,7 @@ pinctrl-1 = <&qupv3_se13_spi_sleep>; interrupts = ; spi-max-frequency = <50000000>; - qcom,wrapper-core = <&qupv3_1>; + qcom,wrapper-core = <&qupv3_2>; dmas = <&gpi_dma2 0 3 1 64 0>, <&gpi_dma2 1 3 1 64 0>; dma-names = "tx", "rx"; @@ -846,11 +846,11 @@ status = "disabled"; }; - qupv3_se15_spi: spi@c90000 { + qupv3_se15_spi: spi@c94000 { compatible = "qcom,spi-geni"; #address-cells = <1>; #size-cells = <0>; - reg = <0xc90000 0x4000>; + reg = <0xc94000 0x4000>; reg-names = "se_phys"; clock-names = "se-clk", "m-ahb", "s-ahb"; clocks = <&clock_gcc GCC_QUPV3_WRAP2_S5_CLK>, -- GitLab From ea605b7bff332056f62e979c161c105ffb28e2d5 Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Tue, 25 Jun 2019 14:46:14 -0700 Subject: [PATCH 0810/1121] ARM: dts: msm: Add entries to the root node for sdmshrike Add nodes for bootargs, vbmeta, and vendor for the sdmshrike target. Change-Id: I9563811c7cd324f0831bec2aac31cfe4a614bc3e Signed-off-by: Anant Goel --- arch/arm64/boot/dts/qcom/sdmshrike.dtsi | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdmshrike.dtsi b/arch/arm64/boot/dts/qcom/sdmshrike.dtsi index 7b6158372845..971edecc6ed6 100644 --- a/arch/arm64/boot/dts/qcom/sdmshrike.dtsi +++ b/arch/arm64/boot/dts/qcom/sdmshrike.dtsi @@ -317,6 +317,10 @@ }; }; + chosen { + bootargs = "rcupdate.rcu_expedited=1 rcu_nocbs=0-7 cgroup.memory=nokmem,nosocket"; + }; + cpuss_dump { compatible = "qcom,cpuss-dump"; @@ -404,6 +408,10 @@ firmware: firmware { android { compatible = "android,firmware"; + vbmeta { + compatible = "android,vbmeta"; + parts = "vbmeta,boot,system,vendor,dtbo"; + }; fstab { compatible = "android,fstab"; vendor { @@ -602,6 +610,13 @@ }; }; + vendor: vendor { + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0 0xffffffff>; + compatible = "simple-bus"; + }; + soc: soc { }; }; -- GitLab From 1038c5dffb65e9f130c6cec26e501ffaa2c46039 Mon Sep 17 00:00:00 2001 From: Ramachandran Venkataramani Date: Wed, 3 Apr 2019 16:17:11 -0700 Subject: [PATCH 0811/1121] ARM: dts: msm: Add USB2 for sdmshrike Add usb2 controller and phy nodes for sdmshrike Change-Id: If03f1712d29f9fc3c15694e5eda9f6d3c67de97e Signed-off-by: Ramachandran Venkataramani --- arch/arm64/boot/dts/qcom/sdmshrike-mtp.dtsi | 9 ++ arch/arm64/boot/dts/qcom/sdmshrike-usb.dtsi | 105 +++++++++++++++++++- 2 files changed, 113 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sdmshrike-mtp.dtsi b/arch/arm64/boot/dts/qcom/sdmshrike-mtp.dtsi index 300b3e67ceae..0988d0e1a7c0 100644 --- a/arch/arm64/boot/dts/qcom/sdmshrike-mtp.dtsi +++ b/arch/arm64/boot/dts/qcom/sdmshrike-mtp.dtsi @@ -145,3 +145,12 @@ status = "ok"; }; + +&usb2_phy1 { + status = "ok"; +}; + +&usb1 { + qcom,default-mode-host; + status ="ok"; +}; diff --git a/arch/arm64/boot/dts/qcom/sdmshrike-usb.dtsi b/arch/arm64/boot/dts/qcom/sdmshrike-usb.dtsi index 9b5e2e1be88b..9362ddd57f99 100644 --- a/arch/arm64/boot/dts/qcom/sdmshrike-usb.dtsi +++ b/arch/arm64/boot/dts/qcom/sdmshrike-usb.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -136,4 +136,107 @@ usb_nop_phy: usb_nop_phy { compatible = "usb-nop-xceiv"; }; + + /* Secondary USB port related controller */ + usb1: ssusb@a800000 { + compatible = "qcom,dwc-usb3-msm"; + reg = <0x0a800000 0x100000>; + reg-names = "core_base"; + + iommus = <&apps_smmu 0x160 0x0>; + qcom,smmu-s1-bypass; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + interrupts = <0 491 0>, <0 135 0>, <0 487 0>, <0 490 0>; + interrupt-names = "dp_hs_phy_irq", "pwr_event_irq", + "ss_phy_irq", "dm_hs_phy_irq"; + qcom,use-pdc-interrupts; + + USB3_GDSC-supply = <&usb30_sec_gdsc>; + clocks = <&clock_gcc GCC_USB30_SEC_MASTER_CLK>, + <&clock_gcc GCC_CFG_NOC_USB3_SEC_AXI_CLK>, + <&clock_gcc GCC_AGGRE_USB3_SEC_AXI_CLK>, + <&clock_gcc GCC_USB30_SEC_MOCK_UTMI_CLK>, + <&clock_gcc GCC_USB30_SEC_SLEEP_CLK>, + <&clock_rpmh RPMH_CXO_CLK>; + clock-names = "core_clk", "iface_clk", "bus_aggr_clk", + "utmi_clk", "sleep_clk", "xo"; + + resets = <&clock_gcc GCC_USB30_SEC_BCR>; + reset-names = "core_reset"; + + qcom,core-clk-rate = <200000000>; + qcom,core-clk-rate-hs = <66666667>; + qcom,num-gsi-evt-buffs = <0x3>; + qcom,gsi-reg-offset = + <0x0fc /* GSI_GENERAL_CFG */ + 0x110 /* GSI_DBL_ADDR_L */ + 0x120 /* GSI_DBL_ADDR_H */ + 0x130 /* GSI_RING_BASE_ADDR_L */ + 0x144 /* GSI_RING_BASE_ADDR_H */ + 0x1a4>; /* GSI_IF_STS */ + qcom,dwc-usb3-msm-tx-fifo-size = <27696>; + qcom,charging-disabled; + + qcom,msm-bus,name = "usb1"; + qcom,msm-bus,num-cases = <3>; + qcom,msm-bus,num-paths = <3>; + qcom,msm-bus,vectors-KBps = + /* suspend vote */ + , + , + , + + /* nominal vote */ + , + , + , + + /* svs vote */ + , + , + ; + + status = "disabled"; + + dwc3@a800000 { + compatible = "snps,dwc3"; + reg = <0x0a800000 0xcd00>; + interrupts = <0 138 0>; + usb-phy = <&usb2_phy1>, <&usb_nop_phy>; + linux,sysdev_is_parent; + snps,disable-clk-gating; + snps,has-lpm-erratum; + snps,hird-threshold = /bits/ 8 <0x10>; + snps,usb3_lpm_capable; + usb-core-id = <1>; + tx-fifo-resize; + maximum-speed = "high-speed"; + dr_mode = "otg"; + }; + }; + + /* Secondary USB port related High Speed PHY */ + usb2_phy1: hsphy@88e3000 { + compatible = "qcom,usb-hsphy-snps-femto"; + reg = <0x88e3000 0x110>; + reg-names = "hsusb_phy_base"; + + vdd-supply = <&pm8150_2_l5>; + vdda18-supply = <&pm8150_1_l12>; + vdda33-supply = <&pm8150_2_l16>; + qcom,vdd-voltage-level = <0 880000 880000>; + + clocks = <&clock_rpmh RPMH_CXO_CLK>; + clock-names = "ref_clk_src"; + + resets = <&clock_gcc GCC_QUSB2PHY_SEC_BCR>; + reset-names = "phy_reset"; + + status = "disabled"; + }; }; -- GitLab From ecb4c97499cac6a7afd1240e9812929113f92ab2 Mon Sep 17 00:00:00 2001 From: Michael Adisumarta Date: Tue, 9 Jul 2019 11:57:24 -0700 Subject: [PATCH 0812/1121] ARM: dts: msm: Raise the IPA threshold for sm8150-sdxprairie Raise the tput threshold for sm8150-sdxprairie to be up to date with sdxprairie. Change-Id: I895950b92d2e720969ceec0280ca23c6b6c66a4a Signed-off-by: Michael Adisumarta --- arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi b/arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi index 3ec7c086acc4..dc71e58f8337 100644 --- a/arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi @@ -126,8 +126,9 @@ qcom,testbus-collection-on-crash; qcom,non-tn-collection-on-crash; qcom,secure-debug-check-action = <0>; - qcom,scaling-exceptions = "USB DPL", "0", "600", - "1000", "ODL", "0", "600", "1000"; + qcom,throughput-threshold = <600 2500 5000>; + qcom,scaling-exceptions = "USB DPL", "0", "2500", + "5000", "ODL", "0", "2500", "5000"; }; qcom,ipa_fws { -- GitLab From f67d1d15e7b8714b173504f5151da8c541421bf3 Mon Sep 17 00:00:00 2001 From: Liam Mark Date: Wed, 10 Jul 2019 15:01:58 -0700 Subject: [PATCH 0813/1121] ARM: dts: msm: Update to memory map V6 for sdxprairie Update the reserved-mem regions to memory map V6 for sdxprairie. Change-Id: Idde986b2f31de685839b7e5f3d0b8af0fed575ff Signed-off-by: Liam Mark --- arch/arm64/boot/dts/qcom/sdxprairie.dtsi | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdxprairie.dtsi b/arch/arm64/boot/dts/qcom/sdxprairie.dtsi index 880c93ab9eee..698f518cd73d 100644 --- a/arch/arm64/boot/dts/qcom/sdxprairie.dtsi +++ b/arch/arm64/boot/dts/qcom/sdxprairie.dtsi @@ -40,6 +40,13 @@ #size-cells = <1>; ranges; + mpss_adsp_mem: mpss_adsp_region@90c00000 { + compatible = "removed-dma-pool"; + no-map; + reg = <0x90c00000 0xd400000>; + label = "mpss_adsp_mem"; + }; + tz_apps_mem: tz_apps_region@0x90000000 { no-map; reg = <0x90000000 0xc00000>; @@ -88,13 +95,6 @@ label = "mpss_debug_mem"; }; - mpss_adsp_mem: mpss_adsp_region@82300000 { - compatible = "removed-dma-pool"; - no-map; - reg = <0x82300000 0xcc00000>; - label = "mpss_adsp_mem"; - }; - qseecom_mem: qseecom_region@0 { compatible = "shared-dma-pool"; reusable; -- GitLab From c1b00eaa78751ef64e95713b50a9bf80c5ebc671 Mon Sep 17 00:00:00 2001 From: hangtian Date: Wed, 10 Jul 2019 15:51:46 +0800 Subject: [PATCH 0814/1121] ARM: dts: msm: Add cnss_sdio dt for QCS405 and enable sdio in sdhc_2 Add cnss_sdio dt for QCS405 and enable sdio in sdhc_2 for 2nd wifi with sdio interface. Change-Id: Iaee42a97fed487c099b6578c0decd0ad629c1e1d CRs-Fixed: 2487180 Signed-off-by: hangtian --- .../bindings/cnss/cnss-sdio-wlan.txt | 63 +++++++++++++++++++ arch/arm64/boot/dts/qcom/qcs405.dtsi | 28 ++++++++- 2 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/cnss/cnss-sdio-wlan.txt diff --git a/Documentation/devicetree/bindings/cnss/cnss-sdio-wlan.txt b/Documentation/devicetree/bindings/cnss/cnss-sdio-wlan.txt new file mode 100644 index 000000000000..fbd136e147e2 --- /dev/null +++ b/Documentation/devicetree/bindings/cnss/cnss-sdio-wlan.txt @@ -0,0 +1,63 @@ +* Qualcomm Technologies, Inc. Connectivity SubSystem Platform Driver + +This platform driver adds support for the CNSS subsystem used for SDIO +based Wi-Fi devices. It also adds support to manage two 1.8V voltage +regulators and WLAN power enable 3.3V regulators. The main purpose of this +device tree entry below is to invoke the CNSS SDIO platform driver +and provide handle to the WLAN power enable 3.3V pmic GPIO and two 1.8V +PMIC voltage regulator resources. + +Required properties: + - compatible: "qcom,cnss_sdio" + - reg: memory resource to save firmware dump, optional. + - reg-names: memory resource name. + - subsys-name: cnss sdio subsytem device name, required. + - vdd-wlan-supply: phandle to the WLAN vdd regulator device tree node. + - vdd-wlan-dsrc-supply: phandle to the WLAN dsrc vdd regulator device tree node. + - vdd-wlan-io-supply: phandle to the WLAN IO regulator device tree node. + - vdd-wlan-xtal-supply: phandle to the WLAM XTAL regulator device tree node. + +Optional properties: + - pinctrl-names: Names corresponding to the numbered pinctrl states + - pinctrl-: Pinctrl states as described in + bindings/pinctrl/pinctrl-bindings.txt + - qcom,is-antenna-shared: Enabled for Platforms with both sdio and pcie QCA + Chipsets are attached. + - qcom,cnss-enable-bus-bandwidth: Boolean - Define this property when target + support to vote for bus bandwidth. + - qcom,msm-bus,name: client name for msm bus register. + - qcom,msm-bus,num-cases: number of cases for bus scaling. + - qcom,msm-bus,num-paths: number of paths for bus scale vector. + - qcom,msm-bus,vectors-KBps: bus scale vector table. + - qcom,skip-wlan-en-toggle: Boolean property to be enabled for platforms where + wlan_en toggling is not supported. + - vdd-wlan-xtal-min: Minimum required voltage in uV for VDD_XTAL regulator. + Minimum required voltage is 1620000. + If not set, a typical 1800000 will be set. + - vdd-wlan-xtal-max: Maximum acceptable voltage in uV for VDD_XTAL regulator. + Maximum acceptable voltage is 3465000. + If not set, a typical 1800000 will be set. +Example: + qcom,cnss-sdio { + compatible = "qcom,cnss_sdio"; + reg = <0x87a00000, 0x200000>; + reg-names = "ramdump"; + subsys-name = "AR6320"; + vdd-wlan-supply = <&rome_vreg>; + vdd-wlan-dsrc-supply = <&sdcard_ext_vreg>; + vdd-wlan-io-supply = <&mdm9607_l11>; + vdd-wlan-xtal-supply = <&mdm9607_l2>; + qcom,is-antenna-shared; + pinctrl-names = "active", "sleep"; + pinctrl-0 = <&cnss_sdio_active>; + pinctrl-1 = <&cnss_sdio_sleep>; + qcom,cnss-enable-bus-bandwidth; + qcom,msm-bus,name = "msm-cnss"; + qcom,msm-bus,num-cases = <4>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <79 512 0 0>, /* No vote */ + <79 512 6250 200000>, /* 50 Mbps */ + <79 512 25000 200000>, /* 200 Mbps */ + <79 512 2048000 4096000>; /* MAX */ + }; diff --git a/arch/arm64/boot/dts/qcom/qcs405.dtsi b/arch/arm64/boot/dts/qcom/qcs405.dtsi index a8639eb4ec0c..c58da349d3b3 100644 --- a/arch/arm64/boot/dts/qcom/qcs405.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs405.dtsi @@ -1311,13 +1311,19 @@ /* VDD is an external regulator eLDO5 */ vdd-io-supply = <&pms405_l11>; - qcom,vdd-io-voltage-level = <1800000 2950000>; + qcom,vdd-io-voltage-level = <1800000 1800000>; qcom,vdd-io-current-level = <0 24200>; + qcom,core_3_0v_support; + qcom,nonremovable; + pinctrl-names = "active", "sleep"; pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on>; pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off>; + /delete-property/ qcom,devfreq,freq-table; + /delete-property/ cd-gpios; + status = "ok"; }; @@ -1511,6 +1517,26 @@ qcom,smmu-s1-bypass; qcom,hyp_disabled; }; + + cnss_sdio: qcom,cnss_sdio { + compatible = "qcom,cnss_sdio"; + subsys-name = "AR6320"; + /** + * There is no vdd-wlan on board and this is not for DSRC. + * IO and XTAL share the same vreg. + **/ + vdd-wlan-io-supply = <&pms405_l5>; + qcom,cap-tsf-gpio = <&tlmm 42 1>; + qcom,wlan-ramdump-dynamic = <0x200000>; + qcom,msm-bus,name = "msm-cnss"; + qcom,msm-bus,num-cases = <4>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <79 512 0 0>, /* No vote */ + <79 512 6250 200000>, /* 50 Mbps */ + <79 512 25000 200000>, /* 200 Mbps */ + <79 512 2048000 4096000>; /* MAX */ + }; }; #include "qcs405-gdsc.dtsi" -- GitLab From bd9292f2b1fe9a7e025b0288b620f9da69e8f709 Mon Sep 17 00:00:00 2001 From: Yao Jiang Date: Mon, 4 Mar 2019 11:54:54 +0800 Subject: [PATCH 0815/1121] soc: qcom: hab: unify variable type to avoid implicit conversion correcting the type of sizebytes and total_size to size_t,it can avoid implicit conversion which maybe cause some unknown issue. Change-Id: I1c1cc9e92ca2920cc49685edef0d928dd67454c7 Signed-off-by: Yao Jiang --- drivers/soc/qcom/hab/ghs_comm.c | 2 +- drivers/soc/qcom/hab/qvm_comm.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/soc/qcom/hab/ghs_comm.c b/drivers/soc/qcom/hab/ghs_comm.c index b426cb1972aa..50b268c8ab7f 100644 --- a/drivers/soc/qcom/hab/ghs_comm.c +++ b/drivers/soc/qcom/hab/ghs_comm.c @@ -39,7 +39,7 @@ int physical_channel_send(struct physical_channel *pchan, struct hab_header *header, void *payload) { - int sizebytes = HAB_HEADER_GET_SIZE(*header); + size_t sizebytes = HAB_HEADER_GET_SIZE(*header); struct ghs_vdev *dev = (struct ghs_vdev *)pchan->hyp_data; GIPC_Result result; uint8_t *msg; diff --git a/drivers/soc/qcom/hab/qvm_comm.c b/drivers/soc/qcom/hab/qvm_comm.c index 985f6b646875..b743e8ddb60b 100644 --- a/drivers/soc/qcom/hab/qvm_comm.c +++ b/drivers/soc/qcom/hab/qvm_comm.c @@ -40,9 +40,9 @@ int physical_channel_send(struct physical_channel *pchan, struct hab_header *header, void *payload) { - int sizebytes = HAB_HEADER_GET_SIZE(*header); + size_t sizebytes = HAB_HEADER_GET_SIZE(*header); struct qvm_channel *dev = (struct qvm_channel *)pchan->hyp_data; - int total_size = sizeof(*header) + sizebytes; + size_t total_size = sizeof(*header) + sizebytes; int irqs_disabled = irqs_disabled(); if (total_size > dev->pipe_ep->tx_info.sh_buf->size) -- GitLab From cc49fed384240f6f89d03e4846405930fe2189c2 Mon Sep 17 00:00:00 2001 From: Mao Jinlong Date: Wed, 10 Jul 2019 15:35:26 +0800 Subject: [PATCH 0816/1121] dcc_v2: Reset the lock register if config dcc list fails Reset the lock register if config dcc list fails. Otherwise the list will be always locked before next dcc_disable. Change-Id: I2bd209ba84fe4896cce5bf72cdb3d06d2377a383 Signed-off-by: Mao Jinlong --- drivers/soc/qcom/dcc_v2.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/soc/qcom/dcc_v2.c b/drivers/soc/qcom/dcc_v2.c index a86cc47f8310..aa7715cf1815 100644 --- a/drivers/soc/qcom/dcc_v2.c +++ b/drivers/soc/qcom/dcc_v2.c @@ -612,6 +612,7 @@ static int dcc_enable(struct dcc_drvdata *drvdata) ram_cfg_base = drvdata->ram_cfg; ret = __dcc_ll_cfg(drvdata, list); if (ret) { + dcc_writel(drvdata, 0, DCC_LL_LOCK(list)); dev_info(drvdata->dev, "DCC ram programming failed\n"); goto err; } -- GitLab From 8584ed2111e8374b1c368b6d421ab8222f129914 Mon Sep 17 00:00:00 2001 From: Tejas Prajapati Date: Thu, 27 Jun 2019 14:25:36 +0530 Subject: [PATCH 0817/1121] msm: camera: cpas: logs added in the failure case for stop hw In cpas_stop_hw for failure case logs were not present, added logs to improve debugging. Updated the callers of cpas_stop_hw to improve debugging. Change-Id: I4694764293575d381efeeb7c062f073d37f8721c Signed-off-by: Tejas Prajapati --- .../msm/camera/cam_cpas/cam_cpas_hw.c | 16 ++++++++++++--- .../msm/camera/cam_icp/icp_hw/a5_hw/a5_core.c | 6 +++++- .../camera/cam_icp/icp_hw/bps_hw/bps_core.c | 6 +++++- .../camera/cam_icp/icp_hw/ipe_hw/ipe_core.c | 6 +++++- .../cam_sensor_module/cam_cci/cam_cci_soc.c | 4 +++- .../cam_csiphy/cam_csiphy_core.c | 20 ++++++++++++++----- 6 files changed, 46 insertions(+), 12 deletions(-) diff --git a/drivers/media/platform/msm/camera/cam_cpas/cam_cpas_hw.c b/drivers/media/platform/msm/camera/cam_cpas/cam_cpas_hw.c index a68032cf6c19..a68e20745b1a 100644 --- a/drivers/media/platform/msm/camera/cam_cpas/cam_cpas_hw.c +++ b/drivers/media/platform/msm/camera/cam_cpas/cam_cpas_hw.c @@ -980,8 +980,10 @@ static int cam_cpas_hw_start(void *hw_priv, void *start_args, return -EINVAL; } - if (!CAM_CPAS_CLIENT_VALID(client_indx)) + if (!CAM_CPAS_CLIENT_VALID(client_indx)) { + CAM_ERR(CAM_CPAS, "Client index invalid %d", client_indx); return -EINVAL; + } mutex_lock(&cpas_hw->hw_mutex); mutex_lock(&cpas_core->client_mutex[client_indx]); @@ -1099,8 +1101,10 @@ static int cam_cpas_hw_stop(void *hw_priv, void *stop_args, cmd_hw_stop = (struct cam_cpas_hw_cmd_stop *)stop_args; client_indx = CAM_CPAS_GET_CLIENT_IDX(cmd_hw_stop->client_handle); - if (!CAM_CPAS_CLIENT_VALID(client_indx)) + if (!CAM_CPAS_CLIENT_VALID(client_indx)) { + CAM_ERR(CAM_CPAS, "Client index invalid %d", client_indx); return -EINVAL; + } mutex_lock(&cpas_hw->hw_mutex); mutex_lock(&cpas_core->client_mutex[client_indx]); @@ -1162,14 +1166,20 @@ static int cam_cpas_hw_stop(void *hw_priv, void *stop_args, ahb_vote.vote.level = CAM_SUSPEND_VOTE; rc = cam_cpas_util_apply_client_ahb_vote(cpas_hw, cpas_client, &ahb_vote, NULL); - if (rc) + if (rc) { + CAM_ERR(CAM_CPAS, "ahb vote failed for %s rc %d", + cpas_client->data.identifier, rc); goto done; + } axi_vote.uncompressed_bw = 0; axi_vote.compressed_bw = 0; axi_vote.compressed_bw_ab = 0; rc = cam_cpas_util_apply_client_axi_vote(cpas_hw, cpas_client, &axi_vote); + if (rc) + CAM_ERR(CAM_CPAS, "axi vote failed for %s rc %d", + cpas_client->data.identifier, rc); done: mutex_unlock(&cpas_core->client_mutex[client_indx]); diff --git a/drivers/media/platform/msm/camera/cam_icp/icp_hw/a5_hw/a5_core.c b/drivers/media/platform/msm/camera/cam_icp/icp_hw/a5_hw/a5_core.c index e13d7f2edcee..4dbc8f1bd991 100644 --- a/drivers/media/platform/msm/camera/cam_icp/icp_hw/a5_hw/a5_core.c +++ b/drivers/media/platform/msm/camera/cam_icp/icp_hw/a5_hw/a5_core.c @@ -464,7 +464,11 @@ int cam_a5_process_cmd(void *device_priv, uint32_t cmd_type, case CAM_ICP_A5_CMD_CPAS_STOP: if (core_info->cpas_start) { - cam_cpas_stop(core_info->cpas_handle); + rc = cam_cpas_stop(core_info->cpas_handle); + if (rc) { + CAM_ERR(CAM_ICP, "cpas stop failed %d", rc); + return rc; + } core_info->cpas_start = false; } break; diff --git a/drivers/media/platform/msm/camera/cam_icp/icp_hw/bps_hw/bps_core.c b/drivers/media/platform/msm/camera/cam_icp/icp_hw/bps_hw/bps_core.c index c94276ce8778..f522f7138765 100644 --- a/drivers/media/platform/msm/camera/cam_icp/icp_hw/bps_hw/bps_core.c +++ b/drivers/media/platform/msm/camera/cam_icp/icp_hw/bps_hw/bps_core.c @@ -347,7 +347,11 @@ int cam_bps_process_cmd(void *device_priv, uint32_t cmd_type, case CAM_ICP_BPS_CMD_CPAS_STOP: if (core_info->cpas_start) { - cam_cpas_stop(core_info->cpas_handle); + rc = cam_cpas_stop(core_info->cpas_handle); + if (rc) { + CAM_ERR(CAM_ICP, "cpas stop failed %d", rc); + return rc; + } core_info->cpas_start = false; } break; diff --git a/drivers/media/platform/msm/camera/cam_icp/icp_hw/ipe_hw/ipe_core.c b/drivers/media/platform/msm/camera/cam_icp/icp_hw/ipe_hw/ipe_core.c index ae3d1343c1c4..ae58b34062d6 100644 --- a/drivers/media/platform/msm/camera/cam_icp/icp_hw/ipe_hw/ipe_core.c +++ b/drivers/media/platform/msm/camera/cam_icp/icp_hw/ipe_hw/ipe_core.c @@ -342,7 +342,11 @@ int cam_ipe_process_cmd(void *device_priv, uint32_t cmd_type, case CAM_ICP_IPE_CMD_CPAS_STOP: if (core_info->cpas_start) { - cam_cpas_stop(core_info->cpas_handle); + rc = cam_cpas_stop(core_info->cpas_handle); + if (rc) { + CAM_ERR(CAM_ICP, "CPAS stop failed %d", rc); + return rc; + } core_info->cpas_start = false; } break; diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_soc.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_soc.c index 0181a4d8e2ff..f66d86ce091e 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_soc.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_soc.c @@ -410,7 +410,9 @@ int cam_cci_soc_release(struct cci_device *cci_dev) cci_dev->cci_state = CCI_STATE_DISABLED; cci_dev->cycles_per_us = 0; - cam_cpas_stop(cci_dev->cpas_handle); + rc = cam_cpas_stop(cci_dev->cpas_handle); + if (rc) + CAM_ERR(CAM_CCI, "cpas stop failed %d", rc); return rc; } diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c index 57f0d0b58288..2a5f0a5c7c0a 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c @@ -551,7 +551,7 @@ int32_t cam_csiphy_config_dev(struct csiphy_device *csiphy_dev) void cam_csiphy_shutdown(struct csiphy_device *csiphy_dev) { struct cam_hw_soc_info *soc_info; - int32_t i = 0; + int32_t i = 0, rc = 0; if (csiphy_dev->csiphy_state == CAM_CSIPHY_INIT) return; @@ -574,7 +574,10 @@ void cam_csiphy_shutdown(struct csiphy_device *csiphy_dev) cam_csiphy_reset(csiphy_dev); cam_soc_util_disable_platform_resource(soc_info, true, true); - cam_cpas_stop(csiphy_dev->cpas_handle); + rc = cam_cpas_stop(csiphy_dev->cpas_handle); + if (rc) + CAM_ERR(CAM_CSIPHY, "cpas stop failed %d", rc); + csiphy_dev->csiphy_state = CAM_CSIPHY_ACQUIRE; } @@ -934,7 +937,10 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, if (rc < 0) { csiphy_dev->csiphy_info.secure_mode[offset] = CAM_SECURE_MODE_NON_SECURE; - cam_cpas_stop(csiphy_dev->cpas_handle); + rc = cam_cpas_stop(csiphy_dev->cpas_handle); + if (rc < 0) + CAM_ERR(CAM_CSIPHY, + "de-voting CPAS: %d", rc); goto release_mutex; } } @@ -942,7 +948,9 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, rc = cam_csiphy_enable_hw(csiphy_dev); if (rc != 0) { CAM_ERR(CAM_CSIPHY, "cam_csiphy_enable_hw failed"); - cam_cpas_stop(csiphy_dev->cpas_handle); + rc = cam_cpas_stop(csiphy_dev->cpas_handle); + if (rc < 0) + CAM_ERR(CAM_CSIPHY, "de-voting CPAS: %d", rc); goto release_mutex; } rc = cam_csiphy_config_dev(csiphy_dev); @@ -952,7 +960,9 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, if (rc < 0) { CAM_ERR(CAM_CSIPHY, "cam_csiphy_config_dev failed"); cam_csiphy_disable_hw(csiphy_dev); - cam_cpas_stop(csiphy_dev->cpas_handle); + rc = cam_cpas_stop(csiphy_dev->cpas_handle); + if (rc < 0) + CAM_ERR(CAM_CSIPHY, "de-voting CPAS: %d", rc); goto release_mutex; } csiphy_dev->start_dev_count++; -- GitLab From 6e083de5a5a0442186d07821c074dda5636af920 Mon Sep 17 00:00:00 2001 From: Rama Krishna Phani A Date: Mon, 1 Jul 2019 11:14:15 +0530 Subject: [PATCH 0818/1121] msm: pcie: add QCS405 device id support Add pci device id support for QCS405 to register root port with PCI driver framework so that it will get probe during PCI enumeration. Change-Id: I94ba432c0e09b9a89fcf1644c80ec4f85b51d9b1 Signed-off-by: Rama Krishna Phani A --- drivers/pci/host/pci-msm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pci/host/pci-msm.c b/drivers/pci/host/pci-msm.c index d844142f5535..1e17d529dcc3 100644 --- a/drivers/pci/host/pci-msm.c +++ b/drivers/pci/host/pci-msm.c @@ -6335,6 +6335,7 @@ int msm_pci_probe(struct pci_dev *pci_dev, static struct pci_device_id msm_pci_device_id[] = { {PCI_DEVICE(0x17cb, 0x0108)}, + {PCI_DEVICE(0x17cb, 0x1000)}, {0}, }; -- GitLab From 5ddc0fe68f43843f61c56023dcf43766af513058 Mon Sep 17 00:00:00 2001 From: Rama Krishna Phani A Date: Mon, 1 Jul 2019 11:02:38 +0530 Subject: [PATCH 0819/1121] ARM: dts: msm: disable lpm and modify boot option for QCS405 Link stability issues are being seen with LPM enabled, Hence disable link low power modes. Modify boot option such that end point enumeration can be initiated by RC during probe. Change-Id: I693bfecfc4cba5ac6862aed009fe976ab237f568 Signed-off-by: Rama Krishna Phani A --- arch/arm64/boot/dts/qcom/qcs405-pcie.dtsi | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/qcs405-pcie.dtsi b/arch/arm64/boot/dts/qcom/qcs405-pcie.dtsi index bda2e511a766..2294ea9e04ca 100644 --- a/arch/arm64/boot/dts/qcom/qcs405-pcie.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs405-pcie.dtsi @@ -82,9 +82,13 @@ qcom,phy-status-offset = <0x3c>; qcom,phy-status-bit = <0>; qcom,phy-power-down-offset = <0x98>; - qcom,boot-option = <0x1>; + qcom,boot-option = <0x0>; qcom,keep-powerdown-phy; + qcom,no-l0s-supported; + qcom,no-l1-supported; + qcom,no-l1ss-supported; + qcom,no-aux-clk-sync; linux,pci-domain = <0>; -- GitLab From 5026b3355e7ff5dbedf48bc903d6a248b139b153 Mon Sep 17 00:00:00 2001 From: Maria Yu Date: Fri, 26 Apr 2019 15:20:18 +0800 Subject: [PATCH 0820/1121] sched/fair: Avoid unnecessary active load balance When find busiest group, it will avoid load balance if it is only 1 task running on src cpu. Consider race when different cpus do newly idle load balance at the same time, check src cpu nr_running to avoid unnecessary active load balance again. See the race condition example here: 1) cpu2 have 2 tasks, so cpu2 rq->nr_running == 2 and cfs.h_nr_running ==2. 2) cpu4 and cpu5 doing newly idle load balance at the same time. 3) cpu4 and cpu5 both see cpu2 sched_load_balance_sg_stats sum_nr_run=2 so they are both see cpu2 as the busiest rq. 4) cpu5 did a success migration task from cpu2, so cpu2 only have 1 task left, cpu2 rq->nr_running == 1 and cfs.h_nr_running ==1. 5) cpu4 surely goes to no_move because currently cpu4 only have 1 task which is currently running. 6) and then cpu4 goes here to check if cpu2 need active load balance. Change-Id: I7c5ea2365f31028e541798cd99f7db993155e9e6 Signed-off-by: Maria Yu --- kernel/sched/fair.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 31e67d999d3e..ee16bb2b6abb 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -10848,9 +10848,10 @@ static int need_active_balance(struct lb_env *env) * It's worth migrating the task if the src_cpu's capacity is reduced * because of other sched_class or IRQs if more capacity stays * available on dst_cpu. + * Avoid pulling the CFS task if it is the only task running. */ if ((env->idle != CPU_NOT_IDLE) && - (env->src_grp_nr_running == 1) && + (env->src_rq->nr_running > 1) && (env->src_rq->cfs.h_nr_running == 1)) { if ((check_cpu_capacity(env->src_rq, sd)) && (capacity_of(env->src_cpu)*sd->imbalance_pct < capacity_of(env->dst_cpu)*100)) -- GitLab From 0983afa8091997ac9d503dddb3293b59beff08a7 Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Tue, 9 Jul 2019 17:58:22 +0530 Subject: [PATCH 0821/1121] Revert "msm: vidc: Check image encode capabilities" This reverts commit cc5e68daf9262461c1e6ad06b36b1d3978ce59bd. CRs-Fixed: 2473618 Change-Id: Ia87796f80d01505788138cd7a1500b41e349b236 Signed-off-by: Manikanta Kanamarlapudi --- drivers/media/platform/msm/vidc/msm_venc.c | 1 - .../media/platform/msm/vidc/msm_vidc_common.c | 64 ------------------- .../platform/msm/vidc/msm_vidc_internal.h | 12 ---- .../platform/msm/vidc/msm_vidc_platform.c | 22 ------- 4 files changed, 99 deletions(-) diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c index e92e3d206cf6..3282b57ed847 100644 --- a/drivers/media/platform/msm/vidc/msm_venc.c +++ b/drivers/media/platform/msm/vidc/msm_venc.c @@ -1606,7 +1606,6 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL, temp_ctrl->val); pdata = &profile_level; - inst->profile = profile_level.profile; break; case V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL: temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE); diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c index 357530ee5e5e..747ce2286511 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_common.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c @@ -5643,65 +5643,6 @@ int msm_vidc_check_scaling_supported(struct msm_vidc_inst *inst) return 0; } -static bool is_image_session(struct msm_vidc_inst *inst) -{ - if (inst->session_type == MSM_VIDC_ENCODER && - get_hal_codec(inst->fmts[CAPTURE_PORT].fourcc) == - HAL_VIDEO_CODEC_HEVC) - return (inst->profile == HAL_HEVC_PROFILE_MAIN_STILL_PIC || - inst->grid_enable); - else - return false; -} - -static int msm_vidc_check_image_session_capabilities(struct msm_vidc_inst *inst) -{ - int rc = 0; - struct msm_vidc_image_capability *capability = NULL; - - u32 output_height = ALIGN(inst->prop.height[CAPTURE_PORT], 512); - u32 output_width = ALIGN(inst->prop.width[CAPTURE_PORT], 512); - - if (inst->grid_enable) - capability = inst->core->platform_data->heic_image_capability; - else - capability = inst->core->platform_data->hevc_image_capability; - - if (!capability) - return -EINVAL; - - if (output_width < capability->width.min || - output_height < capability->height.min) { - dprintk(VIDC_ERR, - "HEIC Unsupported WxH = (%u)x(%u), min supported is - (%u)x(%u)\n", - output_width, - output_height, - capability->width.min, - capability->height.min); - rc = -ENOTSUPP; - } - if (!rc && (output_width > capability->width.max || - output_height > capability->height.max)) { - dprintk(VIDC_ERR, - "HEIC Unsupported WxH = (%u)x(%u), max supported is - (%u)x(%u)\n", - output_width, - output_height, - capability->width.max, - capability->height.max); - rc = -ENOTSUPP; - } - if (!rc && output_height * output_width > - capability->width.max * capability->height.max) { - dprintk(VIDC_ERR, - "HEIC Unsupported WxH = (%u)x(%u), max supported is - (%u)x(%u)\n", - output_width, output_height, - capability->width.max, capability->height.max); - rc = -ENOTSUPP; - } - - return rc; -} - int msm_vidc_check_session_supported(struct msm_vidc_inst *inst) { struct msm_vidc_capability *capability; @@ -5747,11 +5688,6 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst) rc = -ENOTSUPP; } - if (is_image_session(inst)) { - rc = msm_vidc_check_image_session_capabilities(inst); - return rc; - } - output_height = ALIGN(inst->prop.height[CAPTURE_PORT], 16); output_width = ALIGN(inst->prop.width[CAPTURE_PORT], 16); diff --git a/drivers/media/platform/msm/vidc/msm_vidc_internal.h b/drivers/media/platform/msm/vidc/msm_vidc_internal.h index b9cda3e94ec8..cc681d81656c 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_internal.h +++ b/drivers/media/platform/msm/vidc/msm_vidc_internal.h @@ -232,16 +232,6 @@ struct msm_vidc_efuse_data { enum efuse_purpose purpose; }; -struct msm_vidc_capability_range { - u32 min; - u32 max; -}; - -struct msm_vidc_image_capability { - struct msm_vidc_capability_range width; - struct msm_vidc_capability_range height; -}; - enum vpu_version { VPU_VERSION_4 = 1, VPU_VERSION_5, @@ -263,8 +253,6 @@ struct msm_vidc_platform_data { unsigned int efuse_data_length; struct msm_vidc_ubwc_config *ubwc_config; unsigned int ubwc_config_length; - struct msm_vidc_image_capability *heic_image_capability; - struct msm_vidc_image_capability *hevc_image_capability; unsigned int sku_version; uint32_t vpu_ver; }; diff --git a/drivers/media/platform/msm/vidc/msm_vidc_platform.c b/drivers/media/platform/msm/vidc/msm_vidc_platform.c index ca0d912348cd..e4ab7e6a1e93 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_platform.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_platform.c @@ -674,14 +674,6 @@ static struct msm_vidc_ubwc_config trinket_ubwc_data[] = { UBWC_CONFIG(0, 1, 0, 0, 0, 64, 0, 0), }; -static struct msm_vidc_image_capability default_heic_image_capability = { - {512, 8192}, {512, 8192} -}; - -static struct msm_vidc_image_capability default_hevc_image_capability = { - {512, 512}, {512, 512} -}; - static struct msm_vidc_platform_data default_data = { .codec_data = default_codec_data, .codec_data_length = ARRAY_SIZE(default_codec_data), @@ -694,8 +686,6 @@ static struct msm_vidc_platform_data default_data = { .csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff, .efuse_data = NULL, .efuse_data_length = 0, - .heic_image_capability = &default_heic_image_capability, - .hevc_image_capability = &default_hevc_image_capability, .sku_version = 0, .vpu_ver = VPU_VERSION_5, }; @@ -712,8 +702,6 @@ static struct msm_vidc_platform_data sm6150_data = { .csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff, .efuse_data = NULL, .efuse_data_length = 0, - .heic_image_capability = NULL, - .hevc_image_capability = NULL, .sku_version = 0, .vpu_ver = VPU_VERSION_4, }; @@ -730,8 +718,6 @@ static struct msm_vidc_platform_data trinket_data = { .csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff, .efuse_data = NULL, .efuse_data_length = 0, - .heic_image_capability = &default_heic_image_capability, - .hevc_image_capability = &default_hevc_image_capability, .sku_version = 0, .vpu_ver = VPU_VERSION_4, }; @@ -748,8 +734,6 @@ static struct msm_vidc_platform_data sm8150_data = { .csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff, .efuse_data = NULL, .efuse_data_length = 0, - .heic_image_capability = &default_heic_image_capability, - .hevc_image_capability = &default_hevc_image_capability, .sku_version = 0, .vpu_ver = VPU_VERSION_5, }; @@ -766,8 +750,6 @@ static struct msm_vidc_platform_data sdmmagpie_data = { .csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff, .efuse_data = sdmmagpie_efuse_data, .efuse_data_length = ARRAY_SIZE(sdmmagpie_efuse_data), - .heic_image_capability = &default_heic_image_capability, - .hevc_image_capability = &default_hevc_image_capability, .sku_version = 0, .vpu_ver = VPU_VERSION_5, }; @@ -784,8 +766,6 @@ static struct msm_vidc_platform_data sdm845_data = { .csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff, .efuse_data = NULL, .efuse_data_length = 0, - .heic_image_capability = NULL, - .hevc_image_capability = NULL, .sku_version = 0, .vpu_ver = VPU_VERSION_4, }; @@ -802,8 +782,6 @@ static struct msm_vidc_platform_data sdm670_data = { .csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff, .efuse_data = sdm670_efuse_data, .efuse_data_length = ARRAY_SIZE(sdm670_efuse_data), - .heic_image_capability = NULL, - .hevc_image_capability = NULL, .sku_version = 0, .vpu_ver = VPU_VERSION_4, }; -- GitLab From 310a9cbc406da40d0c545e1120480d45ef4fdfa2 Mon Sep 17 00:00:00 2001 From: Rama Krishna Phani A Date: Thu, 4 Jul 2019 20:16:47 +0530 Subject: [PATCH 0822/1121] mhi: core: Transition to READY state if EE is pass through Do MHI reset to ready state transition if EE is pass through. CRs-Fixed: 2486188 Change-Id: Ib09a81e5878037b3892dbadee94a505991ebf2de Acked-by: Bhaumik Vasav Bhatt Signed-off-by: Rama Krishna Phani A --- drivers/bus/mhi/core/mhi_boot.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/bus/mhi/core/mhi_boot.c b/drivers/bus/mhi/core/mhi_boot.c index 6f4c24f659ca..ccde51335022 100644 --- a/drivers/bus/mhi/core/mhi_boot.c +++ b/drivers/bus/mhi/core/mhi_boot.c @@ -441,9 +441,9 @@ void mhi_fw_load_worker(struct work_struct *work) MHI_LOG("Device current EE:%s\n", TO_MHI_EXEC_STR(mhi_cntrl->ee)); - /* if device in pthru, we do not have to load firmware */ + /* if device in pthru, do reset to ready state transition */ if (mhi_cntrl->ee == MHI_EE_PTHRU) - return; + goto fw_load_ee_pthru; fw_name = (mhi_cntrl->ee == MHI_EE_EDL) ? mhi_cntrl->edl_image : mhi_cntrl->fw_image; @@ -507,6 +507,7 @@ void mhi_fw_load_worker(struct work_struct *work) mhi_firmware_copy(mhi_cntrl, firmware, mhi_cntrl->fbc_image); } +fw_load_ee_pthru: /* transitioning into MHI RESET->READY state */ ret = mhi_ready_state_transition(mhi_cntrl); -- GitLab From 1b6e4127eba1905fac46c1a104b68140557af8d9 Mon Sep 17 00:00:00 2001 From: Zhiqiang Tu Date: Tue, 9 Jul 2019 11:18:28 +0800 Subject: [PATCH 0823/1121] ARM: dts: msm: Enable uart for sa8155 virtual machine on single mode Uart is not required on multi mode. Change-Id: Iab640bfe3d674ca2210e34fe3f55086701d4adc1 Signed-off-by: Zhiqiang Tu --- arch/arm64/boot/dts/qcom/sa8155-vm-lv.dts | 4 ++++ arch/arm64/boot/dts/qcom/sa8155-vm.dts | 4 ++++ arch/arm64/boot/dts/qcom/sa8155-vm.dtsi | 4 ---- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sa8155-vm-lv.dts b/arch/arm64/boot/dts/qcom/sa8155-vm-lv.dts index a409dc74b083..28aa9ce98841 100644 --- a/arch/arm64/boot/dts/qcom/sa8155-vm-lv.dts +++ b/arch/arm64/boot/dts/qcom/sa8155-vm-lv.dts @@ -29,6 +29,10 @@ status = "ok"; }; +&qupv3_se13_4uart { + status = "ok"; +}; + &usb0 { status = "ok"; }; diff --git a/arch/arm64/boot/dts/qcom/sa8155-vm.dts b/arch/arm64/boot/dts/qcom/sa8155-vm.dts index 2b2d2e8b53d4..8f9a719cd249 100644 --- a/arch/arm64/boot/dts/qcom/sa8155-vm.dts +++ b/arch/arm64/boot/dts/qcom/sa8155-vm.dts @@ -22,6 +22,10 @@ status = "ok"; }; +&qupv3_se13_4uart { + status = "ok"; +}; + &usb0 { status = "ok"; }; diff --git a/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi b/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi index 2b18f9aa9242..85fbb7da51be 100644 --- a/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi @@ -494,7 +494,3 @@ &tlmm { dirconn-list = <37 216 1>; }; - -&qupv3_se13_4uart { - status = "ok"; -}; -- GitLab From db922aa00fe29e5d388bfd86094cd9bc3e64a5e4 Mon Sep 17 00:00:00 2001 From: Zhiqiang Tu Date: Tue, 9 Jul 2019 13:05:07 +0800 Subject: [PATCH 0824/1121] ARM: dts: msm: Add devices for sa8155 virtual machines on multi mode Update the device allocation for virtual machines. Change-Id: Ibf7998e6c89b9450ad8737f38d4ec830bc47c1f9 Signed-off-by: Zhiqiang Tu --- arch/arm64/boot/dts/qcom/Makefile | 1 + arch/arm64/boot/dts/qcom/sa8155-vm-la-mt.dts | 30 ++++++++++++++++++++ arch/arm64/boot/dts/qcom/sa8155-vm-lv-mt.dts | 12 ++++++++ 3 files changed, 43 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/sa8155-vm-la-mt.dts diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index d31d7aa4926e..33ecfef5ebbc 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -102,6 +102,7 @@ endif dtb-$(CONFIG_QTI_GVM) += sa8155-vm.dtb \ sa8155-vm-lv.dtb \ sa8155-vm-lv-mt.dtb \ + sa8155-vm-la-mt.dtb \ sa6155p-vm.dtb \ sa8195-vm.dtb diff --git a/arch/arm64/boot/dts/qcom/sa8155-vm-la-mt.dts b/arch/arm64/boot/dts/qcom/sa8155-vm-la-mt.dts new file mode 100644 index 000000000000..ad4132c52f38 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sa8155-vm-la-mt.dts @@ -0,0 +1,30 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "sa8155-vm.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. SA8155 Virtual Machine"; + compatible = "qcom,sa8155"; + qcom,pmic-name = "PM8150"; + qcom,board-id = <0 0>; +}; + +&slpi_tlmm { + status = "ok"; +}; + +&apps_smmu { + status = "ok"; +}; diff --git a/arch/arm64/boot/dts/qcom/sa8155-vm-lv-mt.dts b/arch/arm64/boot/dts/qcom/sa8155-vm-lv-mt.dts index e686cf9d7d76..c2a9e394cbaa 100644 --- a/arch/arm64/boot/dts/qcom/sa8155-vm-lv-mt.dts +++ b/arch/arm64/boot/dts/qcom/sa8155-vm-lv-mt.dts @@ -33,6 +33,10 @@ status = "ok"; }; +&qupv3_se13_4uart { + status = "ok"; +}; + &usb0 { status = "ok"; }; @@ -41,6 +45,14 @@ status = "ok"; }; +&pcie0_msi { + status = "ok"; +}; + +&pcie0 { + status = "ok"; +}; + &sde_kms_hyp { /delete-property/ qcom,client-id; qcom,client-id = "7816"; -- GitLab From 2304af342f8d082db657a01510b501c4a750a939 Mon Sep 17 00:00:00 2001 From: Jishnu Prakash Date: Wed, 10 Jul 2019 15:11:55 +0530 Subject: [PATCH 0825/1121] thermal: adc_tm: Ensure drvdata is set for all adc_tm instances For adc_tm instances of type iio, drvdata is not set before exiting probe, which may lead to issues when dev_pm_ops are used. Set drvdata for these adc_tm instances too. Change-Id: If78162455abf44d3071a8816582262d776a12318 Signed-off-by: Jishnu Prakash --- drivers/thermal/qcom/adc-tm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/thermal/qcom/adc-tm.c b/drivers/thermal/qcom/adc-tm.c index 3cefd0a68dde..d7bfc038c696 100644 --- a/drivers/thermal/qcom/adc-tm.c +++ b/drivers/thermal/qcom/adc-tm.c @@ -359,6 +359,8 @@ static int adc_tm_probe(struct platform_device *pdev) adc_tm->base = reg; adc_tm->dt_channels = dt_chan_num; + platform_set_drvdata(pdev, adc_tm); + revid_dev_node = of_parse_phandle(node, "qcom,pmic-revid", 0); if (revid_dev_node) { adc_tm->pmic_rev_id = get_revid_data(revid_dev_node); @@ -402,7 +404,6 @@ static int adc_tm_probe(struct platform_device *pdev) } list_add_tail(&adc_tm->list, &adc_tm_device_list); - platform_set_drvdata(pdev, adc_tm); return 0; fail: i = 0; -- GitLab From 2e07f2a201f60b048fdaade20f121de918811c63 Mon Sep 17 00:00:00 2001 From: Ajay Agarwal Date: Tue, 25 Jun 2019 10:45:41 +0530 Subject: [PATCH 0826/1121] ARM: dts: msm: Add regulator and peripheral devices for SA8195 Add regulator devices for sa8195 as RPMh regulators. This ensures that consumers are able to modify the physical state of the PMIC regulators. Also add the PMIC peripheral devices nodes like PON, GPIOs, CLK-DIV and TEMP-ALARM. Change-Id: Ic9e1686e049d07b05bda77ada89996851f49478e Signed-off-by: Ajay Agarwal --- arch/arm64/boot/dts/qcom/pm8195.dtsi | 251 ++++++ arch/arm64/boot/dts/qcom/sa8195-pmic.dtsi | 121 +++ .../arm64/boot/dts/qcom/sa8195p-adp-star.dtsi | 1 + .../boot/dts/qcom/sa8195p-regulator.dtsi | 837 ++++++++++++++++++ 4 files changed, 1210 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/pm8195.dtsi create mode 100644 arch/arm64/boot/dts/qcom/sa8195-pmic.dtsi diff --git a/arch/arm64/boot/dts/qcom/pm8195.dtsi b/arch/arm64/boot/dts/qcom/pm8195.dtsi new file mode 100644 index 000000000000..51036638acb1 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/pm8195.dtsi @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include + +&spmi_bus { + qcom,pm8195@0 { + compatible = "qcom,spmi-pmic"; + reg = <0x0 SPMI_USID>; + #address-cells = <2>; + #size-cells = <0>; + + pm8195_1_tz: qcom,temp-alarm@2400 { + compatible = "qcom,spmi-temp-alarm"; + reg = <0x2400 0x100>; + interrupts = <0x0 0x24 0x0 IRQ_TYPE_EDGE_RISING>; + #thermal-sensor-cells = <0>; + qcom,temperature-threshold-set = <1>; + }; + + qcom,power-on@800 { + compatible = "qcom,qpnp-power-on"; + reg = <0x800 0x100>; + interrupts = <0x0 0x8 0x0 IRQ_TYPE_NONE>, + <0x0 0x8 0x1 IRQ_TYPE_NONE>; + interrupt-names = "kpdpwr", "resin"; + qcom,pon-dbc-delay = <15625>; + qcom,kpdpwr-sw-debounce; + qcom,system-reset; + qcom,store-hard-reset-reason; + + qcom,pon_1 { + qcom,pon-type = ; + qcom,pull-up = <1>; + linux,code = ; + }; + + qcom,pon_2 { + qcom,pon-type = ; + qcom,pull-up; + linux,code = ; + }; + }; + + pm8195_1_clkdiv: clock-controller@5b00 { + compatible = "qcom,spmi-clkdiv"; + reg = <0x5b00 0x200>; + #clock-cells = <1>; + qcom,num-clkdivs = <2>; + clock-output-names = "pm8195_1_div_clk1", + "pm8195_1_div_clk2"; + clocks = <&clock_rpmh RPMH_CXO_CLK>; + clock-names = "xo"; + }; + + pm8195_1_rtc: qcom,pm8195_1_rtc { + compatible = "qcom,qpnp-rtc"; + #address-cells = <1>; + #size-cells = <1>; + qcom,qpnp-rtc-write = <0>; + qcom,qpnp-rtc-alarm-pwrup = <0>; + + qcom,pm8195_1_rtc_rw@6000 { + reg = <0x6000 0x100>; + }; + qcom,pm8195_1_rtc_alarm@6100 { + reg = <0x6100 0x100>; + interrupts = <0x0 0x61 0x1 IRQ_TYPE_NONE>; + }; + }; + + pm8195_1_gpios: pinctrl@c000 { + compatible = "qcom,spmi-gpio"; + reg = <0xc000 0xa00>; + interrupts = <0x0 0xc0 0 IRQ_TYPE_NONE>, + <0x0 0xc1 0 IRQ_TYPE_NONE>, + <0x0 0xc2 0 IRQ_TYPE_NONE>, + <0x0 0xc3 0 IRQ_TYPE_NONE>, + <0x0 0xc4 0 IRQ_TYPE_NONE>, + <0x0 0xc5 0 IRQ_TYPE_NONE>, + <0x0 0xc6 0 IRQ_TYPE_NONE>, + <0x0 0xc7 0 IRQ_TYPE_NONE>, + <0x0 0xc8 0 IRQ_TYPE_NONE>, + <0x0 0xc9 0 IRQ_TYPE_NONE>; + interrupt-names = "pm8195_1_gpio1", "pm8195_1_gpio2", + "pm8195_1_gpio3", "pm8195_1_gpio4", + "pm8195_1_gpio5", "pm8195_1_gpio6", + "pm8195_1_gpio7", "pm8195_1_gpio8", + "pm8195_1_gpio9", "pm8195_1_gpio10"; + gpio-controller; + #gpio-cells = <2>; + }; + + pm8195_1_sdam_2: sdam@b100 { + compatible = "qcom,spmi-sdam"; + reg = <0xb100 0x100>; + }; + + }; + + qcom,pm8195@1 { + compatible ="qcom,spmi-pmic"; + reg = <0x1 SPMI_USID>; + #address-cells = <2>; + #size-cells = <0>; + }; + + /* below definitions are for the second instance of pm8195 */ + qcom,pm8195@4 { + compatible = "qcom,spmi-pmic"; + reg = <0x4 SPMI_USID>; + #address-cells = <1>; + #size-cells = <1>; + + qcom,power-on@800 { + compatible = "qcom,qpnp-power-on"; + reg = <0x800 0x100>; + }; + + pm8195_2_clkdiv: clock-controller@5b00 { + compatible = "qcom,spmi-clkdiv"; + reg = <0x5b00 0x200>; + #clock-cells = <1>; + qcom,num-clkdivs = <2>; + clock-output-names = "pm8195_2_div_clk1", + "pm8195_2_div_clk2"; + clocks = <&clock_rpmh RPMH_CXO_CLK>; + clock-names = "xo"; + }; + + pm8195_2_gpios: pinctrl@c000 { + compatible = "qcom,spmi-gpio"; + reg = <0xc000 0xa00>; + interrupts = <0x4 0xc0 0 IRQ_TYPE_NONE>, + <0x4 0xc1 0 IRQ_TYPE_NONE>, + <0x4 0xc2 0 IRQ_TYPE_NONE>, + <0x4 0xc3 0 IRQ_TYPE_NONE>, + <0x4 0xc4 0 IRQ_TYPE_NONE>, + <0x4 0xc5 0 IRQ_TYPE_NONE>, + <0x4 0xc6 0 IRQ_TYPE_NONE>, + <0x4 0xc7 0 IRQ_TYPE_NONE>, + <0x4 0xc8 0 IRQ_TYPE_NONE>, + <0x4 0xc9 0 IRQ_TYPE_NONE>; + interrupt-names = "pm8195_2_gpio1", "pm8195_2_gpio2", + "pm8195_2_gpio3", "pm8195_2_gpio4", + "pm8195_2_gpio5", "pm8195_2_gpio6", + "pm8195_2_gpio7", "pm8195_2_gpio8", + "pm8195_2_gpio9", "pm8195_2_gpio10"; + gpio-controller; + #gpio-cells = <2>; + }; + }; + + qcom,pm8195@5 { + compatible ="qcom,spmi-pmic"; + reg = <0x5 SPMI_USID>; + #address-cells = <1>; + #size-cells = <1>; + }; + + /* below definitions are for the third instance of pm8195 */ + qcom,pm8195@8 { + compatible = "qcom,spmi-pmic"; + reg = <0x8 SPMI_USID>; + #address-cells = <1>; + #size-cells = <1>; + + qcom,power-on@800 { + compatible = "qcom,qpnp-power-on"; + reg = <0x800 0x100>; + }; + + pm8195_3_clkdiv: clock-controller@5b00 { + compatible = "qcom,spmi-clkdiv"; + reg = <0x5b00 0x200>; + #clock-cells = <1>; + qcom,num-clkdivs = <2>; + clock-output-names = "pm8195_3_div_clk1", + "pm8195_3_div_clk2"; + clocks = <&clock_rpmh RPMH_CXO_CLK>; + clock-names = "xo"; + }; + + pm8195_3_gpios: pinctrl@c000 { + compatible = "qcom,spmi-gpio"; + reg = <0xc000 0xa00>; + interrupts = <0x8 0xc0 0 IRQ_TYPE_NONE>, + <0x8 0xc1 0 IRQ_TYPE_NONE>, + <0x8 0xc2 0 IRQ_TYPE_NONE>, + <0x8 0xc3 0 IRQ_TYPE_NONE>, + <0x8 0xc4 0 IRQ_TYPE_NONE>, + <0x8 0xc5 0 IRQ_TYPE_NONE>, + <0x8 0xc6 0 IRQ_TYPE_NONE>, + <0x8 0xc7 0 IRQ_TYPE_NONE>, + <0x8 0xc8 0 IRQ_TYPE_NONE>, + <0x8 0xc9 0 IRQ_TYPE_NONE>; + interrupt-names = "pm8195_3_gpio1", "pm8195_3_gpio2", + "pm8195_3_gpio3", "pm8195_3_gpio4", + "pm8195_3_gpio5", "pm8195_3_gpio6", + "pm8195_3_gpio7", "pm8195_3_gpio8", + "pm8195_3_gpio9", "pm8195_3_gpio10"; + gpio-controller; + #gpio-cells = <2>; + }; + }; + + qcom,pm8195@9 { + compatible ="qcom,spmi-pmic"; + reg = <0x9 SPMI_USID>; + #address-cells = <1>; + #size-cells = <1>; + }; +}; + +/* PMIC GPIO pin control configurations */ +&pm8195_1_gpios { + storage_sd_detect { + storage_cd_default: storage_cd_default { + pins = "gpio4"; + function = "normal"; + input-enable; + bias-pull-up; + power-source = <0>; + }; + }; + + key_vol_up { + key_vol_up_default: key_vol_up_default { + pins = "gpio6"; + function = "normal"; + input-enable; + bias-pull-up; + power-source = <1>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/sa8195-pmic.dtsi b/arch/arm64/boot/dts/qcom/sa8195-pmic.dtsi new file mode 100644 index 000000000000..2cdf7df42ed9 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sa8195-pmic.dtsi @@ -0,0 +1,121 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* Remove regulator nodes specific to sdmshrike */ +&soc { + /* Stub regulators */ + /delete-node/ regulator-pm8150_1-s4; + + /* Logical rails */ + /delete-node/ rpmh-regulator-cxlvl; + /delete-node/ rpmh-regulator-mxlvl; + /delete-node/ rpmh-regulator-gfxlvl; + /delete-node/ rpmh-regulator-lmxlvl; + /delete-node/ rpmh-regulator-lcxlvl; + /delete-node/ rpmh-regulator-mmcxlvl; + /delete-node/ rpmh-regulator-msslvl; + /delete-node/ rpmh-regulator-ebilvl; + + /* PM8150_1 regulators */ + /delete-node/ rpmh-regulator-smpa5; + /delete-node/ rpmh-regulator-ldoa3; + /delete-node/ rpmh-regulator-ldoa5; + /delete-node/ rpmh-regulator-ldoa6; + /delete-node/ rpmh-regulator-ldoa7; + /delete-node/ rpmh-regulator-ldoa9; + /delete-node/ rpmh-regulator-ldoa11; + /delete-node/ rpmh-regulator-ldoa12; + /delete-node/ rpmh-regulator-ldoa13; + /delete-node/ rpmh-regulator-ldoa15; + /delete-node/ rpmh-regulator-ldoa16; + /delete-node/ rpmh-regulator-ldoa18; + /delete-node/ rpmh-regulator-smpe4; + /delete-node/ rpmh-regulator-smpe5; + /delete-node/ rpmh-regulator-ldoe1; + /delete-node/ rpmh-regulator-ldoe2; + /delete-node/ rpmh-regulator-ldoe5; + /delete-node/ rpmh-regulator-ldoe7; + /delete-node/ rpmh-regulator-ldoe10; + /delete-node/ rpmh-regulator-ldoe13; + /delete-node/ rpmh-regulator-ldoe14; + /delete-node/ rpmh-regulator-ldoe15; + /delete-node/ rpmh-regulator-ldoe16; + /delete-node/ rpmh-regulator-ldoe17; + /delete-node/ rpmh-regulator-smpc6; + /delete-node/ rpmh-regulator-smpc7; + /delete-node/ rpmh-regulator-smpc8; + /delete-node/ rpmh-regulator-ldoc1; + /delete-node/ rpmh-regulator-ldoc2; + /delete-node/ rpmh-regulator-ldoc3; + /delete-node/ rpmh-regulator-ldoc4; + /delete-node/ rpmh-regulator-ldoc6; + /delete-node/ rpmh-regulator-ldoc7; + /delete-node/ rpmh-regulator-ldoc8; + /delete-node/ rpmh-regulator-ldoc9; + /delete-node/ rpmh-regulator-ldoc10; + /delete-node/ rpmh-regulator-ldoc11; + /delete-node/ rpmh-regulator-bobc1; + + /* refgen-regulator@88e7000 */ + /delete-node/ refgen; +}; + +&usb2_phy0 { + /delete-property/ vdd-supply; + /delete-property/ vdda18-supply; + /delete-property/ vdda33-supply; +}; + +&mdss_dsi0 { + vdda-1p2-supply = <&pm8195_1_l9>; +}; + +&mdss_dsi1 { + vdda-1p2-supply = <&pm8195_1_l9>; +}; + +&mdss_dsi_phy0 { + vdda-0p9-supply = <&pm8195_3_l5>; +}; + +&mdss_dsi_phy1 { + vdda-0p9-supply = <&pm8195_3_l5>; +}; + +&clock_cpucc { + lmh_dcvs1: qcom,limits-dcvs@18350800 { + isens_vref_0p8-supply = <&pm8195_3_l5>; + isens-vref-0p8-settings = <880000 880000 20000>; + isens_vref_1p8-supply = <&pm8195_1_l12>; + isens-vref-1p8-settings = <1800000 1800000 20000>; + }; +}; + + +&soc { + qcom,lpass@17300000 { + vdd_cx-supply = <&VDD_CX_LEVEL>; + }; + clock_camcc: qcom,camcc@ad00000 { + vdd_mx-supply = <&VDD_MX_LEVEL>; + vdd_mm-supply = <&VDD_MMCX_LEVEL>; + }; +}; + +&gpu_gx_gdsc { + parent-supply = <&VDD_MMCX_LEVEL>; + vdd_parent-supply = <&VDD_MMCX_LEVEL>; +}; + +#include "sa8195p-regulator.dtsi" +#include "pm8195.dtsi" + diff --git a/arch/arm64/boot/dts/qcom/sa8195p-adp-star.dtsi b/arch/arm64/boot/dts/qcom/sa8195p-adp-star.dtsi index 02e46d986949..e404382fdfbd 100644 --- a/arch/arm64/boot/dts/qcom/sa8195p-adp-star.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8195p-adp-star.dtsi @@ -11,6 +11,7 @@ */ #include +#include "sa8195-pmic.dtsi" &qupv3_se0_spi { status = "ok"; diff --git a/arch/arm64/boot/dts/qcom/sa8195p-regulator.dtsi b/arch/arm64/boot/dts/qcom/sa8195p-regulator.dtsi index 80b26749a594..b7696d23f8d7 100644 --- a/arch/arm64/boot/dts/qcom/sa8195p-regulator.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8195p-regulator.dtsi @@ -11,3 +11,840 @@ */ #include + +&soc { + /* Stub regulator */ + /* + * RPMh does not provide support for PM8195 S4 because it is always-on + * at 1.8 V in auto mode. Therefore, use a stub regulator for S4. + */ + S4A: pm8195_s4: regulator-pm8195-s4 { + compatible = "qcom,stub-regulator"; + regulator-name = "pm8195_s4"; + qcom,hpm-min-load = <100000>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + /* PM8195_1 S1 = VDD_EBI supply */ + rpmh-regulator-ebilvl { + compatible = "qcom,rpmh-arc-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ebi.lvl"; + S1A_LEVEL: pm8195_1_s1_level: regulator-pm8195-1-s1-level { + regulator-name = "pm8195_1_s1_level"; + qcom,set = ; + regulator-min-microvolt + = ; + regulator-max-microvolt + = ; + qcom,init-voltage-level + = ; + }; + + ebi_cdev: regulator-cdev { + compatible = "qcom,rpmh-reg-cdev"; + mboxes = <&qmp_aop 0>; + qcom,reg-resource-name = "ebi"; + #cooling-cells = <2>; + }; + }; + + /* PM8195_1 S2 = VDDCX_MM supply */ + rpmh-regulator-mmcxlvl { + compatible = "qcom,rpmh-arc-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "mmcx.lvl"; + + VDD_MMCX_LEVEL: + S7A_LEVEL: pm8195_1_s7_level: regulator-pm8195-1-s7-level { + regulator-name = "pm8195_1_s7_level"; + qcom,set = ; + regulator-min-microvolt + = ; + regulator-max-microvolt + = ; + qcom,init-voltage-level + = ; + }; + + VDD_MMCX_LEVEL_AO: S7A_LEVEL_AO: + pm8195_1_s7_level_ao: regulator-pm8195-1-s7-level-ao { + regulator-name = "pm8195_1_s7_level_ao"; + qcom,set = ; + regulator-min-microvolt + = ; + regulator-max-microvolt + = ; + qcom,init-voltage-level + = ; + }; + + mm_cx_cdev: mm-cx-cdev-lvl { + compatible = "qcom,regulator-cooling-device"; + regulator-cdev-supply = <&VDD_MMCX_LEVEL_AO>; + regulator-levels = ; + #cooling-cells = <2>; + }; + }; + + rpmh-regulator-smpa3 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "smpa3"; + S3A: pm8195_1_s3: regulator-pm8195-1-s3 { + regulator-name = "pm8195_1_s3"; + qcom,set = ; + regulator-min-microvolt = <788000>; + regulator-max-microvolt = <969000>; + qcom,init-voltage = <788000>; + }; + }; + + rpmh-regulator-smpa5 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "smpa5"; + S5A: pm8195_1_s5: regulator-pm8195-1-s5 { + regulator-name = "pm8195_1_s5"; + qcom,set = ; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1000000>; + qcom,init-voltage = <900000>; + }; + }; + + rpmh-regulator-smpa6 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "smpa6"; + S6A: pm8195_1_s6: regulator-pm8195-1-s6 { + regulator-name = "pm8195_1_s6"; + qcom,set = ; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1300000>; + qcom,init-voltage = <800000>; + }; + }; + + rpmh-regulator-smpa2 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "smpa2"; + S2A: pm8195_1_s2: regulator-pm8195-1-s2 { + regulator-name = "pm8195_1_s2"; + qcom,set = ; + regulator-min-microvolt = <1179000>; + regulator-max-microvolt = <1379000>; + qcom,init-voltage = <1179000>; + }; + }; + + /* pm8195_1 S8 = VDD_MODEM supply */ + rpmh-regulator-msslvl { + compatible = "qcom,rpmh-arc-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "mss.lvl"; + VDD_MSS_LEVEL: + S8A_LEVEL: pm8195_1_s8_level: regulator-pm8195-1-s8-level { + regulator-name = "pm8195_1_s8_level"; + qcom,set = ; + regulator-min-microvolt + = ; + regulator-max-microvolt + = ; + qcom,init-voltage-level + = ; + }; + }; + + /* PM8195_1 S10 = VDD_MX supply */ + rpmh-regulator-mxlvl { + compatible = "qcom,rpmh-arc-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "mx.lvl"; + + VDD_MX_LEVEL: + S10A_LEVEL: pm8195_1_s10_level: regulator-pm8195-1-s10-level { + regulator-name = "pm8195_1_s10_level"; + qcom,set = ; + regulator-min-microvolt + = ; + regulator-max-microvolt + = ; + qcom,init-voltage-level + = ; + }; + + VDD_MX_LEVEL_AO: S10A_LEVEL_AO: + pm8195_1_s10_level_ao: regulator-pm8195-1-s10-level-ao { + regulator-name = "pm8195_1_s10_level_ao"; + qcom,set = ; + regulator-min-microvolt + = ; + regulator-max-microvolt + = ; + qcom,init-voltage-level + = ; + }; + + mx_cdev: mx-cdev-lvl { + compatible = "qcom,regulator-cooling-device"; + regulator-cdev-supply = <&VDD_MX_LEVEL>; + regulator-levels = ; + #cooling-cells = <2>; + }; + }; + + rpmh-regulator-ldoa2 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoa2"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L2A: pm8195_1_l2: regulator-pm8195-1-l2 { + regulator-name = "pm8195_1_l2"; + qcom,set = ; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + qcom,init-voltage = <1800000>; + qcom,init-mode = ; + }; + }; + + rpmh-regulator-ldoa3 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoa3"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L3A: pm8195_1_l3: regulator-pm8195-1-l3 { + regulator-name = "pm8195_1_l3"; + qcom,set = ; + regulator-min-microvolt = <760000>; + regulator-max-microvolt = <816000>; + qcom,init-voltage = <760000>; + qcom,init-mode = ; + }; + }; + + rpmh-regulator-ldoa5 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoa5"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L5A: pm8195_1_l5: regulator-pm8195-1-l5 { + regulator-name = "pm8195_1_l5"; + qcom,set = ; + regulator-min-microvolt = <720000>; + regulator-max-microvolt = <880000>; + qcom,init-voltage = <720000>; + qcom,init-mode = ; + }; + }; + + /* DSI display 1.2 */ + rpmh-regulator-ldoa9 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoa9"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L9A: pm8195_1_l9: regulator-pm8195-1-l9 { + regulator-name = "pm8195_1_l9"; + qcom,set = ; + regulator-min-microvolt = <1150000>; + regulator-max-microvolt = <1250000>; + qcom,init-voltage = <1150000>; + qcom,init-mode = ; + }; + }; + + rpmh-regulator-ldoa10 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoa10"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L10A: pm8195_1_l10: regulator-pm8195-1-l10 { + regulator-name = "pm8195_1_l10"; + qcom,set = ; + regulator-min-microvolt = <2700000>; + regulator-max-microvolt = <3544000>; + qcom,init-voltage = <2700000>; + qcom,init-mode = ; + }; + }; + + rpmh-regulator-ldoa11 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoa11"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L11A: pm8195_1_l11: regulator-pm8195-1-l11 { + regulator-name = "pm8195_1_l11"; + qcom,set = ; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1300000>; + qcom,init-voltage = <1100000>; + qcom,init-mode = ; + }; + }; + + rpmh-regulator-ldoa12 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoa12"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L12A: pm8195_1_l12: regulator-pm8195-1-l12 { + regulator-name = "pm8195_1_l12"; + qcom,set = ; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1890000>; + qcom,init-voltage = <1800000>; + qcom,init-mode = ; + }; + }; + + rpmh-regulator-ldoa13 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoa13"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L13A: pm8195_1_l13: regulator-pm8195-1-l13 { + regulator-name = "pm8195_1_l13"; + qcom,set = ; + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2900000>; + qcom,init-voltage = <2500000>; + qcom,init-mode = ; + }; + }; + + rpmh-regulator-ldoa15 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoa15"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L15A: pm8195_1_l15: regulator-pm8195-1-l15 { + regulator-name = "pm8195_1_l15"; + qcom,set = ; + regulator-min-microvolt = <1700000>; + regulator-max-microvolt = <1751000>; + qcom,init-voltage = <1700000>; + qcom,init-mode = ; + }; + }; + + rpmh-regulator-ldoa16 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoa16"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L16A: pm8195_1_l16: regulator-pm8195-1-l16 { + regulator-name = "pm8195_1_l16"; + qcom,set = ; + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2900000>; + qcom,init-voltage = <2500000>; + qcom,init-mode = ; + }; + }; + + + rpmh-regulator-ldoa17 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoa17"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L17A: pm8195_1_l17: regulator-pm8195-1-l17 { + regulator-name = "pm8195_1_l17"; + qcom,set = ; + regulator-min-microvolt = <1700000>; + regulator-max-microvolt = <3544000>; + qcom,init-voltage = <1700000>; + qcom,init-mode = ; + }; + }; + + rpmh-regulator-ldoa18 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoa18"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L18A: pm8195_1_l18: regulator-pm8195-1-l18 { + regulator-name = "pm8195_1_l18"; + qcom,set = ; + regulator-min-microvolt = <831000>; + regulator-max-microvolt = <918000>; + qcom,init-voltage = <831000>; + qcom,init-mode = ; + }; + }; + + rpmh-regulator-smpc1 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "smpc1"; + S1C: pm8195_2_s1: regulator-pm8195-2-s1 { + regulator-name = "pm8195_2_s1"; + qcom,set = ; + regulator-min-microvolt = <570000>; + regulator-max-microvolt = <648000>; + qcom,init-voltage = <570000>; + }; + }; + + rpmh-regulator-smpc2 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "smpc2"; + S2C: pm8195_2_s2: regulator-pm8195-2-s2 { + regulator-name = "pm8195_2_s2"; + qcom,set = ; + regulator-min-microvolt = <1060000>; + regulator-max-microvolt = <1170000>; + qcom,init-voltage = <1060000>; + }; + }; + + rpmh-regulator-smpc4 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "smpc4"; + S4C: pm8195_2_s4: regulator-pm8195-2-s4 { + regulator-name = "pm8195_2_s4"; + qcom,set = ; + regulator-min-microvolt = <1620000>; + regulator-max-microvolt = <1900000>; + qcom,init-voltage = <1620000>; + }; + }; + + rpmh-regulator-smpc5 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "smpc5"; + S5C: pm8195_2_s5: regulator-pm8195-2-s5 { + regulator-name = "pm8195_2_s5"; + qcom,set = ; + regulator-min-microvolt = <1713000>; + regulator-max-microvolt = <2040000>; + qcom,init-voltage = <1713000>; + }; + }; + + /* PM8195_2 S10 + S9 + S8 + S7 + S6 = VDD_GFX supply */ + rpmh-regulator-gfxlvl { + compatible = "qcom,rpmh-arc-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "gfx.lvl"; + VDD_GFX: + S10C_LEVEL: pm8195_2_s10_level: regulator-pm8195-2-s10-level { + regulator-name = "pm8195_2_s10_level"; + qcom,set = ; + regulator-min-microvolt + = ; + regulator-max-microvolt + = ; + qcom,init-voltage-level + = ; + }; + }; + + rpmh-regulator-ldoc2 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoc2"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L2C: pm8195_2_l2: regulator-pm8195-2-l2 { + regulator-name = "pm8195_2_l2"; + qcom,set = ; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3330000>; + qcom,init-voltage = <1800000>; + qcom,init-mode = ; + }; + }; + + rpmh-regulator-ldoc5 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoa5"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L5C: pm8195_2_l5: regulator-pm8195-2-l5 { + regulator-name = "pm8195_2_l5"; + qcom,set = ; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + qcom,init-voltage = <1200000>; + qcom,init-mode = ; + }; + }; + + rpmh-regulator-ldoc7 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoc7"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L7C: pm8195_2_l7: regulator-pm8195-2-l7 { + regulator-name = "pm8195_2_l7"; + qcom,set = ; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2040000>; + qcom,init-voltage = <1800000>; + qcom,init-mode = ; + }; + }; + + rpmh-regulator-ldoc10 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoc10"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L10C: pm8195_2_l10: regulator-pm8195-2-l10 { + regulator-name = "pm8195_2_l10"; + qcom,set = ; + regulator-min-microvolt = <1620000>; + regulator-max-microvolt = <3300000>; + qcom,init-voltage = <1620000>; + qcom,init-mode = ; + }; + }; + + rpmh-regulator-ldoc11 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoc11"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L11C: pm8195_2_l11: regulator-pm8195-2-l11 { + regulator-name = "pm8195_2_l11"; + qcom,set = ; + regulator-min-microvolt = <1144000>; + regulator-max-microvolt = <1236000>; + qcom,init-voltage = <1144000>; + qcom,init-mode = ; + }; + }; + + rpmh-regulator-ldoc12 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoc12"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L12C: pm8195_2_l12: regulator-pm8195-2-l12 { + regulator-name = "pm8195_2_l12"; + qcom,set = ; + regulator-min-microvolt = <1700000>; + regulator-max-microvolt = <1900000>; + qcom,init-voltage = <1700000>; + qcom,init-mode = ; + }; + }; + + + /* PM8195_3 S3 + S2 + S1 = VDD_CX supply */ + rpmh-regulator-cxlvl { + compatible = "qcom,rpmh-arc-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "cx.lvl"; + pm8195_3_s3_level-parent-supply = <&VDD_MX_LEVEL>; + pm8195_3_s3_level_ao-parent-supply = <&VDD_MX_LEVEL_AO>; + + VDD_CX_LEVEL: + S3E_LEVEL: pm8195_3_s3_level: regulator-pm8195-3-s3-level { + regulator-name = "pm8195_3_s3_level"; + qcom,set = ; + regulator-min-microvolt + = ; + regulator-max-microvolt + = ; + qcom,init-voltage-level + = ; + qcom,min-dropout-voltage-level = <(-1)>; + }; + + VDD_CX_LEVEL_AO: S3E_LEVEL_AO: + pm8195_3_s3_level_ao: regulator-pm8195-3-s3-level-ao { + regulator-name = "pm8195_3_s3_level_ao"; + qcom,set = ; + regulator-min-microvolt + = ; + regulator-max-microvolt + = ; + qcom,init-voltage-level + = ; + qcom,min-dropout-voltage-level = <(-1)>; + }; + cx_cdev: regulator-cdev { + compatible = "qcom,rpmh-reg-cdev"; + mboxes = <&qmp_aop 0>; + qcom,reg-resource-name = "cx"; + #cooling-cells = <2>; + }; + }; + + rpmh-regulator-smpe4 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "smpe4"; + S4E: pm8195_3_s4: regulator-pm8195-3-s4 { + regulator-name = "pm8195_3_s4"; + qcom,set = ; + regulator-min-microvolt = <402000>; + regulator-max-microvolt = <1980000>; + qcom,init-voltage = <402000>; + }; + }; + + rpmh-regulator-smpe5 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "smpe5"; + S5E: pm8195_3_s5: regulator-pm8195-3-s5 { + regulator-name = "pm8195_3_s5"; + qcom,set = ; + regulator-min-microvolt = <1811000>; + regulator-max-microvolt = <2040000>; + qcom,init-voltage = <1811000>; + }; + }; + + /* PM8195_3 L4 - LPI_MX supply */ + rpmh-regulator-lmxlvl { + compatible = "qcom,rpmh-arc-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "lmx.lvl"; + L4E_LEVEL: pm8195_3_l4_level: regulator-pm8195-3-l4 { + regulator-name = "pm8195_3_l4_level"; + qcom,set = ; + regulator-min-microvolt = + ; + regulator-max-microvolt = + ; + qcom,init-voltage-level = + ; + }; + }; + + rpmh-regulator-ldoe5 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoe5"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L5E: pm8195_3_l5: regulator-pm8195-3-l5 { + regulator-name = "pm8195_3_l5"; + qcom,set = ; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <920000>; + qcom,init-voltage = <800000>; + qcom,init-mode = ; + }; + }; + + rpmh-regulator-ldoe7 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoe7"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L7E: pm8195_3_l7: regulator-pm8195-3-l7 { + regulator-name = "pm8195_3_l7"; + qcom,set = ; + regulator-min-microvolt = <1700000>; + regulator-max-microvolt = <1950000>; + qcom,init-voltage = <1700000>; + qcom,init-mode = ; + }; + }; + + /* pm8195_3 L8 - LPI_CX supply */ + rpmh-regulator-lcxlvl { + compatible = "qcom,rpmh-arc-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "lcx.lvl"; + L8E_LEVEL: pm8195_3_l8_level: regulator-pm8195-3-l8 { + regulator-name = "pm8195_3_l8_level"; + qcom,set = ; + regulator-min-microvolt = + ; + regulator-max-microvolt = + ; + qcom,init-voltage-level = + ; + }; + }; + + rpmh-regulator-ldoe9 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoe9"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L9E: pm8195_3_l9: regulator-pm8195-3-l9 { + regulator-name = "pm8195_3_l9"; + qcom,set = ; + regulator-min-microvolt = <830000>; + regulator-max-microvolt = <920000>; + qcom,init-voltage = <830000>; + qcom,init-mode = ; + }; + }; + + rpmh-regulator-ldoe10 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoe10"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L10E: pm8195_3_l10: regulator-pm8195-3-l10 { + regulator-name = "pm8195_3_l10"; + qcom,set = ; + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <3544000>; + qcom,init-voltage = <2500000>; + qcom,init-mode = ; + }; + }; + + rpmh-regulator-ldoe12 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoe12"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L12E: pm8195_3_l12: regulator-pm8195-3-l12 { + regulator-name = "pm8195_3_l12"; + qcom,set = ; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + qcom,init-mode = ; + }; + }; + + rpmh-regulator-ldoe16 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoe16"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L16E: pm8195_3_l16: regulator-pm8195-3-l16 { + regulator-name = "pm8195_3_l16"; + qcom,set = ; + regulator-min-microvolt = <2921000>; + regulator-max-microvolt = <3300000>; + qcom,init-voltage = <2921000>; + qcom,init-mode = ; + }; + }; + + + rpmh-regulator-ldoe17 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoe17"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L17E: pm8195_3_l17: regulator-pm8195-3-l17 { + regulator-name = "pm8195_3_l17"; + qcom,set = ; + regulator-min-microvolt = <2900000>; + regulator-max-microvolt = <3300000>; + qcom,init-voltage = <2900000>; + qcom,init-mode = ; + }; + }; +}; -- GitLab From 177db32a7101b12529e0eb12e97b2dbff84372d5 Mon Sep 17 00:00:00 2001 From: Mao Jinlong Date: Mon, 8 Jul 2019 12:10:01 +0530 Subject: [PATCH 0827/1121] ARM: dts: msm: Add jtag_mm nodes for atoll Add jtag_mm nodes for atoll to enable ETM save and restore function. Change-Id: I9f4fe34250b185ca063c9f714b53113f332e13eb Signed-off-by: Mao Jinlong --- arch/arm64/boot/dts/qcom/atoll.dtsi | 88 +++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index c513d1e3f62e..66b04416430e 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -711,6 +711,94 @@ interrupts = ; }; + jtag_mm0: jtagmm@7040000 { + compatible = "qcom,jtagv8-mm"; + reg = <0x7040000 0x1000>; + reg-names = "etm-base"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "core_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU0>; + }; + + jtag_mm1: jtagmm@7140000 { + compatible = "qcom,jtagv8-mm"; + reg = <0x7140000 0x1000>; + reg-names = "etm-base"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "core_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU1>; + }; + + jtag_mm2: jtagmm@7240000 { + compatible = "qcom,jtagv8-mm"; + reg = <0x7240000 0x1000>; + reg-names = "etm-base"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "core_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU2>; + }; + + jtag_mm3: jtagmm@7340000 { + compatible = "qcom,jtagv8-mm"; + reg = <0x7340000 0x1000>; + reg-names = "etm-base"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "core_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU3>; + }; + + jtag_mm4: jtagmm@7440000 { + compatible = "qcom,jtagv8-mm"; + reg = <0x7440000 0x1000>; + reg-names = "etm-base"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "core_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU4>; + }; + + jtag_mm5: jtagmm@7540000 { + compatible = "qcom,jtagv8-mm"; + reg = <0x7540000 0x1000>; + reg-names = "etm-base"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "core_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU5>; + }; + + jtag_mm6: jtagmm@7640000 { + compatible = "qcom,jtagv8-mm"; + reg = <0x7640000 0x1000>; + reg-names = "etm-base"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "core_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU6>; + }; + + jtag_mm7: jtagmm@7740000 { + compatible = "qcom,jtagv8-mm"; + reg = <0x7740000 0x1000>; + reg-names = "etm-base"; + + clocks = <&clock_aop QDSS_CLK>; + clock-names = "core_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU7>; + }; + qcom,msm-imem@146aa000 { compatible = "qcom,msm-imem"; reg = <0x146aa000 0x1000>; -- GitLab From 86d77e6ccef58e07b3a80727c8f4cb092863f3fb Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Mon, 8 Jul 2019 21:07:10 +0530 Subject: [PATCH 0828/1121] msm: vidc: Fix validate_pkt_size macro definition [1] Convert validate_pkt_size macro to an inline function as the macro definition always returns true. [2] Handle return error code from hfi_fill_codec_info. Change-Id: I9e7eadfe82c041721565c880eca3a46e4e3e98d9 Signed-off-by: Priyanka Gujjula --- .../platform/msm/vidc/hfi_response_handler.c | 64 +++++++++---------- 1 file changed, 30 insertions(+), 34 deletions(-) diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c index c630e41067f5..435121a640f8 100644 --- a/drivers/media/platform/msm/vidc/hfi_response_handler.c +++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c @@ -104,6 +104,16 @@ static int get_hal_pixel_depth(u32 hfi_bit_depth) return MSM_VIDC_BIT_DEPTH_UNSUPPORTED; } +static inline int validate_pkt_size(u32 rem_size, u32 msg_size) +{ + if (rem_size < msg_size) { + dprintk(VIDC_ERR, "%s: bad_packet_size: %d\n", + __func__, rem_size); + return false; + } + return true; +} + static int hfi_process_sess_evt_seq_changed(u32 device_id, struct hfi_msg_event_notify_packet *pkt, struct msm_vidc_cb_info *info) @@ -123,15 +133,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, int luma_bit_depth, chroma_bit_depth; struct hfi_colour_space *colour_info; -#define VALIDATE_PKT_SIZE(__rem_size, __msg_size) ({ \ - if (__rem_size < __msg_size) { \ - dprintk(VIDC_ERR, \ - "hal_process_session_init_done: bad_pkt_size\n"); \ - false; \ - } \ - true; \ - }) - if (!VALIDATE_PKT_SIZE(pkt->size, + if (!validate_pkt_size(pkt->size, sizeof(struct hfi_msg_event_notify_packet))) return -E2BIG; @@ -157,13 +159,13 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, rem_size = pkt->size - sizeof(struct hfi_msg_event_notify_packet) + sizeof(u32); do { - if (!VALIDATE_PKT_SIZE(rem_size, sizeof(u32))) + if (!validate_pkt_size(rem_size, sizeof(u32))) return -E2BIG; prop_id = (int) *((u32 *)data_ptr); rem_size -= sizeof(u32); switch (prop_id) { case HFI_PROPERTY_PARAM_FRAME_SIZE: - if (!VALIDATE_PKT_SIZE(rem_size, sizeof(struct + if (!validate_pkt_size(rem_size, sizeof(struct hfi_frame_size))) return -E2BIG; data_ptr = data_ptr + sizeof(u32); @@ -178,7 +180,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, rem_size -= sizeof(struct hfi_frame_size); break; case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT: - if (!VALIDATE_PKT_SIZE(rem_size, sizeof(struct + if (!validate_pkt_size(rem_size, sizeof(struct hfi_profile_level))) return -E2BIG; data_ptr = data_ptr + sizeof(u32); @@ -194,7 +196,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, rem_size -= sizeof(struct hfi_profile_level); break; case HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH: - if (!VALIDATE_PKT_SIZE(rem_size, sizeof(struct + if (!validate_pkt_size(rem_size, sizeof(struct hfi_bit_depth))) return -E2BIG; data_ptr = data_ptr + sizeof(u32); @@ -230,7 +232,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, rem_size -= sizeof(struct hfi_bit_depth); break; case HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT: - if (!VALIDATE_PKT_SIZE(rem_size, sizeof(struct + if (!validate_pkt_size(rem_size, sizeof(struct hfi_pic_struct))) return -E2BIG; data_ptr = data_ptr + sizeof(u32); @@ -245,7 +247,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, rem_size -= sizeof(struct hfi_pic_struct); break; case HFI_PROPERTY_PARAM_VDEC_DPB_COUNTS: - if (!VALIDATE_PKT_SIZE(rem_size, sizeof(struct + if (!validate_pkt_size(rem_size, sizeof(struct hfi_dpb_counts))) return -E2BIG; data_ptr = data_ptr + sizeof(u32); @@ -266,7 +268,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, rem_size -= sizeof(struct hfi_dpb_counts); break; case HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE: - if (!VALIDATE_PKT_SIZE(rem_size, sizeof(struct + if (!validate_pkt_size(rem_size, sizeof(struct hfi_colour_space))) return -E2BIG; data_ptr = data_ptr + sizeof(u32); @@ -282,7 +284,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, rem_size -= sizeof(struct hfi_colour_space); break; case HFI_PROPERTY_CONFIG_VDEC_ENTROPY: - if (!VALIDATE_PKT_SIZE(rem_size, sizeof(u32))) + if (!validate_pkt_size(rem_size, sizeof(u32))) return -E2BIG; data_ptr = data_ptr + sizeof(u32); entropy_mode = *(u32 *)data_ptr; @@ -294,7 +296,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, rem_size -= sizeof(u32); break; case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS: - if (!VALIDATE_PKT_SIZE(rem_size, sizeof(struct + if (!validate_pkt_size(rem_size, sizeof(struct hfi_buffer_requirements))) return -E2BIG; data_ptr = data_ptr + sizeof(u32); @@ -312,7 +314,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, sizeof(struct hfi_buffer_requirements); break; case HFI_INDEX_EXTRADATA_INPUT_CROP: - if (!VALIDATE_PKT_SIZE(rem_size, sizeof(struct + if (!validate_pkt_size(rem_size, sizeof(struct hfi_index_extradata_input_crop_payload))) return -E2BIG; data_ptr = data_ptr + sizeof(u32); @@ -347,7 +349,6 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, num_properties_changed--; } while (num_properties_changed > 0); } -#undef VALIDATE_PKT_SIZE info->response_type = HAL_SESSION_EVENT_CHANGE; info->response.event = event_notify; @@ -811,18 +812,10 @@ static int hfi_fill_codec_info(u8 *data_ptr, u32 prop_id = *((u32 *)data_ptr); u8 *orig_data_ptr = data_ptr; -#define VALIDATE_PKT_SIZE(__rem_size, __msg_size) ({ \ - if (__rem_size < __msg_size) { \ - dprintk(VIDC_ERR, \ - "hfi_msg_sys_init_done: Bad packet size\n"); \ - false; \ - } \ - true; \ - }) if (prop_id == HFI_PROPERTY_PARAM_CODEC_SUPPORTED) { struct hfi_codec_supported *prop; - if (!VALIDATE_PKT_SIZE(rem_size - sizeof(u32), + if (!validate_pkt_size(rem_size - sizeof(u32), sizeof(struct hfi_codec_supported))) return -E2BIG; data_ptr = data_ptr + sizeof(u32); @@ -874,13 +867,13 @@ static int hfi_fill_codec_info(u8 *data_ptr, } sys_init_done->codec_count = codec_count; - if (!VALIDATE_PKT_SIZE(rem_size, sizeof(u32))) + if (!validate_pkt_size(rem_size, sizeof(u32))) return -E2BIG; prop_id = *((u32 *)(orig_data_ptr + size)); if (prop_id == HFI_PROPERTY_PARAM_MAX_SESSIONS_SUPPORTED) { struct hfi_max_sessions_supported *prop; - if (!VALIDATE_PKT_SIZE(rem_size - sizeof(u32), sizeof(struct + if (!validate_pkt_size(rem_size - sizeof(u32), sizeof(struct hfi_max_sessions_supported))) return -E2BIG; prop = (struct hfi_max_sessions_supported *) @@ -893,7 +886,6 @@ static int hfi_fill_codec_info(u8 *data_ptr, dprintk(VIDC_DBG, "max_sessions_supported %d\n", prop->max_sessions); } -#undef VALIDATE_PKT_SIZE return size; } @@ -1247,7 +1239,8 @@ enum vidc_status hfi_process_sys_init_done_prop_read( struct vidc_hal_sys_init_done *sys_init_done) { enum vidc_status status = VIDC_ERR_NONE; - u32 rem_bytes, bytes_read, num_properties; + int bytes_read; + u32 rem_bytes, num_properties; u8 *data_ptr; if (!pkt || !sys_init_done) { @@ -1256,7 +1249,8 @@ enum vidc_status hfi_process_sys_init_done_prop_read( return VIDC_ERR_FAIL; } if (pkt->size < sizeof(struct hfi_msg_sys_init_done_packet)) { - dprintk(VIDC_ERR, "hfi_msg_sys_init_done: bad packet size\n"); + dprintk(VIDC_ERR, "%s: bad_packet_size: %d\n", + __func__, pkt->size); return VIDC_ERR_FAIL; } @@ -1287,6 +1281,8 @@ enum vidc_status hfi_process_sys_init_done_prop_read( return status; } bytes_read = hfi_fill_codec_info(data_ptr, sys_init_done, rem_bytes); + if (bytes_read < 0) + return VIDC_ERR_FAIL; data_ptr += bytes_read; rem_bytes -= bytes_read; num_properties--; -- GitLab From 66f0a6fb7324a576a725e039d0a5e2edff05b150 Mon Sep 17 00:00:00 2001 From: Zhiqiang Tu Date: Thu, 11 Jul 2019 14:40:39 +0800 Subject: [PATCH 0829/1121] clk: qcom: fix pcie virtual clock name mismatch The clock name mismatch between frontend and backend causes clock operation failure. Change-Id: If0d09485251e7a031d56fe51385026a6f1227b9b Signed-off-by: Zhiqiang Tu --- drivers/clk/qcom/virtio_clk_sm6150.c | 2 +- drivers/clk/qcom/virtio_clk_sm8150.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/qcom/virtio_clk_sm6150.c b/drivers/clk/qcom/virtio_clk_sm6150.c index 64a1c530644e..ef49397fe48a 100644 --- a/drivers/clk/qcom/virtio_clk_sm6150.c +++ b/drivers/clk/qcom/virtio_clk_sm6150.c @@ -48,7 +48,7 @@ static const char * const sm6150_gcc_virtio_clocks[] = { [GCC_PCIE_0_CFG_AHB_CLK] = "gcc_pcie_0_cfg_ahb_clk", [GCC_PCIE_0_MSTR_AXI_CLK] = "gcc_pcie_0_mstr_axi_clk", [GCC_PCIE_0_SLV_AXI_CLK] = "gcc_pcie_0_slv_axi_clk", - [GCC_PCIE_0_CLKREF_CLK] = "gcc_pcie_0_clkref_clk", + [GCC_PCIE_0_CLKREF_CLK] = "gcc_pcie_0_clkref_en", [GCC_PCIE_0_SLV_Q2A_AXI_CLK] = "gcc_pcie_0_slv_q2a_axi_clk", [GCC_PCIE0_PHY_REFGEN_CLK] = "gcc_pcie0_phy_refgen_clk", [GCC_PCIE_PHY_AUX_CLK] = "gcc_pcie_phy_aux_clk", diff --git a/drivers/clk/qcom/virtio_clk_sm8150.c b/drivers/clk/qcom/virtio_clk_sm8150.c index f71ec943b323..68b0f52d21b2 100644 --- a/drivers/clk/qcom/virtio_clk_sm8150.c +++ b/drivers/clk/qcom/virtio_clk_sm8150.c @@ -65,7 +65,7 @@ static const char * const sm8150_gcc_virtio_clocks[] = { [GCC_PCIE_0_CFG_AHB_CLK] = "gcc_pcie_0_cfg_ahb_clk", [GCC_PCIE_0_MSTR_AXI_CLK] = "gcc_pcie_0_mstr_axi_clk", [GCC_PCIE_0_SLV_AXI_CLK] = "gcc_pcie_0_slv_axi_clk", - [GCC_PCIE_0_CLKREF_CLK] = "gcc_pcie_0_clkref_clk", + [GCC_PCIE_0_CLKREF_CLK] = "gcc_pcie_0_clkref_en", [GCC_PCIE_0_SLV_Q2A_AXI_CLK] = "gcc_pcie_0_slv_q2a_axi_clk", [GCC_AGGRE_NOC_PCIE_TBU_CLK] = "gcc_aggre_noc_pcie_tbu_clk", [GCC_PCIE0_PHY_REFGEN_CLK] = "gcc_pcie0_phy_refgen_clk", -- GitLab From 6d59f94947ab1cc0973feadda0d8d34cdff57b85 Mon Sep 17 00:00:00 2001 From: Mitul Golani Date: Mon, 13 May 2019 21:00:41 +0530 Subject: [PATCH 0830/1121] serial: msm_geni_serial: Maintain correct line id for port Maintain and initialize the line ID in case of alias is not defined properly. Change-Id: Id911cc4de33bf39ce7290d53ed0817912afbd61b Signed-off-by: Mitul Golani Signed-off-by: ashish kori --- drivers/tty/serial/msm_geni_serial.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/tty/serial/msm_geni_serial.c b/drivers/tty/serial/msm_geni_serial.c index d7c10dbb6ff5..594e7515308e 100644 --- a/drivers/tty/serial/msm_geni_serial.c +++ b/drivers/tty/serial/msm_geni_serial.c @@ -192,8 +192,7 @@ static int msm_geni_serial_poll_bit(struct uart_port *uport, static void msm_geni_serial_stop_rx(struct uart_port *uport); static int msm_geni_serial_runtime_resume(struct device *dev); static int msm_geni_serial_runtime_suspend(struct device *dev); - -static atomic_t uart_line_id = ATOMIC_INIT(0); +static int uart_line_id; #define GET_DEV_PORT(uport) \ container_of(uport, struct msm_geni_serial_port, uport) @@ -2375,20 +2374,21 @@ static int msm_geni_serial_probe(struct platform_device *pdev) } if (pdev->dev.of_node) { - if (drv->cons) + if (drv->cons) { line = of_alias_get_id(pdev->dev.of_node, "serial"); - else + if (line < 0) + line = 0; + } else { line = of_alias_get_id(pdev->dev.of_node, "hsuart"); + if (line < 0) + line = uart_line_id++; + else + uart_line_id++; + } } else { line = pdev->id; } - if (line < 0) - line = atomic_inc_return(&uart_line_id) - 1; - - if ((line < 0) || (line >= GENI_UART_NR_PORTS)) - return -ENXIO; - if (strcmp(id->compatible, "qcom,msm-geni-console") == 0) snprintf(boot_marker, sizeof(boot_marker), "M - DRIVER GENI_UART_%d Init", line); -- GitLab From cfc4e4efee649c102c7f0647d37cfeb284229217 Mon Sep 17 00:00:00 2001 From: Ram Chandrasekar Date: Wed, 26 Jun 2019 12:20:53 -0600 Subject: [PATCH 0831/1121] drivers: thermal: qmi_sensor: Add support for new sensors Add support for monitoring new sensors that are available in the modem sub system. This will enable the driver to register them as thermal zone and perform any mitigation when a threshold is reached. Change-Id: I436e05249e52e25cbf017b2c923e1d3efe62303a Signed-off-by: Ram Chandrasekar --- drivers/thermal/qcom/qmi_sensors.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/thermal/qcom/qmi_sensors.c b/drivers/thermal/qcom/qmi_sensors.c index dbd2eb4bfd69..7bca52588f51 100644 --- a/drivers/thermal/qcom/qmi_sensors.c +++ b/drivers/thermal/qcom/qmi_sensors.c @@ -51,6 +51,19 @@ enum qmi_ts_sensor { QMI_TS_MODEM_SKIN, QMI_TS_QFE_PA_MDM, QMI_TS_QFE_PA_WTR, + QMI_TS_STREAMER_0, + QMI_TS_MOD_MMW_0, + QMI_TS_MOD_MMW_1, + QMI_TS_MOD_MMW_2, + QMI_TS_MOD_MMW_3, + QMI_TS_RET_PA_0, + QMI_TS_WTR_PA_0, + QMI_TS_WTR_PA_1, + QMI_TS_WTR_PA_2, + QMI_TS_WTR_PA_3, + QMI_SYS_THERM1, + QMI_SYS_THERM2, + QMI_TS_TSENS_1, QMI_TS_MAX_NR }; @@ -95,6 +108,19 @@ static char sensor_clients[QMI_TS_MAX_NR][QMI_CLIENT_NAME_LENGTH] = { {"xo_therm"}, {"qfe_pa_mdm"}, {"qfe_pa_wtr"}, + {"qfe_mmw_streamer0"}, + {"qfe_mmw0_mod"}, + {"qfe_mmw1_mod"}, + {"qfe_mmw2_mod"}, + {"qfe_mmw3_mod"}, + {"qfe_ret_pa0"}, + {"qfe_wtr_pa0"}, + {"qfe_wtr_pa1"}, + {"qfe_wtr_pa2"}, + {"qfe_wtr_pa3"}, + {"sys_therm1"}, + {"sys_therm2"}, + {"modem_tsens1"}, }; static int32_t encode_qmi(int32_t val) -- GitLab From 95165ac0c421632d3112fdcdf0a47c0e6e8bb312 Mon Sep 17 00:00:00 2001 From: Manaf Meethalavalappu Pallikunhi Date: Thu, 11 Jul 2019 19:08:59 +0530 Subject: [PATCH 0832/1121] dt-bindings: thermal: Add new thermal QMI sensors New modem sensors are available over QMI and new sensors names are assigned which can be used by devicetree to define a thermal zone. Change-Id: Iaa4c7561a2aff3cab9215bef72710244449a2654 Signed-off-by: Manaf Meethalavalappu Pallikunhi --- .../bindings/thermal/qti-qmi-sensor.txt | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/thermal/qti-qmi-sensor.txt b/Documentation/devicetree/bindings/thermal/qti-qmi-sensor.txt index 12cf0276805d..e558027e9c91 100644 --- a/Documentation/devicetree/bindings/thermal/qti-qmi-sensor.txt +++ b/Documentation/devicetree/bindings/thermal/qti-qmi-sensor.txt @@ -32,8 +32,8 @@ Subsystem properties: Definition: Remote sensor names. Below strings are the only acceptable sensor names, 1. pa - 2. pa1 - 3. pa2 + 2. pa_1 + 3. pa_2 4. qfe_pa0 5. qfe_wtr0 6. modem_tsens @@ -44,6 +44,19 @@ Subsystem properties: 11. xo_therm 12. qfe_pa_mdm 13. qfe_pa_wtr + 14. qfe_mmw_streamer0 + 15. qfe_mmw0_mod + 16. qfe_mmw1_mod + 17. qfe_mmw2_mod + 18. qfe_mmw3_mod + 19. qfe_ret_pa0 + 20. qfe_wtr_pa0 + 21. qfe_wtr_pa1 + 22. qfe_wtr_pa2 + 23. qfe_wtr_pa3 + 24. sys_therm1 + 25. sys_therm2 + 26. modem_tsens1 Example: -- GitLab From 01b74bec90ad37b542cb7e23cb662bd74ff7c483 Mon Sep 17 00:00:00 2001 From: Ram Chandrasekar Date: Mon, 22 Apr 2019 14:25:59 -0600 Subject: [PATCH 0833/1121] dt-bindings: thermal: qmi_sensor: Add MACROs for QMI sensors Add MACROs to reference different QMI sensor indexes. This will help in referencing the QMI sensor when defining a thermal zone. Change-Id: I96d576d9d5eed91cb69279248e5536acb9ba5972 Signed-off-by: Ram Chandrasekar --- include/dt-bindings/thermal/qmi_thermal.h | 49 +++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 include/dt-bindings/thermal/qmi_thermal.h diff --git a/include/dt-bindings/thermal/qmi_thermal.h b/include/dt-bindings/thermal/qmi_thermal.h new file mode 100644 index 000000000000..d41157d9d73c --- /dev/null +++ b/include/dt-bindings/thermal/qmi_thermal.h @@ -0,0 +1,49 @@ +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _DT_BINDINGS_QCOM_QMI_THERMAL_H +#define _DT_BINDINGS_QCOM_QMI_THERMAL_H + +#define QMI_PA 0 +#define QMI_PA_1 1 +#define QMI_PA_2 2 +#define QMI_QFE_PA_0 3 +#define QMI_QFE_WTR_0 4 +#define QMI_MODEM_TSENS 5 +#define QMI_QFE_MMW_0 6 +#define QMI_QFE_MMW_1 7 +#define QMI_QFE_MMW_2 8 +#define QMI_QFE_MMW_3 9 +#define QMI_XO_THERM 10 +#define QMI_QFE_PA_MDM 11 +#define QMI_QFE_PA_WTR 12 +#define QMI_QFE_MMW_STREAMER_0 13 +#define QMI_QFE_MMW_0_MOD 14 +#define QMI_QFE_MMW_1_MOD 15 +#define QMI_QFE_MMW_2_MOD 16 +#define QMI_QFE_MMW_3_MOD 17 +#define QMI_QFE_RET_PA_0 18 +#define QMI_QFE_WTR_PA_0 19 +#define QMI_QFE_WTR_PA_1 20 +#define QMI_QFE_WTR_PA_2 21 +#define QMI_QFE_WTR_PA_3 22 +#define QMI_SYS_THERM_1 23 +#define QMI_SYS_THERM_2 24 +#define QMI_MODEM_TSENS_1 25 + +#define QMI_MODEM_INST_ID 0x0 +#define QMI_ADSP_INST_ID 0x1 +#define QMI_CDSP_INST_ID 0x43 +#define QMI_SLPI_INST_ID 0x53 +#define QMI_MODEM_NR_INST_ID 0x64 + +#endif -- GitLab From aaf6235816d40e8d81aa759b733172a09ddba25a Mon Sep 17 00:00:00 2001 From: Manaf Meethalavalappu Pallikunhi Date: Thu, 11 Jul 2019 17:51:16 +0530 Subject: [PATCH 0834/1121] ARM: dts: msm: Enable QMI cooling devices for SM8150-SDXPRAIRIE Enable QMI cooling devices for SM8150-SDXPRAIRIE. These cooling devices will be used to apply cold temperature voltage restriction and other mitigation for remote subsystems. Change-Id: Ic6bc86b85fe742790fd8cf0eb200f9293f94ea9b Signed-off-by: Manaf Meethalavalappu Pallikunhi --- .../boot/dts/qcom/sm8150-sdxprairie.dtsi | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi b/arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi index 3ec7c086acc4..b4a8b0af500c 100644 --- a/arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi @@ -202,3 +202,78 @@ &wil6210 { status = "disabled"; }; + +&soc { + qmi-tmd-devices { + compatible = "qcom,qmi-cooling-devices"; + + modem { + qcom,instance-id = ; + + modem_pa: modem_pa { + qcom,qmi-dev-name = "pa"; + #cooling-cells = <2>; + }; + + modem_tj: modem_tj { + qcom,qmi-dev-name = "modem"; + #cooling-cells = <2>; + }; + + modem_current: modem_current { + qcom,qmi-dev-name = "modem_current"; + #cooling-cells = <2>; + }; + + modem_skin: modem_skin { + qcom,qmi-dev-name = "modem_skin"; + #cooling-cells = <2>; + }; + + modem_mmw_skin0: modem_mmw_skin0 { + qcom,qmi-dev-name = "modem_skin0"; + #cooling-cells = <2>; + }; + + modem_mmw_skin1: modem_mmw_skin1 { + qcom,qmi-dev-name = "modem_skin1"; + #cooling-cells = <2>; + }; + + modem_mmw_skin2: modem_mmw_skin2 { + qcom,qmi-dev-name = "modem_skin2"; + #cooling-cells = <2>; + }; + + modem_mmw_skin3: modem_mmw_skin3 { + qcom,qmi-dev-name = "modem_skin3"; + #cooling-cells = <2>; + }; + + modem_mmw0: modem_mmw0 { + qcom,qmi-dev-name = "mmw0"; + #cooling-cells = <2>; + }; + + modem_mmw1: modem_mmw1 { + qcom,qmi-dev-name = "mmw1"; + #cooling-cells = <2>; + }; + + modem_mmw2: modem_mmw2 { + qcom,qmi-dev-name = "mmw2"; + #cooling-cells = <2>; + }; + + modem_mmw3: modem_mmw3 { + qcom,qmi-dev-name = "mmw3"; + #cooling-cells = <2>; + }; + + modem_bcl: modem_bcl { + qcom,qmi-dev-name = "vbatt_low"; + #cooling-cells = <2>; + }; + }; + }; +}; -- GitLab From 6d2bed15d71f04ee755323f73b418bd051973cee Mon Sep 17 00:00:00 2001 From: Manaf Meethalavalappu Pallikunhi Date: Thu, 11 Jul 2019 19:04:09 +0530 Subject: [PATCH 0835/1121] ARM: dts: msm: Add modem sensors for SM8150-SDXPRAIRIE Add all the modem sensors to thermal framework so that it can be monitored and mitigated for thermal conditions in SM8150-SDXPRAIRIE. Change-Id: Ice10f631c2eb73b90fa28711139785e631681b72 Signed-off-by: Manaf Meethalavalappu Pallikunhi --- .../boot/dts/qcom/sm8150-sdxprairie.dtsi | 291 ++++++++++++++++++ 1 file changed, 291 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi b/arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi index b4a8b0af500c..8edd84fb97fe 100644 --- a/arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi @@ -10,6 +10,8 @@ * GNU General Public License for more details. */ +#include + &mdm3 { compatible = "qcom,ext-sdxprairie"; qcom,mdm-link-info = "0306_01.01.00"; @@ -276,4 +278,293 @@ }; }; }; + + qmi_sensor: qmi-ts-sensors { + compatible = "qcom,qmi-sensors"; + #thermal-sensor-cells = <1>; + + modem { + qcom,instance-id = ; + qcom,qmi-sensor-names = "pa", + "pa_1", + "qfe_wtr0", + "modem_tsens", + "qfe_mmw0", + "qfe_mmw1", + "qfe_mmw2", + "qfe_mmw3", + "xo_therm", + "qfe_mmw_streamer0", + "qfe_mmw0_mod", + "qfe_mmw1_mod", + "qfe_mmw2_mod", + "qfe_mmw3_mod", + "qfe_ret_pa0", + "qfe_wtr_pa0", + "qfe_wtr_pa1", + "qfe_wtr_pa2", + "qfe_wtr_pa3", + "sys_therm1", + "sys_therm2", + "modem_tsens1"; + }; + }; +}; + +&thermal_zones { + modem-lte-sub6-pa1 { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&qmi_sensor + (QMI_MODEM_NR_INST_ID+QMI_PA)>; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + modem-lte-sub6-pa2 { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&qmi_sensor + (QMI_MODEM_NR_INST_ID+QMI_PA_1)>; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + modem-mmw0-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&qmi_sensor + (QMI_MODEM_NR_INST_ID+QMI_QFE_MMW_0)>; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + modem-mmw1-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&qmi_sensor + (QMI_MODEM_NR_INST_ID+QMI_QFE_MMW_1)>; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + modem-mmw2-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&qmi_sensor + (QMI_MODEM_NR_INST_ID+QMI_QFE_MMW_2)>; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + modem-mmw3-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&qmi_sensor + (QMI_MODEM_NR_INST_ID+QMI_QFE_MMW_3)>; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + modem-skin-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&qmi_sensor + (QMI_MODEM_NR_INST_ID+QMI_XO_THERM)>; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + modem-wifi-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&qmi_sensor + (QMI_MODEM_NR_INST_ID+QMI_SYS_THERM_1)>; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + modem-ambient-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&qmi_sensor + (QMI_MODEM_NR_INST_ID+QMI_SYS_THERM_2)>; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + modem-0-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&qmi_sensor + (QMI_MODEM_NR_INST_ID+QMI_MODEM_TSENS)>; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + modem-1-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&qmi_sensor + (QMI_MODEM_NR_INST_ID+QMI_MODEM_TSENS_1)>; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + modem-streamer-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&qmi_sensor + (QMI_MODEM_NR_INST_ID+QMI_QFE_MMW_STREAMER_0)>; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + modem-mmw0-mod-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&qmi_sensor + (QMI_MODEM_NR_INST_ID+QMI_QFE_MMW_0_MOD)>; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + modem-mmw1-mod-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&qmi_sensor + (QMI_MODEM_NR_INST_ID+QMI_QFE_MMW_1_MOD)>; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + modem-mmw2-mod-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&qmi_sensor + (QMI_MODEM_NR_INST_ID+QMI_QFE_MMW_2_MOD)>; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + modem-mmw3-mod-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&qmi_sensor + (QMI_MODEM_NR_INST_ID+QMI_QFE_MMW_3_MOD)>; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; }; -- GitLab From c1e0ddf00d8c73b2f9d5124b26a840b49d8eb593 Mon Sep 17 00:00:00 2001 From: Naman Padhiar Date: Wed, 10 Jul 2019 20:04:19 +0530 Subject: [PATCH 0836/1121] icnss: Skip removing WLAN host driver during recovery Add the necessary checks to skip the invalid operation of driver remove during the recovery. Change-Id: I12d755b3b19eb4b8a7cc09e3893d778d88201cae Signed-off-by: Naman Padhiar --- drivers/soc/qcom/icnss.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c index 5b4cdf93774b..4a65f9079c4e 100644 --- a/drivers/soc/qcom/icnss.c +++ b/drivers/soc/qcom/icnss.c @@ -1587,7 +1587,10 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb, if (code == SUBSYS_BEFORE_SHUTDOWN && !notif->crashed && atomic_read(&priv->is_shutdown)) { atomic_set(&priv->is_shutdown, false); - icnss_call_driver_remove(priv); + if (!test_bit(ICNSS_PD_RESTART, &priv->state) && + !test_bit(ICNSS_SHUTDOWN_DONE, &priv->state)) { + icnss_call_driver_remove(priv); + } } if (code == SUBSYS_BEFORE_SHUTDOWN && !notif->crashed && -- GitLab From 912b7c9971bde1ea9c07f0f92b7b25b73e73a6ba Mon Sep 17 00:00:00 2001 From: Sean Tranchetti Date: Wed, 3 Jul 2019 17:35:46 -0600 Subject: [PATCH 0837/1121] net: qualcomm: rmnet: check for over-pulling When pulling data from the packet descriptor or when trimming the descriptor to a specific length, passing invalid or overly large sizes can result in the descriptor being recycled as it no longer contains any packet data. We must check for this situation occurring, and gracefully handle the packet drop. Change-Id: Idb1354105904b0fff265a7ef32fee8905f7825ae Signed-off-by: Sean Tranchetti --- .../qualcomm/rmnet/rmnet_descriptor.c | 43 ++++++++++++++----- .../qualcomm/rmnet/rmnet_descriptor.h | 4 ++ 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c index b2aa3edf42a4..55a06d0fcd1c 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c @@ -69,9 +69,11 @@ void rmnet_recycle_frag_descriptor(struct rmnet_frag_descriptor *frag_desc, struct rmnet_port *port) { struct rmnet_frag_descriptor_pool *pool = port->frag_desc_pool; + struct page *page = skb_frag_page(&frag_desc->frag); list_del(&frag_desc->list); - put_page(skb_frag_page(&frag_desc->frag)); + if (page) + put_page(page); memset(frag_desc, 0, sizeof(*frag_desc)); INIT_LIST_HEAD(&frag_desc->list); @@ -457,8 +459,12 @@ static struct sk_buff *rmnet_alloc_skb(struct rmnet_frag_descriptor *frag_desc, /* If the headers we added are the start of the page, * we don't want to add them twice */ - if (frag_desc->hdr_ptr == rmnet_frag_data_ptr(frag_desc)) - rmnet_frag_pull(frag_desc, port, hdr_len); + if (frag_desc->hdr_ptr == rmnet_frag_data_ptr(frag_desc)) { + if (!rmnet_frag_pull(frag_desc, port, hdr_len)) { + kfree_skb(head_skb); + return NULL; + } + } } else { /* Allocate enough space to avoid penalties in the stack * from __pskb_pull_tail() @@ -645,10 +651,13 @@ rmnet_frag_segment_coal_data(struct rmnet_frag_descriptor *coal_desc, bool gro = coal_desc->dev->features & NETIF_F_GRO_HW; /* Pull off the headers we no longer need */ - rmnet_frag_pull(coal_desc, port, sizeof(struct rmnet_map_header)); + if (!rmnet_frag_pull(coal_desc, port, sizeof(struct rmnet_map_header))) + return; + coal_hdr = (struct rmnet_map_v5_coal_header *) rmnet_frag_data_ptr(coal_desc); - rmnet_frag_pull(coal_desc, port, sizeof(*coal_hdr)); + if (!rmnet_frag_pull(coal_desc, port, sizeof(*coal_hdr))) + return; iph = (struct iphdr *)rmnet_frag_data_ptr(coal_desc); @@ -897,15 +906,23 @@ int rmnet_frag_process_next_hdr_packet(struct rmnet_frag_descriptor *frag_desc, priv->stats.csum_valid_unset++; } - rmnet_frag_pull(frag_desc, port, - sizeof(struct rmnet_map_header) + - sizeof(struct rmnet_map_v5_csum_header)); + if (!rmnet_frag_pull(frag_desc, port, + sizeof(struct rmnet_map_header) + + sizeof(struct rmnet_map_v5_csum_header))) { + rc = -EINVAL; + break; + } + frag_desc->hdr_ptr = rmnet_frag_data_ptr(frag_desc); /* Remove padding only for csum offload packets. * Coalesced packets should never have padding. */ - rmnet_frag_trim(frag_desc, port, len); + if (!rmnet_frag_trim(frag_desc, port, len)) { + rc = -EINVAL; + break; + } + list_del_init(&frag_desc->list); list_add_tail(&frag_desc->list, list); break; @@ -969,10 +986,14 @@ __rmnet_frag_ingress_handler(struct rmnet_frag_descriptor *frag_desc, goto recycle; } else { /* We only have the main QMAP header to worry about */ - rmnet_frag_pull(frag_desc, port, sizeof(*qmap)); + if (!rmnet_frag_pull(frag_desc, port, sizeof(*qmap))) + return; + frag_desc->hdr_ptr = rmnet_frag_data_ptr(frag_desc); - rmnet_frag_trim(frag_desc, port, len); + if (!rmnet_frag_trim(frag_desc, port, len)) + return; + list_add_tail(&frag_desc->list, &segs); } diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.h b/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.h index 0b0489dde732..795f6f27d773 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.h +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.h @@ -92,6 +92,8 @@ static inline void *rmnet_frag_pull(struct rmnet_frag_descriptor *frag_desc, unsigned int size) { if (size >= skb_frag_size(&frag_desc->frag)) { + pr_info("%s(): Pulling %u bytes from %u byte pkt. Dropping\n", + __func__, size, skb_frag_size(&frag_desc->frag)); rmnet_recycle_frag_descriptor(frag_desc, port); return NULL; } @@ -107,6 +109,8 @@ static inline void *rmnet_frag_trim(struct rmnet_frag_descriptor *frag_desc, unsigned int size) { if (!size) { + pr_info("%s(): Trimming %u byte pkt to 0. Dropping\n", + __func__, skb_frag_size(&frag_desc->frag)); rmnet_recycle_frag_descriptor(frag_desc, port); return NULL; } -- GitLab From 2c916d3611386e96dd6b47888cc1a45517988db9 Mon Sep 17 00:00:00 2001 From: Shiju Mathew Date: Tue, 25 Jun 2019 20:25:36 -0400 Subject: [PATCH 0838/1121] msm: vidc: Enable input crop extradata To support encode usecases that require input crop. Change-Id: Ib66f0ed74a40eea40b2e94461a8be083ac4e71c1 Signed-off-by: Shiju Mathew --- drivers/media/platform/msm/vidc/hfi_packetization.c | 4 ++++ drivers/media/platform/msm/vidc/msm_venc.c | 2 ++ drivers/media/platform/msm/vidc/msm_vidc_common.c | 3 +++ drivers/media/platform/msm/vidc/vidc_hfi_api.h | 1 + include/uapi/linux/v4l2-controls.h | 3 +++ 5 files changed, 13 insertions(+) diff --git a/drivers/media/platform/msm/vidc/hfi_packetization.c b/drivers/media/platform/msm/vidc/hfi_packetization.c index e191a4201b8c..463f56f4a8ac 100644 --- a/drivers/media/platform/msm/vidc/hfi_packetization.c +++ b/drivers/media/platform/msm/vidc/hfi_packetization.c @@ -544,6 +544,7 @@ static int get_hfi_extradata_index(enum hal_extradata_id index) break; case HAL_EXTRADATA_ASPECT_RATIO: case HAL_EXTRADATA_OUTPUT_CROP: + case HAL_EXTRADATA_INPUT_CROP: ret = HFI_PROPERTY_PARAM_INDEX_EXTRADATA; break; case HAL_EXTRADATA_MPEG2_SEQDISP: @@ -604,6 +605,9 @@ static int get_hfi_extradata_id(enum hal_extradata_id index) case HAL_EXTRADATA_OUTPUT_CROP: ret = MSM_VIDC_EXTRADATA_OUTPUT_CROP; break; + case HAL_EXTRADATA_INPUT_CROP: + ret = MSM_VIDC_EXTRADATA_INPUT_CROP; + break; default: ret = get_hfi_extradata_index(index); break; diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c index e92e3d206cf6..8bd216f6f1c1 100644 --- a/drivers/media/platform/msm/vidc/msm_venc.c +++ b/drivers/media/platform/msm/vidc/msm_venc.c @@ -699,6 +699,7 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { (1 << V4L2_MPEG_VIDC_EXTRADATA_LTR) | (1 << V4L2_MPEG_VIDC_EXTRADATA_ROI_QP) | (1 << V4L2_MPEG_VIDC_EXTRADATA_HDR10PLUS_METADATA) | + (1 << V4L2_MPEG_VIDC_EXTRADATA_INPUT_CROP) | (1ULL << V4L2_MPEG_VIDC_EXTRADATA_ENC_FRAME_QP) ), .qmenu = mpeg_video_vidc_extradata, @@ -1828,6 +1829,7 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) case V4L2_MPEG_VIDC_EXTRADATA_ASPECT_RATIO: case V4L2_MPEG_VIDC_EXTRADATA_ROI_QP: case V4L2_MPEG_VIDC_EXTRADATA_HDR10PLUS_METADATA: + case V4L2_MPEG_VIDC_EXTRADATA_INPUT_CROP: inst->bufq[OUTPUT_PORT].num_planes = 2; break; case V4L2_MPEG_VIDC_EXTRADATA_LTR: diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c index 357530ee5e5e..a9545c3ce871 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_common.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c @@ -5457,6 +5457,9 @@ enum hal_extradata_id msm_comm_get_hal_extradata_index( case V4L2_MPEG_VIDC_EXTRADATA_ENC_DTS: ret = HAL_EXTRADATA_ENC_DTS_METADATA; break; + case V4L2_MPEG_VIDC_EXTRADATA_INPUT_CROP: + ret = HAL_EXTRADATA_INPUT_CROP; + break; default: dprintk(VIDC_WARN, "Extradata not found: %d\n", index); break; diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_api.h b/drivers/media/platform/msm/vidc/vidc_hfi_api.h index 9e4bdaa4bbd6..206be4be9a02 100644 --- a/drivers/media/platform/msm/vidc/vidc_hfi_api.h +++ b/drivers/media/platform/msm/vidc/vidc_hfi_api.h @@ -120,6 +120,7 @@ enum hal_extradata_id { HAL_EXTRADATA_UBWC_CR_STATS_INFO, HAL_EXTRADATA_HDR10PLUS_METADATA, HAL_EXTRADATA_ENC_DTS_METADATA, + HAL_EXTRADATA_INPUT_CROP, }; enum hal_property { diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h index dbb39efbf3e5..5af6fb88086e 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h @@ -735,6 +735,9 @@ enum v4l2_mpeg_vidc_extradata { V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW = 8, V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI = 9, V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB = 11, +#define V4L2_MPEG_VIDC_EXTRADATA_INPUT_CROP \ + V4L2_MPEG_VIDC_EXTRADATA_INPUT_CROP + V4L2_MPEG_VIDC_EXTRADATA_INPUT_CROP = 13, V4L2_MPEG_VIDC_EXTRADATA_ASPECT_RATIO = 15, V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP = 16, V4L2_MPEG_VIDC_EXTRADATA_STREAM_USERDATA = 17, -- GitLab From 2606708ca95b5900a38f698f6a399a770b95411c Mon Sep 17 00:00:00 2001 From: Zhen Kong Date: Mon, 10 Jun 2019 13:06:41 -0700 Subject: [PATCH 0839/1121] qseecom: use scm_call2 for shutdown app Unlike scm_call2, __qseecom_scm_call2_locked() will unlock app_access_lock to let another qseecom thread work. But this mutex should not be released for shutdown app thread to prevent another thread accessing the resource that is freed by shutdown thread. So change to use scm_call2 for this cmd. Change-Id: Ifdd526e0b401cab5c9d6df71d5854022e0f273f0 Signed-off-by: Zhen Kong --- drivers/misc/qseecom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c index 02422cdbb5a8..00b9957cc2fa 100644 --- a/drivers/misc/qseecom.c +++ b/drivers/misc/qseecom.c @@ -547,7 +547,7 @@ static int qseecom_scm_call2(uint32_t svc_id, uint32_t tz_cmd_id, smc_id = TZ_OS_APP_SHUTDOWN_ID; desc.arginfo = TZ_OS_APP_SHUTDOWN_ID_PARAM_ID; desc.args[0] = req->app_id; - ret = __qseecom_scm_call2_locked(smc_id, &desc); + ret = scm_call2(smc_id, &desc); break; } case QSEOS_APP_LOOKUP_COMMAND: { -- GitLab From 9795e5126033916afa801a4cda332581979bf1b9 Mon Sep 17 00:00:00 2001 From: Chris Lew Date: Thu, 27 Jun 2019 16:11:11 -0700 Subject: [PATCH 0840/1121] msm: mhi_dev: Update IPCR channel enums Change the DCI channel macros to IPCR so they match the host side mhi channel identifiers. Change-Id: Ief1e4d603f571b5203dec20dc8ed31da92440021 Signed-off-by: Chris Lew --- include/linux/msm_mhi_dev.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/msm_mhi_dev.h b/include/linux/msm_mhi_dev.h index ba4ac4358ac3..88ec5492ca75 100644 --- a/include/linux/msm_mhi_dev.h +++ b/include/linux/msm_mhi_dev.h @@ -97,8 +97,8 @@ enum mhi_client_channel { MHI_CLIENT_IP_CTRL_0_IN = 17, MHI_CLIENT_IP_CTRL_1_OUT = 18, MHI_CLIENT_IP_CTRL_1_IN = 19, - MHI_CLIENT_DCI_OUT = 20, - MHI_CLIENT_DCI_IN = 21, + MHI_CLIENT_IPCR_OUT = 20, + MHI_CLIENT_IPCR_IN = 21, MHI_CLIENT_IP_CTRL_3_OUT = 22, MHI_CLIENT_IP_CTRL_3_IN = 23, MHI_CLIENT_IP_CTRL_4_OUT = 24, -- GitLab From a5dbed3f467c79309e3a4e2c31701ef3989edee6 Mon Sep 17 00:00:00 2001 From: Chris Lew Date: Tue, 9 Jul 2019 15:33:22 -0700 Subject: [PATCH 0841/1121] dt-bindings: net: qrtr: Add MHI Device transport bindings The QRTR MHI DEV driver acts as a transport driver for a device that is configured as a pcie endpoint. Document the bindings for this qrtr transport. Change-Id: I289b858b094d7e3e62a5ded61d42cde04518093c Signed-off-by: Chris Lew --- .../devicetree/bindings/net/qrtr-mhi-dev.txt | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/qrtr-mhi-dev.txt diff --git a/Documentation/devicetree/bindings/net/qrtr-mhi-dev.txt b/Documentation/devicetree/bindings/net/qrtr-mhi-dev.txt new file mode 100644 index 000000000000..9d15e9d6fe9f --- /dev/null +++ b/Documentation/devicetree/bindings/net/qrtr-mhi-dev.txt @@ -0,0 +1,30 @@ +QTI QRTR MHI Dev transport binding + +- compatible: + Usage: required + Value type: + Definition: must be "qcom,qrtr-mhi-dev" + +- qcom,net-id: + Usage: optional + Value type: + Definition: indicates what subnet this transport belongs to. Should be + passed into the qrtr core logic to determine if forwarding + is needed on this endpoint. + +- qcom,low-latency: + Usage: optional + Value type: + Definition: indicates whether this transport receiving thread needs to + be set to realtime priority for enhanced performance. + += EXAMPLE +The following example represents the qrtr mhi dev transport node on a device +configured as a pcie endpoint and needs to forward data from the host to a +modem co-processor. + + qcom,mhi_dev_qrtr { + compatible = "qcom,qrtr-mhi-dev"; + qcom,net-id = <3>; + qcom,low-latency; + }; -- GitLab From b0079fb73c08e195498ba2b2ea9623b0cc0f5fed Mon Sep 17 00:00:00 2001 From: Omkar Savagaonkar Date: Thu, 20 Jun 2019 15:54:44 +0530 Subject: [PATCH 0842/1121] irqchip/gic-v3: Re-init GIC hardware upon hibernation restore Code added in this patch takes backup of different set of registers during hibernation suspend. On receiving hibernation restore callback, it restores register values from backup. This ensures state of hardware to be same just before hibernation and after restore. Change-Id: I36cfce8901ccfd82562764d8f6614f8760273248 Signed-off-by: Omkar Savagaonkar Signed-off-by: Arun KS --- drivers/irqchip/irq-gic-v3.c | 108 ++++++++++++++++++++++++++++++++++- 1 file changed, 106 insertions(+), 2 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index dae3bddaa7fd..d0a199e96e44 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -41,6 +41,8 @@ #include #include +#include +#include #include "irq-gic-common.h" @@ -60,6 +62,14 @@ struct gic_chip_data { u32 nr_redist_regions; unsigned int irq_nr; struct partition_desc *ppi_descs[16]; +#ifdef CONFIG_HIBERNATION + unsigned int enabled_irqs[32]; + unsigned int active_irqs[32]; + unsigned int irq_edg_lvl[64]; + unsigned int ppi_edg_lvl; + unsigned int enabled_sgis; + unsigned int pending_sgis; +#endif }; static struct gic_chip_data gic_data __read_mostly; @@ -74,6 +84,9 @@ static struct gic_kvm_info gic_v3_kvm_info; /* Our default, arbitrary priority value. Linux only uses one anyway. */ #define DEFAULT_PMR_VALUE 0xf0 +static void gic_dist_init(void); +static void gic_cpu_init(void); + static inline unsigned int gic_irq(struct irq_data *d) { return d->hwirq; @@ -334,9 +347,54 @@ static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu) } #ifdef CONFIG_PM +#ifdef CONFIG_HIBERNATION +extern int in_suspend; +static bool hibernation; + +static int gic_suspend_notifier(struct notifier_block *nb, + unsigned long event, + void *dummy) +{ + if (event == PM_HIBERNATION_PREPARE) + hibernation = true; + else if (event == PM_POST_HIBERNATION) + hibernation = false; + return NOTIFY_OK; +} +static struct notifier_block gic_notif_block = { + .notifier_call = gic_suspend_notifier, +}; + +static void gic_hibernation_suspend(void) +{ + int i; + void __iomem *base = gic_data.dist_base; + void __iomem *rdist_base = gic_data_rdist_sgi_base(); + + gic_data.enabled_sgis = readl_relaxed(rdist_base + GICD_ISENABLER); + gic_data.pending_sgis = readl_relaxed(rdist_base + GICD_ISPENDR); + /* Store edge level for PPIs by reading GICR_ICFGR1 */ + gic_data.ppi_edg_lvl = readl_relaxed(rdist_base + GICR_ICFGR0 + 4); + + for (i = 0; i * 32 < gic_data.irq_nr; i++) { + gic_data.enabled_irqs[i] = readl_relaxed(base + + GICD_ISENABLER + i * 4); + gic_data.active_irqs[i] = readl_relaxed(base + + GICD_ISPENDR + i * 4); + } + + for (i = 2; i < gic_data.irq_nr / 16; i++) + gic_data.irq_edg_lvl[i] = readl_relaxed(base + + GICD_ICFGR + i * 4); +} +#endif static int gic_suspend(void) { +#ifdef CONFIG_HIBERNATION + if (unlikely(hibernation)) + gic_hibernation_suspend(); +#endif return 0; } @@ -379,6 +437,48 @@ static void gic_resume_one(struct gic_chip_data *gic) static void gic_resume(void) { +#ifdef CONFIG_HIBERNATION + int i; + void __iomem *base = gic_data.dist_base; + void __iomem *rdist_base = gic_data_rdist_sgi_base(); + + /* + * in_suspend is defined in hibernate.c and will be 0 during + * hibernation restore case. Also it willl be 0 for suspend to ram case + * and similar cases. Underlying code will not get executed in regular + * cases and will be executed only for hibernation restore. + */ + if (unlikely((in_suspend == 0 && hibernation))) { + pr_info("Re-initializing gic in hibernation restore\n"); + gic_dist_init(); + gic_cpu_init(); + + /* Activate and enable SGIs and PPIs */ + writel_relaxed(gic_data.enabled_sgis, + rdist_base + GICD_ISENABLER); + writel_relaxed(gic_data.pending_sgis, + rdist_base + GICD_ISPENDR); + /* Restore edge and level triggers for PPIs from GICR_ICFGR1 */ + writel_relaxed(gic_data.ppi_edg_lvl, + rdist_base + GICR_ICFGR0 + 4); + + /* Restore edge and level triggers */ + for (i = 2; i < gic_data.irq_nr / 16; i++) + writel_relaxed(gic_data.irq_edg_lvl[i], + base + GICD_ICFGR + i * 4); + gic_dist_wait_for_rwp(); + + /* Activate and enable interupts from backup */ + for (i = 0; i * 32 < gic_data.irq_nr; i++) { + writel_relaxed(gic_data.active_irqs[i], + base + GICD_ISPENDR + i * 4); + + writel_relaxed(gic_data.enabled_irqs[i], + base + GICD_ISENABLER + i * 4); + } + gic_dist_wait_for_rwp(); + } +#endif gic_resume_one(&gic_data); } @@ -458,7 +558,7 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs } while (irqnr != ICC_IAR1_EL1_SPURIOUS); } -static void __init gic_dist_init(void) +static void gic_dist_init(void) { unsigned int i; u64 affinity; @@ -1278,7 +1378,11 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare redist_stride, &node->fwnode); if (err) goto out_unmap_rdist; - +#ifdef CONFIG_HIBERNATION + err = register_pm_notifier(&gic_notif_block); + if (err) + goto out_unmap_rdist; +#endif gic_populate_ppi_partitions(node); gic_of_setup_kvm_info(node); return 0; -- GitLab From 6edc4771b995a020983d4412d1ec343657b4aff3 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Mon, 1 Jul 2019 14:43:05 +0530 Subject: [PATCH 0843/1121] ARM: dts: msm: Add venus pil node for atoll Add venus pil node to facilitate VENUS subsystem loading for atoll target. Change-Id: Ia6fa0be99e3111ec68387dcb44110383a1a682d7 Signed-off-by: Dikshita Agarwal --- arch/arm64/boot/dts/qcom/atoll.dtsi | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index c513d1e3f62e..1a729e25c51e 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -2056,6 +2056,31 @@ interrupt-names = "tsens-upper-lower", "tsens-critical"; #thermal-sensor-cells = <1>; }; + + qcom,venus@aae0000 { + compatible = "qcom,pil-tz-generic"; + reg = <0xaae0000 0x4000>; + + vdd-supply = <&venus_gdsc>; + qcom,proxy-reg-names = "vdd"; + + clocks = <&clock_videocc VIDEO_CC_VENUS_CTL_CORE_CLK>, + <&clock_videocc VIDEO_CC_VENUS_AHB_CLK>, + <&clock_videocc VIDEO_CC_VENUS_CTL_AXI_CLK>; + clock-names = "core_clk", "iface_clk", "bus_clk"; + qcom,proxy-clock-names = "core_clk", "iface_clk", "bus_clk"; + + qcom,pas-id = <9>; + qcom,msm-bus,name = "pil-venus"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <63 512 0 0>, + <63 512 0 304000>; + qcom,proxy-timeout-ms = <100>; + qcom,firmware-name = "venus"; + memory-region = <&pil_video_mem>; + }; }; #include "atoll-gdsc.dtsi" -- GitLab From 7b3b9aa4b6ee5e16cb0dd7827deca29b14ecae04 Mon Sep 17 00:00:00 2001 From: Omkar Savagaonkar Date: Wed, 10 Jul 2019 12:36:06 +0530 Subject: [PATCH 0844/1121] Hibernate: Add check for pte_valid in saveable page Add check for pte_valid in saveable page after being checked for the rest. This is required as PTE is removed for pages allocated with __dma_alloc_coherent with DMA_ATTR_NO_KERNEL_MAPPING flag set. This patch makes sure that these pages are not considered for snapshot. Change-Id: Idc7dede2d45be0a8e19899004b5277e5aba24db8 Signed-off-by: Omkar Savagaonkar --- kernel/power/snapshot.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index 0972a8e09d08..b7a6889439a7 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c @@ -1257,6 +1257,33 @@ static inline void *saveable_highmem_page(struct zone *z, unsigned long p) } #endif /* CONFIG_HIGHMEM */ +static bool kernel_pte_present(struct page *page) +{ + pgd_t *pgd; + pud_t *pud; + pmd_t *pmd; + pte_t *pte; + unsigned long addr = (unsigned long)page_address(page); + + pgd = pgd_offset_k(addr); + if (pgd_none(*pgd)) + return false; + + pud = pud_offset(pgd, addr); + if (pud_none(*pud)) + return false; + if (pud_sect(*pud)) + return true; + + pmd = pmd_offset(pud, addr); + if (pmd_none(*pmd)) + return false; + if (pmd_sect(*pmd)) + return true; + + pte = pte_offset_kernel(pmd, addr); + return pte_valid(*pte); +} /** * saveable_page - Check if the given page is saveable. * @@ -1287,6 +1314,14 @@ static struct page *saveable_page(struct zone *zone, unsigned long pfn) && (!kernel_page_present(page) || pfn_is_nosave(pfn))) return NULL; + /* + * Even if page is not reserved and if it's not present in kernel PTE; + * don't snapshot it ! This happens to the pages allocated using + * __dma_alloc_coherent with DMA_ATTR_NO_KERNEL_MAPPING flag set. + */ + if (!kernel_pte_present(page)) + return NULL; + if (page_is_guard(page)) return NULL; -- GitLab From 9f6b5c3141d128da5aa56cf7c56c29552c4a0813 Mon Sep 17 00:00:00 2001 From: Satish Kodishala Date: Tue, 9 Jul 2019 14:54:33 +0530 Subject: [PATCH 0845/1121] BTFM: Add support for Apache 1.2.* cards Add support for Apache 1.2.* cards. Remove support for non-existing 1.1.1 cards. CRs-Fixed: 2486383 Change-Id: I7a58585db68436a4d811b7b9706ca5c2fe92ab5c Signed-off-by: Satish Kodishala --- drivers/bluetooth/btfm_slim_wcn3990.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/bluetooth/btfm_slim_wcn3990.h b/drivers/bluetooth/btfm_slim_wcn3990.h index 7cf07d8ae6ca..545d21ec67e9 100644 --- a/drivers/bluetooth/btfm_slim_wcn3990.h +++ b/drivers/bluetooth/btfm_slim_wcn3990.h @@ -103,8 +103,8 @@ enum{ QCA_APACHE_SOC_ID_0102 = 0x40020122, QCA_APACHE_SOC_ID_0103 = 0x40020123, QCA_APACHE_SOC_ID_0110 = 0x40020130, - QCA_APACHE_SOC_ID_0111 = 0x40020140, - QCA_APACHE_SOC_ID_0120 = 0x40020240, + QCA_APACHE_SOC_ID_0120 = 0x40020140, + QCA_APACHE_SOC_ID_0121 = 0x40020150, }; enum { -- GitLab From dbec963d0d358ff948052c5148a14d0a9e49307e Mon Sep 17 00:00:00 2001 From: Manoj Prabhu B Date: Thu, 11 Jul 2019 12:52:51 +0530 Subject: [PATCH 0846/1121] diag: Update new msg, log and event masks for diag logging Log and event mask ranges are updated and new entry of msg mask array is updated. Change-Id: I0a257e6b54b8d6ccdb3ec5d7ac2400751c95fa61 Signed-off-by: Manoj Prabhu B --- include/linux/diagchar.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/include/linux/diagchar.h b/include/linux/diagchar.h index 21b29707bfed..72b41a1d1296 100644 --- a/include/linux/diagchar.h +++ b/include/linux/diagchar.h @@ -149,7 +149,7 @@ * a new RANGE of SSIDs to the msg_mask_tbl. */ #define MSG_MASK_TBL_CNT 26 -#define APPS_EVENT_LAST_ID 0xCA7 +#define APPS_EVENT_LAST_ID 0xCAA #define MSG_SSID_0 0 #define MSG_SSID_0_LAST 130 @@ -184,7 +184,7 @@ #define MSG_SSID_15 8000 #define MSG_SSID_15_LAST 8000 #define MSG_SSID_16 8500 -#define MSG_SSID_16_LAST 8531 +#define MSG_SSID_16_LAST 8532 #define MSG_SSID_17 9000 #define MSG_SSID_17_LAST 9008 #define MSG_SSID_18 9500 @@ -784,7 +784,8 @@ static const uint32_t msg_bld_masks_16[] = { MSG_LVL_LOW | MSG_LVL_MED | MSG_LVL_HIGH | MSG_LVL_ERROR | MSG_LVL_FATAL, MSG_LVL_MED, - MSG_LVL_MED + MSG_LVL_MED, + MSG_LVL_LOW }; static const uint32_t msg_bld_masks_17[] = { @@ -922,7 +923,7 @@ static const uint32_t msg_bld_masks_25[] = { /* LOG CODES */ static const uint32_t log_code_last_tbl[] = { 0x0, /* EQUIP ID 0 */ - 0x1C94, /* EQUIP ID 1 */ + 0x1C9A, /* EQUIP ID 1 */ 0x0, /* EQUIP ID 2 */ 0x0, /* EQUIP ID 3 */ 0x4910, /* EQUIP ID 4 */ -- GitLab From 575b6566f8f21fd8595cfb102c7560a09a5bcc3b Mon Sep 17 00:00:00 2001 From: Sreelakshmi Gownipalli Date: Tue, 9 Jul 2019 16:00:08 -0700 Subject: [PATCH 0847/1121] diag: Close the control channel during SSR Close the control channel when diag receives bye packet from qrtr during SSR. Change-Id: I4b26edc1ac6c114b486ca4ad3e1703b296760945 Signed-off-by: Sreelakshmi Gownipalli --- drivers/char/diag/diagfwd_socket.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/char/diag/diagfwd_socket.c b/drivers/char/diag/diagfwd_socket.c index bad35d6ccf7d..8228e7d54f60 100644 --- a/drivers/char/diag/diagfwd_socket.c +++ b/drivers/char/diag/diagfwd_socket.c @@ -632,13 +632,10 @@ static void handle_ctrl_pkt(struct diag_socket_info *info, void *buf, int len) info->name); mutex_lock(&driver->diag_notifier_mutex); - if (bootup_req[info->peripheral] == PERIPHERAL_SSR_UP) { + if (bootup_req[info->peripheral] == PERIPHERAL_SSR_UP) DIAG_LOG(DIAG_DEBUG_PERIPHERALS, - "diag: %s is up, stopping cleanup: bootup_req = %d\n", + "diag: %s is up, bootup_req = %d\n", info->name, (int)bootup_req[info->peripheral]); - mutex_unlock(&driver->diag_notifier_mutex); - break; - } mutex_unlock(&driver->diag_notifier_mutex); socket_close_channel(info); } -- GitLab From 3ceccc66bbb857b8d69d3af1bbc69f1c5f6f9350 Mon Sep 17 00:00:00 2001 From: Mao Jinlong Date: Thu, 11 Jul 2019 12:44:06 +0530 Subject: [PATCH 0848/1121] ARM: dts: msm: Add mem_dump node for atoll Add mem_dump node for atoll to support memory dump feature. Change-Id: I3e1237e262d215783cd62a260a717fc2dc69e4dd Signed-off-by: Mao Jinlong --- arch/arm64/boot/dts/qcom/atoll.dtsi | 61 +++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index 66b04416430e..810de11bf43e 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -591,6 +591,12 @@ size = <0x0 0x800000>; }; + dump_mem: mem_dump_region { + compatible = "shared-dma-pool"; + reusable; + size = <0 0x2400000>; + }; + /* global autoconfigured region for contiguous allocations */ linux,cma { compatible = "shared-dma-pool"; @@ -1308,6 +1314,61 @@ }; }; + mem_dump { + compatible = "qcom,mem-dump"; + memory-region = <&dump_mem>; + + rpmh { + qcom,dump-size = <0x2000000>; + qcom,dump-id = <0xec>; + }; + + rpm_sw { + qcom,dump-size = <0x28000>; + qcom,dump-id = <0xea>; + }; + + pmic { + qcom,dump-size = <0x10000>; + qcom,dump-id = <0xe4>; + }; + + fcm { + qcom,dump-size = <0x8400>; + qcom,dump-id = <0xee>; + }; + + etf_swao { + qcom,dump-size = <0x10000>; + qcom,dump-id = <0xf1>; + }; + + etr_reg { + qcom,dump-size = <0x1000>; + qcom,dump-id = <0x100>; + }; + + etfswao_reg { + qcom,dump-size = <0x1000>; + qcom,dump-id = <0x102>; + }; + + misc_data { + qcom,dump-size = <0x1000>; + qcom,dump-id = <0xe8>; + }; + + etf_lpass { + qcom,dump-size = <0x4000>; + qcom,dump-id = <0xf4>; + }; + + etflpass_reg { + qcom,dump-size = <0x1000>; + qcom,dump-id = <0x104>; + }; + }; + clock_rpmh: qcom,rpmh { compatible = "qcom,dummycc"; clock-output-names = "rpm_clocks"; -- GitLab From 1562c8cebe22c968113504bf59e595d9107b95fa Mon Sep 17 00:00:00 2001 From: Mao Jinlong Date: Fri, 12 Jul 2019 12:06:24 +0530 Subject: [PATCH 0849/1121] ARM: dts: msm: Add dcc node for atoll Add dcc node for atoll to support dcc functions. Change-Id: I364d43d65fbdd9bc7592382a015d7d7ee0535637 Signed-off-by: Mao Jinlong --- arch/arm64/boot/dts/qcom/atoll.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index 810de11bf43e..f5393251734c 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -848,6 +848,14 @@ }; }; + dcc: dcc_v2@10a2000 { + compatible = "qcom,dcc-v2"; + reg = <0x10a2000 0x1000>, + <0x10ae000 0x2000>; + reg-names = "dcc-base", "dcc-ram-base"; + dcc-ram-offset = <0x6000>; + }; + restart@c264000 { compatible = "qcom,pshold"; reg = <0xc264000 0x4>, -- GitLab From d0606a644d075a70d4855164d44de6f24e7b0581 Mon Sep 17 00:00:00 2001 From: Arun Prakash P P Date: Mon, 4 Mar 2019 15:53:45 +0530 Subject: [PATCH 0850/1121] mailbox: msm_qmp: Add support for suspend to disk Add support in qmp driver for suspend to disk feature. Change-Id: I0135b8fd4efc9168545e63c82e020aa0f407a638 Signed-off-by: Rama Krishna Phani A Signed-off-by: ArunPrakash --- drivers/mailbox/msm_qmp.c | 69 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 3 deletions(-) diff --git a/drivers/mailbox/msm_qmp.c b/drivers/mailbox/msm_qmp.c index 4ba32ea3bf14..ceb57d48d933 100644 --- a/drivers/mailbox/msm_qmp.c +++ b/drivers/mailbox/msm_qmp.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -168,6 +168,7 @@ struct qmp_mbox { struct completion ch_complete; struct delayed_work dwork; struct qmp_device *mdev; + bool suspend_flag; }; /** @@ -208,6 +209,7 @@ struct qmp_device { u32 rx_irq_count; void *ilc; + bool early_boot; }; /** @@ -376,8 +378,14 @@ static int qmp_send_data(struct mbox_chan *chan, void *data) unsigned long flags; int i; - if (!mbox || !data || mbox->local_state != CHANNEL_CONNECTED) + if (!mbox || !data) return -EINVAL; + /* + * Return -EAGAIN if client tried to send data after hibernation + * and channel is not yet opened + */ + if (!completion_done(&mbox->ch_complete)) + return -EAGAIN; mdev = mbox->mdev; @@ -568,6 +576,16 @@ static void __qmp_rx_worker(struct qmp_mbox *mbox) mbox->local_state = LINK_CONNECTED; complete_all(&mbox->link_complete); QMP_INFO(mdev->ilc, "Set to link connected\n"); + /* + * If link connection happened after hibernation + * manualy trigger the channel open procedure since client + * won't try to re-open the channel + */ + if (mbox->suspend_flag == true) { + set_mcore_ch(mbox, QMP_MBOX_CH_CONNECTED); + mbox->local_state = LOCAL_CONNECTING; + send_irq(mbox->mdev); + } break; case LINK_CONNECTED: if (desc.ucore.ch_state == desc.ucore.ch_state_ack) { @@ -851,6 +869,7 @@ static int qmp_mbox_init(struct device_node *n, struct qmp_device *mdev) mbox->tx_sent = false; mbox->num_assigned = 0; INIT_DELAYED_WORK(&mbox->dwork, qmp_notify_timeout); + mbox->suspend_flag = false; mdev_add_mbox(mdev, mbox); return 0; @@ -938,6 +957,8 @@ static int qmp_mbox_probe(struct platform_device *pdev) if (ret) return ret; + dev_set_drvdata(&pdev->dev, mdev); + mdev->ilc = ipc_log_context_create(QMP_IPC_LOG_PAGE_CNT, mdev->name, 0); kthread_init_work(&mdev->kwork, rx_worker); @@ -960,12 +981,53 @@ static int qmp_mbox_probe(struct platform_device *pdev) mdev->rx_irq_line, ret); /* Trigger fake RX in case of missed interrupt */ - if (of_property_read_bool(edge_node, "qcom,early-boot")) + if (of_property_read_bool(edge_node, "qcom,early-boot")) { + mdev->early_boot = true; qmp_irq_handler(0, mdev); + } return 0; } +static int qmp_mbox_suspend(struct device *dev) +{ + struct qmp_device *mdev = dev_get_drvdata(dev); + struct qmp_mbox *mbox; + + list_for_each_entry(mbox, &mdev->mboxes, list) { + mbox->local_state = LINK_DISCONNECTED; + init_completion(&mbox->link_complete); + init_completion(&mbox->ch_complete); + mbox->tx_sent = false; + /* + * set suspend flag to indicate self channel open is required + * after restore operation + */ + mbox->suspend_flag = true; + /* Release rx packet buffer */ + if (mbox->rx_pkt.data) { + devm_kfree(mdev->dev, mbox->rx_pkt.data); + mbox->rx_pkt.data = NULL; + } + } + return 0; +} + +static int qmp_mbox_resume(struct device *dev) +{ + struct qmp_device *mdev = dev_get_drvdata(dev); + + if (mdev->early_boot) + qmp_irq_handler(0, mdev); + + return 0; +} + +static const struct dev_pm_ops qmp_mbox_pm_ops = { + .freeze = qmp_mbox_suspend, + .restore = qmp_mbox_resume, +}; + static struct platform_driver qmp_mbox_driver = { .probe = qmp_mbox_probe, .remove = qmp_mbox_remove, @@ -973,6 +1035,7 @@ static struct platform_driver qmp_mbox_driver = { .name = "qmp_mbox", .owner = THIS_MODULE, .of_match_table = qmp_mbox_match_table, + .pm = &qmp_mbox_pm_ops, }, }; -- GitLab From 8938ebd3893ea65a63a1606aeb54d06c4a2eec40 Mon Sep 17 00:00:00 2001 From: Rama Krishna Phani A Date: Wed, 20 Feb 2019 15:40:15 +0530 Subject: [PATCH 0851/1121] soc: qcom: smp2p: Add support for suspend to disk Add support in smp2p driver for suspend to disk feature. Get SMEM related items during resume from hibernation. Change-Id: Ib342d914e8f5ed1cdee610e5d1f64128b080fb91 Signed-off-by: Rama Krishna Phani A Signed-off-by: ArunPrakash --- drivers/soc/qcom/smp2p.c | 144 +++++++++++++++++++++++++++++---------- 1 file changed, 108 insertions(+), 36 deletions(-) diff --git a/drivers/soc/qcom/smp2p.c b/drivers/soc/qcom/smp2p.c index 788d16f59a63..bfc4aad91f44 100644 --- a/drivers/soc/qcom/smp2p.c +++ b/drivers/soc/qcom/smp2p.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Sony Mobile Communications AB. - * Copyright (c) 2012-2013, 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2013, 2018-2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -558,10 +558,80 @@ static int smp2p_parse_ipc(struct qcom_smp2p *smp2p) return 0; } -static int qcom_smp2p_probe(struct platform_device *pdev) +static int qcom_smp2p_alloc_item(struct platform_device *pdev, + struct qcom_smp2p *smp2p) { + int ret = 0; struct smp2p_entry *entry; struct device_node *node; + + ret = qcom_smp2p_alloc_outbound_item(smp2p); + if (ret < 0) + return ret; + + for_each_available_child_of_node(pdev->dev.of_node, node) { + entry = devm_kzalloc(&pdev->dev, sizeof(*entry), GFP_KERNEL); + if (!entry) + return -ENOMEM; + + entry->smp2p = smp2p; + spin_lock_init(&entry->lock); + + ret = of_property_read_string(node, "qcom,entry-name", + &entry->name); + if (ret < 0) + return ret; + + if (of_property_read_bool(node, "interrupt-controller")) { + ret = qcom_smp2p_inbound_entry(smp2p, entry, node); + if (ret < 0) + return ret; + + list_add(&entry->node, &smp2p->inbound); + } else { + ret = qcom_smp2p_outbound_entry(smp2p, entry, node); + if (ret < 0) + return ret; + + list_add(&entry->node, &smp2p->outbound); + } + } + wakeup_source_init(&smp2p->ws, "smp2p"); + + /* Kick the outgoing edge after allocating entries */ + qcom_smp2p_kick(smp2p); + + return ret; +} + +static void qcom_smp2p_release_item(struct device *dev, + struct qcom_smp2p *smp2p) +{ + struct smp2p_entry *entry; + struct smp2p_entry *next_entry; + + /* Walk through the out bound list and release state and entry */ + list_for_each_entry_safe(entry, next_entry, &smp2p->outbound, node) { + qcom_smem_state_unregister(entry->state); + list_del(&entry->node); + devm_kfree(smp2p->dev, entry); + } + INIT_LIST_HEAD(&smp2p->outbound); + + /* Walk through the inbound list and release domain and entry */ + list_for_each_entry_safe(entry, next_entry, &smp2p->inbound, node) { + irq_domain_remove(entry->domain); + list_del(&entry->node); + devm_kfree(smp2p->dev, entry); + } + INIT_LIST_HEAD(&smp2p->inbound); + /* remove wakeup source */ + wakeup_source_trash(&smp2p->ws); +} + +static int qcom_smp2p_probe(struct platform_device *pdev) +{ + struct smp2p_entry *entry; struct qcom_smp2p *smp2p; const char *key; int ret; @@ -619,42 +689,16 @@ static int qcom_smp2p_probe(struct platform_device *pdev) return ret; } - ret = qcom_smp2p_alloc_outbound_item(smp2p); - if (ret < 0) - goto release_mbox; - - for_each_available_child_of_node(pdev->dev.of_node, node) { - entry = devm_kzalloc(&pdev->dev, sizeof(*entry), GFP_KERNEL); - if (!entry) { - ret = -ENOMEM; - goto unwind_interfaces; - } - - entry->smp2p = smp2p; - spin_lock_init(&entry->lock); - - ret = of_property_read_string(node, "qcom,entry-name", &entry->name); - if (ret < 0) - goto unwind_interfaces; - - if (of_property_read_bool(node, "interrupt-controller")) { - ret = qcom_smp2p_inbound_entry(smp2p, entry, node); - if (ret < 0) - goto unwind_interfaces; - - list_add(&entry->node, &smp2p->inbound); - } else { - ret = qcom_smp2p_outbound_entry(smp2p, entry, node); - if (ret < 0) - goto unwind_interfaces; - - list_add(&entry->node, &smp2p->outbound); + ret = qcom_smp2p_alloc_item(pdev, smp2p); + if (ret < 0 && ret != -EEXIST) { + if (ret != -EPROBE_DEFER) { + dev_err(&pdev->dev, "failed to alloc outbound items\n"); + goto release_mbox; } + } else if (ret) { + dev_err(&pdev->dev, "failed to get smp2p entries\n"); + goto unwind_interfaces; } - wakeup_source_init(&smp2p->ws, "smp2p"); - - /* Kick the outgoing edge after allocating entries */ - qcom_smp2p_kick(smp2p); ret = devm_request_threaded_irq(&pdev->dev, smp2p->irq, qcom_smp2p_isr, qcom_smp2p_intr, @@ -701,6 +745,33 @@ static int qcom_smp2p_remove(struct platform_device *pdev) return 0; } +static int qcom_smp2p_resume(struct device *dev) +{ + int ret = 0; + struct qcom_smp2p *smp2p = dev_get_drvdata(dev); + struct platform_device *pdev = container_of(dev, struct + platform_device, dev); + + ret = qcom_smp2p_alloc_item(pdev, smp2p); + if (ret < 0 && ret != -EEXIST) + dev_err(dev, "failed to alloc items ret = %d\n", ret); + + return ret; +} + +static int qcom_smp2p_suspend(struct device *dev) +{ + struct qcom_smp2p *smp2p = dev_get_drvdata(dev); + + qcom_smp2p_release_item(dev, smp2p); + return 0; +} + +static const struct dev_pm_ops qcom_smp2p_pm_ops = { + .freeze = qcom_smp2p_suspend, + .restore = qcom_smp2p_resume, +}; + static const struct of_device_id qcom_smp2p_of_match[] = { { .compatible = "qcom,smp2p" }, {} @@ -713,6 +784,7 @@ static struct platform_driver qcom_smp2p_driver = { .driver = { .name = "qcom_smp2p", .of_match_table = qcom_smp2p_of_match, + .pm = &qcom_smp2p_pm_ops, }, }; module_platform_driver(qcom_smp2p_driver); -- GitLab From d6a9708ba061f3d3ed9aa6df63b486f9b0f82889 Mon Sep 17 00:00:00 2001 From: Vijayavardhan Vennapusa Date: Tue, 9 Jul 2019 11:10:29 +0530 Subject: [PATCH 0852/1121] ARM: dts: msm: Add wake-gpio for qcs405-iot-sku6 variant only GPIO 21 can be used for either PCIe or mute button. Hence add wake-gpio property only for qcs405-iot-sku6 variant only so that mute button works for other varaints. Also delete mute button node for allowing PCIe EP to wakeup PCIe RC. Change-Id: Ic3a327b855d50ddac0b8c0efdb24a1742300108f Signed-off-by: Vijayavardhan Vennapusa --- arch/arm64/boot/dts/qcom/qcs405-iot-sku6.dts | 11 ++++++++++- arch/arm64/boot/dts/qcom/qcs405-pcie.dtsi | 3 +-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/qcs405-iot-sku6.dts b/arch/arm64/boot/dts/qcom/qcs405-iot-sku6.dts index 227b8e703377..dddd2f01b5d1 100644 --- a/arch/arm64/boot/dts/qcom/qcs405-iot-sku6.dts +++ b/arch/arm64/boot/dts/qcom/qcs405-iot-sku6.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -60,4 +60,13 @@ spi-max-frequency = <50000000>; }; }; + + gpio_keys { + /delete-node/ vol_mute; + }; +}; + +&pcie0 { + pinctrl-0 = <&pcie0_perst_default &pcie0_wake_default>; + wake-gpio = <&tlmm 21 0>; }; diff --git a/arch/arm64/boot/dts/qcom/qcs405-pcie.dtsi b/arch/arm64/boot/dts/qcom/qcs405-pcie.dtsi index bda2e511a766..1094f9725fb0 100644 --- a/arch/arm64/boot/dts/qcom/qcs405-pcie.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs405-pcie.dtsi @@ -65,10 +65,9 @@ 0x0044 0x00 0x0>; pinctrl-names = "default"; - pinctrl-0 = <&pcie0_perst_default &pcie0_wake_default>; + pinctrl-0 = <&pcie0_perst_default>; perst-gpio = <&tlmm 43 0>; - wake-gpio = <&tlmm 21 0>; vreg-1.8-supply = <&pms405_l5>; vreg-0.9-supply = <&pms405_l3>; -- GitLab From 6afd052343989c10e0aafcf17a04c92f98ee3ad0 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Tue, 2 Jul 2019 12:51:32 +0530 Subject: [PATCH 0853/1121] msm: vidc: Add configurations specific to atoll Add configurations specific to atoll platform as per H/W and spec. Eg: Codec data, performance configs etc. Change-Id: I69309acc0d33e9b61c0f3fd2eedbb44b2cb2c0d9 Signed-off-by: Dikshita Agarwal --- .../platform/msm/vidc/msm_vidc_platform.c | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/drivers/media/platform/msm/vidc/msm_vidc_platform.c b/drivers/media/platform/msm/vidc/msm_vidc_platform.c index ca0d912348cd..7bbeba205895 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_platform.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_platform.c @@ -63,6 +63,19 @@ static struct msm_vidc_codec_data default_codec_data[] = { CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 125, 675, 320), }; +/* Update with atoll data */ +static struct msm_vidc_codec_data atoll_codec_data[] = { + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 125, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 125, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_ENCODER, 125, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_TME, MSM_VIDC_ENCODER, 0, 540, 540), + CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 50, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 50, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 50, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_DECODER, 50, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 50, 200, 200), +}; + /* Update with SM6150 data */ static struct msm_vidc_codec_data sm6150_codec_data[] = { CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 125, 675, 320), @@ -165,6 +178,65 @@ static struct msm_vidc_common_data default_common_data[] = { }, }; +static struct msm_vidc_common_data atoll_common_data[] = { + { + .key = "qcom,never-unload-fw", + .value = 1, + }, + { + .key = "qcom,sw-power-collapse", + .value = 1, + }, + { + .key = "qcom,domain-attr-non-fatal-faults", + .value = 1, + }, + { + .key = "qcom,max-secure-instances", + .value = 3, + }, + { + .key = "qcom,max-hw-load", + .value = 1944000, + }, + { + .key = "qcom,max-hq-mbs-per-frame", + .value = 8160, + }, + { + .key = "qcom,max-hq-mbs-per-sec", + .value = 244800, /* 1920 x 1088 @ 30 fps */ + }, + { + .key = "qcom,max-b-frame-size", + .value = 8160, + }, + { + .key = "qcom,max-b-frames-per-sec", + .value = 60, + }, + { + .key = "qcom,power-collapse-delay", + .value = 1500, + }, + { + .key = "qcom,hw-resp-timeout", + .value = 1000, + }, + { + .key = "qcom,dcvs", + .value = 1, + }, + { + .key = "qcom,fw-cycles", + .value = 733003, + }, + { + .key = "qcom,fw-vpp-cycles", + .value = 225975, + }, +}; + static struct msm_vidc_common_data sm6150_common_data[] = { { .key = "qcom,never-unload-fw", @@ -700,6 +772,22 @@ static struct msm_vidc_platform_data default_data = { .vpu_ver = VPU_VERSION_5, }; +static struct msm_vidc_platform_data atoll_data = { + .codec_data = atoll_codec_data, + .codec_data_length = ARRAY_SIZE(atoll_codec_data), + .common_data = atoll_common_data, + .common_data_length = ARRAY_SIZE(atoll_common_data), + .ubwc_config = NULL, + .ubwc_config_length = 0, + .csc_data.vpe_csc_custom_bias_coeff = vpe_csc_custom_bias_coeff, + .csc_data.vpe_csc_custom_matrix_coeff = vpe_csc_custom_matrix_coeff, + .csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff, + .efuse_data = NULL, + .efuse_data_length = 0, + .sku_version = 0, + .vpu_ver = VPU_VERSION_4, +}; + static struct msm_vidc_platform_data sm6150_data = { .codec_data = sm6150_codec_data, .codec_data_length = ARRAY_SIZE(sm6150_codec_data), @@ -809,6 +897,10 @@ static struct msm_vidc_platform_data sdm670_data = { }; static const struct of_device_id msm_vidc_dt_match[] = { + { + .compatible = "qcom,atoll-vidc", + .data = &atoll_data, + }, { .compatible = "qcom,sm6150-vidc", .data = &sm6150_data, -- GitLab From 251b09ac09c64f5d54f6b77ff03d5aa9b403cd65 Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Thu, 7 Mar 2019 11:47:56 +0530 Subject: [PATCH 0854/1121] Revert "ARM: dts: msm: set dmic sampling rate in QCS405" This reverts commit ffa497414be78c550768e2e3be12063630d7cec1. Change-Id: I6f017431c90d299b7fdd81c9e291ec2a06d63008 Signed-off-by: Mangesh Kunchamwar --- arch/arm64/boot/dts/qcom/qcs405-linear-pca9956.dtsi | 4 ---- arch/arm64/boot/dts/qcom/qcs405-va-bolero.dtsi | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/qcs405-linear-pca9956.dtsi b/arch/arm64/boot/dts/qcom/qcs405-linear-pca9956.dtsi index aa18e3b0ddd7..6980899b38ba 100644 --- a/arch/arm64/boot/dts/qcom/qcs405-linear-pca9956.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs405-linear-pca9956.dtsi @@ -11,10 +11,6 @@ * GNU General Public License for more details. */ -&va_macro { - qcom,va-dmic-sample-rate = <2400000>; -}; - &i2c_2 { status = "ok"; qcom,clk-freq-out = <100000>; diff --git a/arch/arm64/boot/dts/qcom/qcs405-va-bolero.dtsi b/arch/arm64/boot/dts/qcom/qcs405-va-bolero.dtsi index 766714c24e6f..7b5fa64c4e44 100644 --- a/arch/arm64/boot/dts/qcom/qcs405-va-bolero.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs405-va-bolero.dtsi @@ -19,7 +19,7 @@ va-vdd-micb-supply = <&pms405_l7>; qcom,va-vdd-micb-voltage = <1800000 1800000>; qcom,va-vdd-micb-current = <9000>; - qcom,va-dmic-sample-rate = <600000>; + qcom,va-dmic-sample-rate = <2400000>; }; }; -- GitLab From bfbf1b38f09057cabf38a5ab6686208d6ddfc032 Mon Sep 17 00:00:00 2001 From: Srinivas Rao L Date: Fri, 5 Jul 2019 18:39:13 +0530 Subject: [PATCH 0855/1121] cpuidle: lpm_levels: Wakeup biased cpu If a biased cpu entered shallowest LPM state and there are no wakeups for it, can stay in the shallowest state for long. Program wakeup for the biased CPU to wakeup after the expected bias window is completed, so that the cpu can enter a deeper state. Change-Id: Ic92c779f0f8b1fa85aa8b3afa68d075f8d5d7dd6 Signed-off-by: Srinivas Rao L --- drivers/cpuidle/lpm-levels.c | 55 +++++++++++++++++++++++++++++++++--- drivers/cpuidle/lpm-levels.h | 3 +- 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/drivers/cpuidle/lpm-levels.c b/drivers/cpuidle/lpm-levels.c index 7553ee21b6f9..ac2c6f7ea8d0 100644 --- a/drivers/cpuidle/lpm-levels.c +++ b/drivers/cpuidle/lpm-levels.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. * Copyright (C) 2006-2007 Adam Belay * Copyright (C) 2009 Intel Corporation * @@ -109,6 +109,7 @@ static DEFINE_PER_CPU(struct lpm_cpu*, cpu_lpm); static bool suspend_in_progress; static struct hrtimer lpm_hrtimer; static DEFINE_PER_CPU(struct hrtimer, histtimer); +static DEFINE_PER_CPU(struct hrtimer, biastimer); static struct lpm_debug *lpm_debug; static phys_addr_t lpm_debug_phys; static const int num_dbg_elements = 0x100; @@ -435,6 +436,34 @@ static void msm_pm_set_timer(uint32_t modified_time_us) hrtimer_start(&lpm_hrtimer, modified_ktime, HRTIMER_MODE_REL_PINNED); } +static void biastimer_cancel(void) +{ + unsigned int cpu = raw_smp_processor_id(); + struct hrtimer *cpu_biastimer = &per_cpu(biastimer, cpu); + ktime_t time_rem; + + time_rem = hrtimer_get_remaining(cpu_biastimer); + if (ktime_to_us(time_rem) <= 0) + return; + + hrtimer_try_to_cancel(cpu_biastimer); +} + +static enum hrtimer_restart biastimer_fn(struct hrtimer *h) +{ + return HRTIMER_NORESTART; +} + +static void biastimer_start(uint32_t time_ns) +{ + ktime_t bias_ktime = ns_to_ktime(time_ns); + unsigned int cpu = raw_smp_processor_id(); + struct hrtimer *cpu_biastimer = &per_cpu(biastimer, cpu); + + cpu_biastimer->function = biastimer_fn; + hrtimer_start(cpu_biastimer, bias_ktime, HRTIMER_MODE_REL_PINNED); +} + static uint64_t lpm_cpuidle_predict(struct cpuidle_device *dev, struct lpm_cpu *cpu, int *idx_restrict, uint32_t *idx_restrict_time) @@ -595,15 +624,22 @@ static void clear_predict_history(void) static void update_history(struct cpuidle_device *dev, int idx); -static inline bool is_cpu_biased(int cpu) +static inline bool is_cpu_biased(int cpu, uint64_t *bias_time) { u64 now = sched_clock(); u64 last = sched_get_cpu_last_busy_time(cpu); + u64 diff = 0; if (!last) return false; - return (now - last) < BIAS_HYST; + diff = now - last; + if (diff < BIAS_HYST) { + *bias_time = BIAS_HYST - diff; + return true; + } + + return false; } static int cpu_power_select(struct cpuidle_device *dev, @@ -623,6 +659,7 @@ static int cpu_power_select(struct cpuidle_device *dev, uint32_t next_wakeup_us = (uint32_t)sleep_us; uint32_t min_residency, max_residency; struct power_params *pwr_params; + uint64_t bias_time = 0; if ((sleep_disabled && !cpu_isolated(dev->cpu)) || sleep_us < 0) return best_level; @@ -631,8 +668,10 @@ static int cpu_power_select(struct cpuidle_device *dev, next_event_us = (uint32_t)(ktime_to_us(get_next_event_time(dev->cpu))); - if (is_cpu_biased(dev->cpu) && (!cpu_isolated(dev->cpu))) + if (is_cpu_biased(dev->cpu, &bias_time) && (!cpu_isolated(dev->cpu))) { + cpu->bias = bias_time; goto done_select; + } for (i = 0; i < cpu->nlevels; i++) { bool allow; @@ -1310,6 +1349,8 @@ static bool psci_enter_sleep(struct lpm_cpu *cpu, int idx, bool from_idle) */ if (!idx) { + if (cpu->bias) + biastimer_start(cpu->bias); stop_critical_timings(); wfi(); start_critical_timings(); @@ -1420,6 +1461,10 @@ static int lpm_cpuidle_enter(struct cpuidle_device *dev, histtimer_cancel(); clusttimer_cancel(); } + if (cpu->bias) { + biastimer_cancel(); + cpu->bias = 0; + } local_irq_enable(); return idx; } @@ -1723,6 +1768,8 @@ static int lpm_probe(struct platform_device *pdev) for_each_possible_cpu(cpu) { cpu_histtimer = &per_cpu(histtimer, cpu); hrtimer_init(cpu_histtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + cpu_histtimer = &per_cpu(biastimer, cpu); + hrtimer_init(cpu_histtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); } cluster_timer_init(lpm_root_node); diff --git a/drivers/cpuidle/lpm-levels.h b/drivers/cpuidle/lpm-levels.h index ae336d26c37b..e6207e5ecd89 100644 --- a/drivers/cpuidle/lpm-levels.h +++ b/drivers/cpuidle/lpm-levels.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -52,6 +52,7 @@ struct lpm_cpu { uint32_t ref_premature_cnt; uint32_t tmr_add; bool lpm_prediction; + uint64_t bias; struct cpuidle_driver *drv; struct lpm_cluster *parent; }; -- GitLab From aad6f0a0186ef9116557c0ca02ea6ae922053169 Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Tue, 25 Jun 2019 16:15:57 -0700 Subject: [PATCH 0856/1121] ARM: dts: msm: Add syscon nodes to the sdmshrike target Provide an entry to invoke the syscon driver. Associate the global clock controller, camera clock controller, and GPU clock controller with the syscon driver for clock measurement support. Change-Id: I0ecf832c89a5d773c2e237b5a05e0cea52f7f515 Signed-off-by: Anant Goel --- arch/arm64/boot/dts/qcom/sdmshrike.dtsi | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdmshrike.dtsi b/arch/arm64/boot/dts/qcom/sdmshrike.dtsi index 7b6158372845..e0749ee04d33 100644 --- a/arch/arm64/boot/dts/qcom/sdmshrike.dtsi +++ b/arch/arm64/boot/dts/qcom/sdmshrike.dtsi @@ -1372,7 +1372,7 @@ }; clock_gcc: qcom,gcc@100000 { - compatible = "qcom,gcc-sdmshrike"; + compatible = "qcom,gcc-sdmshrike", "syscon"; reg = <0x100000 0x1f0000>; reg-names = "cc_base"; vdd_cx-supply = <&VDD_CX_LEVEL>; @@ -1415,7 +1415,7 @@ }; clock_camcc: qcom,camcc@ad00000 { - compatible = "qcom,camcc-sdmshrike"; + compatible = "qcom,camcc-sdmshrike", "syscon"; reg = <0xad00000 0x20000>; reg-names = "cc_base"; vdd_mx-supply = <&pm8150c_s3_level>; @@ -1437,7 +1437,7 @@ }; clock_gpucc: qcom,gpucc@2c90000 { - compatible = "qcom,gpucc-sdmshrike"; + compatible = "qcom,gpucc-sdmshrike", "syscon"; reg = <0x2c90000 0x9000>; reg-names = "cc_base"; vdd_cx-supply = <&VDD_CX_LEVEL>; @@ -1453,6 +1453,11 @@ status = "disabled"; }; + cpucc_debug: syscon@182a0018 { + compatible = "syscon"; + reg = <0x182a0018 0x4>; + }; + tsens0: tsens@c222000 { compatible = "qcom,tsens24xx"; reg = <0xc222000 0x4>, -- GitLab From ad4706f238ccafb33c605e952e1bf1a4e63af7af Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Fri, 26 Apr 2019 14:16:00 -0700 Subject: [PATCH 0857/1121] ARM: dts: msm: Add QDSS CTI pin definition for sdmshrike Provide device nodes for QDSS CTI pin definition needed by sdmshrike. Change-Id: I3850a24a9ee6f63c21e2510933b7a238f75e7328 Signed-off-by: Anant Goel --- arch/arm64/boot/dts/qcom/sdmshrike-pinctrl.dtsi | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdmshrike-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sdmshrike-pinctrl.dtsi index a90667d2aa7d..36a98fc4fbc0 100644 --- a/arch/arm64/boot/dts/qcom/sdmshrike-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/sdmshrike-pinctrl.dtsi @@ -4133,6 +4133,18 @@ }; }; + trigout_a: trigout_a { + mux { + pins = "gpio141"; + function = "qdss_cti"; + }; + config { + pins = "gpio141"; + drive-strength = <2>; + bias-disable; + }; + }; + /* SE 10 pin mappings */ qupv3_se10_2uart_pins: qupv3_se10_2uart_pins { qupv3_se10_2uart_active: qupv3_se10_2uart_active { -- GitLab From 9d8664b8e27481c7e5b4c2de6eb95fdba9fe1d71 Mon Sep 17 00:00:00 2001 From: Subash Abhinov Kasiviswanathan Date: Fri, 28 Jun 2019 17:03:27 -0600 Subject: [PATCH 0858/1121] net: qualcomm: rmnet: Avoid copy twice in non linear cases This avoids the linearization in the uplink aggregation path when a non linear skb is received from stack. CRs-fixed: 2485919 Change-Id: Id86e54494340cb3a7d40aa70620741d79078ad5f Signed-off-by: Subash Abhinov Kasiviswanathan --- .../ethernet/qualcomm/rmnet/rmnet_handlers.c | 10 ----- .../ethernet/qualcomm/rmnet/rmnet_map_data.c | 42 +++++++++++++++++-- 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c index 8b79b52f2988..b833ad1d1375 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c @@ -387,19 +387,9 @@ static int rmnet_map_egress_handler(struct sk_buff *skb, map_header->mux_id = mux_id; if (port->data_format & RMNET_EGRESS_FORMAT_AGGREGATION) { - int non_linear_skb; - if (rmnet_map_tx_agg_skip(skb, required_headroom)) goto done; - non_linear_skb = (orig_dev->features & NETIF_F_GSO) && - skb_is_nonlinear(skb); - - if (non_linear_skb) { - if (unlikely(__skb_linearize(skb))) - goto done; - } - rmnet_map_tx_aggregate(skb, port); return -EINPROGRESS; } diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c index ff9aa988f900..1d298b4882fb 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c @@ -1105,13 +1105,45 @@ enum hrtimer_restart rmnet_map_flush_tx_packet_queue(struct hrtimer *t) return HRTIMER_NORESTART; } +static void rmnet_map_linearize_copy(struct sk_buff *dst, struct sk_buff *src) +{ + unsigned int linear = src->len - src->data_len, target = src->len; + unsigned char *src_buf; + struct sk_buff *skb; + + src_buf = src->data; + skb_put_data(dst, src_buf, linear); + target -= linear; + + skb = src; + + while (target) { + unsigned int i = 0, non_linear = 0; + + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + non_linear = skb_frag_size(&skb_shinfo(skb)->frags[i]); + src_buf = skb_frag_address(&skb_shinfo(skb)->frags[i]); + + skb_put_data(dst, src_buf, non_linear); + target -= non_linear; + } + + if (skb_shinfo(skb)->frag_list) { + skb = skb_shinfo(skb)->frag_list; + continue; + } + + if (skb->next) + skb = skb->next; + } +} + void rmnet_map_tx_aggregate(struct sk_buff *skb, struct rmnet_port *port) { struct timespec diff, last; int size, agg_count = 0; struct sk_buff *agg_skb; unsigned long flags; - u8 *dest_buff; new_packet: spin_lock_irqsave(&port->agg_lock, flags); @@ -1133,7 +1165,8 @@ void rmnet_map_tx_aggregate(struct sk_buff *skb, struct rmnet_port *port) return; } - port->agg_skb = skb_copy_expand(skb, 0, size, GFP_ATOMIC); + port->agg_skb = alloc_skb(port->egress_agg_params.agg_size, + GFP_ATOMIC); if (!port->agg_skb) { port->agg_skb = 0; port->agg_count = 0; @@ -1143,6 +1176,8 @@ void rmnet_map_tx_aggregate(struct sk_buff *skb, struct rmnet_port *port) dev_queue_xmit(skb); return; } + rmnet_map_linearize_copy(port->agg_skb, skb); + port->agg_skb->dev = skb->dev; port->agg_skb->protocol = htons(ETH_P_MAP); port->agg_count = 1; getnstimeofday(&port->agg_time); @@ -1167,8 +1202,7 @@ void rmnet_map_tx_aggregate(struct sk_buff *skb, struct rmnet_port *port) goto new_packet; } - dest_buff = skb_put(port->agg_skb, skb->len); - memcpy(dest_buff, skb->data, skb->len); + rmnet_map_linearize_copy(port->agg_skb, skb); port->agg_count++; dev_kfree_skb_any(skb); -- GitLab From 0042b957999a61f756621728de0c104bd0dd44a9 Mon Sep 17 00:00:00 2001 From: Siddartha Mohanadoss Date: Mon, 17 Jun 2019 15:45:30 -0700 Subject: [PATCH 0859/1121] ARM: dts: msm: Update PCIe EP link speed for sdxprairie On resume from hibernate/sleep the PCIe EP link is re-configured and enabled. Update the link speed to Gen3 speed. Change-Id: Ia31d3bdfaa9785eb035debf458547e4454e3c37f Signed-off-by: Siddartha Mohanadoss --- arch/arm64/boot/dts/qcom/sdxprairie.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sdxprairie.dtsi b/arch/arm64/boot/dts/qcom/sdxprairie.dtsi index 880c93ab9eee..54ea08e532ab 100644 --- a/arch/arm64/boot/dts/qcom/sdxprairie.dtsi +++ b/arch/arm64/boot/dts/qcom/sdxprairie.dtsi @@ -1225,7 +1225,7 @@ qcom,pcie-vendor-id = /bits/ 16 <0x17cb>; qcom,pcie-device-id = /bits/ 16 <0x0306>; - qcom,pcie-link-speed = <2>; + qcom,pcie-link-speed = <3>; qcom,pcie-phy-ver = <6>; qcom,pcie-active-config; qcom,pcie-aggregated-irq; -- GitLab From 04edc9abbb4df2e2fa7d672ca1ead2e7b64321da Mon Sep 17 00:00:00 2001 From: Siddartha Mohanadoss Date: Fri, 12 Jul 2019 11:57:51 -0700 Subject: [PATCH 0860/1121] ARM: dts: msm: Update PHY sequence for PCIe EP on sdxprairie Update PHY training parameters sequence done as part of link training. Change-Id: If84b13a81f2e8128ef7ccc59b0580a8e3f5cc27c Signed-off-by: Siddartha Mohanadoss --- arch/arm64/boot/dts/qcom/sdxprairie.dtsi | 59 +++++++++++++++++++++--- 1 file changed, 52 insertions(+), 7 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdxprairie.dtsi b/arch/arm64/boot/dts/qcom/sdxprairie.dtsi index 54ea08e532ab..a2479bfb520b 100644 --- a/arch/arm64/boot/dts/qcom/sdxprairie.dtsi +++ b/arch/arm64/boot/dts/qcom/sdxprairie.dtsi @@ -1237,12 +1237,12 @@ 0x1044 0x018 0x0 0x1 0x104c 0x007 0x0 0x1 0x1058 0x00f 0x0 0x1 - 0x1074 0x006 0x0 0x1 - 0x1078 0x028 0x0 0x1 - 0x107c 0x016 0x0 0x1 - 0x1080 0x00d 0x0 0x1 - 0x1084 0x036 0x0 0x1 - 0x1088 0x000 0x0 0x1 + 0x1074 0x009 0x0 0x1 + 0x1078 0x00a 0x0 0x1 + 0x107c 0x018 0x0 0x1 + 0x1080 0x019 0x0 0x1 + 0x1084 0x006 0x0 0x1 + 0x1088 0x003 0x0 0x1 0x1094 0x000 0x0 0x1 0x10a4 0x046 0x0 0x1 0x10a8 0x004 0x0 0x1 @@ -1254,7 +1254,7 @@ 0x10c4 0x028 0x0 0x1 0x10d4 0x008 0x0 0x1 0x10f4 0x0fb 0x0 0x1 - 0x10f8 0x003 0x0 0x1 + 0x10f8 0x001 0x0 0x1 0x110c 0x002 0x0 0x1 0x1158 0x012 0x0 0x1 0x115c 0x000 0x0 0x1 @@ -1267,20 +1267,65 @@ 0x11b4 0x04b 0x0 0x1 0x11b8 0x01f 0x0 0x1 0x11bc 0x022 0x0 0x1 + 0x11a4 0x015 0x0 0x1 + 0x11a8 0x00f 0x0 0x1 + 0x008c 0x006 0x0 0x1 + 0x00e0 0x001 0x0 0x1 + 0x00c4 0x001 0x0 0x1 0x0258 0x016 0x0 0x1 0x0378 0x083 0x0 0x1 0x0360 0x0e2 0x0 0x1 0x0364 0x004 0x0 0x1 0x0368 0x030 0x0 0x1 0x0370 0x0ff 0x0 0x1 + 0x03cc 0x042 0x0 0x1 + 0x03d0 0x00d 0x0 0x1 + 0x03d4 0x077 0x0 0x1 + 0x03d8 0x02d 0x0 0x1 + 0x03dc 0x039 0x0 0x1 + 0x03e0 0x09f 0x0 0x1 + 0x03e4 0x00f 0x0 0x1 + 0x03e8 0x063 0x0 0x1 + 0x03ec 0x0bf 0x0 0x1 + 0x03f0 0x079 0x0 0x1 + 0x03f4 0x04f 0x0 0x1 + 0x03f8 0x00f 0x0 0x1 + 0x03fc 0x0d5 0x0 0x1 + 0x02ac 0x075 0x0 0x1 + 0x0310 0x055 0x0 0x1 + 0x0334 0x00c 0x0 0x1 + 0x0338 0x000 0x0 0x1 + 0x0350 0x00f 0x0 0x1 + 0x088c 0x006 0x0 0x1 + 0x08e0 0x001 0x0 0x1 + 0x08c4 0x001 0x0 0x1 0x0a58 0x016 0x0 0x1 0x0b78 0x083 0x0 0x1 0x0b60 0x0e2 0x0 0x1 0x0b64 0x004 0x0 0x1 0x0b68 0x030 0x0 0x1 0x0b70 0x0ff 0x0 0x1 + 0x0bcc 0x042 0x0 0x1 + 0x0bd0 0x00d 0x0 0x1 + 0x0bd4 0x077 0x0 0x1 + 0x0bd8 0x02d 0x0 0x1 + 0x0bdc 0x039 0x0 0x1 + 0x0be0 0x09f 0x0 0x1 + 0x0be4 0x00f 0x0 0x1 + 0x0be8 0x063 0x0 0x1 + 0x0bec 0x0bf 0x0 0x1 + 0x0bf0 0x079 0x0 0x1 + 0x0bf4 0x04f 0x0 0x1 + 0x0bf8 0x00f 0x0 0x1 + 0x0bfc 0x0d5 0x0 0x1 + 0x0aac 0x07f 0x0 0x1 + 0x0b10 0x055 0x0 0x1 + 0x0b34 0x00c 0x0 0x1 + 0x0b38 0x000 0x0 0x1 + 0x0b50 0x00f 0x0 0x1 0x13e4 0x003 0x0 0x1 0x1708 0x003 0x0 0x1 + 0x16a0 0x016 0x0 0x1 0x13e0 0x016 0x0 0x1 0x13d8 0x001 0x0 0x1 0x16fc 0x001 0x0 0x1 -- GitLab From dd17d8364f4816d570aaebf8140535735fe23d7a Mon Sep 17 00:00:00 2001 From: Ramachandran Venkataramani Date: Sun, 23 Jun 2019 21:02:12 -0700 Subject: [PATCH 0861/1121] ARM: dts: msm: Add SDE DP support on SA8195 Add the device nodes required to enable support for native display port on SA8195. Change-Id: I0779dd95df24023be9ab2f4a9e1192caed3edf19 Signed-off-by: Ramachandran Venkataramani --- .../boot/dts/qcom/sdmshrike-sde-pll.dtsi | 26 +++- arch/arm64/boot/dts/qcom/sdmshrike-sde.dtsi | 119 +++++++++++++++++- 2 files changed, 139 insertions(+), 6 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdmshrike-sde-pll.dtsi b/arch/arm64/boot/dts/qcom/sdmshrike-sde-pll.dtsi index 6b350e54feb2..943f295bb301 100644 --- a/arch/arm64/boot/dts/qcom/sdmshrike-sde-pll.dtsi +++ b/arch/arm64/boot/dts/qcom/sdmshrike-sde-pll.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -65,4 +65,28 @@ }; }; + mdss_dp_pll: qcom,mdss_dp_pll@88ea000 { + compatible = "qcom,mdss_dp_pll_7nm"; + label = "MDSS DP PLL"; + cell-index = <0>; + #clock-cells = <1>; + + reg = <0x88ea000 0x200>, + <0x88eaa00 0x200>, + <0x88ea200 0x200>, + <0x88ea600 0x200>, + <0xaf03000 0x8>; + reg-names = "pll_base", "phy_base", "ln_tx0_base", + "ln_tx1_base", "gdsc_base"; + + clocks = <&clock_dispcc DISP_CC_MDSS_AHB_CLK>, + <&clock_rpmh RPMH_CXO_CLK>, + <&clock_gcc GCC_DISP_AHB_CLK>, + <&clock_gcc GCC_USB3_PRIM_CLKREF_CLK>, + <&clock_gcc GCC_USB3_PRIM_PHY_PIPE_CLK>; + clock-names = "iface_clk", "ref_clk_src", "gcc_iface", + "ref_clk", "pipe_clk"; + clock-rate = <0>; + }; + }; diff --git a/arch/arm64/boot/dts/qcom/sdmshrike-sde.dtsi b/arch/arm64/boot/dts/qcom/sdmshrike-sde.dtsi index 57e4c7fe66f7..c6717c6de5d5 100644 --- a/arch/arm64/boot/dts/qcom/sdmshrike-sde.dtsi +++ b/arch/arm64/boot/dts/qcom/sdmshrike-sde.dtsi @@ -14,9 +14,9 @@ &soc { mdss_mdp: qcom,mdss_mdp@ae00000 { compatible = "qcom,sde-kms"; - reg = <0x0ae00000 0x84208>, - <0x0aeb0000 0x2008>, - <0x0aeac000 0x214>; + reg = <0xae00000 0x84208>, + <0xaeb0000 0x2008>, + <0xaeac000 0x214>; reg-names = "mdp_phys", "vbif_phys", "regdma_phys"; @@ -394,8 +394,8 @@ mdss_rotator: qcom,mdss_rotator@ae00000 { compatible = "qcom,sde_rotator"; - reg = <0x0ae00000 0xac000>, - <0x0aeb8000 0x3000>; + reg = <0xae00000 0xac000>, + <0xaeb8000 0x3000>; reg-names = "mdp_phys", "rot_vbif_phys"; @@ -605,4 +605,113 @@ }; }; }; + + sde_dp: qcom,dp_display@0{ + cell-index = <0>; + compatible = "qcom,dp-display"; + + reg = <0xae90000 0x0dc>, + <0xae90200 0x0c0>, + <0xae90400 0x508>, + <0xae90a00 0x094>, + <0x88eaa00 0x200>, + <0x88ea200 0x200>, + <0x88ea600 0x200>, + <0xaf02000 0x1a0>, + <0x780000 0x621c>, + <0x88ea040 0x10>, + <0x88e8000 0x20>, + <0xaee1000 0x034>, + <0xae91000 0x094>; + /* dp_ctrl: dp_ahb, dp_aux, dp_link, dp_p0 */ + reg-names = "dp_ahb", "dp_aux", "dp_link", + "dp_p0", "dp_phy", "dp_ln_tx0", "dp_ln_tx1", + "dp_mmss_cc", "qfprom_physical", "dp_pll", + "usb3_dp_com", "hdcp_physical", "dp_p1"; + + interrupt-parent = <&mdss_mdp>; + interrupts = <12 0>; + + clocks = <&clock_dispcc DISP_CC_MDSS_DP_AUX_CLK>, + <&clock_rpmh RPMH_CXO_CLK>, + <&clock_gcc GCC_USB3_PRIM_CLKREF_CLK>, + <&clock_gcc GCC_USB3_PRIM_PHY_PIPE_CLK>, + <&clock_dispcc DISP_CC_MDSS_DP_LINK_CLK>, + <&clock_dispcc DISP_CC_MDSS_DP_LINK_INTF_CLK>, + <&clock_dispcc DISP_CC_MDSS_DP_CRYPTO_CLK>, + <&clock_dispcc DISP_CC_MDSS_DP_PIXEL_CLK_SRC>, + <&mdss_dp_pll DP_VCO_DIVIDED_CLK_SRC_MUX>, + <&clock_dispcc DISP_CC_MDSS_DP_PIXEL1_CLK_SRC>, + <&mdss_dp_pll DP_VCO_DIVIDED_CLK_SRC_MUX>, + <&clock_dispcc DISP_CC_MDSS_DP_PIXEL_CLK>, + <&clock_dispcc DISP_CC_MDSS_DP_PIXEL1_CLK>; + clock-names = "core_aux_clk", "core_usb_ref_clk_src", + "core_usb_ref_clk", "core_usb_pipe_clk", + "link_clk", "link_iface_clk", + "crypto_clk", "pixel_clk_rcg", "pixel_parent", + "pixel1_clk_rcg", "pixel1_parent", + "strm0_pixel_clk", "strm1_pixel_clk"; + + qcom,phy-version = <0x420>; + qcom,aux-cfg0-settings = [20 00]; + qcom,aux-cfg1-settings = [24 13]; + qcom,aux-cfg2-settings = [28 24]; + qcom,aux-cfg3-settings = [2c 00]; + qcom,aux-cfg4-settings = [30 0a]; + qcom,aux-cfg5-settings = [34 26]; + qcom,aux-cfg6-settings = [38 0a]; + qcom,aux-cfg7-settings = [3c 03]; + qcom,aux-cfg8-settings = [40 b7]; + qcom,aux-cfg9-settings = [44 03]; + + qcom,max-pclk-frequency-khz = <675000>; + + qcom,mst-enable; + qcom,dsc-feature-enable; + qcom,fec-feature-enable; + qcom,max-dp-dsc-blks = <2>; + qcom,max-dp-dsc-input-width-pixs = <2048>; + + qcom,ctrl-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,ctrl-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vdda-1p2"; + qcom,supply-min-voltage = <1200000>; + qcom,supply-max-voltage = <1200000>; + qcom,supply-enable-load = <21800>; + qcom,supply-disable-load = <0>; + }; + }; + + qcom,phy-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,phy-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vdda-0p9"; + qcom,supply-min-voltage = <880000>; + qcom,supply-max-voltage = <880000>; + qcom,supply-enable-load = <36000>; + qcom,supply-disable-load = <0>; + }; + }; + + qcom,core-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,core-supply-entry@0 { + reg = <0>; + qcom,supply-name = "refgen"; + qcom,supply-min-voltage = <0>; + qcom,supply-max-voltage = <0>; + qcom,supply-enable-load = <0>; + qcom,supply-disable-load = <0>; + }; + }; + }; }; -- GitLab From 7be78c8d6afa8efd287187aa64f3c79dd62b956e Mon Sep 17 00:00:00 2001 From: Chris Lew Date: Wed, 26 Jun 2019 11:20:18 -0700 Subject: [PATCH 0862/1121] net: qrtr: mhi: Register for early notifications Register for status callback to receive fatal error notifications. Cancel any pending transactions and assume all future transactions will return immediately with an error. Early notification can be called from atomic context, change spin_lock APIs to irqsave/irqrestore variants. Change-Id: I17ed3a800411eef1bdcaf22c088cb1c9dbd393a6 Signed-off-by: Chris Lew --- net/qrtr/mhi.c | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/net/qrtr/mhi.c b/net/qrtr/mhi.c index dbc0d1efaadf..17a7677e8e40 100644 --- a/net/qrtr/mhi.c +++ b/net/qrtr/mhi.c @@ -25,6 +25,7 @@ struct qrtr_mhi_dev { struct device *dev; spinlock_t ul_lock; /* lock to protect ul_pkts */ struct list_head ul_pkts; + atomic_t in_reset; }; struct qrtr_mhi_pkt { @@ -68,14 +69,33 @@ static void qcom_mhi_qrtr_ul_callback(struct mhi_device *mhi_dev, { struct qrtr_mhi_dev *qdev = dev_get_drvdata(&mhi_dev->dev); struct qrtr_mhi_pkt *pkt; + unsigned long flags; - spin_lock_bh(&qdev->ul_lock); + spin_lock_irqsave(&qdev->ul_lock, flags); pkt = list_first_entry(&qdev->ul_pkts, struct qrtr_mhi_pkt, node); list_del(&pkt->node); complete_all(&pkt->done); kref_put(&pkt->refcount, qrtr_mhi_pkt_release); - spin_unlock_bh(&qdev->ul_lock); + spin_unlock_irqrestore(&qdev->ul_lock, flags); +} + +/* fatal error */ +static void qcom_mhi_qrtr_status_callback(struct mhi_device *mhi_dev, + enum MHI_CB mhi_cb) +{ + struct qrtr_mhi_dev *qdev = dev_get_drvdata(&mhi_dev->dev); + struct qrtr_mhi_pkt *pkt; + unsigned long flags; + + if (mhi_cb != MHI_CB_FATAL_ERROR) + return; + + atomic_inc(&qdev->in_reset); + spin_lock_irqsave(&qdev->ul_lock, flags); + list_for_each_entry(pkt, &qdev->ul_pkts, node) + complete_all(&pkt->done); + spin_unlock_irqrestore(&qdev->ul_lock, flags); } /* from qrtr to mhi */ @@ -83,6 +103,7 @@ static int qcom_mhi_qrtr_send(struct qrtr_endpoint *ep, struct sk_buff *skb) { struct qrtr_mhi_dev *qdev = container_of(ep, struct qrtr_mhi_dev, ep); struct qrtr_mhi_pkt *pkt; + unsigned long flags; int rc; rc = skb_linearize(skb); @@ -102,7 +123,7 @@ static int qcom_mhi_qrtr_send(struct qrtr_endpoint *ep, struct sk_buff *skb) kref_get(&pkt->refcount); pkt->skb = skb; - spin_lock_bh(&qdev->ul_lock); + spin_lock_irqsave(&qdev->ul_lock, flags); list_add_tail(&pkt->node, &qdev->ul_pkts); rc = mhi_queue_transfer(qdev->mhi_dev, DMA_TO_DEVICE, skb, skb->len, MHI_EOT); @@ -110,18 +131,20 @@ static int qcom_mhi_qrtr_send(struct qrtr_endpoint *ep, struct sk_buff *skb) list_del(&pkt->node); kfree_skb(skb); kfree(pkt); - spin_unlock_bh(&qdev->ul_lock); + spin_unlock_irqrestore(&qdev->ul_lock, flags); return rc; } - spin_unlock_bh(&qdev->ul_lock); + spin_unlock_irqrestore(&qdev->ul_lock, flags); if (skb->sk) sock_hold(skb->sk); rc = wait_for_completion_interruptible_timeout(&pkt->done, HZ * 5); - if (rc > 0) - rc = 0; + if (atomic_read(&qdev->in_reset)) + rc = -ECONNRESET; else if (rc == 0) rc = -ETIMEDOUT; + else if (rc > 0) + rc = 0; kref_put(&pkt->refcount, qrtr_mhi_pkt_release); return rc; @@ -142,6 +165,7 @@ static int qcom_mhi_qrtr_probe(struct mhi_device *mhi_dev, qdev->mhi_dev = mhi_dev; qdev->dev = &mhi_dev->dev; qdev->ep.xmit = qcom_mhi_qrtr_send; + atomic_set(&qdev->in_reset, 0); rc = of_property_read_u32(mhi_dev->dev.of_node, "qcom,net-id", &net_id); if (rc < 0) @@ -181,6 +205,7 @@ static struct mhi_driver qcom_mhi_qrtr_driver = { .remove = qcom_mhi_qrtr_remove, .dl_xfer_cb = qcom_mhi_qrtr_dl_callback, .ul_xfer_cb = qcom_mhi_qrtr_ul_callback, + .status_cb = qcom_mhi_qrtr_status_callback, .id_table = qcom_mhi_qrtr_mhi_match, .driver = { .name = "qcom_mhi_qrtr", -- GitLab From a203bd767ccb2a21d63c9a166f3cfcd5120a8866 Mon Sep 17 00:00:00 2001 From: Ram Prakash Gupta Date: Fri, 12 Jul 2019 18:35:35 +0530 Subject: [PATCH 0863/1121] Revert "mmc: core: rescan for card if deferred resume fails" This reverts commit 9de18caa8e7d40afc3585822bdec785c0ae32e33. Reverting this change as this is introducing race condition with sdcard plug out scenario and leading to device crash. 1. Deferred resume kicks in 2. SDCard is plugged out 3. Deferred resume failed 4. SDCard detection scheduled as resume fails 5. Device crashing Change-Id: I6fd81d6c21be4a0e3139246c9d66959010fd240c Signed-off-by: Ram Prakash Gupta --- drivers/mmc/core/core.c | 17 +---------------- drivers/mmc/core/sd.c | 2 -- 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 05e448186c16..0e60ff45e618 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -3251,22 +3251,7 @@ int mmc_resume_bus(struct mmc_host *host) if (host->bus_ops && !host->bus_dead && host->card && card_present) { mmc_power_up(host, host->card->ocr); BUG_ON(!host->bus_ops->resume); - err = host->bus_ops->resume(host); - if (err) { - pr_err("%s: %s: resume failed: %d\n", - mmc_hostname(host), __func__, err); - /* - * If we have cd-gpio based detection mechanism and - * deferred resume is supported, we will not detect - * card removal event when system is suspended. So if - * resume fails after a system suspend/resume, - * schedule the work to detect card presence. - */ - if (mmc_card_is_removable(host) && - !(host->caps & MMC_CAP_NEEDS_POLL)) { - mmc_detect_change(host, 0); - } - } + host->bus_ops->resume(host); if (mmc_card_cmdq(host->card)) { err = mmc_cmdq_halt(host, false); if (err) diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index baddf6a44d32..43b6ad94f6c9 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -1322,8 +1322,6 @@ static int _mmc_sd_resume(struct mmc_host *host) mmc_hostname(host), __func__, err); mmc_card_set_removed(host->card); mmc_detect_change(host, msecs_to_jiffies(200)); - } else if (err) { - goto out; } mmc_card_clr_suspended(host->card); -- GitLab From 092f6ef95c6ec0d414039c14510dccf66d709812 Mon Sep 17 00:00:00 2001 From: Asutosh Das Date: Tue, 2 Jan 2018 15:38:27 +0530 Subject: [PATCH 0864/1121] mmc: core: Reset on error during deferred resume If resume fails, there is no way to handle it now. Also there's no attempt to recover from it. This leads to lot of warnings while issuing requests. Check for resume errors & reset the stack on error as an attempt to recover from it. Change-Id: Ie4d6d2a34c2c7a8154696e93d85e50d60410e0c2 Signed-off-by: Asutosh Das Signed-off-by: Ram Prakash Gupta --- drivers/mmc/core/core.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 0e60ff45e618..25fa3d3b318f 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -3251,20 +3251,31 @@ int mmc_resume_bus(struct mmc_host *host) if (host->bus_ops && !host->bus_dead && host->card && card_present) { mmc_power_up(host, host->card->ocr); BUG_ON(!host->bus_ops->resume); - host->bus_ops->resume(host); + err = host->bus_ops->resume(host); + if (err && (err != -ENOMEDIUM)) { + pr_err("%s: bus resume: failed: %d\n", + mmc_hostname(host), err); + err = mmc_hw_reset(host); + if (err) { + pr_err("%s: reset: failed: %d\n", + mmc_hostname(host), err); + goto err_reset; + } else { + mmc_card_clr_suspended(host->card); + } + } if (mmc_card_cmdq(host->card)) { err = mmc_cmdq_halt(host, false); if (err) pr_err("%s: %s: unhalt failed: %d\n", mmc_hostname(host), __func__, err); - else - mmc_card_clr_suspended(host->card); } } +err_reset: mmc_bus_put(host); pr_debug("%s: Deferred resume completed\n", mmc_hostname(host)); - return 0; + return err; } EXPORT_SYMBOL(mmc_resume_bus); -- GitLab From 184d6f52ef2dc82d8dd1a7eecb222b3f278011ff Mon Sep 17 00:00:00 2001 From: Asutosh Das Date: Wed, 3 Apr 2019 16:35:33 +0530 Subject: [PATCH 0865/1121] mmc: sd: set card removed to true Sometimes when the card is removed and a request is in queue the resume fails. But there's no way to inform the in-flight request that the card is removed since the resume itself fails and rescan is waiting for claim_host which was acquired by the in-flight request. This request percolates to platform driver which sees that the pre-requisites to issue the request are not met i.e. the clocks are OFF. So it tries to dump the registers and results in a NoC error. Set the card removed when resume fails to avoid this problem. CRs-fixed: 2430862 Change-Id: I171ad435ec11c1212e6528592b8db43cd0171b11 Signed-off-by: Asutosh Das Signed-off-by: Ram Prakash Gupta --- drivers/mmc/core/core.c | 8 +++++++- drivers/mmc/core/sd.c | 18 ++++++++++++++---- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 25fa3d3b318f..ac5182881d9f 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -3245,8 +3245,14 @@ int mmc_resume_bus(struct mmc_host *host) spin_unlock_irqrestore(&host->lock, flags); mmc_bus_get(host); - if (host->ops->get_cd) + if (host->ops->get_cd) { card_present = host->ops->get_cd(host); + if (!card_present) { + pr_err("%s: Card removed - card_present:%d\n", + mmc_hostname(host), card_present); + mmc_card_set_removed(host->card); + } + } if (host->bus_ops && !host->bus_dead && host->card && card_present) { mmc_power_up(host, host->card->ocr); diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 43b6ad94f6c9..3fb8c152167a 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -1346,11 +1346,21 @@ static int mmc_sd_resume(struct mmc_host *host) MMC_TRACE(host, "%s: Enter\n", __func__); err = _mmc_sd_resume(host); - pm_runtime_set_active(&host->card->dev); - pm_runtime_mark_last_busy(&host->card->dev); - pm_runtime_enable(&host->card->dev); - MMC_TRACE(host, "%s: Exit err: %d\n", __func__, err); + if (err) { + pr_err("%s: sd resume err: %d\n", mmc_hostname(host), err); + if (host->ops->get_cd && !host->ops->get_cd(host)) { + err = -ENOMEDIUM; + mmc_card_set_removed(host->card); + } + } + if (err != -ENOMEDIUM) { + pm_runtime_set_active(&host->card->dev); + pm_runtime_mark_last_busy(&host->card->dev); + pm_runtime_enable(&host->card->dev); + } + + MMC_TRACE(host, "%s: Exit err: %d\n", __func__, err); return err; } -- GitLab From ade08b55aa67692887ee9b0883c2ed24ea206ae6 Mon Sep 17 00:00:00 2001 From: Ramachandran Venkataramani Date: Wed, 10 Jul 2019 06:50:55 -0700 Subject: [PATCH 0866/1121] ARM: dts: msm: Add pwr levels for gpu on sdmshrike Add the updated power levels and opp table for gpu and gmu on sdmshrike-v2. Change-Id: I15a6d4245b076f8e65ed4f0a529e6a80e5c1e57f Signed-off-by: Ramachandran Venkataramani --- arch/arm64/boot/dts/qcom/sdmshrike-v2.dtsi | 177 +++++++++++++++++++++ 1 file changed, 177 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdmshrike-v2.dtsi b/arch/arm64/boot/dts/qcom/sdmshrike-v2.dtsi index b32e6449c892..83cbe38416cb 100644 --- a/arch/arm64/boot/dts/qcom/sdmshrike-v2.dtsi +++ b/arch/arm64/boot/dts/qcom/sdmshrike-v2.dtsi @@ -17,13 +17,190 @@ qcom,msm-id = <340 0x20000>; }; +&soc { + gpu_opp_table_v2: gpu_opp_table_v2 { + compatible = "operating-points-v2"; + + opp-700000000 { + opp-hz = /bits/ 64 <700000000>; + opp-microvolt = ; + }; + + opp-675000000 { + opp-hz = /bits/ 64 <675000000>; + opp-microvolt = ; + }; + opp-585000000 { + opp-hz = /bits/ 64 <585000000>; + opp-microvolt = ; + }; + + opp-499200000 { + opp-hz = /bits/ 64 <499200000>; + opp-microvolt = ; + }; + + opp-427000000 { + opp-hz = /bits/ 64 <427000000>; + opp-microvolt = ; + }; + + opp-345000000 { + opp-hz = /bits/ 64 <345000000>; + opp-microvolt = ; + }; + + opp-257000000 { + opp-hz = /bits/ 64 <257000000>; + opp-microvolt = ; + }; + }; +}; /* GPU overrides */ &msm_gpu { /* Updated chip ID */ qcom,chipid = <0x6080001>; + /* Power level to start throttling */ + qcom,throttle-pwrlevel = <3>; + + /* Updated Bus Scale Settings */ + qcom,msm-bus,num-cases = <12>; + + /* + * Value for vote is: (DDR freq) * 4 - 5 + * The 5 value is to ensure that there is no rounding errors + * where the total request doesn't divide evenly by the BCM + * DDR bandwidth unit (note, 5 is greater than this unit). + */ + qcom,msm-bus,vectors-KBps = + <26 512 0 0>, // 0 bus=0 + <26 512 0 795000>, // 1 bus=200 + <26 512 0 1195000>, // 2 bus=300 + <26 512 0 1799000>, // 3 bus=451 + <26 512 0 2183000>, // 4 bus=547 + <26 512 0 2719000>, // 5 bus=681 + <26 512 0 3067000>, // 6 bus=768 + <26 512 0 4063000>, // 7 bus=1017 + <26 512 0 5407000>, // 8 bus=1353 + <26 512 0 6215000>, // 9 bus=1555 + <26 512 0 7211000>, // 10 bus=1804 + <26 512 0 8363000>; // 11 bus=2092 + + qcom,initial-pwrlevel = <4>; + + operating-points-v2 = <&gpu_opp_table_v2>; + + qcom,gpu-pwrlevels { + #address-cells = <1>; + #size-cells = <0>; + + compatible = "qcom,gpu-pwrlevels"; + + qcom,gpu-pwrlevel@0 { + reg = <0>; + qcom,gpu-freq = <700000000>; + qcom,bus-freq = <10>; + qcom,bus-min = <8>; + qcom,bus-max = <11>; + }; + + qcom,gpu-pwrlevel@1 { + reg = <1>; + qcom,gpu-freq = <675000000>; + qcom,bus-freq = <8>; + qcom,bus-min = <7>; + qcom,bus-max = <9>; + }; + + qcom,gpu-pwrlevel@2 { + reg = <2>; + qcom,gpu-freq = <585000000>; + qcom,bus-freq = <7>; + qcom,bus-min = <6>; + qcom,bus-max = <11>; + }; + + qcom,gpu-pwrlevel@3 { + reg = <3>; + qcom,gpu-freq = <427000000>; + qcom,bus-freq = <6>; + qcom,bus-min = <5>; + qcom,bus-max = <9>; + }; + + qcom,gpu-pwrlevel@4 { + reg = <4>; + qcom,gpu-freq = <345000000>; + qcom,bus-freq = <3>; + qcom,bus-min = <3>; + qcom,bus-max = <8>; + }; + + qcom,gpu-pwrlevel@5 { + reg = <5>; + qcom,gpu-freq = <257000000>; + qcom,bus-freq = <2>; + qcom,bus-min = <1>; + qcom,bus-max = <8>; + }; + + qcom,gpu-pwrlevel@6 { + reg = <6>; + qcom,gpu-freq = <0>; + qcom,bus-freq = <0>; + qcom,bus-min = <0>; + qcom,bus-max = <0>; + }; + + }; + + qcom,l3-pwrlevels { + #address-cells = <1>; + #size-cells = <0>; + + compatible = "qcom,l3-pwrlevels"; + + qcom,l3-pwrlevel@0 { + reg = <0>; + qcom,l3-freq = <0>; + }; + + qcom,l3-pwrlevel@1 { + reg = <1>; + qcom,l3-freq = <1344000000>; + }; + + qcom,l3-pwrlevel@2 { + reg = <2>; + qcom,l3-freq = <1612800000>; + }; + }; }; +&gmu { + reg = <0x2c6a000 0x30000>, + <0xb290000 0x10000>, + <0xb490000 0x10000>; + reg-names = "kgsl_gmu_reg", + "kgsl_gmu_pdc_cfg", + "kgsl_gmu_pdc_seq"; + + qcom,gpu-acd-table { + /* Corresponds to levels in the GPU perf table */ + qcom,acd-enable-by-level = <0x7e>; + qcom,acd-stride = <0x2>; + qcom,acd-num-levels = <0x6>; + + /* ACDCR, ACDTD */ + qcom,acd-data = <0xa02d5ffd 0x00007611 /* LowSVS */ + 0xa02d5ffd 0x00006911 /* SVS */ + 0xa02d5ffd 0x00006111 /* SVS_L1 */ + 0xa02d5ffd 0x00006011 /* SVS_L2 */ + 0x802d5ffd 0x00005411 /* NOM */ + 0x802d5ffd 0x00005411>; /* NOM_L1 */ + }; +}; &mdss_mdp { qcom,fullsize-va-map; qcom,sde-min-core-ib-kbps = <0>; -- GitLab From 246cbe324448be9ae6cbfd048bf9be1aee8d5f00 Mon Sep 17 00:00:00 2001 From: Ramachandran Venkataramani Date: Wed, 10 Jul 2019 14:23:24 -0700 Subject: [PATCH 0867/1121] ARM: dts: msm: Update clocks for sdmshrike-v2 Update clock version to v2 for display and npu. Change-Id: I6441224f9c726068a496a7a7c3f4760cf618ecf0 Signed-off-by: Ramachandran Venkataramani --- arch/arm64/boot/dts/qcom/sdmshrike-v2.dtsi | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdmshrike-v2.dtsi b/arch/arm64/boot/dts/qcom/sdmshrike-v2.dtsi index b32e6449c892..f544cac42142 100644 --- a/arch/arm64/boot/dts/qcom/sdmshrike-v2.dtsi +++ b/arch/arm64/boot/dts/qcom/sdmshrike-v2.dtsi @@ -29,3 +29,19 @@ qcom,sde-min-core-ib-kbps = <0>; qcom,sde-min-llcc-ib-kbps = <0>; }; + +&clock_npucc { + compatible = "qcom,npucc-sm8150-v2", "syscon"; +}; + +&clock_dispcc { + compatible = "qcom,dispcc-sdmshrike-v2", "syscon"; +}; + +&mdss_dsi0_pll { + compatible = "qcom,mdss_dsi_pll_7nm_v2"; +}; + +&mdss_dsi1_pll { + compatible = "qcom,mdss_dsi_pll_7nm_v2"; +}; -- GitLab From 358fc0a19fa18647de4882ec12931b999dd42118 Mon Sep 17 00:00:00 2001 From: Prakasha Nayak Date: Fri, 14 Jun 2019 17:36:06 +0530 Subject: [PATCH 0868/1121] msm: camera: util: Enabling logs to improve debugging Enable logs to improve debugging. This will print desired information in the case of an error. Change-Id: Ia0dcbdbf5b1babf1f2099ca7e39952f538c4aa27 Signed-off-by: Prakasha Nayak --- .../hw_utils/cam_isp_packet_parser.c | 14 +++-- .../msm/camera/cam_utils/cam_packet_util.c | 52 ++++++++++++++++--- 2 files changed, 57 insertions(+), 9 deletions(-) diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c index 593c9bf0aacc..8c38a3071608 100644 --- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c +++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c @@ -497,7 +497,7 @@ int cam_isp_add_io_buffers( CAM_DBG(CAM_ISP, "======= io config idx %d ============", i); CAM_DBG(CAM_REQ, "i %d req_id %llu resource_type:%d fence:%d direction %d", - i, prepare->packet->header.request_id, + i, req_id, io_cfg[i].resource_type, io_cfg[i].fence, io_cfg[i].direction); CAM_DBG(CAM_ISP, "format: %d", io_cfg[i].format); @@ -624,8 +624,16 @@ int cam_isp_add_io_buffers( mmu_hdl, &io_addr[plane_id], &size); if (rc) { CAM_ERR(CAM_ISP, - "no io addr for plane%d", - plane_id); + "no io addr for plane%d Bufhdl:%d, Size =%d", + plane_id, + io_cfg[i].mem_handle[plane_id], + (int)size); + CAM_ERR(CAM_ISP, + "Port i %d Reqid %llu res_type:%d fence:%d dir %d", + i, req_id, + io_cfg[i].resource_type, + io_cfg[i].fence, + io_cfg[i].direction); rc = -ENOMEM; return rc; } diff --git a/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.c b/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.c index 4eae9ae5f276..593bed9b137d 100644 --- a/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.c +++ b/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.c @@ -182,11 +182,15 @@ int cam_packet_util_process_patches(struct cam_packet *packet, int i; int rc = 0; int32_t hdl; + uint64_t requestId; + uint32_t num_patches; /* process patch descriptor */ patch_desc = (struct cam_patch_desc *) ((uint32_t *) &packet->payload + packet->patch_offset/4); + requestId = packet->header.request_id; + num_patches = packet->num_patches; CAM_DBG(CAM_UTIL, "packet = %pK patch_desc = %pK size = %lu", (void *)packet, (void *)patch_desc, sizeof(struct cam_patch_desc)); @@ -197,7 +201,16 @@ int cam_packet_util_process_patches(struct cam_packet *packet, rc = cam_mem_get_io_buf(patch_desc[i].src_buf_hdl, hdl, &iova_addr, &src_buf_size); if (rc < 0) { - CAM_ERR(CAM_UTIL, "unable to get src buf address"); + CAM_ERR(CAM_UTIL, + "unable to get src buf address ReqId: %llu, num_patches = %d", + requestId, num_patches); + CAM_ERR(CAM_UTIL, + "i = %d patch info = %x %x %x %x src_bfsz:0x%x", + i, patch_desc[i].dst_buf_hdl, + patch_desc[i].dst_offset, + patch_desc[i].src_buf_hdl, + patch_desc[i].src_offset, + (uint32_t)src_buf_size); return rc; } src_buf_iova_addr = (uint32_t *)iova_addr; @@ -206,18 +219,37 @@ int cam_packet_util_process_patches(struct cam_packet *packet, rc = cam_mem_get_cpu_buf(patch_desc[i].dst_buf_hdl, &cpu_addr, &dst_buf_len); if (rc < 0 || !cpu_addr || (dst_buf_len == 0)) { - CAM_ERR(CAM_UTIL, "unable to get dst buf address"); + CAM_ERR(CAM_UTIL, + "unable to get dst buf address ReqId: %llu, num_patches = %d", + requestId, num_patches); + CAM_ERR(CAM_UTIL, + "i = %d patch info = %x %x %x %x dst_bfsz:0x%x", + i, patch_desc[i].dst_buf_hdl, + patch_desc[i].dst_offset, + patch_desc[i].src_buf_hdl, + patch_desc[i].src_offset, + (uint32_t)dst_buf_len); return rc; } dst_cpu_addr = (uint32_t *)cpu_addr; - CAM_DBG(CAM_UTIL, "i = %d patch info = %x %x %x %x", i, - patch_desc[i].dst_buf_hdl, patch_desc[i].dst_offset, + CAM_DBG(CAM_UTIL, + "ReqId: %llu, i = %d patch info = %x %x %x %x", + requestId, i, patch_desc[i].dst_buf_hdl, + patch_desc[i].dst_offset, patch_desc[i].src_buf_hdl, patch_desc[i].src_offset); if ((size_t)patch_desc[i].src_offset >= src_buf_size) { CAM_ERR(CAM_UTIL, - "Invalid src buf patch offset"); + "Invalid src buf patch offset ReqId: %llu, num_patches = %d", + requestId, num_patches); + CAM_ERR(CAM_UTIL, + "i = %d patch info = %x %x %x %x src_bfsz:0x%x", + i, patch_desc[i].dst_buf_hdl, + patch_desc[i].dst_offset, + patch_desc[i].src_buf_hdl, + patch_desc[i].src_offset, + (uint32_t)src_buf_size); return -EINVAL; } @@ -225,7 +257,15 @@ int cam_packet_util_process_patches(struct cam_packet *packet, ((dst_buf_len - sizeof(void *)) < (size_t)patch_desc[i].dst_offset)) { CAM_ERR(CAM_UTIL, - "Invalid dst buf patch offset"); + "Invalid dst buf patch offset ReqId: %llu, num_patches = %d", + requestId, num_patches); + CAM_ERR(CAM_UTIL, + "i = %d patch info = %x %x %x %x dst_bfsz:0x%x", + i, patch_desc[i].dst_buf_hdl, + patch_desc[i].dst_offset, + patch_desc[i].src_buf_hdl, + patch_desc[i].src_offset, + (uint32_t)dst_buf_len); return -EINVAL; } -- GitLab From 8fc52d130f8520ee0c4369f45bfa1f5c6669685b Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Thu, 20 Jun 2019 18:14:54 -0700 Subject: [PATCH 0869/1121] usb: dwc3: Stop active transfer on control endpoints If cable disconnects before data stage completion dwc3_remove_requests() gets called for ep0 in and out but dwc3_ep0_complete_data() does not get called. dwc3_ep0_complete_data() function resets TRB enqueue count to 0. As a result upon next cable connect start transfer is called with wrong TRB address because trb_enqueue is set to 1. Since this TRB was completed in the past, HWO bit is cleared for this TRB. This results into usb enumeration failure due to control transfer stall. Fix this issue by issuing end transfer command on control endpoints after ep0 requests are removed for IN and OUT and reset trb_enqueue counters to 0. Change-Id: Ic5364f11372d85ec7c133024dc48bbc5d848ebf4 Signed-off-by: Hemant Kumar --- drivers/usb/dwc3/gadget.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index aff6059aa854..7228cf206620 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -845,6 +845,21 @@ static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep) dwc3_gadget_giveback(dep, req, -ESHUTDOWN); } + + if (dep->number == 1 && dwc->ep0state != EP0_SETUP_PHASE) { + unsigned int dir; + + dbg_log_string("CTRLPEND", dwc->ep0state); + dir = !!dwc->ep0_expect_in; + if (dwc->ep0state == EP0_DATA_PHASE) + dwc3_ep0_end_control_data(dwc, dwc->eps[dir]); + else + dwc3_ep0_end_control_data(dwc, dwc->eps[!dir]); + + dwc->eps[0]->trb_enqueue = 0; + dwc->eps[1]->trb_enqueue = 0; + } + dbg_log_string("DONE for %s(%d)", dep->name, dep->number); } -- GitLab From c64c020aac67ed8186f00c71d81c0f8e90ff93fb Mon Sep 17 00:00:00 2001 From: Terence Ho Date: Thu, 4 Jul 2019 11:50:37 -0400 Subject: [PATCH 0870/1121] msm: ais: Support multi-client for req and sync mgr Allow mulitple clients to access camera request manager and sync manager. Change-Id: Icff965722b30fcf58bce6fd0753dcdcf8af92266 Signed-off-by: Terence Ho --- .../msm/ais/cam_req_mgr/cam_req_mgr_dev.c | 50 +++++++++++-------- .../platform/msm/ais/cam_sync/cam_sync.c | 46 +++++++++++------ 2 files changed, 60 insertions(+), 36 deletions(-) diff --git a/drivers/media/platform/msm/ais/cam_req_mgr/cam_req_mgr_dev.c b/drivers/media/platform/msm/ais/cam_req_mgr/cam_req_mgr_dev.c index 5cf1d844f5e2..5e800ae8c5aa 100644 --- a/drivers/media/platform/msm/ais/cam_req_mgr/cam_req_mgr_dev.c +++ b/drivers/media/platform/msm/ais/cam_req_mgr/cam_req_mgr_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -103,10 +103,6 @@ static int cam_req_mgr_open(struct file *filep) int rc; mutex_lock(&g_dev.cam_lock); - if (g_dev.open_cnt >= 1) { - rc = -EALREADY; - goto end; - } rc = v4l2_fh_open(filep); if (rc) { @@ -114,11 +110,18 @@ static int cam_req_mgr_open(struct file *filep) goto end; } + g_dev.open_cnt++; + + /* return if already initialized before */ + if (g_dev.open_cnt > 1) { + CAM_ERR(CAM_CRM, "Already opened", rc); + goto end; + } + spin_lock_bh(&g_dev.cam_eventq_lock); g_dev.cam_eventq = filep->private_data; spin_unlock_bh(&g_dev.cam_eventq_lock); - g_dev.open_cnt++; rc = cam_mem_mgr_init(); if (rc) { g_dev.open_cnt--; @@ -165,27 +168,34 @@ static int cam_req_mgr_close(struct file *filep) return -EINVAL; } - cam_req_mgr_handle_core_shutdown(); + g_dev.open_cnt--; - list_for_each_entry(sd, &g_dev.v4l2_dev->subdevs, list) { - if (!(sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE)) - continue; - if (sd->internal_ops && sd->internal_ops->close) { - CAM_DBG(CAM_CRM, "Invoke subdev close for device %s", - sd->name); - sd->internal_ops->close(sd, subdev_fh); + if (g_dev.open_cnt == 0) { + cam_req_mgr_handle_core_shutdown(); + + list_for_each_entry(sd, &g_dev.v4l2_dev->subdevs, list) { + if (!(sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE)) + continue; + if (sd->internal_ops && sd->internal_ops->close) { + CAM_DBG(CAM_CRM, + "Invoke subdev close for device %s", + sd->name); + sd->internal_ops->close(sd, subdev_fh); + } } } - g_dev.open_cnt--; v4l2_fh_release(filep); - spin_lock_bh(&g_dev.cam_eventq_lock); - g_dev.cam_eventq = NULL; - spin_unlock_bh(&g_dev.cam_eventq_lock); + if (g_dev.open_cnt == 0) { + spin_lock_bh(&g_dev.cam_eventq_lock); + g_dev.cam_eventq = NULL; + spin_unlock_bh(&g_dev.cam_eventq_lock); + + cam_req_mgr_util_free_hdls(); + cam_mem_mgr_deinit(); + } - cam_req_mgr_util_free_hdls(); - cam_mem_mgr_deinit(); mutex_unlock(&g_dev.cam_lock); return 0; diff --git a/drivers/media/platform/msm/ais/cam_sync/cam_sync.c b/drivers/media/platform/msm/ais/cam_sync/cam_sync.c index 84acb71707e2..a1518e464884 100644 --- a/drivers/media/platform/msm/ais/cam_sync/cam_sync.c +++ b/drivers/media/platform/msm/ais/cam_sync/cam_sync.c @@ -439,9 +439,10 @@ static int cam_sync_handle_create(struct cam_private_ioctl_arg *k_ioctl) k_ioctl->size)) return -EFAULT; + mutex_lock(&sync_dev->table_lock); result = cam_sync_create(&sync_create.sync_obj, sync_create.name); - + mutex_unlock(&sync_dev->table_lock); if (!result) if (copy_to_user( u64_to_user_ptr(k_ioctl->ioctl_ptr), @@ -560,6 +561,7 @@ static int cam_sync_handle_wait(struct cam_private_ioctl_arg *k_ioctl) static int cam_sync_handle_destroy(struct cam_private_ioctl_arg *k_ioctl) { struct cam_sync_info sync_create; + int rc; if (k_ioctl->size != sizeof(struct cam_sync_info)) return -EINVAL; @@ -572,7 +574,11 @@ static int cam_sync_handle_destroy(struct cam_private_ioctl_arg *k_ioctl) k_ioctl->size)) return -EFAULT; - return cam_sync_destroy(sync_create.sync_obj); + mutex_lock(&sync_dev->table_lock); + rc = cam_sync_destroy(sync_create.sync_obj); + mutex_unlock(&sync_dev->table_lock); + + return rc; } static int cam_sync_handle_register_user_payload( @@ -789,20 +795,26 @@ static int cam_sync_open(struct file *filep) sync_dev->err_cnt = 0; mutex_lock(&sync_dev->table_lock); - if (sync_dev->open_cnt >= 1) { - mutex_unlock(&sync_dev->table_lock); - return -EALREADY; - } rc = v4l2_fh_open(filep); - if (!rc) { - sync_dev->open_cnt++; - spin_lock_bh(&sync_dev->cam_sync_eventq_lock); - sync_dev->cam_sync_eventq = filep->private_data; - spin_unlock_bh(&sync_dev->cam_sync_eventq_lock); - } else { - CAM_ERR(CAM_SYNC, "v4l2_fh_open failed : %d", rc); + if (rc) { + CAM_ERR(CAM_SYNC, "v4l2_fh_open failed: %d", rc); + goto end; } + + sync_dev->open_cnt++; + + /* return if already initialized before */ + if (sync_dev->open_cnt > 1) { + CAM_ERR(CAM_SYNC, "Already opened", rc); + goto end; + } + + spin_lock_bh(&sync_dev->cam_sync_eventq_lock); + sync_dev->cam_sync_eventq = filep->private_data; + spin_unlock_bh(&sync_dev->cam_sync_eventq_lock); + +end: mutex_unlock(&sync_dev->table_lock); return rc; @@ -864,11 +876,13 @@ static int cam_sync_close(struct file *filep) i); } } + + spin_lock_bh(&sync_dev->cam_sync_eventq_lock); + sync_dev->cam_sync_eventq = NULL; + spin_unlock_bh(&sync_dev->cam_sync_eventq_lock); } mutex_unlock(&sync_dev->table_lock); - spin_lock_bh(&sync_dev->cam_sync_eventq_lock); - sync_dev->cam_sync_eventq = NULL; - spin_unlock_bh(&sync_dev->cam_sync_eventq_lock); + v4l2_fh_release(filep); return rc; -- GitLab From 2861f691bd414572d760bb27273f334c81826d65 Mon Sep 17 00:00:00 2001 From: Manoj Prabhu B Date: Fri, 12 Jul 2019 11:50:07 +0530 Subject: [PATCH 0871/1121] diag: Replace improper checks with proper ones to clear stats Invalid checks to reset the debugfs stats causes invalid behaviour in using debug structures. Use proper check to effect the proper clearing of the debug stats. Change-Id: I29e6f3d8909914a506337f4e788b521439e9d69b Signed-off-by: Manoj Prabhu B --- drivers/char/diag/diag_debugfs.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/char/diag/diag_debugfs.c b/drivers/char/diag/diag_debugfs.c index 1cbfb97f9a21..73b7f194b984 100644 --- a/drivers/char/diag/diag_debugfs.c +++ b/drivers/char/diag/diag_debugfs.c @@ -553,7 +553,7 @@ static ssize_t diag_dbgfs_read_socketinfo(struct file *file, char __user *ubuf, struct diag_socket_info *info = NULL; struct diagfwd_info *fwd_ctxt = NULL; - if (diag_dbgfs_socketinfo_index >= NUM_PERIPHERALS) { + if (diag_dbgfs_socketinfo_index >= NUM_TYPES) { /* Done. Reset to prepare for future requests */ diag_dbgfs_socketinfo_index = 0; return 0; @@ -659,7 +659,7 @@ static ssize_t diag_dbgfs_read_rpmsginfo(struct file *file, char __user *ubuf, struct diag_rpmsg_info *info = NULL; struct diagfwd_info *fwd_ctxt = NULL; - if (diag_dbgfs_rpmsginfo_index >= NUM_PERIPHERALS) { + if (diag_dbgfs_rpmsginfo_index >= NUM_TYPES) { /* Done. Reset to prepare for future requests */ diag_dbgfs_rpmsginfo_index = 0; return 0; @@ -697,7 +697,7 @@ static ssize_t diag_dbgfs_read_rpmsginfo(struct file *file, char __user *ubuf, bytes_written = scnprintf(buf+bytes_in_buffer, bytes_remaining, - "name\t\t:\t%s\n" + "name\t\t:\t%s:\t%s\n" "hdl\t\t:\t%pK\n" "inited\t\t:\t%d\n" "opened\t\t:\t%d\n" @@ -712,6 +712,7 @@ static ssize_t diag_dbgfs_read_rpmsginfo(struct file *file, char __user *ubuf, "fwd inited\t:\t%d\n" "fwd opened\t:\t%d\n" "fwd ch_open\t:\t%d\n\n", + info->edge, info->name, info->hdl, info->inited, @@ -793,7 +794,7 @@ static ssize_t diag_dbgfs_read_hsicinfo(struct file *file, char __user *ubuf, unsigned int bytes_in_buffer = 0; struct diag_hsic_info *hsic_info = NULL; - if (diag_dbgfs_hsicinfo_index >= NUM_DIAG_USB_DEV) { + if (diag_dbgfs_hsicinfo_index >= NUM_HSIC_DEV) { /* Done. Reset to prepare for future requests */ diag_dbgfs_hsicinfo_index = 0; return 0; @@ -938,7 +939,7 @@ static ssize_t diag_dbgfs_read_bridge(struct file *file, char __user *ubuf, unsigned int bytes_in_buffer = 0; struct diagfwd_bridge_info *info = NULL; - if (diag_dbgfs_bridgeinfo_index >= NUM_DIAG_USB_DEV) { + if (diag_dbgfs_bridgeinfo_index >= NUM_REMOTE_DEV) { /* Done. Reset to prepare for future requests */ diag_dbgfs_bridgeinfo_index = 0; return 0; -- GitLab From 0ed84179d01b3d0cbe852551053d9a1ce0ac2d54 Mon Sep 17 00:00:00 2001 From: Sriharsha Allenki Date: Wed, 3 Jul 2019 14:37:26 +0530 Subject: [PATCH 0872/1121] sound: usb: Fix possible race between release and cleanup In a case where the physical disconnect of headset and the disable call from QMI race with each other, there is a possibility that usb_sec_event_ring_cleanup is called at the same time from uaudio_dev_cleanup and uaudio_dev_release leading to kernel panic. Fix this by seriailizing both these calls using the dev_lock mutex. Change-Id: I88abccca704786446e0826fc60994c9580828156 Signed-off-by: Sriharsha Allenki --- sound/usb/usb_audio_qmi_svc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/usb/usb_audio_qmi_svc.c b/sound/usb/usb_audio_qmi_svc.c index 7bb404eb7bce..307ebcf78b15 100644 --- a/sound/usb/usb_audio_qmi_svc.c +++ b/sound/usb/usb_audio_qmi_svc.c @@ -1156,17 +1156,17 @@ static void handle_uaudio_stream_req(struct qmi_handle *handle, response: if (!req_msg->enable && ret != -EINVAL) { + mutex_lock(&chip->dev_lock); if (info_idx >= 0) { - mutex_lock(&chip->dev_lock); info = &uadev[pcm_card_num].info[info_idx]; uaudio_dev_intf_cleanup(uadev[pcm_card_num].udev, info); uaudio_dbg("release resources: intf# %d card# %d\n", subs->interface, pcm_card_num); - mutex_unlock(&chip->dev_lock); } if (atomic_read(&uadev[pcm_card_num].in_use)) kref_put(&uadev[pcm_card_num].kref, uaudio_dev_release); + mutex_unlock(&chip->dev_lock); } resp.usb_token = req_msg->usb_token; -- GitLab From 58997453607f73cc207488437c240a758c0901b8 Mon Sep 17 00:00:00 2001 From: Rama Krishna Phani A Date: Wed, 13 Feb 2019 19:34:33 +0530 Subject: [PATCH 0873/1121] input: qpnp-power-on: Add support for suspend to disk Add support to pon driver for suspend to disk feature. Free interrupts during hibernation and re-register them during resume. Also, re-configure the boot time registers on resume. Change-Id: I027d0d44e93b0ca20d8ab6498976886fafb117a0 Signed-off-by: Rama Krishna Phani A Signed-off-by: Veera Vegivada --- drivers/input/misc/qpnp-power-on.c | 161 +++++++++++++++++++++++++---- 1 file changed, 143 insertions(+), 18 deletions(-) diff --git a/drivers/input/misc/qpnp-power-on.c b/drivers/input/misc/qpnp-power-on.c index 8f25279903ec..bee8be0066c7 100644 --- a/drivers/input/misc/qpnp-power-on.c +++ b/drivers/input/misc/qpnp-power-on.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -167,6 +167,12 @@ enum pon_type { PON_KPDPWR_RESIN = PON_POWER_ON_TYPE_KPDPWR_RESIN, }; +struct pon_reg { + unsigned int val; + u16 addr; + struct list_head list; +}; + struct qpnp_pon_config { u32 pon_type; u32 support_reset; @@ -199,7 +205,9 @@ struct qpnp_pon { struct input_dev *pon_input; struct qpnp_pon_config *pon_cfg; struct pon_regulator *pon_reg_cfg; + struct list_head restore_regs; struct list_head list; + struct mutex restore_lock; struct delayed_work bark_work; struct dentry *debugfs; u16 base; @@ -305,6 +313,42 @@ static const char * const qpnp_poff_reason[] = { [39] = "Triggered from S3_RESET_KPDPWR_ANDOR_RESIN", }; +static int qpnp_pon_store_reg(struct qpnp_pon *pon, u16 addr) +{ + int rc; + unsigned int val; + struct pon_reg *reg, *pos = NULL; + + mutex_lock(&pon->restore_lock); + rc = regmap_read(pon->regmap, addr, &val); + if (rc < 0) { + dev_info(pon->dev, "Register read failed, addr=0x%04X, rc=%d\n", + addr, rc); + } else { + list_for_each_entry(pos, &pon->restore_regs, list) { + if (pos->addr == addr) { + pos->val = val; + goto done; + } + } + + reg = devm_kzalloc(pon->dev, sizeof(*reg), GFP_KERNEL); + if (!reg) { + rc = -ENOMEM; + goto done; + } + + reg->addr = addr; + reg->val = val; + INIT_LIST_HEAD(®->list); + list_add_tail(®->list, &pon->restore_regs); + } + +done: + mutex_unlock(&pon->restore_lock); + return rc; +} + static int qpnp_pon_masked_write(struct qpnp_pon *pon, u16 addr, u8 mask, u8 val) { @@ -317,6 +361,18 @@ qpnp_pon_masked_write(struct qpnp_pon *pon, u16 addr, u8 mask, u8 val) return rc; } +static int +qpnp_pon_masked_write_backup(struct qpnp_pon *pon, u16 addr, u8 mask, u8 val) +{ + int rc; + + rc = qpnp_pon_masked_write(pon, addr, mask, val); + if (rc < 0) + return rc; + + return qpnp_pon_store_reg(pon, addr); +} + static int qpnp_pon_read(struct qpnp_pon *pon, u16 addr, unsigned int *val) { int rc; @@ -416,7 +472,7 @@ static int qpnp_pon_set_dbc(struct qpnp_pon *pon, u32 delay) } val = ilog2(val); - rc = qpnp_pon_masked_write(pon, QPNP_PON_DBC_CTL(pon), + rc = qpnp_pon_masked_write_backup(pon, QPNP_PON_DBC_CTL(pon), QPNP_PON_DBC_DELAY_MASK(pon), val); if (!rc) pon->dbc_time_us = delay; @@ -794,10 +850,10 @@ int qpnp_pon_trigger_config(enum pon_trigger_source pon_src, bool enable) } if (is_pon_gen2(pon) && pon_src == PON_SMPL) - rc = qpnp_pon_masked_write(pon, QPNP_PON_SMPL_CTL(pon), + rc = qpnp_pon_masked_write_backup(pon, QPNP_PON_SMPL_CTL(pon), QPNP_PON_SMPL_EN, enable ? QPNP_PON_SMPL_EN : 0); else - rc = qpnp_pon_masked_write(pon, QPNP_PON_TRIGGER_EN(pon), + rc = qpnp_pon_masked_write_backup(pon, QPNP_PON_TRIGGER_EN(pon), BIT(pon_src), enable ? BIT(pon_src) : 0); return rc; @@ -834,6 +890,7 @@ static int qpnp_pon_store_and_clear_warm_reset(struct qpnp_pon *pon) QPNP_PON_WARM_RESET_REASON1(pon), rc); return rc; } + qpnp_pon_store_reg(pon, QPNP_PON_WARM_RESET_REASON1(pon)); } return 0; @@ -1122,8 +1179,8 @@ static int qpnp_config_pull(struct qpnp_pon *pon, struct qpnp_pon_config *cfg) return -EINVAL; } - return qpnp_pon_masked_write(pon, QPNP_PON_PULL_CTL(pon), pull_bit, - cfg->pull_up ? pull_bit : 0); + return qpnp_pon_masked_write_backup(pon, QPNP_PON_PULL_CTL(pon), + pull_bit, cfg->pull_up ? pull_bit : 0); } static int qpnp_config_reset(struct qpnp_pon *pon, struct qpnp_pon_config *cfg) @@ -1150,8 +1207,8 @@ static int qpnp_config_reset(struct qpnp_pon *pon, struct qpnp_pon_config *cfg) } /* Disable S2 reset */ - rc = qpnp_pon_masked_write(pon, cfg->s2_cntl2_addr, QPNP_PON_S2_CNTL_EN, - 0); + rc = qpnp_pon_masked_write_backup(pon, cfg->s2_cntl2_addr, + QPNP_PON_S2_CNTL_EN, 0); if (rc) return rc; @@ -1162,7 +1219,7 @@ static int qpnp_config_reset(struct qpnp_pon *pon, struct qpnp_pon_config *cfg) if (cfg->s1_timer <= s1_delay[i]) break; } - rc = qpnp_pon_masked_write(pon, s1_timer_addr, + rc = qpnp_pon_masked_write_backup(pon, s1_timer_addr, QPNP_PON_S1_TIMER_MASK, i); if (rc) return rc; @@ -1173,18 +1230,18 @@ static int qpnp_config_reset(struct qpnp_pon *pon, struct qpnp_pon_config *cfg) i = ilog2(i + 1); } - rc = qpnp_pon_masked_write(pon, s2_timer_addr, QPNP_PON_S2_TIMER_MASK, - i); + rc = qpnp_pon_masked_write_backup(pon, s2_timer_addr, + QPNP_PON_S2_TIMER_MASK, i); if (rc) return rc; - rc = qpnp_pon_masked_write(pon, cfg->s2_cntl_addr, + rc = qpnp_pon_masked_write_backup(pon, cfg->s2_cntl_addr, QPNP_PON_S2_CNTL_TYPE_MASK, (u8)cfg->s2_type); if (rc) return rc; /* Enable S2 reset */ - return qpnp_pon_masked_write(pon, cfg->s2_cntl2_addr, + return qpnp_pon_masked_write_backup(pon, cfg->s2_cntl2_addr, QPNP_PON_S2_CNTL_EN, QPNP_PON_S2_CNTL_EN); } @@ -1277,6 +1334,18 @@ qpnp_pon_request_irqs(struct qpnp_pon *pon, struct qpnp_pon_config *cfg) return 0; } +static int +qpnp_pon_free_irqs(struct qpnp_pon *pon, struct qpnp_pon_config *cfg) +{ + if (cfg->state_irq > 0) + devm_free_irq(pon->dev, cfg->state_irq, pon); + + if (cfg->use_bark && cfg->bark_irq > 0) + devm_free_irq(pon->dev, cfg->bark_irq, pon); + + return 0; +} + static int qpnp_pon_config_input(struct qpnp_pon *pon, struct qpnp_pon_config *cfg) { @@ -1632,7 +1701,7 @@ static int qpnp_pon_config_init(struct qpnp_pon *pon, return rc; } else if (cfg->pon_type != PON_CBLPWR) { /* Disable S2 reset */ - rc = qpnp_pon_masked_write(pon, + rc = qpnp_pon_masked_write_backup(pon, cfg->s2_cntl2_addr, QPNP_PON_S2_CNTL_EN, 0); if (rc) @@ -1847,7 +1916,7 @@ qpnp_pon_uvlo_dload_set(const char *val, const struct kernel_param *kp) reg = *(bool *)kp->arg ? QPNP_PON_UVLO_DLOAD_EN : 0; - return qpnp_pon_masked_write(pon, QPNP_PON_XVDD_RB_SPARE(pon), + return qpnp_pon_masked_write_backup(pon, QPNP_PON_XVDD_RB_SPARE(pon), QPNP_PON_UVLO_DLOAD_EN, reg); } @@ -1970,12 +2039,12 @@ static int qpnp_pon_configure_s3_reset(struct qpnp_pon *pon) debounce = ilog2(debounce); /* S3 debounce is a SEC_ACCESS register */ - rc = qpnp_pon_masked_write(pon, QPNP_PON_SEC_ACCESS(pon), + rc = qpnp_pon_masked_write_backup(pon, QPNP_PON_SEC_ACCESS(pon), 0xFF, QPNP_PON_SEC_UNLOCK); if (rc) return rc; - rc = qpnp_pon_masked_write(pon, QPNP_PON_S3_DBC_CTL(pon), + rc = qpnp_pon_masked_write_backup(pon, QPNP_PON_S3_DBC_CTL(pon), QPNP_PON_S3_DBC_DELAY_MASK, debounce); if (rc) return rc; @@ -2003,7 +2072,7 @@ static int qpnp_pon_configure_s3_reset(struct qpnp_pon *pon) * been configured by the bootloader then this operation will * not have an effect. */ - rc = qpnp_pon_masked_write(pon, QPNP_PON_S3_SRC(pon), + rc = qpnp_pon_masked_write_backup(pon, QPNP_PON_S3_SRC(pon), QPNP_PON_S3_SRC_MASK, src_val); if (rc) return rc; @@ -2224,6 +2293,9 @@ static int qpnp_pon_probe(struct platform_device *pdev) return -EINVAL; } + INIT_LIST_HEAD(&pon->restore_regs); + mutex_init(&pon->restore_lock); + /* Get the total number of pon configurations and regulators */ for_each_available_child_of_node(dev->of_node, node) { if (of_find_property(node, "regulator-name", NULL)) { @@ -2325,10 +2397,60 @@ static int qpnp_pon_remove(struct platform_device *pdev) list_del(&pon->list); spin_unlock_irqrestore(&spon_list_slock, flags); } + mutex_destroy(&pon->restore_lock); return 0; } +#ifdef CONFIG_PM +static int qpnp_pon_restore(struct device *dev) +{ + int i, rc = 0; + struct qpnp_pon_config *cfg; + struct qpnp_pon *pon = dev_get_drvdata(dev); + struct pon_reg *pos = NULL; + + list_for_each_entry(pos, &pon->restore_regs, list) { + rc = regmap_write(pon->regmap, pos->addr, pos->val); + if (rc < 0) { + dev_err(dev, "Failed to restore reg addr=0x%04X rc=%d\n", + pos->addr, rc); + return rc; + } + } + + for (i = 0; i < pon->num_pon_config; i++) { + cfg = &pon->pon_cfg[i]; + rc = qpnp_pon_request_irqs(pon, cfg); + if (rc < 0) + return rc; + } + + return rc; +} + +static int qpnp_pon_freeze(struct device *dev) +{ + int i, rc = 0; + struct qpnp_pon_config *cfg; + struct qpnp_pon *pon = dev_get_drvdata(dev); + + for (i = 0; i < pon->num_pon_config; i++) { + cfg = &pon->pon_cfg[i]; + rc = qpnp_pon_free_irqs(pon, cfg); + if (rc < 0) + return rc; + } + + return rc; +} + +static const struct dev_pm_ops qpnp_pon_pm_ops = { + .freeze = qpnp_pon_freeze, + .restore = qpnp_pon_restore, +}; +#endif + static const struct of_device_id qpnp_pon_match_table[] = { { .compatible = "qcom,qpnp-power-on" }, {} @@ -2338,6 +2460,9 @@ static struct platform_driver qpnp_pon_driver = { .driver = { .name = "qcom,qpnp-power-on", .of_match_table = qpnp_pon_match_table, +#ifdef CONFIG_PM + .pm = &qpnp_pon_pm_ops, +#endif }, .probe = qpnp_pon_probe, .remove = qpnp_pon_remove, -- GitLab From 8068ac4f90258bc2e22eecb809cc304daf4ee8a7 Mon Sep 17 00:00:00 2001 From: Sriharsha Allenki Date: Mon, 8 Jul 2019 10:29:27 +0530 Subject: [PATCH 0874/1121] usb: phy: snps: Enable auto resume feature only in host mode If the auto resume feature is enabled in device mode, the device is unable to detect the resume signalling by the host in some cases. And the auto resume feature is applicable only in host mode. So, enable the auto resume feature only in host mode. Change-Id: I870ee8fdc3fe4712d072952025a37b6e954fdab8 Signed-off-by: Sriharsha Allenki --- drivers/usb/phy/phy-msm-snps-hs.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/usb/phy/phy-msm-snps-hs.c b/drivers/usb/phy/phy-msm-snps-hs.c index 0353f9aee409..e5dc7e47f744 100644 --- a/drivers/usb/phy/phy-msm-snps-hs.c +++ b/drivers/usb/phy/phy-msm-snps-hs.c @@ -510,16 +510,17 @@ static int msm_hsphy_set_suspend(struct usb_phy *uphy, int suspend) } if (suspend) { /* Bus suspend */ - if (phy->cable_connected || - (phy->phy.flags & PHY_HOST_MODE)) { + if (phy->cable_connected) { /* Enable auto-resume functionality by pulsing signal */ - msm_usb_write_readback(phy->base, - USB2_PHY_USB_PHY_HS_PHY_CTRL2, - USB2_AUTO_RESUME, USB2_AUTO_RESUME); - usleep_range(500, 1000); - msm_usb_write_readback(phy->base, - USB2_PHY_USB_PHY_HS_PHY_CTRL2, - USB2_AUTO_RESUME, 0); + if (phy->phy.flags & PHY_HOST_MODE) { + msm_usb_write_readback(phy->base, + USB2_PHY_USB_PHY_HS_PHY_CTRL2, + USB2_AUTO_RESUME, USB2_AUTO_RESUME); + usleep_range(500, 1000); + msm_usb_write_readback(phy->base, + USB2_PHY_USB_PHY_HS_PHY_CTRL2, + USB2_AUTO_RESUME, 0); + } msm_hsphy_enable_clocks(phy, false); } else {/* Cable disconnect */ -- GitLab From cf86abf17ab8578e65a6fd426dc6e3d4eaa24a1e Mon Sep 17 00:00:00 2001 From: Chandana Kishori Chiluveru Date: Fri, 7 Jun 2019 18:41:18 +0530 Subject: [PATCH 0875/1121] usb: pd: Do not allow pending out going requests with src_cap_ext Currently, charger daemon requesting get_src_cap_ext request back to back, resulting in too many PD messages from userspace to handle get_src_cap_ext. There is a case where phy_msg_received() for SOURCE_CAPABILITIES_EXTENDED and sm_work is queued to handle the response. Meanwhile userspace daemon requested for select_pdo which will set the pd->send_request flag and queue another sm_work immediately. But there is a possibility that usbpd_sm work is still in running state to handle previous rx_msg received for src_cap_ext. It will further checks for any pending out going requests and try to handle it from from the same work hence state transition to select_capability. In this state it will send the pd_msg for SNK_SELECT_CAPABILITY and wait for response. In this case the next sm_work has a deliberate delay such as waiting for minimum 26msec of SENDER_RESPONSE_TIME, but the delay is effectively eliminated and usbpd_sm gets executed immediately again which can cause the state machine to think that timeout occurred and will result in hard reset. Hence fix this issue by exit the work after complete of src_ext_cap so that it won't handle other pending outgoing requests from the same work. Also handle this for other possible cases like PPS_Status, Status, Battery_Capabilities and Battery_Status. Change-Id: I586fbf50837c81b856eb30176564013e9bcde90f Signed-off-by: Chandana Kishori Chiluveru --- drivers/usb/pd/policy_engine.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c index 29aed6b118f0..3cbe8b8a7768 100644 --- a/drivers/usb/pd/policy_engine.c +++ b/drivers/usb/pd/policy_engine.c @@ -3105,6 +3105,7 @@ static void usbpd_sm(struct work_struct *w) memcpy(&pd->src_cap_ext_db, rx_msg->payload, sizeof(pd->src_cap_ext_db)); complete(&pd->is_ready); + break; } else if (IS_EXT(rx_msg, MSG_PPS_STATUS)) { if (rx_msg->data_len != sizeof(pd->pps_status_db)) { usbpd_err(&pd->dev, "Invalid pps status db\n"); @@ -3113,6 +3114,7 @@ static void usbpd_sm(struct work_struct *w) memcpy(&pd->pps_status_db, rx_msg->payload, sizeof(pd->pps_status_db)); complete(&pd->is_ready); + break; } else if (IS_EXT(rx_msg, MSG_STATUS)) { if (rx_msg->data_len != PD_STATUS_DB_LEN) { usbpd_err(&pd->dev, "Invalid status db\n"); @@ -3122,6 +3124,7 @@ static void usbpd_sm(struct work_struct *w) sizeof(pd->status_db)); kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE); complete(&pd->is_ready); + break; } else if (IS_EXT(rx_msg, MSG_BATTERY_CAPABILITIES)) { if (rx_msg->data_len != PD_BATTERY_CAP_DB_LEN) { usbpd_err(&pd->dev, "Invalid battery cap db\n"); @@ -3130,6 +3133,7 @@ static void usbpd_sm(struct work_struct *w) memcpy(&pd->battery_cap_db, rx_msg->payload, sizeof(pd->battery_cap_db)); complete(&pd->is_ready); + break; } else if (IS_EXT(rx_msg, MSG_BATTERY_STATUS)) { if (rx_msg->data_len != sizeof(pd->battery_sts_dobj)) { usbpd_err(&pd->dev, "Invalid bat sts dobj\n"); @@ -3138,6 +3142,7 @@ static void usbpd_sm(struct work_struct *w) memcpy(&pd->battery_sts_dobj, rx_msg->payload, sizeof(pd->battery_sts_dobj)); complete(&pd->is_ready); + break; } else if (IS_CTRL(rx_msg, MSG_GET_SOURCE_CAP_EXTENDED)) { handle_get_src_cap_extended(pd); } else if (IS_EXT(rx_msg, MSG_GET_BATTERY_CAP)) { -- GitLab From 70021e9eaa454591528ea1b74893b1df2f5b023d Mon Sep 17 00:00:00 2001 From: Mohammed Javid Date: Fri, 5 Jul 2019 20:51:52 +0530 Subject: [PATCH 0876/1121] msm: ipa: wdi3: Update with right sequence Make sure gsi channel is started after all ep config are in place as otherwise it would lead ipa-hw to bad state. Change-Id: Ib15f3e04376d61dbe899ea5395e65871d444c2a1 Signed-off-by: Mohammed Javid --- drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c | 44 +++++++++++--------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c b/drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c index bea91b734aae..9fd231fbe967 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c @@ -731,20 +731,33 @@ int ipa3_enable_wdi3_pipes(int ipa_ep_idx_tx, int ipa_ep_idx_rx) IPA_ACTIVE_CLIENTS_INC_EP(ipa3_get_client_mapping(ipa_ep_idx_tx)); + /* enable data path */ + result = ipa3_enable_data_path(ipa_ep_idx_rx); + if (result) { + IPAERR("enable data path failed res=%d clnt=%d\n", result, + ipa_ep_idx_rx); + goto exit; + } + + result = ipa3_enable_data_path(ipa_ep_idx_tx); + if (result) { + IPAERR("enable data path failed res=%d clnt=%d\n", result, + ipa_ep_idx_tx); + goto fail_enable_path1; + } + /* start gsi tx channel */ result = gsi_start_channel(ep_tx->gsi_chan_hdl); if (result) { IPAERR("failed to start gsi tx channel\n"); - result = -EFAULT; - goto exit; + goto fail_enable_path2; } /* start gsi rx channel */ result = gsi_start_channel(ep_rx->gsi_chan_hdl); if (result) { IPAERR("failed to start gsi rx channel\n"); - result = -EFAULT; - goto exit; + goto fail_start_channel1; } /* start uC gsi dbg stats monitor */ if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5 || @@ -761,23 +774,14 @@ int ipa3_enable_wdi3_pipes(int ipa_ep_idx_tx, int ipa_ep_idx_rx) ipa3_uc_debug_stats_alloc( ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_WDI3]); } - /* enable data path */ - result = ipa3_enable_data_path(ipa_ep_idx_rx); - if (result) { - IPAERR("enable data path failed res=%d clnt=%d.\n", result, - ipa_ep_idx_rx); - result = -EFAULT; - goto exit; - } - - result = ipa3_enable_data_path(ipa_ep_idx_tx); - if (result) { - IPAERR("enable data path failed res=%d clnt=%d.\n", result, - ipa_ep_idx_tx); - result = -EFAULT; - goto exit; - } + goto exit; +fail_start_channel1: + gsi_stop_channel(ep_tx->gsi_chan_hdl); +fail_enable_path2: + ipa3_disable_data_path(ipa_ep_idx_tx); +fail_enable_path1: + ipa3_disable_data_path(ipa_ep_idx_rx); exit: IPA_ACTIVE_CLIENTS_DEC_EP(ipa3_get_client_mapping(ipa_ep_idx_tx)); return result; -- GitLab From 7a6155807d1fc106ddb3e8839aa13e5709023843 Mon Sep 17 00:00:00 2001 From: Ajay Agarwal Date: Tue, 16 Jul 2019 21:13:34 +0530 Subject: [PATCH 0877/1121] ARM: dts: msm: Use sdmshrike regulators for SA8195P ADP STAR SA8195P ADP STAR platform uses sa8195-pmic regulator and GPIO definitions but the references to these nodes by various systems have not been updated yet from sdmshrike regulator/gpio ones. This is failing kernel compilation for sa8195p-adp-star platform. Fix this by using sdmshrike regulators for SA8195P ADP STAR for now until the LDO/gpio references are updated properly. Change-Id: I804861357ed98f7191535e92e99103e824f3f291 Signed-off-by: Ajay Agarwal --- arch/arm64/boot/dts/qcom/sa8195p-adp-star.dtsi | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sa8195p-adp-star.dtsi b/arch/arm64/boot/dts/qcom/sa8195p-adp-star.dtsi index e404382fdfbd..02e46d986949 100644 --- a/arch/arm64/boot/dts/qcom/sa8195p-adp-star.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8195p-adp-star.dtsi @@ -11,7 +11,6 @@ */ #include -#include "sa8195-pmic.dtsi" &qupv3_se0_spi { status = "ok"; -- GitLab From 60283b03864071add183343344f688f3549013b9 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Thu, 9 May 2019 20:35:09 +0530 Subject: [PATCH 0878/1121] msm: vidc: Ensure size of the data available before typecasting Ensure the available data with in the packet size before type casting from a smaller data type to larger data type in order to avoid information leak or packet out of boundary access. Change-Id: I8614a8b3f930c87af8aa49f77ea9d768a73ea203 Signed-off-by: Priyanka Gujjula --- .../platform/msm/vidc/hfi_response_handler.c | 30 +++++++++++++------ drivers/media/platform/msm/vidc/vidc_hfi.h | 2 +- .../media/platform/msm/vidc/vidc_hfi_helper.h | 1 - 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c index 435121a640f8..cb804b175024 100644 --- a/drivers/media/platform/msm/vidc/hfi_response_handler.c +++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c @@ -371,6 +371,12 @@ static int hfi_process_evt_release_buffer_ref(u32 device_id, "hal_process_session_init_done: bad_pkt_size\n"); return -E2BIG; } + if (pkt->size < sizeof(struct hfi_msg_event_notify_packet) - sizeof(u32) + + sizeof(struct hfi_msg_release_buffer_ref_event_packet)) { + dprintk(VIDC_ERR, "%s: bad_pkt_size: %d\n", + __func__, pkt->size); + return -E2BIG; + } data = (struct hfi_msg_release_buffer_ref_event_packet *) pkt->rg_ext_event_data; @@ -1567,15 +1573,13 @@ static int hfi_process_session_etb_done(u32 device_id, struct hfi_msg_session_empty_buffer_done_packet *pkt = _pkt; struct msm_vidc_cb_data_done data_done = {0}; struct hfi_picture_type *hfi_picture_type = NULL; + u32 is_sync_frame; dprintk(VIDC_DBG, "RECEIVED: SESSION_ETB_DONE[%#x]\n", pkt->session_id); if (!pkt || pkt->size < - sizeof(struct hfi_msg_session_empty_buffer_done_packet)) { - dprintk(VIDC_ERR, - "hal_process_session_etb_done: bad_pkt_size\n"); - return -E2BIG; - } + sizeof(struct hfi_msg_session_empty_buffer_done_packet)) + goto bad_packet_size; data_done.device_id = device_id; data_done.session_id = (void *)(uintptr_t)pkt->session_id; @@ -1595,8 +1599,13 @@ static int hfi_process_session_etb_done(u32 device_id, data_done.input_done.extra_data_buffer = pkt->extra_data_buffer; data_done.input_done.status = hfi_map_err_status(pkt->error_type); - hfi_picture_type = (struct hfi_picture_type *)&pkt->rgData[0]; - if (hfi_picture_type->is_sync_frame) { + is_sync_frame = pkt->rgData[0]; + if (is_sync_frame) { + if (pkt->size < + sizeof(struct hfi_msg_session_empty_buffer_done_packet) + + sizeof(struct hfi_picture_type)) + goto bad_packet_size; + hfi_picture_type = (struct hfi_picture_type *)&pkt->rgData[1]; if (hfi_picture_type->picture_type) data_done.input_done.flags = hfi_picture_type->picture_type; @@ -1613,6 +1622,10 @@ static int hfi_process_session_etb_done(u32 device_id, info->response.data = data_done; return 0; +bad_packet_size: + dprintk(VIDC_ERR, "%s: bad_pkt_size: %d\n", + __func__, pkt ? pkt->size : 0); + return -E2BIG; } static int hfi_process_session_ftb_done( @@ -1847,8 +1860,7 @@ static int hfi_process_session_rel_buf_done(u32 device_id, cmd_done.size = sizeof(struct msm_vidc_cb_cmd_done); cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; cmd_done.status = hfi_map_err_status(pkt->error_type); - cmd_done.data.buffer_info = - *(struct hal_buffer_info *)pkt->rg_buffer_info; + cmd_done.data.buffer_info.buffer_addr = *pkt->rg_buffer_info; cmd_done.size = sizeof(struct hal_buffer_info); info->response_type = HAL_SESSION_RELEASE_BUFFER_DONE; diff --git a/drivers/media/platform/msm/vidc/vidc_hfi.h b/drivers/media/platform/msm/vidc/vidc_hfi.h index aa0cd4ae7779..8a1a7cec757b 100644 --- a/drivers/media/platform/msm/vidc/vidc_hfi.h +++ b/drivers/media/platform/msm/vidc/vidc_hfi.h @@ -613,7 +613,7 @@ struct hfi_msg_session_empty_buffer_done_packet { u32 extra_data_buffer; u32 flags; struct hfi_frame_cr_stats_type ubwc_cr_stats; - u32 rgData[0]; + u32 rgData[1]; }; struct hfi_msg_session_fill_buffer_done_compressed_packet { diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h index a49e8fd7f9f5..b9c2e90313d0 100644 --- a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h +++ b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h @@ -670,7 +670,6 @@ struct hfi_bit_depth { }; struct hfi_picture_type { - u32 is_sync_frame; u32 picture_type; }; -- GitLab From b9aa48d6f7c89312a0122623811b3e85527540f7 Mon Sep 17 00:00:00 2001 From: YUE CHEN Date: Mon, 15 Jul 2019 12:08:31 +0800 Subject: [PATCH 0879/1121] msm: ais: change packet fmt to 0 for plain16 The packet format only support plain128 for RDI0/1/2/3. Change-Id: Id14dba00969c7680d7f79d7fdeeea43a4a0b8b01 Signed-off-by: YUE CHEN --- .../isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c index b1751a16e101..dcb77bee29c0 100644 --- a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c +++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c @@ -947,24 +947,17 @@ static int cam_vfe_bus_acquire_wm( case CAM_FORMAT_MIPI_RAW_14: case CAM_FORMAT_MIPI_RAW_16: case CAM_FORMAT_MIPI_RAW_20: + case CAM_FORMAT_PLAIN16_10: + case CAM_FORMAT_PLAIN16_12: + case CAM_FORMAT_PLAIN16_14: + case CAM_FORMAT_PLAIN16_16: case CAM_FORMAT_PLAIN128: + /*repacking is done in CSID for PLAIN*/ rsrc_data->pack_fmt = 0x0; break; case CAM_FORMAT_PLAIN8: rsrc_data->pack_fmt = 0x1; break; - case CAM_FORMAT_PLAIN16_10: - rsrc_data->pack_fmt = 0x2; - break; - case CAM_FORMAT_PLAIN16_12: - rsrc_data->pack_fmt = 0x3; - break; - case CAM_FORMAT_PLAIN16_14: - rsrc_data->pack_fmt = 0x4; - break; - case CAM_FORMAT_PLAIN16_16: - rsrc_data->pack_fmt = 0x5; - break; case CAM_FORMAT_PLAIN64: rsrc_data->pack_fmt = 0xA; break; -- GitLab From 4b31f8989c48ccd81e6dc0fc98d4e1282406936d Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Tue, 18 Jun 2019 19:25:45 +0530 Subject: [PATCH 0880/1121] ARM: dts: msm: Make wakegic as interrupt parent for subsystem on trinket Each subsystem enroll with PIL framework, they register their interrupt as wake up capable to APSS. The IRQCHIP_SKIP_SET_WAKE flag in the gic-v3 driver was missing which will give warning as "Unbalanced IRQ 19 wake disable". But, later after WakeGIC change in the DT and in the IRQCHIP_SKIP_SET_WAKE flag set in mpm driver, this does not required to be set in gic-v3 driver. If we make dt change by making wakegic as parent for the subsystem interrupts to APSS, it will fix the warning. Change-Id: I83a01cf27b452f6c66d8cb72d891e1ee42c954d0 Signed-off-by: Mukesh Ojha --- arch/arm64/boot/dts/qcom/trinket.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/trinket.dtsi b/arch/arm64/boot/dts/qcom/trinket.dtsi index 12df0695e95d..83ae25fdc9e8 100644 --- a/arch/arm64/boot/dts/qcom/trinket.dtsi +++ b/arch/arm64/boot/dts/qcom/trinket.dtsi @@ -1188,7 +1188,7 @@ qcom,complete-ramdump; /* Inputs from mss */ - interrupts-extended = <&intc 0 307 1>, + interrupts-extended = <&wakegic 0 307 1>, <&modem_smp2p_in 0 0>, <&modem_smp2p_in 2 0>, <&modem_smp2p_in 1 0>, @@ -1312,7 +1312,7 @@ qcom,complete-ramdump; /* Inputs from lpass */ - interrupts-extended = <&intc 0 396 1>, + interrupts-extended = <&wakegic 0 396 1>, <&adsp_smp2p_in 0 0>, <&adsp_smp2p_in 2 0>, <&adsp_smp2p_in 1 0>, @@ -1352,7 +1352,7 @@ qcom,complete-ramdump; /* Inputs from turing */ - interrupts-extended = <&intc 0 265 1>, + interrupts-extended = <&wakegic 0 265 1>, <&cdsp_smp2p_in 0 0>, <&cdsp_smp2p_in 2 0>, <&cdsp_smp2p_in 1 0>, -- GitLab From 226c3cd33e2884a21eb707e39b2c9f72ccc036de Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Wed, 17 Jul 2019 13:05:04 +0530 Subject: [PATCH 0881/1121] ARM: dts: msm: fix video node name for atoll Fix the compatibility string for the video node to match with video driver. Change-Id: Ice91d5f0e3c23873095a8e4b9f20af4988b03ce3 Signed-off-by: Dikshita Agarwal --- arch/arm64/boot/dts/qcom/atoll-vidc.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/atoll-vidc.dtsi b/arch/arm64/boot/dts/qcom/atoll-vidc.dtsi index 24e21d0080ca..ec3b77ba77f2 100644 --- a/arch/arm64/boot/dts/qcom/atoll-vidc.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll-vidc.dtsi @@ -16,7 +16,7 @@ &soc { msm_vidc: qcom,vidc@aa00000 { - compatible = "qcom,msm-vidc", "qcom,atoll"; + compatible = "qcom,msm-vidc", "qcom,atoll-vidc"; status = "ok"; reg = <0xaa00000 0x200000>; interrupts = ; -- GitLab From 061b74b210eae1181fd52345be9d7129a97b1f24 Mon Sep 17 00:00:00 2001 From: Ramesh V Date: Fri, 12 Jul 2019 10:19:13 +0530 Subject: [PATCH 0882/1121] msm: camera_v2: isp: Double stats ub size To prevent stats overflow in zoom cases, double the stats ub size. Change-Id: Icb1989a5dc58ba574fc09242b402d542cfe38639 Signed-off-by: Ramesh V --- .../platform/msm/camera_v2/isp/msm_isp47.c | 2 +- .../platform/msm/camera_v2/isp/msm_isp48.c | 20 +++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c index 5d77e7565dcc..d9ef0ea1513a 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c @@ -38,7 +38,7 @@ #define VFE47_STATS_BURST_LEN 3 #define VFE47_UB_SIZE_VFE0 2048 #define VFE47_UB_SIZE_VFE1 1536 -#define VFE47_UB_STATS_SIZE 144 +#define VFE47_UB_STATS_SIZE 288 #define MSM_ISP47_TOTAL_IMAGE_UB_VFE0 (VFE47_UB_SIZE_VFE0 - VFE47_UB_STATS_SIZE) #define MSM_ISP47_TOTAL_IMAGE_UB_VFE1 (VFE47_UB_SIZE_VFE1 - VFE47_UB_STATS_SIZE) #define VFE47_WM_BASE(idx) (0xA0 + 0x2C * idx) diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp48.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp48.c index d23c7caf004b..80f98182d624 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp48.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp48.c @@ -30,7 +30,7 @@ #define MSM_VFE48_BUS_CLIENT_INIT 0xABAB #define VFE48_STATS_BURST_LEN 3 #define VFE48_UB_SIZE_VFE 2048 /* 2048 * 256 bits = 64KB */ -#define VFE48_UB_STATS_SIZE 144 +#define VFE48_UB_STATS_SIZE 288 #define MSM_ISP48_TOTAL_IMAGE_UB_VFE (VFE48_UB_SIZE_VFE - VFE48_UB_STATS_SIZE) @@ -321,15 +321,15 @@ void msm_vfe48_stats_cfg_ub(struct vfe_device *vfe_dev) int i; uint32_t ub_offset = 0, stats_burst_len; uint32_t ub_size[VFE47_NUM_STATS_TYPE] = { - 16, /* MSM_ISP_STATS_HDR_BE */ - 16, /* MSM_ISP_STATS_BG */ - 16, /* MSM_ISP_STATS_BF */ - 16, /* MSM_ISP_STATS_HDR_BHIST */ - 16, /* MSM_ISP_STATS_RS */ - 16, /* MSM_ISP_STATS_CS */ - 16, /* MSM_ISP_STATS_IHIST */ - 16, /* MSM_ISP_STATS_BHIST */ - 16, /* MSM_ISP_STATS_AEC_BG */ + 32, /* MSM_ISP_STATS_HDR_BE */ + 32, /* MSM_ISP_STATS_BG */ + 32, /* MSM_ISP_STATS_BF */ + 32, /* MSM_ISP_STATS_HDR_BHIST */ + 32, /* MSM_ISP_STATS_RS */ + 32, /* MSM_ISP_STATS_CS */ + 32, /* MSM_ISP_STATS_IHIST */ + 32, /* MSM_ISP_STATS_BHIST */ + 32, /* MSM_ISP_STATS_AEC_BG */ }; stats_burst_len = VFE48_STATS_BURST_LEN; -- GitLab From 962b3d7f1f15b08cea010085ecc9539c01a9ae24 Mon Sep 17 00:00:00 2001 From: lijuang Date: Mon, 15 Jul 2019 21:53:34 +0800 Subject: [PATCH 0883/1121] AndroidKernel: Fixed compile errors after enable boot header version 2 Look for vendor under arch/arm64/boot/dts before creating a dtb.img. The target maybe doesn't have vendor folder. Change-Id: I872f6f7f2d4c7f46c5d871d129403c733896832b Signed-off-by: lijuang --- AndroidKernel.mk | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/AndroidKernel.mk b/AndroidKernel.mk index e17150c54e53..e19c5eb406a5 100644 --- a/AndroidKernel.mk +++ b/AndroidKernel.mk @@ -194,7 +194,11 @@ $(KERNEL_HEADERS_INSTALL): $(KERNEL_OUT) # Creating a dtb.img once the kernel is compiled if TARGET_KERNEL_APPEND_DTB is set to be false $(INSTALLED_DTBIMAGE_TARGET): $(TARGET_PREBUILT_INT_KERNEL) - cat $(KERNEL_OUT)/arch/$(KERNEL_ARCH)/boot/dts/vendor/qcom/*.dtb > $@ + $(hide) if [ -d "$(KERNEL_OUT)/arch/$(KERNEL_ARCH)/boot/dts/vendor/" ]; then \ + cat $(KERNEL_OUT)/arch/$(KERNEL_ARCH)/boot/dts/vendor/qcom/*.dtb > $@; \ + else \ + cat $(KERNEL_OUT)/arch/$(KERNEL_ARCH)/boot/dts/qcom/*.dtb > $@; \ + fi .PHONY: kerneltags kerneltags: $(KERNEL_OUT) $(KERNEL_CONFIG) -- GitLab From ea4e85bae49e7a6840201704cc5bfa46076809b7 Mon Sep 17 00:00:00 2001 From: Charan Teja Reddy Date: Tue, 16 Jul 2019 16:54:31 +0530 Subject: [PATCH 0884/1121] zram: fix race condition while returning zram_entry refcount With deduplication enabled, the duplicated zram objects are tracked using the zram_entry backed by a refcount. The race condition while decrementing the refcount through zram_dedup_put() is as follows: Say Task A and task B share the same object and thus the zram_entry->refcount = 2. Task A Task B zram_dedup_put zram_dedup_put spin_lock(&hash->lock); entry->refcount--; (Now it is 1) spin_unlock(&hash->lock); spin_lock(&hash->lock); entry->refcount--; (Now it is 0) spin_unlock(&hash->lock); return entry->refcount return entry->refcount We return 0 in above steps thus leading to double free of the handle, which is a slab object. Change-Id: I8dd9bad27140a6e3a295905bf4411050d8eac931 Signed-off-by: Charan Teja Reddy --- drivers/block/zram/zram_dedup.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/block/zram/zram_dedup.c b/drivers/block/zram/zram_dedup.c index 14c4988f8ff7..e441289fff81 100644 --- a/drivers/block/zram/zram_dedup.c +++ b/drivers/block/zram/zram_dedup.c @@ -92,13 +92,14 @@ static unsigned long zram_dedup_put(struct zram *zram, { struct zram_hash *hash; u32 checksum; + unsigned long val; checksum = entry->checksum; hash = &zram->hash[checksum % zram->hash_size]; spin_lock(&hash->lock); - entry->refcount--; + val = --entry->refcount; if (!entry->refcount) rb_erase(&entry->rb_node, &hash->rb_root); else @@ -106,7 +107,7 @@ static unsigned long zram_dedup_put(struct zram *zram, spin_unlock(&hash->lock); - return entry->refcount; + return val; } static struct zram_entry *__zram_dedup_get(struct zram *zram, -- GitLab From 31b4ae6f99d80ce06e39630f7f81b39ee6d25d3d Mon Sep 17 00:00:00 2001 From: Raghavendra Kakarla Date: Wed, 17 Jul 2019 14:46:53 +0530 Subject: [PATCH 0885/1121] ARM: dts: msm: Correct active tcs count for atoll Atoll does not have dedicated active tcs. correct active tcs count for display rsc node. Change-Id: I6322cd3aba0e3d636e22ff41c6a5c5f408de40ce Signed-off-by: Raghavendra Kakarla --- arch/arm64/boot/dts/qcom/atoll.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index 1a729e25c51e..828e908e73d9 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -2019,7 +2019,7 @@ qcom,drv-id = <0>; qcom,tcs-config = , , - , + , ; }; -- GitLab From 2419866aa68207ff5ddbac0262eb7ecb7ed22bb9 Mon Sep 17 00:00:00 2001 From: YUE CHEN Date: Thu, 11 Jul 2019 10:33:03 +0800 Subject: [PATCH 0886/1121] msm: ais: enable/disable rdi separately When multiple clients open different rdi paths on the same DES, if one of them stop camera, it will cause the other client's camera preview to stop. So open per RDI path, just enable the individual irq mask. Change-Id: I4d5d30129a5911a73eb135ef2cc637e8ddd45782 Signed-off-by: YUE CHEN --- .../isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c | 43 ++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c index a26c11264d2c..43531c173f89 100644 --- a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c +++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c @@ -23,6 +23,7 @@ #include "cam_vfe_top.h" #include "cam_ife_hw_mgr.h" #include "cam_debug_util.h" +#include "cam_vfe_hw_intf.h" static const char drv_name[] = "vfe"; static uint32_t irq_reg_offset[CAM_IFE_IRQ_REGISTERS_MAX] = { @@ -51,6 +52,26 @@ static uint32_t rdi_irq_reg_mask[CAM_IFE_IRQ_REGISTERS_MAX] = { 0x00000000, }; +static uint32_t rdi0_irq_reg_mask[CAM_IFE_IRQ_REGISTERS_MAX] = { + 0x08000020, + 0x00000000, +}; + +static uint32_t rdi1_irq_reg_mask[CAM_IFE_IRQ_REGISTERS_MAX] = { + 0x10000040, + 0x00000000, +}; + +static uint32_t rdi2_irq_reg_mask[CAM_IFE_IRQ_REGISTERS_MAX] = { + 0x20000080, + 0x00000000, +}; + +static uint32_t rdi3_irq_reg_mask[CAM_IFE_IRQ_REGISTERS_MAX] = { + 0x40000100, + 0x00000000, +}; + static uint32_t top_reset_irq_reg_mask[CAM_IFE_IRQ_REGISTERS_MAX] = { 0x80000000, 0x00000000, @@ -579,6 +600,7 @@ int cam_vfe_start(void *hw_priv, void *start_args, uint32_t arg_size) struct cam_vfe_hw_core_info *core_info = NULL; struct cam_hw_info *vfe_hw = hw_priv; struct cam_isp_resource_node *isp_res; + uint32_t *evt_bit_mask_arr = NULL; int rc = 0; if (!hw_priv || !start_args || @@ -620,16 +642,35 @@ int cam_vfe_start(void *hw_priv, void *start_args, uint32_t arg_size) if (isp_res->irq_handle < 1) rc = -ENOMEM; } else if (isp_res->rdi_only_ctx) { + switch (isp_res->res_id) { + case CAM_ISP_HW_VFE_IN_RDI0: + evt_bit_mask_arr = rdi0_irq_reg_mask; + break; + case CAM_ISP_HW_VFE_IN_RDI1: + evt_bit_mask_arr = rdi1_irq_reg_mask; + break; + case CAM_ISP_HW_VFE_IN_RDI2: + evt_bit_mask_arr = rdi2_irq_reg_mask; + break; + case CAM_ISP_HW_VFE_IN_RDI3: + evt_bit_mask_arr = rdi3_irq_reg_mask; + break; + default: + evt_bit_mask_arr = rdi_irq_reg_mask; + break; + } + isp_res->irq_handle = cam_irq_controller_subscribe_irq( core_info->vfe_irq_controller, CAM_IRQ_PRIORITY_1, - rdi_irq_reg_mask, + evt_bit_mask_arr, &core_info->irq_payload, cam_vfe_irq_top_half, cam_ife_mgr_do_tasklet, isp_res->tasklet_info, &tasklet_bh_api); + if (isp_res->irq_handle < 1) rc = -ENOMEM; } -- GitLab From 0c30b8d2bd247494f006b073227e4b05ba50258c Mon Sep 17 00:00:00 2001 From: Lijuan Gao Date: Wed, 10 Jul 2019 21:27:13 +0800 Subject: [PATCH 0887/1121] ARM: dts: msm: Add initial qrd support for atoll Add device tree support for atoll on qrd platforms. Change-Id: Id49128f167b201b473042de37618779481a882b7 Signed-off-by: Lijuan Gao --- .../devicetree/bindings/arm/msm/msm.txt | 1 + arch/arm64/boot/dts/qcom/Makefile | 3 +++ .../arm64/boot/dts/qcom/atoll-qrd-overlay.dts | 23 +++++++++++++++++++ arch/arm64/boot/dts/qcom/atoll-qrd.dts | 22 ++++++++++++++++++ arch/arm64/boot/dts/qcom/atoll-qrd.dtsi | 14 +++++++++++ 5 files changed, 63 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/atoll-qrd-overlay.dts create mode 100644 arch/arm64/boot/dts/qcom/atoll-qrd.dts create mode 100644 arch/arm64/boot/dts/qcom/atoll-qrd.dtsi diff --git a/Documentation/devicetree/bindings/arm/msm/msm.txt b/Documentation/devicetree/bindings/arm/msm/msm.txt index ed31d3edb60c..850bb51db595 100644 --- a/Documentation/devicetree/bindings/arm/msm/msm.txt +++ b/Documentation/devicetree/bindings/arm/msm/msm.txt @@ -223,5 +223,6 @@ compatible = "qcom,trinket-idp" compatible = "qcom,trinket-qrd" compatible = "qcom,atoll-rumi" compatible = "qcom,atoll-idp" +compatible = "qcom,atoll-qrd" compatible = "qcom,qcs610-iot" compatible = "qcom,qcs410-iot" diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index 33ecfef5ebbc..f0f397929b8c 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -247,12 +247,15 @@ endif ifeq ($(CONFIG_BUILD_ARM64_DT_OVERLAY),y) dtbo-$(CONFIG_ARCH_ATOLL) += \ atoll-idp-overlay.dtbo\ + atoll-qrd-overlay.dtbo\ atoll-rumi-overlay.dtbo atoll-idp-overlay.dtbo-base := atoll.dtb +atoll-qrd-overlay.dtbo-base := atoll.dtb atoll-rumi-overlay.dtbo-base := atoll.dtb else dtb-$(CONFIG_ARCH_ATOLL) += atoll-idp.dtb\ + atoll-qrd.dtb\ atoll-rumi.dtb endif diff --git a/arch/arm64/boot/dts/qcom/atoll-qrd-overlay.dts b/arch/arm64/boot/dts/qcom/atoll-qrd-overlay.dts new file mode 100644 index 000000000000..a041d8a82236 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/atoll-qrd-overlay.dts @@ -0,0 +1,23 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; +/plugin/; + +#include "atoll-qrd.dtsi" + +/ { + model = "QRD"; + compatible = "qcom,atoll-qrd", "qcom,atoll", "qcom,qrd"; + qcom,msm-id = <407 0x0>; + qcom,board-id = <0x1000B 0>; +}; diff --git a/arch/arm64/boot/dts/qcom/atoll-qrd.dts b/arch/arm64/boot/dts/qcom/atoll-qrd.dts new file mode 100644 index 000000000000..9a61533fdfec --- /dev/null +++ b/arch/arm64/boot/dts/qcom/atoll-qrd.dts @@ -0,0 +1,22 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "atoll.dtsi" +#include "atoll-qrd.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. ATOLL PM6150 QRD"; + compatible = "qcom,atoll-qrd", "qcom,atoll", "qcom,qrd"; + qcom,board-id = <0x1000B 0>; +}; diff --git a/arch/arm64/boot/dts/qcom/atoll-qrd.dtsi b/arch/arm64/boot/dts/qcom/atoll-qrd.dtsi new file mode 100644 index 000000000000..9132ac26e635 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/atoll-qrd.dtsi @@ -0,0 +1,14 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { +}; -- GitLab From 6068dc23b36aadb2ec032cd50ab114392720df6f Mon Sep 17 00:00:00 2001 From: Anmolpreet Kaur Date: Mon, 15 Jul 2019 20:02:56 +0530 Subject: [PATCH 0888/1121] ARM: dts: msm: Enable AVB system property on atoll Enable avb_version and add android,vbmeta for setting system properties for verified boot on atoll target. Change-Id: Ic7885e27bb946ec2c6ff7fb87a478259a032ce88 Signed-off-by: Anmolpreet Kaur --- arch/arm64/boot/dts/qcom/atoll.dtsi | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index 1a729e25c51e..b8e53476c150 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -454,6 +454,10 @@ firmware: firmware { android { compatible = "android,firmware"; + vbmeta { + compatible = "android,vbmeta"; + parts = "vbmeta,boot,system,vendor,dtbo"; + }; fstab { compatible = "android,fstab"; vendor { @@ -461,7 +465,7 @@ dev = "/dev/block/platform/soc/7c4000.sdhci/by-name/vendor"; type = "ext4"; mnt_flags = "ro,barrier=1,discard"; - fsmgr_flags = "wait,slotselect"; + fsmgr_flags = "wait,slotselect,avb"; status = "ok"; }; }; -- GitLab From ba5bc0eab78992d4c76015461712624fad111a3f Mon Sep 17 00:00:00 2001 From: Sandeep Singh Date: Fri, 12 Jul 2019 19:09:45 +0530 Subject: [PATCH 0889/1121] icnss: Check firmware status to ignore QMI handshake In case of Full Disk Encryption feature enablement, all core class services including qrtr service gets restarted. When qrtr service started wlan platform driver starts handshake with firmware. In this case firmware rejects handshake request from platform driver as QMI is out of sync between firmware and platform driver. In order avoid handshake between platform driver and firmware if it is already done, check firmware status during indication registration request. Change-Id: If5e2a9e90427f18304b1a9369d922f1021a9ab65 Signed-off-by: Sandeep Singh --- drivers/soc/qcom/icnss.c | 19 +++++++++++++++++++ drivers/soc/qcom/icnss_qmi.c | 11 ++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c index 4a65f9079c4e..126a31435df9 100644 --- a/drivers/soc/qcom/icnss.c +++ b/drivers/soc/qcom/icnss.c @@ -985,6 +985,10 @@ static int icnss_driver_event_server_arrive(void *data) ret = wlfw_ind_register_send_sync_msg(penv); if (ret < 0) { + if (ret == -EALREADY) { + ret = 0; + goto qmi_registered; + } ignore_assert = true; goto err_power_on; } @@ -1044,6 +1048,7 @@ static int icnss_driver_event_server_arrive(void *data) icnss_clear_server(penv); fail: ICNSS_ASSERT(ignore_assert); +qmi_registered: return ret; } @@ -2942,6 +2947,15 @@ static void icnss_allow_recursive_recovery(struct device *dev) icnss_pr_info("Recursive recovery allowed for WLAN\n"); } +static void icnss_disallow_recursive_recovery(struct device *dev) +{ + struct icnss_priv *priv = dev_get_drvdata(dev); + + priv->allow_recursive_recovery = false; + + icnss_pr_info("Recursive recovery disallowed for WLAN\n"); +} + static ssize_t icnss_fw_debug_write(struct file *fp, const char __user *user_buf, size_t count, loff_t *off) @@ -2993,6 +3007,9 @@ static ssize_t icnss_fw_debug_write(struct file *fp, case 4: icnss_allow_recursive_recovery(&priv->pdev->dev); break; + case 5: + icnss_disallow_recursive_recovery(&priv->pdev->dev); + break; default: return -EINVAL; } @@ -3649,6 +3666,8 @@ static int icnss_probe(struct platform_device *pdev) priv->vreg_info = icnss_vreg_info; + icnss_allow_recursive_recovery(dev); + if (of_property_read_bool(pdev->dev.of_node, "qcom,icnss-adc_tm")) { ret = icnss_get_vbatt_info(priv); if (ret == -EPROBE_DEFER) diff --git a/drivers/soc/qcom/icnss_qmi.c b/drivers/soc/qcom/icnss_qmi.c index c35149d4a2c1..57a30421d9da 100644 --- a/drivers/soc/qcom/icnss_qmi.c +++ b/drivers/soc/qcom/icnss_qmi.c @@ -315,14 +315,23 @@ int wlfw_ind_register_send_sync_msg(struct icnss_priv *priv) priv->stats.ind_register_resp++; + if (resp->fw_status_valid && + (resp->fw_status & QMI_WLFW_ALREADY_REGISTERED_V01)) { + ret = -EALREADY; + icnss_pr_dbg("WLFW already registered\n"); + goto qmi_registered; + } + kfree(resp); kfree(req); + return 0; out: + priv->stats.ind_register_err++; +qmi_registered: kfree(resp); kfree(req); - priv->stats.ind_register_err++; return ret; } -- GitLab From e2653fbd747622ca150622f0158ff5ee1ea1d37a Mon Sep 17 00:00:00 2001 From: Arun KS Date: Fri, 28 Jun 2019 09:25:52 +0530 Subject: [PATCH 0890/1121] pinctrl: qcom: Save and restore TLMM registers Save and restore TLMM registers to make hibernation work. Uses power management notifiers for differentiating between suspend to RAM and suspend to disk(hibernation) operations during system suspend and restore. Change-Id: I4042054fc04e17da07eaab3dc36dbac58d1a1b24 Signed-off-by: Ankur Saxena Signed-off-by: Arun KS --- drivers/pinctrl/qcom/pinctrl-msm.c | 170 ++++++++++++++++++++++++++++- drivers/pinctrl/qcom/pinctrl-msm.h | 6 +- 2 files changed, 174 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c index e9c2795615be..034d9d4c5674 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013, Sony Mobile Communications AB. - * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -40,10 +40,27 @@ #include "../pinconf.h" #include "pinctrl-msm.h" #include "../pinctrl-utils.h" +#include +#ifdef CONFIG_HIBERNATION +#include +#endif #define MAX_NR_GPIO 300 #define PS_HOLD_OFFSET 0x820 +#ifdef CONFIG_HIBERNATION +struct msm_gpio_regs { + u32 ctl_reg; + u32 io_reg; + u32 intr_cfg_reg; + u32 intr_status_reg; +}; + +struct msm_tile { + u32 dir_con_regs[8]; +}; +#endif + /** * struct msm_pinctrl - state for a pinctrl-msm device * @dev: device handle. @@ -80,6 +97,10 @@ struct msm_pinctrl { #endif phys_addr_t spi_cfg_regs; phys_addr_t spi_cfg_end; +#ifdef CONFIG_HIBERNATION + struct msm_gpio_regs *gpio_regs; + struct msm_tile *msm_tile_regs; +#endif }; static struct msm_pinctrl *msm_pinctrl_data; @@ -1786,8 +1807,144 @@ static void msm_pinctrl_setup_pm_reset(struct msm_pinctrl *pctrl) } #ifdef CONFIG_PM +#ifdef CONFIG_HIBERNATION +static bool hibernation; + +static int pinctrl_hibernation_notifier(struct notifier_block *nb, + unsigned long event, void *dummy) +{ + struct msm_pinctrl *pctrl = msm_pinctrl_data; + const struct msm_pinctrl_soc_data *soc = pctrl->soc; + + if (event == PM_HIBERNATION_PREPARE) { + pctrl->gpio_regs = kcalloc(soc->ngroups, + sizeof(*pctrl->gpio_regs), GFP_KERNEL); + if (pctrl->gpio_regs == NULL) + return -ENOMEM; + + if (soc->tile_count) { + pctrl->msm_tile_regs = kcalloc(soc->tile_count, + sizeof(*pctrl->msm_tile_regs), GFP_KERNEL); + if (pctrl->msm_tile_regs == NULL) { + kfree(pctrl->gpio_regs); + return -ENOMEM; + } + } + hibernation = true; + } else if (event == PM_POST_HIBERNATION) { + kfree(pctrl->gpio_regs); + kfree(pctrl->msm_tile_regs); + pctrl->gpio_regs = NULL; + pctrl->msm_tile_regs = NULL; + hibernation = false; + } + return NOTIFY_OK; +} + +static struct notifier_block pinctrl_notif_block = { + .notifier_call = pinctrl_hibernation_notifier, +}; + +static int msm_pinctrl_hibernation_suspend(void) +{ + const struct msm_pingroup *pgroup; + struct msm_pinctrl *pctrl = msm_pinctrl_data; + const struct msm_pinctrl_soc_data *soc = pctrl->soc; + void __iomem *base = NULL; + void __iomem *tile_addr = NULL; + u32 i, j; + + /* Save direction conn registers for hmss */ + for (i = 0; i < soc->tile_count; i++) { + base = reassign_pctrl_reg(soc, i); + tile_addr = base + soc->dir_conn_addr[i]; + for (j = 0; j < 8; j++) + pctrl->msm_tile_regs[i].dir_con_regs[j] = + readl_relaxed(tile_addr + j*4); + } + + /* All normal gpios will have common registers, first save them */ + for (i = 0; i < soc->ngpios; i++) { + pgroup = &soc->groups[i]; + base = reassign_pctrl_reg(soc, i); + pctrl->gpio_regs[i].ctl_reg = + readl_relaxed(base + pgroup->ctl_reg); + pctrl->gpio_regs[i].io_reg = + readl_relaxed(base + pgroup->io_reg); + pctrl->gpio_regs[i].intr_cfg_reg = + readl_relaxed(base + pgroup->intr_cfg_reg); + pctrl->gpio_regs[i].intr_status_reg = + readl_relaxed(base + pgroup->intr_status_reg); + } + + /* Save other special gpios. Variable i in fallthrough */ + for ( ; i < soc->ngroups; i++) { + pgroup = &soc->groups[i]; + base = reassign_pctrl_reg(soc, i); + if (pgroup->ctl_reg) + pctrl->gpio_regs[i].ctl_reg = + readl_relaxed(base + pgroup->ctl_reg); + if (pgroup->io_reg) + pctrl->gpio_regs[i].io_reg = + readl_relaxed(base + pgroup->io_reg); + } + return 0; +} + +static void msm_pinctrl_hibernation_resume(void) +{ + u32 i, j; + const struct msm_pingroup *pgroup; + struct msm_pinctrl *pctrl = msm_pinctrl_data; + const struct msm_pinctrl_soc_data *soc = pctrl->soc; + void __iomem *base = NULL; + void __iomem *tile_addr = NULL; + + if (!pctrl->gpio_regs || !pctrl->msm_tile_regs) + return; + + for (i = 0; i < soc->tile_count; i++) { + base = reassign_pctrl_reg(soc, i); + tile_addr = base + soc->dir_conn_addr[i]; + for (j = 0; j < 8; j++) + writel_relaxed(pctrl->msm_tile_regs[i].dir_con_regs[j], + tile_addr + j*4); + } + + /* Restore normal gpios */ + for (i = 0; i < soc->ngpios; i++) { + pgroup = &soc->groups[i]; + base = reassign_pctrl_reg(soc, i); + writel_relaxed(pctrl->gpio_regs[i].ctl_reg, + base + pgroup->ctl_reg); + writel_relaxed(pctrl->gpio_regs[i].io_reg, + base + pgroup->io_reg); + writel_relaxed(pctrl->gpio_regs[i].intr_cfg_reg, + base + pgroup->intr_cfg_reg); + writel_relaxed(pctrl->gpio_regs[i].intr_status_reg, + base + pgroup->intr_status_reg); + } + + /* Restore other special gpios. Variable i in fallthrough */ + for ( ; i < soc->ngroups; i++) { + pgroup = &soc->groups[i]; + base = reassign_pctrl_reg(soc, i); + if (pgroup->ctl_reg) + writel_relaxed(pctrl->gpio_regs[i].ctl_reg, + base + pgroup->ctl_reg); + if (pgroup->io_reg) + writel_relaxed(pctrl->gpio_regs[i].io_reg, + base + pgroup->io_reg); + } +} +#endif + static int msm_pinctrl_suspend(void) { +#ifdef CONFIG_HIBERNATION + if (unlikely(hibernation)) + msm_pinctrl_hibernation_suspend(); +#endif return 0; } @@ -1800,6 +1957,12 @@ static void msm_pinctrl_resume(void) const struct msm_pingroup *g; const char *name = "null"; struct msm_pinctrl *pctrl = msm_pinctrl_data; +#ifdef CONFIG_HIBERNATION + if (unlikely(hibernation)) { + msm_pinctrl_hibernation_resume(); + return; + } +#endif if (!msm_show_resume_irq_mask) return; @@ -1907,6 +2070,11 @@ int msm_pinctrl_probe(struct platform_device *pdev, platform_set_drvdata(pdev, pctrl); register_syscore_ops(&msm_pinctrl_pm_ops); +#ifdef CONFIG_HIBERNATION + ret = register_pm_notifier(&pinctrl_notif_block); + if (ret) + return ret; +#endif dev_dbg(&pdev->dev, "Probed Qualcomm pinctrl driver\n"); return 0; diff --git a/drivers/pinctrl/qcom/pinctrl-msm.h b/drivers/pinctrl/qcom/pinctrl-msm.h index 4602e450c82c..4061ebcf0991 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.h +++ b/drivers/pinctrl/qcom/pinctrl-msm.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2013, Sony Mobile Communications AB. - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -177,6 +177,10 @@ struct msm_pinctrl_soc_data { struct msm_gpio_mux_input *gpio_mux_in; unsigned int n_gpio_mux_in; unsigned int n_pdc_mux_offset; +#ifdef CONFIG_HIBERNATION + u32 *dir_conn_addr; + u32 tile_count; +#endif #ifdef CONFIG_FRAGMENTED_GPIO_ADDRESS_SPACE const u32 *tile_start; const u32 *tile_offsets; -- GitLab From 74ce5307042846d1370b2ea643ca852a42a161b1 Mon Sep 17 00:00:00 2001 From: Arun KS Date: Sun, 14 Jul 2019 18:51:47 +0530 Subject: [PATCH 0891/1121] pinctrl: qcom: Add hibernation support for sm8150 MSM pinctrl core driver takes care of saving and restoring registers during hibernation. Pass required dir_conn_addr to core driver for hibernation to work. Change-Id: I63708e9dfbe02366bed00b90a815f29255dd8cd9 Signed-off-by: Arun KS --- drivers/pinctrl/qcom/pinctrl-sm8150.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/qcom/pinctrl-sm8150.c b/drivers/pinctrl/qcom/pinctrl-sm8150.c index c0a853d7b511..c57d3a4deaca 100644 --- a/drivers/pinctrl/qcom/pinctrl-sm8150.c +++ b/drivers/pinctrl/qcom/pinctrl-sm8150.c @@ -29,6 +29,11 @@ #define SOUTH 0x00D00000 #define WEST 0x00100000 #define EAST 0x00500000 +#define NORTH_PDC_OFFSET 0xbc000 +#define SOUTH_PDC_OFFSET 0xbe000 +#define WEST_PDC_OFFSET 0xbb000 +#define EAST_PDC_OFFSET 0xb7000 +#define NUM_TILES 4 #define REG_SIZE 0x1000 #define PINGROUP(id, base, f1, f2, f3, f4, f5, f6, f7, f8, f9) \ { \ @@ -53,9 +58,10 @@ .intr_cfg_reg = base + 0x8 + REG_SIZE * id, \ .intr_status_reg = base + 0xc + REG_SIZE * id, \ .intr_target_reg = base + 0x8 + REG_SIZE * id, \ - .dir_conn_reg = (base == EAST) ? base + 0xb7000 : \ - ((base == WEST) ? base + 0xbb000 : \ - ((base == NORTH) ? base + 0xbc000 : base + 0xbe000)), \ + .dir_conn_reg = (base == EAST) ? base + EAST_PDC_OFFSET : \ + ((base == WEST) ? base + WEST_PDC_OFFSET : \ + ((base == NORTH) ? base + NORTH_PDC_OFFSET : \ + base + SOUTH_PDC_OFFSET)), \ .mux_bit = 2, \ .pull_bit = 0, \ .drv_bit = 6, \ @@ -1939,6 +1945,15 @@ static struct msm_dir_conn sm8150_dir_conn[] = { {-1, 209}, }; +#ifdef CONFIG_HIBERNATION +static u32 tile_dir_conn_addr[NUM_TILES] = { + [0] = NORTH + NORTH_PDC_OFFSET, + [1] = SOUTH + SOUTH_PDC_OFFSET, + [2] = WEST + WEST_PDC_OFFSET, + [3] = EAST + EAST_PDC_OFFSET +}; +#endif + static struct msm_pinctrl_soc_data sm8150_pinctrl = { .pins = sm8150_pins, .npins = ARRAY_SIZE(sm8150_pins), @@ -1950,6 +1965,10 @@ static struct msm_pinctrl_soc_data sm8150_pinctrl = { .dir_conn = sm8150_dir_conn, .n_dir_conns = ARRAY_SIZE(sm8150_dir_conn), .dir_conn_irq_base = 216, +#ifdef CONFIG_HIBERNATION + .dir_conn_addr = tile_dir_conn_addr, + .tile_count = ARRAY_SIZE(tile_dir_conn_addr), +#endif }; static int sm8150_pinctrl_dir_conn_probe(struct platform_device *pdev) -- GitLab From b3fd77235fa23e048ca94bd1048876aa9b432030 Mon Sep 17 00:00:00 2001 From: Jigarkumar Zala Date: Wed, 29 May 2019 10:24:40 -0700 Subject: [PATCH 0892/1121] msm: camera: eeprom: Fix OOB condition for memory map count Fix OOB check for memory map count to access correct memory map. Change-Id: Ifa3d323103725e4df57e86295bb7567835654b71 Signed-off-by: Jigarkumar Zala Signed-off-by: Sridhar Gujje --- .../camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c index 57aa7955a6db..c74be4cf4e45 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c @@ -439,7 +439,8 @@ static int32_t cam_eeprom_parse_memory_map( validate_size = sizeof(struct cam_cmd_unconditional_wait); if (remain_buf_len < validate_size || - *num_map >= MSM_EEPROM_MAX_MEM_MAP_CNT) { + *num_map >= (MSM_EEPROM_MAX_MEM_MAP_CNT * + MSM_EEPROM_MEMORY_MAP_MAX_SIZE)) { CAM_ERR(CAM_EEPROM, "not enough buffer"); return -EINVAL; } @@ -449,7 +450,9 @@ static int32_t cam_eeprom_parse_memory_map( if (i2c_random_wr->header.count == 0 || i2c_random_wr->header.count >= MSM_EEPROM_MAX_MEM_MAP_CNT || - (size_t)*num_map > U16_MAX - i2c_random_wr->header.count) { + (size_t)*num_map >= ((MSM_EEPROM_MAX_MEM_MAP_CNT * + MSM_EEPROM_MEMORY_MAP_MAX_SIZE) - + i2c_random_wr->header.count)) { CAM_ERR(CAM_EEPROM, "OOB Error"); return -EINVAL; } -- GitLab From 11fa35a5aac527f44a43e676248bfec45586856d Mon Sep 17 00:00:00 2001 From: Sean Tranchetti Date: Thu, 11 Jul 2019 15:29:13 -0600 Subject: [PATCH 0893/1121] net: qualcomm: rmnet: Workaround for HW checksum error When processing a coalesced frame with only a single packet, the error bitmask can be incorrect in certain circumstatnce. When the coalescing frame is closed due to the hardware hitting the packet limit, the byte limit, the time limit, or encountered an EOF during DMA, the checksum will always be marked is valid. In the case where we receive such a frame, we need to checksum the packet ourselves to determine if the checksum is actually valid. Change-Id: Ia14c627231731f5484609fd135549ed2848a88d4 Signed-off-by: Sean Tranchetti --- .../qualcomm/rmnet/rmnet_descriptor.c | 42 +++++++++++++ .../net/ethernet/qualcomm/rmnet/rmnet_map.h | 1 + .../ethernet/qualcomm/rmnet/rmnet_map_data.c | 62 +++++++++++++++++++ 3 files changed, 105 insertions(+) diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c index b2aa3edf42a4..c28d457c2f5f 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c @@ -628,6 +628,33 @@ static void __rmnet_frag_segment_data(struct rmnet_frag_descriptor *coal_desc, list_add_tail(&new_frag->list, list); } +static bool rmnet_frag_validate_csum(struct rmnet_frag_descriptor *frag_desc) +{ + u8 *data = rmnet_frag_data_ptr(frag_desc); + unsigned int datagram_len; + __wsum csum; + __sum16 pseudo; + + datagram_len = skb_frag_size(&frag_desc->frag) - frag_desc->ip_len; + if (frag_desc->ip_proto == 4) { + struct iphdr *iph = (struct iphdr *)data; + + pseudo = ~csum_tcpudp_magic(iph->saddr, iph->daddr, + datagram_len, + frag_desc->trans_proto, 0); + } else { + struct ipv6hdr *ip6h = (struct ipv6hdr *)data; + + pseudo = ~csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, + datagram_len, frag_desc->trans_proto, + 0); + } + + csum = csum_partial(data + frag_desc->ip_len, datagram_len, + csum_unfold(pseudo)); + return !csum_fold(csum); +} + /* Converts the coalesced frame into a list of descriptors. * NLOs containing csum erros will not be included. */ @@ -703,6 +730,21 @@ rmnet_frag_segment_coal_data(struct rmnet_frag_descriptor *coal_desc, } coal_desc->hdrs_valid = 1; + + if (rmnet_map_v5_csum_buggy(coal_hdr)) { + /* Mark the checksum as valid if it checks out */ + if (rmnet_frag_validate_csum(coal_desc)) + coal_desc->csum_valid = true; + + coal_desc->hdr_ptr = rmnet_frag_data_ptr(coal_desc); + coal_desc->gso_size = ntohs(coal_hdr->nl_pairs[0].pkt_len); + coal_desc->gso_size -= coal_desc->ip_len + coal_desc->trans_len; + coal_desc->gso_segs = coal_hdr->nl_pairs[0].num_packets; + list_add_tail(&coal_desc->list, list); + return; + } + + /* Segment the coalesced descriptor into new packets */ for (nlo = 0; nlo < coal_hdr->num_nlos; nlo++) { pkt_len = ntohs(coal_hdr->nl_pairs[nlo].pkt_len); pkt_len -= coal_desc->ip_len + coal_desc->trans_len; diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h index 07164d952384..6f7b4b2d83bd 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h @@ -260,6 +260,7 @@ int rmnet_map_checksum_downlink_packet(struct sk_buff *skb, u16 len); void rmnet_map_checksum_uplink_packet(struct sk_buff *skb, struct net_device *orig_dev, int csum_type); +bool rmnet_map_v5_csum_buggy(struct rmnet_map_v5_coal_header *coal_hdr); int rmnet_map_process_next_hdr_packet(struct sk_buff *skb, struct sk_buff_head *list, u16 len); diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c index 1d298b4882fb..96ad754ae68f 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c @@ -550,6 +550,29 @@ void rmnet_map_checksum_uplink_packet(struct sk_buff *skb, } } +bool rmnet_map_v5_csum_buggy(struct rmnet_map_v5_coal_header *coal_hdr) +{ + /* Only applies to frames with a single packet */ + if (coal_hdr->num_nlos != 1 || coal_hdr->nl_pairs[0].num_packets != 1) + return false; + + /* TCP header has FIN or PUSH set */ + if (coal_hdr->close_type == RMNET_MAP_COAL_CLOSE_COAL) + return true; + + /* Hit packet limit, byte limit, or time limit/EOF on DMA */ + if (coal_hdr->close_type == RMNET_MAP_COAL_CLOSE_HW) { + switch (coal_hdr->close_value) { + case RMNET_MAP_COAL_CLOSE_HW_PKT: + case RMNET_MAP_COAL_CLOSE_HW_BYTE: + case RMNET_MAP_COAL_CLOSE_HW_TIME: + return true; + } + } + + return false; +} + static void rmnet_map_move_headers(struct sk_buff *skb) { struct iphdr *iph; @@ -742,6 +765,34 @@ __rmnet_map_segment_coal_skb(struct sk_buff *coal_skb, coal_meta->pkt_count = 0; } +static bool rmnet_map_validate_csum(struct sk_buff *skb, + struct rmnet_map_coal_metadata *meta) +{ + u8 *data = rmnet_map_data_ptr(skb); + unsigned int datagram_len; + __wsum csum; + __sum16 pseudo; + + datagram_len = skb->len - meta->ip_len; + if (meta->ip_proto == 4) { + struct iphdr *iph = (struct iphdr *)data; + + pseudo = ~csum_tcpudp_magic(iph->saddr, iph->daddr, + datagram_len, + meta->trans_proto, 0); + } else { + struct ipv6hdr *ip6h = (struct ipv6hdr *)data; + + pseudo = ~csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, + datagram_len, meta->trans_proto, + 0); + } + + csum = skb_checksum(skb, meta->ip_len, datagram_len, + csum_unfold(pseudo)); + return !csum_fold(csum); +} + /* Converts the coalesced SKB into a list of SKBs. * NLOs containing csum erros will not be included. * The original coalesced SKB should be treated as invalid and @@ -825,6 +876,17 @@ static void rmnet_map_segment_coal_skb(struct sk_buff *coal_skb, return; } + if (rmnet_map_v5_csum_buggy(coal_hdr)) { + rmnet_map_move_headers(coal_skb); + /* Mark as valid if it checks out */ + if (rmnet_map_validate_csum(coal_skb, &coal_meta)) + coal_skb->ip_summed = CHECKSUM_UNNECESSARY; + + __skb_queue_tail(list, coal_skb); + return; + } + + /* Segment the coalesced SKB into new packets */ for (nlo = 0; nlo < coal_hdr->num_nlos; nlo++) { pkt_len = ntohs(coal_hdr->nl_pairs[nlo].pkt_len); pkt_len -= coal_meta.ip_len + coal_meta.trans_len; -- GitLab From f08e23c4b0dcc9f44fbfca58a2f7f366b3abce76 Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Wed, 10 Jul 2019 14:30:40 -0700 Subject: [PATCH 0894/1121] ARM: dts: msm: Add fastrpc SMMU sids for sdmshrike v2 target Add fastrpc SMMU sids for the sdmshrike v2 target as they are different than the sdmshrike v1 target. Change-Id: I505251304ffe0ae759b0a68e62e437937816c06c Signed-off-by: Anant Goel --- arch/arm64/boot/dts/qcom/sdmshrike-v2.dtsi | 38 ++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdmshrike-v2.dtsi b/arch/arm64/boot/dts/qcom/sdmshrike-v2.dtsi index f544cac42142..ee3ff1ff1886 100644 --- a/arch/arm64/boot/dts/qcom/sdmshrike-v2.dtsi +++ b/arch/arm64/boot/dts/qcom/sdmshrike-v2.dtsi @@ -45,3 +45,41 @@ &mdss_dsi1_pll { compatible = "qcom,mdss_dsi_pll_7nm_v2"; }; + +&msm_fastrpc { + qcom,msm_fastrpc_compute_cb1 { + iommus = <&apps_smmu 0x1001 0x0460>; + }; + + qcom,msm_fastrpc_compute_cb2 { + iommus = <&apps_smmu 0x1002 0x0460>; + }; + + qcom,msm_fastrpc_compute_cb3 { + iommus = <&apps_smmu 0x1003 0x0460>; + }; + + qcom,msm_fastrpc_compute_cb4 { + iommus = <&apps_smmu 0x1004 0x0460>; + }; + + qcom,msm_fastrpc_compute_cb5 { + iommus = <&apps_smmu 0x1005 0x0460>; + }; + + qcom,msm_fastrpc_compute_cb6 { + iommus = <&apps_smmu 0x1006 0x0460>; + }; + + qcom,msm_fastrpc_compute_cb7 { + iommus = <&apps_smmu 0x1007 0x0460>; + }; + + qcom,msm_fastrpc_compute_cb8 { + iommus = <&apps_smmu 0x1008 0x0460>; + }; + + qcom,msm_fastrpc_compute_cb9 { + iommus = <&apps_smmu 0x1009 0x0460>; + }; +}; -- GitLab From dddf7fedf9bc229081de6ed9af002355b4772f68 Mon Sep 17 00:00:00 2001 From: Aditya Mathur Date: Fri, 12 Jul 2019 13:19:58 -0700 Subject: [PATCH 0895/1121] drivers: net: qti-can: Use div_u64 for 64-bit division Use div_u64 to avoid compilation error in 32-bit architectures. Change-Id: I2a247dff5ee0a601deaee9e3375c5026788ef2df Signed-off-by: Aditya Mathur Signed-off-by: Gustavo Solaira --- drivers/net/can/spi/qti-can.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/spi/qti-can.c b/drivers/net/can/spi/qti-can.c index c38f047d73a4..738caea83ffe 100644 --- a/drivers/net/can/spi/qti-can.c +++ b/drivers/net/can/spi/qti-can.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #define DEBUG_QTI_CAN 0 @@ -449,7 +450,7 @@ static int qti_can_process_response(struct qti_can *priv_data, (struct can_time_info *)resp->data; if (priv_data->use_qtimer) - mstime = (((s64)qtimer_time()) / NSEC_PER_MSEC); + mstime = div_u64(qtimer_time(), NSEC_PER_MSEC); else mstime = ktime_to_ms(ktime_get_boottime()); -- GitLab From 76853f2afad31a463dcdf4c76f0a7dd07352b564 Mon Sep 17 00:00:00 2001 From: Aditya Mathur Date: Fri, 12 Jul 2019 15:20:53 -0700 Subject: [PATCH 0896/1121] defconfig: Enable CAN for SA515M Enable CAN drivers for SA515M. Change-Id: I00bf1627c1b1e476b37557c0687c5bbc32e84fee Signed-off-by: Aditya Mathur --- arch/arm/configs/vendor/sdxprairie-auto-perf_defconfig | 2 ++ arch/arm/configs/vendor/sdxprairie-auto_defconfig | 2 ++ 2 files changed, 4 insertions(+) diff --git a/arch/arm/configs/vendor/sdxprairie-auto-perf_defconfig b/arch/arm/configs/vendor/sdxprairie-auto-perf_defconfig index 8dc781b37772..d17bcd2a0aff 100644 --- a/arch/arm/configs/vendor/sdxprairie-auto-perf_defconfig +++ b/arch/arm/configs/vendor/sdxprairie-auto-perf_defconfig @@ -158,6 +158,8 @@ CONFIG_NET_SCH_PRIO=y CONFIG_QRTR=y CONFIG_QRTR_SMD=y CONFIG_QRTR_MHI=y +CONFIG_CAN=y +CONFIG_QTI_CAN=y CONFIG_BT=y # CONFIG_BT_BREDR is not set # CONFIG_BT_LE is not set diff --git a/arch/arm/configs/vendor/sdxprairie-auto_defconfig b/arch/arm/configs/vendor/sdxprairie-auto_defconfig index ae512352a79d..2f668844cf39 100644 --- a/arch/arm/configs/vendor/sdxprairie-auto_defconfig +++ b/arch/arm/configs/vendor/sdxprairie-auto_defconfig @@ -158,6 +158,8 @@ CONFIG_NET_SCH_PRIO=y CONFIG_QRTR=y CONFIG_QRTR_SMD=y CONFIG_QRTR_MHI=y +CONFIG_CAN=y +CONFIG_QTI_CAN=y CONFIG_BT=y # CONFIG_BT_BREDR is not set # CONFIG_BT_LE is not set -- GitLab From 657d5337600ac55bbc848584dc9ca1750d42d562 Mon Sep 17 00:00:00 2001 From: Aditya Mathur Date: Fri, 12 Jul 2019 15:40:16 -0700 Subject: [PATCH 0897/1121] defconfig: Enable MICREL_PHY for SA515M Enable MICREL_PHY driver for SA515M. Change-Id: I39283dc73f40b68e4ad43f06bf3b9ee4ccee5077 Signed-off-by: Aditya Mathur --- arch/arm/configs/vendor/sdxprairie-auto-perf_defconfig | 1 + arch/arm/configs/vendor/sdxprairie-auto_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm/configs/vendor/sdxprairie-auto-perf_defconfig b/arch/arm/configs/vendor/sdxprairie-auto-perf_defconfig index d17bcd2a0aff..489f15ac8fef 100644 --- a/arch/arm/configs/vendor/sdxprairie-auto-perf_defconfig +++ b/arch/arm/configs/vendor/sdxprairie-auto-perf_defconfig @@ -211,6 +211,7 @@ CONFIG_RMNET=y # CONFIG_NET_VENDOR_SMSC is not set # CONFIG_NET_VENDOR_STMICRO is not set CONFIG_AT803X_PHY=y +CONFIG_MICREL_PHY=y CONFIG_PPP=y CONFIG_PPP_ASYNC=y CONFIG_USB_USBNET=y diff --git a/arch/arm/configs/vendor/sdxprairie-auto_defconfig b/arch/arm/configs/vendor/sdxprairie-auto_defconfig index 2f668844cf39..5e5f5756b227 100644 --- a/arch/arm/configs/vendor/sdxprairie-auto_defconfig +++ b/arch/arm/configs/vendor/sdxprairie-auto_defconfig @@ -209,6 +209,7 @@ CONFIG_RMNET=y # CONFIG_NET_VENDOR_SMSC is not set # CONFIG_NET_VENDOR_STMICRO is not set CONFIG_AT803X_PHY=y +CONFIG_MICREL_PHY=y CONFIG_PPP=y CONFIG_PPP_ASYNC=y CONFIG_USB_USBNET=y -- GitLab From 0b0950fa50cbcb495efacceb1774ad406e51b8d4 Mon Sep 17 00:00:00 2001 From: Jilai Wang Date: Tue, 16 Jul 2019 15:53:53 -0400 Subject: [PATCH 0898/1121] msm: npu: Use mutex to protect map/unmap to avoid race condition If multiple processes call map/unmap funciton concurrently, it's possible to cause data structure corruption while both of them accesses the same buffer at the same time. This change is to use mutex to avoid this problem. Change-Id: I3aeab502566c4105695a5d14736c9bea73d060e5 Signed-off-by: Jilai Wang --- drivers/media/platform/msm/npu/npu_mgr.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/msm/npu/npu_mgr.c b/drivers/media/platform/msm/npu/npu_mgr.c index 7e8a9c3f591b..29fb49b928df 100644 --- a/drivers/media/platform/msm/npu/npu_mgr.c +++ b/drivers/media/platform/msm/npu/npu_mgr.c @@ -1078,8 +1078,16 @@ int32_t npu_host_get_info(struct npu_device *npu_dev, int32_t npu_host_map_buf(struct npu_client *client, struct msm_npu_map_buf_ioctl *map_ioctl) { - return npu_mem_map(client, map_ioctl->buf_ion_hdl, map_ioctl->size, + struct npu_device *npu_dev = client->npu_dev; + struct npu_host_ctx *host_ctx = &npu_dev->host_ctx; + int ret; + + mutex_lock(&host_ctx->lock); + ret = npu_mem_map(client, map_ioctl->buf_ion_hdl, map_ioctl->size, &map_ioctl->npu_phys_addr); + mutex_unlock(&host_ctx->lock); + + return ret; } int32_t npu_host_unmap_buf(struct npu_client *client, @@ -1097,8 +1105,10 @@ int32_t npu_host_unmap_buf(struct npu_client *client, &host_ctx->fw_deinit_done, NW_CMD_TIMEOUT)) pr_warn("npu: wait for fw_deinit_done time out\n"); + mutex_lock(&host_ctx->lock); npu_mem_unmap(client, unmap_ioctl->buf_ion_hdl, unmap_ioctl->npu_phys_addr); + mutex_unlock(&host_ctx->lock); return 0; } -- GitLab From d4a114deb2f406a16b462731739a910f7d494a38 Mon Sep 17 00:00:00 2001 From: Jilai Wang Date: Wed, 17 Jul 2019 11:39:41 -0400 Subject: [PATCH 0899/1121] msm: npu: Don't sync dma buffer after mapping User driver will take care of flushing or invalidating dma buffer. It's not needed to do it in kernel driver after mapping. Change-Id: I8c3858bd84a5b74bd57cb67b91c4541b023a8d37 Signed-off-by: Jilai Wang --- drivers/media/platform/msm/npu/npu_hw_access.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/media/platform/msm/npu/npu_hw_access.c b/drivers/media/platform/msm/npu/npu_hw_access.c index 084236998037..27b3a2e2db01 100644 --- a/drivers/media/platform/msm/npu/npu_hw_access.c +++ b/drivers/media/platform/msm/npu/npu_hw_access.c @@ -298,8 +298,6 @@ int npu_mem_map(struct npu_client *client, int buf_hdl, uint32_t size, goto map_end; } - dma_sync_sg_for_device(&(npu_dev->pdev->dev), ion_buf->table->sgl, - ion_buf->table->nents, DMA_BIDIRECTIONAL); ion_buf->iova = ion_buf->table->sgl->dma_address; ion_buf->size = ion_buf->dma_buf->size; *addr = ion_buf->iova; -- GitLab From 395d349bc2d005b2e2f30bfed5edd9a36069cd8d Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Wed, 10 Jul 2019 14:55:25 -0700 Subject: [PATCH 0900/1121] ARM: dts: msm: Update bandwidth values for the sdmshrike v2 target Provide updated bandwidth entries for LLCC, DDR, GPU, and CPU on the sdmshrike v2 target. Change-Id: I1f45e5571377f746bcde9739375d595fbd521be2 Signed-off-by: Anant Goel --- arch/arm64/boot/dts/qcom/sdmshrike-v2.dtsi | 131 +++++++++++++++++++++ 1 file changed, 131 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdmshrike-v2.dtsi b/arch/arm64/boot/dts/qcom/sdmshrike-v2.dtsi index ee3ff1ff1886..708949872b26 100644 --- a/arch/arm64/boot/dts/qcom/sdmshrike-v2.dtsi +++ b/arch/arm64/boot/dts/qcom/sdmshrike-v2.dtsi @@ -83,3 +83,134 @@ iommus = <&apps_smmu 0x1009 0x0460>; }; }; + +&soc { + /delete-node/ llcc-bw-opp-table; + /delete-node/ ddr-bw-opp-table; + /delete-node/ suspendable-ddr-bw-opp-table; + + llcc_bw_opp_table: llcc-bw-opp-table { + compatible = "operating-points-v2"; + BW_OPP_ENTRY( 150, 16); /* 2288 MB/s */ + BW_OPP_ENTRY( 300, 16); /* 4577 MB/s */ + BW_OPP_ENTRY( 466, 16); /* 7110 MB/s */ + BW_OPP_ENTRY( 600, 16); /* 9155 MB/s */ + BW_OPP_ENTRY( 806, 16); /* 12298 MB/s */ + BW_OPP_ENTRY( 933, 16); /* 14236 MB/s */ + BW_OPP_ENTRY(1000, 16); /* 15258 MB/s */ + }; + + ddr_bw_opp_table: ddr-bw-opp-table { + compatible = "operating-points-v2"; + BW_OPP_ENTRY( 200, 4); /* 762 MB/s */ + BW_OPP_ENTRY( 300, 4); /* 1144 MB/s */ + BW_OPP_ENTRY( 451, 4); /* 1720 MB/s */ + BW_OPP_ENTRY( 547, 4); /* 2086 MB/s */ + BW_OPP_ENTRY( 681, 4); /* 2597 MB/s */ + BW_OPP_ENTRY( 768, 4); /* 2929 MB/s */ + BW_OPP_ENTRY(1017, 4); /* 3879 MB/s */ + BW_OPP_ENTRY(1353, 4); /* 5161 MB/s */ + BW_OPP_ENTRY(1555, 4); /* 5931 MB/s */ + BW_OPP_ENTRY(1804, 4); /* 6881 MB/s */ + BW_OPP_ENTRY(2092, 4); /* 7980 MB/s */ + }; + + suspendable_ddr_bw_opp_table: suspendable-ddr-bw-opp-table { + compatible = "operating-points-v2"; + BW_OPP_ENTRY( 0, 4); /* 0 MB/s */ + BW_OPP_ENTRY( 200, 4); /* 762 MB/s */ + BW_OPP_ENTRY( 300, 4); /* 1144 MB/s */ + BW_OPP_ENTRY( 451, 4); /* 1720 MB/s */ + BW_OPP_ENTRY( 547, 4); /* 2086 MB/s */ + BW_OPP_ENTRY( 681, 4); /* 2597 MB/s */ + BW_OPP_ENTRY( 768, 4); /* 2929 MB/s */ + BW_OPP_ENTRY(1017, 4); /* 3879 MB/s */ + BW_OPP_ENTRY(1353, 4); /* 5161 MB/s */ + BW_OPP_ENTRY(1555, 4); /* 5931 MB/s */ + BW_OPP_ENTRY(1804, 4); /* 6881 MB/s */ + BW_OPP_ENTRY(2092, 4); /* 7980 MB/s */ + }; +}; + +&gpubw { + /delete-property/ qcom,bw-tbl; + operating-points-v2 = <&suspendable_ddr_bw_opp_table>; +}; + +&cpu4_computemon { + qcom,core-dev-table = + < 1920000 MHZ_TO_MBPS( 200, 4) >, + < 2793600 MHZ_TO_MBPS(1017, 4) >, + < 3000000 MHZ_TO_MBPS(2092, 4) >; +}; + +&cpu0_llcc_ddr_latmon { + qcom,core-dev-table = + < 300000 MHZ_TO_MBPS( 200, 4) >, + < 768000 MHZ_TO_MBPS( 451, 4) >, + < 1113600 MHZ_TO_MBPS( 547, 4) >, + < 1478400 MHZ_TO_MBPS( 768, 4) >, + < 1632000 MHZ_TO_MBPS(1017, 4) >; +}; + +&cpu4_llcc_ddr_latmon { + qcom,core-dev-table = + < 300000 MHZ_TO_MBPS( 200, 4) >, + < 710400 MHZ_TO_MBPS( 451, 4) >, + < 825600 MHZ_TO_MBPS( 547, 4) >, + < 1056000 MHZ_TO_MBPS( 768, 4) >, + < 1286400 MHZ_TO_MBPS(1017, 4) >, + < 1612800 MHZ_TO_MBPS(1353, 4) >, + < 1804800 MHZ_TO_MBPS(1555, 4) >, + < 2649600 MHZ_TO_MBPS(1804, 4) >, + < 3000000 MHZ_TO_MBPS(2092, 4) >; +}; + +&cpu0_cpu_l3_latmon { + qcom,core-dev-table = + < 300000 300000000 >, + < 499200 403200000 >, + < 576000 499200000 >, + < 672000 614400000 >, + < 768000 710400000 >, + < 940800 806400000 >, + < 1036800 902400000 >, + < 1113600 998400000 >, + < 1209600 1075280000 >, + < 1305600 1171200000 >, + < 1382400 1267200000 >, + < 1478400 1344000000 >, + < 1632000 1536000000 >, + < 1785600 1612800000 >; +}; + +&cpu4_cpu_l3_latmon { + qcom,core-dev-table = + < 300000 300000000 >, + < 825600 614400000 >, + < 1171200 806400000 >, + < 1401600 998400000 >, + < 1708800 1267200000 >, + < 2016000 1344000000 >, + < 2419200 1536000000 >, + < 2841600 1612800000 >; +}; + +&cpu0_cpu_llcc_latmon { + qcom,core-dev-table = + < 300000 MHZ_TO_MBPS( 150, 16) >, + < 768000 MHZ_TO_MBPS( 300, 16) >, + < 1478400 MHZ_TO_MBPS( 466, 16) >, + < 1632000 MHZ_TO_MBPS( 600, 16) >; +}; + +&cpu4_cpu_llcc_latmon { + qcom,core-dev-table = + < 300000 MHZ_TO_MBPS( 150, 16) >, + < 710400 MHZ_TO_MBPS( 300, 16) >, + < 1056000 MHZ_TO_MBPS( 466, 16) >, + < 1286400 MHZ_TO_MBPS( 600, 16) >, + < 1804800 MHZ_TO_MBPS( 806, 16) >, + < 2649600 MHZ_TO_MBPS( 933, 16) >, + < 3000000 MHZ_TO_MBPS(1000, 16) >; +}; -- GitLab From 3f7787b13692a454dbcbd5f532cc11dacb1f71f8 Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Thu, 11 Jul 2019 22:15:33 -0700 Subject: [PATCH 0901/1121] ARM: dts: msm: Set the default mode for USB on SA8195P The SA8195P target requires the primary USB controller to run in host mode. Add the property to set the mode of the primary USB controller to host on the SA8195P target. Change-Id: If525fc7b10a893a69e7317577efb94f193cade66 Signed-off-by: Anant Goel --- arch/arm64/boot/dts/qcom/sa8195p.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sa8195p.dtsi b/arch/arm64/boot/dts/qcom/sa8195p.dtsi index 237ab398e218..6dfcaa300047 100644 --- a/arch/arm64/boot/dts/qcom/sa8195p.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8195p.dtsi @@ -106,3 +106,8 @@ }; }; }; + +&usb1 { + qcom,default-mode-host; + status = "ok"; +}; -- GitLab From 9ba9aa51181fac11410b6a8e605ea1c655ff584b Mon Sep 17 00:00:00 2001 From: Michael Adisumarta Date: Wed, 17 Jul 2019 13:58:32 -0700 Subject: [PATCH 0902/1121] msm:ipa: mutex protect mhi dev for voting/unvoting pcie clocks This change mutex protects mhi dev for pcie clock voting/unvoting in concurrency scenarios such as USB disconnect and SSR. Not protecting may cause invalid mhi dev access. Change-Id: Ib3745068a94a8e15fc61c7dfd4245c97e777c9ae Signed-off-by: Michael Adisumarta --- drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c b/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c index 31c430cc7ab7..717bc6928e6c 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c @@ -373,9 +373,20 @@ struct ipa_mpm_mhi_driver { struct ipa_mpm_channel dl_cons; enum ipa_mpm_mhip_client_type mhip_client; enum ipa_mpm_teth_state teth_state; - struct mutex mutex; bool init_complete; + /* General MPM mutex to protect concurrent update of MPM GSI states */ + struct mutex mutex; + /* + * Mutex to protect IPA clock vote/unvote to make sure IPA isn't double + * devoted for concurrency scenarios such as SSR and LPM mode CB + * concurrency. + */ struct mutex lpm_mutex; + /* + * Mutex to protect mhi_dev update/ access, for concurrency such as + * 5G SSR and USB disconnect/connect. + */ + struct mutex mhi_mutex; bool in_lpm; struct ipa_mpm_clk_cnt_type clk_cnt; }; @@ -1308,8 +1319,10 @@ static void ipa_mpm_mhip_shutdown(int mhip_idx) ipa_mpm_ctx->md[mhip_idx].in_lpm = true; } mutex_unlock(&ipa_mpm_ctx->md[mhip_idx].lpm_mutex); + mutex_lock(&ipa_mpm_ctx->md[mhip_idx].mhi_mutex); ipa_mpm_ctx->md[mhip_idx].mhi_dev = NULL; ipa_mpm_ctx->md[mhip_idx].init_complete = false; + mutex_unlock(&ipa_mpm_ctx->md[mhip_idx].mhi_mutex); IPA_MPM_FUNC_EXIT(); } @@ -1332,8 +1345,10 @@ static int ipa_mpm_vote_unvote_pcie_clk(enum ipa_mpm_clk_vote_type vote, return -EINVAL; } + mutex_lock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); if (ipa_mpm_ctx->md[probe_id].mhi_dev == NULL) { IPA_MPM_ERR("MHI not initialized yet\n"); + mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); return 0; } @@ -1347,6 +1362,7 @@ static int ipa_mpm_vote_unvote_pcie_clk(enum ipa_mpm_clk_vote_type vote, if (result) { IPA_MPM_ERR("mhi_sync_get failed for probe_id %d\n", result, probe_id); + mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); return result; } @@ -1360,6 +1376,7 @@ static int ipa_mpm_vote_unvote_pcie_clk(enum ipa_mpm_clk_vote_type vote, IPA_MPM_DBG("probe_id %d PCIE clock already devoted\n", probe_id); WARN_ON(1); + mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); return 0; } mhi_device_put(ipa_mpm_ctx->md[probe_id].mhi_dev, MHI_VOTE_BUS); @@ -1368,6 +1385,7 @@ static int ipa_mpm_vote_unvote_pcie_clk(enum ipa_mpm_clk_vote_type vote, atomic_dec(&ipa_mpm_ctx->pcie_clk_total_cnt); } + mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); return result; } @@ -2256,8 +2274,8 @@ static void ipa_mpm_mhi_remove_cb(struct mhi_device *mhi_dev) } IPA_MPM_DBG("remove_cb for mhip_idx = %d", mhip_idx); - ipa_mpm_mhip_shutdown(mhip_idx); + atomic_dec(&ipa_mpm_ctx->probe_cnt); if (atomic_read(&ipa_mpm_ctx->probe_cnt) == 0) { @@ -2676,6 +2694,7 @@ static int ipa_mpm_probe(struct platform_device *pdev) for (i = 0; i < IPA_MPM_MHIP_CH_ID_MAX; i++) { mutex_init(&ipa_mpm_ctx->md[i].mutex); + mutex_init(&ipa_mpm_ctx->md[i].mhi_mutex); mutex_init(&ipa_mpm_ctx->md[i].lpm_mutex); } -- GitLab From 022bfd9ee3a14a12e4fdb89aa3588d8c30c638da Mon Sep 17 00:00:00 2001 From: Gustavo Solaira Date: Wed, 17 Jul 2019 16:55:05 -0700 Subject: [PATCH 0903/1121] ARM: dts: msm: Remove MHI device tree for QCS405 Remove the MHI device tree file and references since it will be provided by EAP kernel bundle. Change-Id: Id53f49302d22060de9acbd7dce6b1c503da278f1 Signed-off-by: Gustavo Solaira --- arch/arm64/boot/dts/qcom/qcs405-mhi.dtsi | 716 ----------------------- arch/arm64/boot/dts/qcom/qcs405.dtsi | 8 - 2 files changed, 724 deletions(-) delete mode 100644 arch/arm64/boot/dts/qcom/qcs405-mhi.dtsi diff --git a/arch/arm64/boot/dts/qcom/qcs405-mhi.dtsi b/arch/arm64/boot/dts/qcom/qcs405-mhi.dtsi deleted file mode 100644 index 12ba814820f3..000000000000 --- a/arch/arm64/boot/dts/qcom/qcs405-mhi.dtsi +++ /dev/null @@ -1,716 +0,0 @@ -/* - * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -&pcie_rc0 { - reg = <0 0 0 0 0>; - - mhi_0: qcom,mhi@0 { - reg = <0 0 0 0 0 >; - - pci-ids = "17cb:0304"; - - /* controller specific configuration */ - qcom,smmu-cfg = <0x0>; - qcom,msm-bus,name = "mhi"; - qcom,msm-bus,num-cases = <2>; - qcom,msm-bus,num-paths = <1>; - qcom,msm-bus,vectors-KBps = - <45 512 0 0>, - <45 512 1200000000 650000000>; - - /* mhi bus specific settings */ - mhi,max-channels = <110>; - mhi,timeout = <2000>; - - mhi_channels { - #address-cells = <1>; - #size-cells = <0>; - mhi_chan@0 { - reg = <0>; - label = "LOOPBACK"; - mhi,num-elements = <64>; - mhi,event-ring = <2>; - mhi,chan-dir = <1>; - mhi,data-type = <0>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x4>; - }; - - mhi_chan@1 { - reg = <1>; - label = "LOOPBACK"; - mhi,num-elements = <64>; - mhi,event-ring = <2>; - mhi,chan-dir = <2>; - mhi,data-type = <0>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x4>; - }; - - mhi_chan@4 { - reg = <4>; - label = "DIAG"; - mhi,num-elements = <64>; - mhi,event-ring = <1>; - mhi,chan-dir = <1>; - mhi,data-type = <0>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x4>; - }; - - mhi_chan@5 { - reg = <5>; - label = "DIAG"; - mhi,num-elements = <64>; - mhi,event-ring = <3>; - mhi,chan-dir = <2>; - mhi,data-type = <0>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x4>; - }; - - mhi_chan@14 { - reg = <14>; - label = "QMI0"; - mhi,num-elements = <64>; - mhi,event-ring = <1>; - mhi,chan-dir = <1>; - mhi,data-type = <0>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x4>; - }; - - mhi_chan@15 { - reg = <15>; - label = "QMI0"; - mhi,num-elements = <64>; - mhi,event-ring = <2>; - mhi,chan-dir = <2>; - mhi,data-type = <0>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x4>; - }; - - mhi_chan@16 { - reg = <16>; - label = "QMI1"; - mhi,num-elements = <64>; - mhi,event-ring = <3>; - mhi,chan-dir = <1>; - mhi,data-type = <0>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x4>; - }; - - mhi_chan@17 { - reg = <17>; - label = "QMI1"; - mhi,num-elements = <64>; - mhi,event-ring = <3>; - mhi,chan-dir = <2>; - mhi,data-type = <0>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x4>; - }; - - mhi_chan@20 { - reg = <20>; - label = "IPCR"; - mhi,num-elements = <64>; - mhi,event-ring = <2>; - mhi,chan-dir = <1>; - mhi,data-type = <1>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x4>; - mhi,auto-start; - }; - - mhi_chan@21 { - reg = <21>; - label = "IPCR"; - mhi,num-elements = <64>; - mhi,event-ring = <2>; - mhi,chan-dir = <2>; - mhi,data-type = <0>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x4>; - mhi,auto-queue; - mhi,auto-start; - }; - - mhi_chan@32 { - reg = <32>; - label = "DUN"; - mhi,num-elements = <64>; - mhi,event-ring = <3>; - mhi,chan-dir = <1>; - mhi,data-type = <0>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x4>; - }; - - mhi_chan@33 { - reg = <33>; - label = "DUN"; - mhi,num-elements = <64>; - mhi,event-ring = <3>; - mhi,chan-dir = <2>; - mhi,data-type = <0>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x4>; - }; - - mhi_chan@46 { - reg = <46>; - label = "IP_SW_0"; - mhi,num-elements = <512>; - mhi,event-ring = <4>; - mhi,chan-dir = <1>; - mhi,data-type = <1>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x4>; - }; - - mhi_chan@47 { - reg = <47>; - label = "IP_SW_0"; - mhi,num-elements = <512>; - mhi,event-ring = <5>; - mhi,chan-dir = <2>; - mhi,data-type = <4>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x4>; - }; - - mhi_chan@100 { - reg = <100>; - label = "IP_HW0"; - mhi,num-elements = <512>; - mhi,event-ring = <6>; - mhi,chan-dir = <1>; - mhi,data-type = <1>; - mhi,doorbell-mode = <3>; - mhi,ee = <0x4>; - mhi,db-mode-switch; - }; - - mhi_chan@101 { - reg = <101>; - label = "IP_HW0"; - mhi,num-elements = <512>; - mhi,event-ring = <7>; - mhi,chan-dir = <2>; - mhi,data-type = <4>; - mhi,doorbell-mode = <3>; - mhi,ee = <0x4>; - }; - - mhi_chan@105 { - reg = <105>; - label = "IP_HW1"; - mhi,num-elements = <512>; - mhi,event-ring = <8>; - mhi,chan-dir = <1>; - mhi,data-type = <1>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x4>; - }; - - mhi_chan@106 { - reg = <106>; - label = "IP_HW1"; - mhi,num-elements = <512>; - mhi,event-ring = <9>; - mhi,chan-dir = <2>; - mhi,data-type = <4>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x4>; - }; - }; - - mhi_events { - mhi_event@0 { - mhi,num-elements = <32>; - mhi,intmod = <1>; - mhi,msi = <1>; - mhi,priority = <1>; - mhi,brstmode = <2>; - mhi,data-type = <1>; - }; - - mhi_event@1 { - mhi,num-elements = <256>; - mhi,intmod = <1>; - mhi,msi = <2>; - mhi,priority = <1>; - mhi,brstmode = <2>; - }; - - mhi_event@2 { - mhi,num-elements = <256>; - mhi,intmod = <1>; - mhi,msi = <3>; - mhi,priority = <1>; - mhi,brstmode = <2>; - }; - - mhi_event@3 { - mhi,num-elements = <256>; - mhi,intmod = <1>; - mhi,msi = <4>; - mhi,priority = <1>; - mhi,brstmode = <2>; - }; - - mhi_event@4 { - mhi,num-elements = <1024>; - mhi,intmod = <5>; - mhi,msi = <5>; - mhi,chan = <46>; - mhi,priority = <1>; - mhi,brstmode = <2>; - }; - - mhi_event@5 { - mhi,num-elements = <1024>; - mhi,intmod = <5>; - mhi,msi = <6>; - mhi,chan = <47>; - mhi,priority = <1>; - mhi,brstmode = <2>; - mhi,client-manage; - }; - - mhi_event@6 { - mhi,num-elements = <1024>; - mhi,intmod = <5>; - mhi,msi = <5>; - mhi,chan = <100>; - mhi,priority = <1>; - mhi,brstmode = <3>; - mhi,hw-ev; - }; - - mhi_event@7 { - mhi,num-elements = <1024>; - mhi,intmod = <5>; - mhi,msi = <6>; - mhi,chan = <101>; - mhi,priority = <1>; - mhi,brstmode = <3>; - mhi,hw-ev; - mhi,client-manage; - }; - - mhi_event@8 { - mhi,num-elements = <1024>; - mhi,intmod = <0>; - mhi,msi = <7>; - mhi,chan = <105>; - mhi,priority = <1>; - mhi,brstmode = <2>; - mhi,hw-ev; - }; - - mhi_event@9 { - mhi,num-elements = <1024>; - mhi,intmod = <0>; - mhi,msi = <8>; - mhi,chan = <106>; - mhi,priority = <1>; - mhi,brstmode = <2>; - mhi,hw-ev; - mhi,client-manage; - }; - }; - - mhi_devices { - #address-cells = <1>; - #size-cells = <0>; - mhi_netdev_0: mhi_rmnet@0 { - reg = <0x0>; - mhi,chan = "IP_HW0"; - mhi,interface-name = "rmnet_mhi"; - mhi,mru = <0x8000>; - mhi,disable-chain-skb; - }; - - mhi_netdev_1: mhi_rmnet@1 { - reg = <0x1>; - mhi,chan = "IP_HW1"; - mhi,interface-name = "rmnet_mhi"; - mhi,mru = <0x8000>; - mhi,disable-chain-skb; - }; - - mhi_netdev_2: mhi_rmnet@2 { - reg = <0x2>; - mhi,chan = "IP_SW_0"; - mhi,interface-name = "mhi_swip"; - mhi,mru = <0x4000>; - mhi,ethernet-interface; - mhi,disable-chain-skb; - }; - }; - }; - - mhi_1: qcom,mhi@1 { - reg = <0 0 0 0 0 >; - - pci-ids = "17cb:0306"; - - /* controller specific configuration */ - qcom,smmu-cfg = <0x0>; - qcom,msm-bus,name = "mhi"; - qcom,msm-bus,num-cases = <2>; - qcom,msm-bus,num-paths = <1>; - qcom,msm-bus,vectors-KBps = - <45 512 0 0>, - <45 512 1200000000 650000000>; - - /* mhi bus specific settings */ - mhi,max-channels = <110>; - mhi,timeout = <2000>; - - mhi_channels { - #address-cells = <1>; - #size-cells = <0>; - mhi_chan@0 { - reg = <0>; - label = "LOOPBACK"; - mhi,num-elements = <64>; - mhi,event-ring = <2>; - mhi,chan-dir = <1>; - mhi,data-type = <0>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x4>; - }; - - mhi_chan@1 { - reg = <1>; - label = "LOOPBACK"; - mhi,num-elements = <64>; - mhi,event-ring = <2>; - mhi,chan-dir = <2>; - mhi,data-type = <0>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x4>; - }; - - mhi_chan@4 { - reg = <4>; - label = "DIAG"; - mhi,num-elements = <64>; - mhi,event-ring = <1>; - mhi,chan-dir = <1>; - mhi,data-type = <0>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x4>; - }; - - mhi_chan@5 { - reg = <5>; - label = "DIAG"; - mhi,num-elements = <64>; - mhi,event-ring = <3>; - mhi,chan-dir = <2>; - mhi,data-type = <0>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x4>; - }; - - mhi_chan@14 { - reg = <14>; - label = "QMI0"; - mhi,num-elements = <64>; - mhi,event-ring = <1>; - mhi,chan-dir = <1>; - mhi,data-type = <0>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x4>; - }; - - mhi_chan@15 { - reg = <15>; - label = "QMI0"; - mhi,num-elements = <64>; - mhi,event-ring = <2>; - mhi,chan-dir = <2>; - mhi,data-type = <0>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x4>; - }; - - mhi_chan@16 { - reg = <16>; - label = "QMI1"; - mhi,num-elements = <64>; - mhi,event-ring = <3>; - mhi,chan-dir = <1>; - mhi,data-type = <0>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x4>; - }; - - mhi_chan@17 { - reg = <17>; - label = "QMI1"; - mhi,num-elements = <64>; - mhi,event-ring = <3>; - mhi,chan-dir = <2>; - mhi,data-type = <0>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x4>; - }; - - mhi_chan@20 { - reg = <20>; - label = "IPCR"; - mhi,num-elements = <64>; - mhi,event-ring = <2>; - mhi,chan-dir = <1>; - mhi,data-type = <1>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x4>; - mhi,auto-start; - }; - - mhi_chan@21 { - reg = <21>; - label = "IPCR"; - mhi,num-elements = <64>; - mhi,event-ring = <2>; - mhi,chan-dir = <2>; - mhi,data-type = <0>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x4>; - mhi,auto-queue; - mhi,auto-start; - }; - - mhi_chan@32 { - reg = <32>; - label = "DUN"; - mhi,num-elements = <64>; - mhi,event-ring = <3>; - mhi,chan-dir = <1>; - mhi,data-type = <0>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x4>; - }; - - mhi_chan@33 { - reg = <33>; - label = "DUN"; - mhi,num-elements = <64>; - mhi,event-ring = <3>; - mhi,chan-dir = <2>; - mhi,data-type = <0>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x4>; - }; - - mhi_chan@46 { - reg = <46>; - label = "IP_SW_0"; - mhi,num-elements = <512>; - mhi,event-ring = <4>; - mhi,chan-dir = <1>; - mhi,data-type = <1>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x4>; - }; - - mhi_chan@47 { - reg = <47>; - label = "IP_SW_0"; - mhi,num-elements = <512>; - mhi,event-ring = <5>; - mhi,chan-dir = <2>; - mhi,data-type = <4>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x4>; - }; - - mhi_chan@100 { - reg = <100>; - label = "IP_HW0"; - mhi,num-elements = <512>; - mhi,event-ring = <6>; - mhi,chan-dir = <1>; - mhi,data-type = <1>; - mhi,doorbell-mode = <3>; - mhi,ee = <0x4>; - mhi,db-mode-switch; - }; - - mhi_chan@101 { - reg = <101>; - label = "IP_HW0"; - mhi,num-elements = <512>; - mhi,event-ring = <7>; - mhi,chan-dir = <2>; - mhi,data-type = <4>; - mhi,doorbell-mode = <3>; - mhi,ee = <0x4>; - }; - - mhi_chan@105 { - reg = <105>; - label = "IP_HW1"; - mhi,num-elements = <512>; - mhi,event-ring = <8>; - mhi,chan-dir = <1>; - mhi,data-type = <1>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x4>; - }; - - mhi_chan@106 { - reg = <106>; - label = "IP_HW1"; - mhi,num-elements = <512>; - mhi,event-ring = <9>; - mhi,chan-dir = <2>; - mhi,data-type = <4>; - mhi,doorbell-mode = <2>; - mhi,ee = <0x4>; - }; - }; - - mhi_events { - mhi_event@0 { - mhi,num-elements = <32>; - mhi,intmod = <1>; - mhi,msi = <1>; - mhi,priority = <1>; - mhi,brstmode = <2>; - mhi,data-type = <1>; - }; - - mhi_event@1 { - mhi,num-elements = <256>; - mhi,intmod = <1>; - mhi,msi = <2>; - mhi,priority = <1>; - mhi,brstmode = <2>; - }; - - mhi_event@2 { - mhi,num-elements = <256>; - mhi,intmod = <1>; - mhi,msi = <3>; - mhi,priority = <1>; - mhi,brstmode = <2>; - }; - - mhi_event@3 { - mhi,num-elements = <256>; - mhi,intmod = <1>; - mhi,msi = <4>; - mhi,priority = <1>; - mhi,brstmode = <2>; - }; - - mhi_event@4 { - mhi,num-elements = <1024>; - mhi,intmod = <5>; - mhi,msi = <5>; - mhi,chan = <46>; - mhi,priority = <1>; - mhi,brstmode = <2>; - }; - - mhi_event@5 { - mhi,num-elements = <1024>; - mhi,intmod = <5>; - mhi,msi = <6>; - mhi,chan = <47>; - mhi,priority = <1>; - mhi,brstmode = <2>; - mhi,client-manage; - }; - - mhi_event@6 { - mhi,num-elements = <1024>; - mhi,intmod = <5>; - mhi,msi = <5>; - mhi,chan = <100>; - mhi,priority = <1>; - mhi,brstmode = <3>; - mhi,hw-ev; - }; - - mhi_event@7 { - mhi,num-elements = <1024>; - mhi,intmod = <5>; - mhi,msi = <6>; - mhi,chan = <101>; - mhi,priority = <1>; - mhi,brstmode = <3>; - mhi,hw-ev; - mhi,client-manage; - }; - - mhi_event@8 { - mhi,num-elements = <1024>; - mhi,intmod = <0>; - mhi,msi = <7>; - mhi,chan = <105>; - mhi,priority = <1>; - mhi,brstmode = <2>; - mhi,hw-ev; - }; - - mhi_event@9 { - mhi,num-elements = <1024>; - mhi,intmod = <0>; - mhi,msi = <8>; - mhi,chan = <106>; - mhi,priority = <1>; - mhi,brstmode = <2>; - mhi,hw-ev; - mhi,client-manage; - }; - }; - - mhi_devices { - #address-cells = <1>; - #size-cells = <0>; - mhi_netdev_3: mhi_rmnet@0 { - reg = <0x0>; - mhi,chan = "IP_HW0"; - mhi,interface-name = "rmnet_mhi"; - mhi,mru = <0x8000>; - mhi,disable-chain-skb; - }; - - mhi_netdev_4: mhi_rmnet@1 { - reg = <0x1>; - mhi,chan = "IP_HW1"; - mhi,interface-name = "rmnet_mhi"; - mhi,mru = <0x8000>; - mhi,disable-chain-skb; - }; - - mhi_netdev_5: mhi_rmnet@2 { - reg = <0x2>; - mhi,chan = "IP_SW_0"; - mhi,interface-name = "mhi_swip"; - mhi,mru = <0x4000>; - mhi,ethernet-interface; - mhi,disable-chain-skb; - }; - }; - }; -}; diff --git a/arch/arm64/boot/dts/qcom/qcs405.dtsi b/arch/arm64/boot/dts/qcom/qcs405.dtsi index d9187013e918..a8639eb4ec0c 100644 --- a/arch/arm64/boot/dts/qcom/qcs405.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs405.dtsi @@ -139,13 +139,6 @@ sdhc2 = &sdhc_2; /* SDC2 SD Card slot */ qpic_nand1 = &qnand_1; pci-domain0 = &pcie0; /* PCIe0 domain */ - mhi0 = &mhi_0; - mhi_netdev0 = &mhi_netdev_0; - mhi_netdev1 = &mhi_netdev_1; - mhi_netdev2 = &mhi_netdev_2; - mhi_netdev3 = &mhi_netdev_3; - mhi_netdev4 = &mhi_netdev_4; - mhi_netdev5 = &mhi_netdev_5; }; soc: soc { }; @@ -1543,7 +1536,6 @@ #include "qcs405-coresight.dtsi" #include "qcs405-usb.dtsi" #include "qcs405-pcie.dtsi" -#include "qcs405-mhi.dtsi" &i2c_5 { smb1351_otg_supply: smb1351-charger@55 { -- GitLab From 1db981f0ac8b0249f5a8044a54182a75bba03157 Mon Sep 17 00:00:00 2001 From: Anirudh Ghayal Date: Mon, 8 Jul 2019 16:24:39 +0530 Subject: [PATCH 0904/1121] dt-bindings: qpnp-qg: Add properties to specify S2 config in sleep Allow configuring the FIFO length, accumulator length and accumulator interval when system goes to sleep during discharge. Change-Id: I8018f8033d05273320fd92cc7d21fcdce0885df6 Signed-off-by: Anirudh Ghayal --- .../bindings/power/supply/qcom/qpnp-qg.txt | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-qg.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-qg.txt index d754b0b6e027..b00d7c7534d2 100644 --- a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-qg.txt +++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-qg.txt @@ -357,6 +357,38 @@ First Level Node - QGAUGE device the available power. If this property is not specified, then the default value used is 2800 mV. +- qcom,qg-sleep-config + Usage: optional + Value type: bool + Definition: Enables sleep-state configurtion for QG. This + allows configuring the FIFO length, accumulator + interval and the accumulator length when system + enters sleep. + +- qcom,sleep-s2-fifo-length + Usage: optional + Value type: + Definition: The FIFO length to be applied when system enters sleep + while discharging. Takes effect only if + 'qcom,qg-sleep-config' is enabled. the default value + if not specified is 8. + +- qcom,sleep-s2-acc-length + Usage: optional + Value type: + Definition: The accululator length to be applied when system + enters sleep while discharging. Takes effect only if + 'qcom,qg-sleep-config' is enabled. the default value + if not specified is 256. + +- qcom,sleep-s2-acc-intvl-ms + Usage: optional + Value type: + Definition: The accululator count to be applied when system + enters sleep while discharging. Takes effect only if + 'qcom,qg-sleep-config' is enabled. the default value + if not specified is 200ms. + ========================================================== Second Level Nodes - Peripherals managed by QGAUGE driver ========================================================== -- GitLab From 40212054c8ed1a150ae3cab578df126b79d047c1 Mon Sep 17 00:00:00 2001 From: Vinayak Menon Date: Tue, 25 Jun 2019 13:19:32 +0530 Subject: [PATCH 0905/1121] android: lowmemorykiller: disable ALMK during memory offline Make lowmemorykiller aware of memory offline and disable adaptive lowmemorykiller (ALMK) during the offline process. This reduces the unnecessary kills during offlining. ALMK is meant to improve app launch performances, thus not something to be run during offlining. Change-Id: I3bde808cf18db76a787d0a4e864d1d8693f4885b Signed-off-by: Vinayak Menon --- drivers/staging/android/lowmemorykiller.c | 38 +++++++++++++++++++++-- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index e196bdba0dc6..5c7fb1b802cc 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -49,6 +49,7 @@ #include #include #include +#include #define CREATE_TRACE_POINTS #include @@ -111,8 +112,14 @@ static atomic_t shift_adj = ATOMIC_INIT(0); static short adj_max_shift = 353; module_param_named(adj_max_shift, adj_max_shift, short, 0644); +enum { + ADAPTIVE_LMK_DISABLED = 0, + ADAPTIVE_LMK_ENABLED, + ADAPTIVE_LMK_WAS_ENABLED, +}; + /* User knob to enable/disable adaptive lmk feature */ -static int enable_adaptive_lmk; +static int enable_adaptive_lmk = ADAPTIVE_LMK_DISABLED; module_param_named(enable_adaptive_lmk, enable_adaptive_lmk, int, 0644); /* @@ -153,7 +160,7 @@ static int adjust_minadj(short *min_score_adj) { int ret = VMPRESSURE_NO_ADJUST; - if (!enable_adaptive_lmk) + if (enable_adaptive_lmk != ADAPTIVE_LMK_ENABLED) return 0; if (atomic_read(&shift_adj) && @@ -176,7 +183,7 @@ static int lmk_vmpressure_notifier(struct notifier_block *nb, unsigned long pressure = action; int array_size = ARRAY_SIZE(lowmem_adj); - if (!enable_adaptive_lmk) + if (enable_adaptive_lmk != ADAPTIVE_LMK_ENABLED) return 0; if (pressure >= 95) { @@ -678,16 +685,41 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc) return rem; } +static int lmk_hotplug_callback(struct notifier_block *self, + unsigned long action, void *arg) +{ + switch (action) { + case MEM_GOING_OFFLINE: + if (enable_adaptive_lmk == ADAPTIVE_LMK_ENABLED) + enable_adaptive_lmk = ADAPTIVE_LMK_WAS_ENABLED; + break; + case MEM_OFFLINE: + if (enable_adaptive_lmk == ADAPTIVE_LMK_WAS_ENABLED) + enable_adaptive_lmk = ADAPTIVE_LMK_ENABLED; + break; + default: + break; + } + return NOTIFY_OK; +} + static struct shrinker lowmem_shrinker = { .scan_objects = lowmem_scan, .count_objects = lowmem_count, .seeks = DEFAULT_SEEKS * 16 }; +static struct notifier_block lmk_memory_callback_nb = { + .notifier_call = lmk_hotplug_callback, + .priority = 0, +}; + static int __init lowmem_init(void) { register_shrinker(&lowmem_shrinker); vmpressure_notifier_register(&lmk_vmpr_nb); + if (register_hotmemory_notifier(&lmk_memory_callback_nb)) + lowmem_print(1, "Registering memory hotplug notifier failed\n"); return 0; } device_initcall(lowmem_init); -- GitLab From 6416d6ecaf456a6de4ca449b2e54dda2bd408468 Mon Sep 17 00:00:00 2001 From: Zhenhua Huang Date: Tue, 9 Jul 2019 14:42:42 +0800 Subject: [PATCH 0906/1121] ARM: dts: msm: Rename the smmu dtsi file name for atoll Generally the name of smmu dtsi is same as the name of main dtsi. Do the change accordingly. Change-Id: I18df3f3c566073060e81169fd1d6d93fd2472829 Signed-off-by: Zhenhua Huang --- arch/arm64/boot/dts/qcom/atoll.dtsi | 2 +- .../{msm-arm-smmu-sdmatoll.dtsi => msm-arm-smmu-atoll.dtsi} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename arch/arm64/boot/dts/qcom/{msm-arm-smmu-sdmatoll.dtsi => msm-arm-smmu-atoll.dtsi} (100%) diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index 1a729e25c51e..90bfaa9a91b3 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -2085,7 +2085,7 @@ #include "atoll-gdsc.dtsi" #include "atoll-ion.dtsi" -#include "msm-arm-smmu-sdmatoll.dtsi" +#include "msm-arm-smmu-atoll.dtsi" #include "atoll-qupv3.dtsi" #include "sdmmagpie-gpu.dtsi" diff --git a/arch/arm64/boot/dts/qcom/msm-arm-smmu-sdmatoll.dtsi b/arch/arm64/boot/dts/qcom/msm-arm-smmu-atoll.dtsi similarity index 100% rename from arch/arm64/boot/dts/qcom/msm-arm-smmu-sdmatoll.dtsi rename to arch/arm64/boot/dts/qcom/msm-arm-smmu-atoll.dtsi -- GitLab From b4436458772940796bd49bef24a0e9e51fbf7c95 Mon Sep 17 00:00:00 2001 From: Pallavi Date: Thu, 4 Jul 2019 10:39:36 +0530 Subject: [PATCH 0907/1121] ARM: dts: msm: change audio memory type for sdxprairie Change audio memory type to no-map, to prevent allocation to non-audio domain. Change-Id: I5cb2000665627429eb62fa3fc1dca50442429f14 CRs-fixed: 2461466 Signed-off-by: Pallavi --- arch/arm64/boot/dts/qcom/sdxprairie.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sdxprairie.dtsi b/arch/arm64/boot/dts/qcom/sdxprairie.dtsi index 09e144edae38..9ca2c95b20c8 100644 --- a/arch/arm64/boot/dts/qcom/sdxprairie.dtsi +++ b/arch/arm64/boot/dts/qcom/sdxprairie.dtsi @@ -111,7 +111,7 @@ audio_mem: audio_region@0 { compatible = "shared-dma-pool"; - reusable; + no-map; size = <0x400000>; }; -- GitLab From 506b6645b219dff4c5031ac0bab9b51be390d5e4 Mon Sep 17 00:00:00 2001 From: Tharun Kumar Merugu Date: Thu, 6 Jun 2019 21:22:39 +0530 Subject: [PATCH 0908/1121] msm: adsprpc: Check fastrpc channel and context during map and unmap Check if the fastrpc channel and context is created before during map and unmap. Also check for dsp process to be initialized. Change-Id: I0d7195e28e5185dc8d3394d8d1c24b4ec35f7d46 Acked-by: Himateja Reddy Signed-off-by: Tharun Kumar Merugu --- drivers/char/adsprpc.c | 51 ++++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index a404057e647f..5b6af11f9db3 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -377,7 +377,7 @@ struct fastrpc_file { int pd; char *spdname; int file_close; - int dsp_process_init; + int dsp_proc_init; struct fastrpc_apps *apps; struct hlist_head perf; struct dentry *debugfs_file; @@ -1896,12 +1896,13 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode, } } - VERIFY(err, fl->sctx != NULL); - if (err) - goto bail; - VERIFY(err, fl->cid >= 0 && fl->cid < NUM_CHANNELS); - if (err) + VERIFY(err, fl->cid >= 0 && fl->cid < NUM_CHANNELS && fl->sctx != NULL); + if (err) { + pr_err("adsprpc: ERROR: %s: user application %s domain is not set\n", + __func__, current->comm); + err = -EBADR; goto bail; + } if (!kernel) { VERIFY(err, 0 == context_restore_interrupted(fl, inv, @@ -2235,7 +2236,7 @@ static int fastrpc_init_process(struct fastrpc_file *fl, err = -ENOTTY; goto bail; } - fl->dsp_process_init = 1; + fl->dsp_proc_init = 1; bail: kfree(proc_name); if (err && (init->flags == FASTRPC_INIT_CREATE_STATIC)) @@ -2289,7 +2290,7 @@ static int fastrpc_release_current_dsp_process(struct fastrpc_file *fl) ioctl.crc = NULL; VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl, FASTRPC_MODE_PARALLEL, 1, &ioctl))); - if (err && fl->dsp_process_init) + if (err && fl->dsp_proc_init) pr_err("adsprpc: %s: releasing DSP process failed for %s, returned 0x%x", __func__, current->comm, err); bail: @@ -2580,6 +2581,13 @@ static int fastrpc_internal_munmap(struct fastrpc_file *fl, struct fastrpc_buf *rbuf = NULL, *free = NULL; struct hlist_node *n; + VERIFY(err, fl->dsp_proc_init == 1); + if (err) { + pr_err("adsprpc: ERROR: %s: user application %s trying to unmap without initialization\n", + __func__, current->comm); + err = -EBADR; + goto bail; + } mutex_lock(&fl->internal_map_mutex); spin_lock(&fl->hlock); @@ -2635,6 +2643,13 @@ static int fastrpc_internal_munmap_fd(struct fastrpc_file *fl, VERIFY(err, (fl && ud)); if (err) goto bail; + VERIFY(err, fl->dsp_proc_init == 1); + if (err) { + pr_err("adsprpc: ERROR: %s: user application %s trying to unmap without initialization\n", + __func__, current->comm); + err = -EBADR; + goto bail; + } mutex_lock(&fl->map_mutex); if (fastrpc_mmap_find(fl, ud->fd, ud->va, ud->len, 0, 0, &map)) { pr_err("adsprpc: mapping not found to unmap fd 0x%x, va 0x%llx, len 0x%x\n", @@ -2661,6 +2676,13 @@ static int fastrpc_internal_mmap(struct fastrpc_file *fl, uintptr_t raddr = 0; int err = 0; + VERIFY(err, fl->dsp_proc_init == 1); + if (err) { + pr_err("adsprpc: ERROR: %s: user application %s trying to map without initialization\n", + __func__, current->comm); + err = -EBADR; + goto bail; + } mutex_lock(&fl->internal_map_mutex); if (ud->flags == ADSP_MMAP_ADD_PAGES) { if (ud->vaddrin) { @@ -3191,13 +3213,14 @@ static int fastrpc_channel_open(struct fastrpc_file *fl) int cid, err = 0; - VERIFY(err, fl && fl->sctx); - if (err) + VERIFY(err, fl && fl->sctx && fl->cid >= 0 && fl->cid < NUM_CHANNELS); + if (err) { + pr_err("adsprpc: ERROR: %s: user application %s domain is not set\n", + __func__, current->comm); + err = -EBADR; return err; + } cid = fl->cid; - VERIFY(err, cid >= 0 && cid < NUM_CHANNELS); - if (err) - return err; mutex_lock(&me->channel[cid].rpmsg_mutex); VERIFY(err, NULL != me->channel[cid].rpdev); @@ -3294,7 +3317,7 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp) fl->debugfs_file = debugfs_file; memset(&fl->perf, 0, sizeof(fl->perf)); fl->qos_request = 0; - fl->dsp_process_init = 0; + fl->dsp_proc_init = 0; filp->private_data = fl; mutex_init(&fl->internal_map_mutex); mutex_init(&fl->map_mutex); -- GitLab From de0c90774523a59719ba78dbb1ffc8081e6745fc Mon Sep 17 00:00:00 2001 From: Chandana Kishori Chiluveru Date: Wed, 26 Jun 2019 19:07:32 +0530 Subject: [PATCH 0909/1121] ARM: dts: msm: Add dtsi entries of QMP PHY and QUSB2PHY for ATOLL This change adds dtsi node for QMP PHY and QUSB2PHY, Add macro definitions in a dt-bindings header file for all the QMP USB DP register offsets. Also adds extcon handles to support USB type-c or uAB connectors on ATOLL. In case of uAB connector charger driver provides extcon notifications whereas for Type-C connector case PD driver provides extcon notifications. Change-Id: I97904882be2d082494b456b032e7eecae6a2384b Signed-off-by: Chandana Kishori Chiluveru --- arch/arm64/boot/dts/qcom/atoll-usb.dtsi | 242 +++++++ arch/arm64/boot/dts/qcom/atoll.dtsi | 8 + include/dt-bindings/phy/qcom,atoll-qmp-usb3.h | 646 ++++++++++++++++++ 3 files changed, 896 insertions(+) create mode 100644 include/dt-bindings/phy/qcom,atoll-qmp-usb3.h diff --git a/arch/arm64/boot/dts/qcom/atoll-usb.dtsi b/arch/arm64/boot/dts/qcom/atoll-usb.dtsi index 1dc6626553fc..90b79a03bf55 100644 --- a/arch/arm64/boot/dts/qcom/atoll-usb.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll-usb.dtsi @@ -12,6 +12,7 @@ #include #include +#include &soc { usb0: ssusb@a600000 { @@ -28,6 +29,7 @@ interrupt-names = "dp_hs_phy_irq", "pwr_event_irq", "ss_phy_irq", "dm_hs_phy_irq"; USB3_GDSC-supply = <&usb30_prim_gdsc>; + dpdm-supply = <&qusb_phy0>; qcom,use-pdc-interrupts; clocks = <&clock_gcc GCC_USB30_PRIM_MASTER_CLK>, @@ -81,10 +83,12 @@ , ; + qcom,default-bus-vote = <2>; /* use svs bus voting */ dwc3@a600000 { compatible = "snps,dwc3"; reg = <0x0a600000 0xcd00>; interrupts = <0 133 0>; + usb-phy = <&qusb_phy0>, <&usb_qmp_dp_phy>; linux,sysdev_is_parent; snps,disable-clk-gating; snps,dis_u2_susphy_quirk; @@ -127,4 +131,242 @@ }; }; }; + + /* Primary USB port related QUSB2 PHY */ + qusb_phy0: qusb@88e2000 { + compatible = "qcom,qusb2phy-v2"; + reg = <0x088e2000 0x400>, + <0x00780200 0x4>, + <0x088e7014 0x4>; + reg-names = "qusb_phy_base", "efuse_addr", + "refgen_north_bg_reg_addr"; + + qcom,efuse-bit-pos = <25>; + qcom,efuse-num-bits = <3>; + vdd-supply = <&pm6150_l4>; + vdda18-supply = <&pm6150_l11>; + vdda33-supply = <&pm6150_l17>; + qcom,vdd-voltage-level = <0 880000 880000>; + qcom,qusb-phy-reg-offset = + <0x240 /* QUSB2PHY_PORT_TUNE1 */ + 0x1a0 /* QUSB2PHY_PLL_COMMON_STATUS_ONE */ + 0x210 /* QUSB2PHY_PWR_CTRL1 */ + 0x230 /* QUSB2PHY_INTR_CTRL */ + 0x0a8 /* QUSB2PHY_PLL_CORE_INPUT_OVERRIDE */ + 0x254 /* QUSB2PHY_TEST1 */ + 0x198 /* PLL_BIAS_CONTROL_2 */ + 0x27c /* QUSB2PHY_DEBUG_CTRL1 */ + 0x280 /* QUSB2PHY_DEBUG_CTRL2 */ + 0x2a0>; /* QUSB2PHY_STAT5 */ + + qcom,qusb-phy-init-seq = + /* */ + <0x23 0x210 /* PWR_CTRL1 */ + 0x03 0x04 /* PLL_ANALOG_CONTROLS_TWO */ + 0x7c 0x18c /* PLL_CLOCK_INVERTERS */ + 0x80 0x2c /* PLL_CMODE */ + 0x0a 0x184 /* PLL_LOCK_DELAY */ + 0x19 0xb4 /* PLL_DIGITAL_TIMERS_TWO */ + 0x40 0x194 /* PLL_BIAS_CONTROL_1 */ + 0x22 0x198 /* PLL_BIAS_CONTROL_2 */ + 0x21 0x214 /* PWR_CTRL2 */ + 0x08 0x220 /* IMP_CTRL1 */ + 0x58 0x224 /* IMP_CTRL2 */ + 0x45 0x240 /* TUNE1 */ + 0x29 0x244 /* TUNE2 */ + 0xca 0x248 /* TUNE3 */ + 0x04 0x24c /* TUNE4 */ + 0x03 0x250 /* TUNE5 */ + 0x30 0x23c /* CHG_CTRL2 */ + 0x22 0x210>; /* PWR_CTRL1 */ + + qcom,qusb-phy-host-init-seq = + /* */ + <0x23 0x210 /* PWR_CTRL1 */ + 0x03 0x04 /* PLL_ANALOG_CONTROLS_TWO */ + 0x7c 0x18c /* PLL_CLOCK_INVERTERS */ + 0x80 0x2c /* PLL_CMODE */ + 0x0a 0x184 /* PLL_LOCK_DELAY */ + 0x19 0xb4 /* PLL_DIGITAL_TIMERS_TWO */ + 0x40 0x194 /* PLL_BIAS_CONTROL_1 */ + 0x22 0x198 /* PLL_BIAS_CONTROL_2 */ + 0x21 0x214 /* PWR_CTRL2 */ + 0x08 0x220 /* IMP_CTRL1 */ + 0x58 0x224 /* IMP_CTRL2 */ + 0x45 0x240 /* TUNE1 */ + 0x29 0x244 /* TUNE2 */ + 0xca 0x248 /* TUNE3 */ + 0x04 0x24c /* TUNE4 */ + 0x03 0x250 /* TUNE5 */ + 0x30 0x23c /* CHG_CTRL2 */ + 0x22 0x210>; /* PWR_CTRL1 */ + + phy_type= "utmi"; + clocks = <&clock_rpmh RPMH_CXO_CLK>, + <&clock_gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>; + clock-names = "ref_clk_src", "cfg_ahb_clk"; + + resets = <&clock_gcc GCC_QUSB2PHY_PRIM_BCR>; + reset-names = "phy_reset"; + }; + + /* Primary USB port related QMP USB DP Combo PHY */ + usb_qmp_dp_phy: ssphy@88e8000 { + compatible = "qcom,usb-ssphy-qmp-dp-combo"; + reg = <0x88e8000 0x3000>; + reg-names = "qmp_phy_base"; + vdd-supply = <&pm6150_l4>; + qcom,vdd-voltage-level = <0 880000 880000>; + core-supply = <&pm6150l_l3>; + qcom,vbus-valid-override; + qcom,qmp-phy-init-seq = + /* */ + ; + + qcom,qmp-phy-reg-offset = + ; + + clocks = <&clock_gcc GCC_USB3_PRIM_PHY_AUX_CLK>, + <&clock_gcc GCC_USB3_PRIM_PHY_PIPE_CLK>, + <&clock_rpmh RPMH_CXO_CLK>, + <&clock_gcc GCC_USB3_PRIM_CLKREF_CLK>, + <&clock_gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>, + <&clock_gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>; + clock-names = "aux_clk", "pipe_clk", "ref_clk_src", + "ref_clk", "com_aux_clk", "cfg_ahb_clk"; + + resets = <&clock_gcc GCC_USB3_DP_PHY_PRIM_BCR>, + <&clock_gcc GCC_USB3_PHY_PRIM_BCR>; + reset-names = "global_phy_reset", "phy_reset"; + }; + + usb_audio_qmi_dev { + compatible = "qcom,usb-audio-qmi-dev"; + iommus = <&apps_smmu 0x1b2f 0x0>; + qcom,usb-audio-stream-id = <0xf>; + qcom,usb-audio-intr-num = <2>; + }; }; diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index 1a729e25c51e..8dca00a6630f 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -2166,6 +2166,14 @@ #include "atoll-usb.dtsi" #include "atoll-vidc.dtsi" +&usb0 { + extcon = <&pm6150_pdphy>, <&pm6150_charger>; +}; + +&usb_qmp_dp_phy { + extcon = <&pm6150_pdphy>; +}; + &pm6150_vadc { pinctrl-names = "default"; pinctrl-0 = <&nvm_therm_default &sdm_skin_therm_default>; diff --git a/include/dt-bindings/phy/qcom,atoll-qmp-usb3.h b/include/dt-bindings/phy/qcom,atoll-qmp-usb3.h new file mode 100644 index 000000000000..8eb478311975 --- /dev/null +++ b/include/dt-bindings/phy/qcom,atoll-qmp-usb3.h @@ -0,0 +1,646 @@ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _DT_BINDINGS_PHY_QCOM_ATOLL_QMP_USB_H +#define _DT_BINDINGS_PHY_QCOM_ATOLL_QMP_USB_H + +/* USB3-DP Combo PHY register offsets */ + +#define USB3_DP_COM_PHY_MODE_CTRL 0x0000 +#define USB3_DP_COM_SW_RESET 0x0004 +#define USB3_DP_COM_POWER_DOWN_CTRL 0x0008 +#define USB3_DP_COM_SWI_CTRL 0x000c +#define USB3_DP_COM_TYPEC_CTRL 0x0010 +#define USB3_DP_COM_TYPEC_PWRDN_CTRL 0x0014 +#define USB3_DP_COM_DP_BIST_CFG_0 0x0018 +#define USB3_DP_COM_RESET_OVRD_CTRL 0x001c +#define USB3_DP_COM_TYPEC_STATUS 0x0020 +#define USB3_DP_COM_PLACEHOLDER_STATUS 0x0024 +#define USB3_DP_COM_REVISION_ID0 0x0028 +#define USB3_DP_COM_REVISION_ID1 0x002c +#define USB3_DP_COM_REVISION_ID2 0x0030 +#define USB3_DP_COM_REVISION_ID3 0x0034 +#define USB3_DP_QSERDES_COM_ATB_SEL1 0x1000 +#define USB3_DP_QSERDES_COM_ATB_SEL2 0x1004 +#define USB3_DP_QSERDES_COM_FREQ_UPDATE 0x1008 +#define USB3_DP_QSERDES_COM_BG_TIMER 0x100c +#define USB3_DP_QSERDES_COM_SSC_EN_CENTER 0x1010 +#define USB3_DP_QSERDES_COM_SSC_ADJ_PER1 0x1014 +#define USB3_DP_QSERDES_COM_SSC_ADJ_PER2 0x1018 +#define USB3_DP_QSERDES_COM_SSC_PER1 0x101c +#define USB3_DP_QSERDES_COM_SSC_PER2 0x1020 +#define USB3_DP_QSERDES_COM_SSC_STEP_SIZE1 0x1024 +#define USB3_DP_QSERDES_COM_SSC_STEP_SIZE2 0x1028 +#define USB3_DP_QSERDES_COM_POST_DIV 0x102c +#define USB3_DP_QSERDES_COM_POST_DIV_MUX 0x1030 +#define USB3_DP_QSERDES_COM_BIAS_EN_CLKBUFLR_EN 0x1034 +#define USB3_DP_QSERDES_COM_CLK_ENABLE1 0x1038 +#define USB3_DP_QSERDES_COM_SYS_CLK_CTRL 0x103c +#define USB3_DP_QSERDES_COM_SYSCLK_BUF_ENABLE 0x1040 +#define USB3_DP_QSERDES_COM_PLL_EN 0x1044 +#define USB3_DP_QSERDES_COM_PLL_IVCO 0x1048 +#define USB3_DP_QSERDES_COM_CMN_IETRIM 0x104c +#define USB3_DP_QSERDES_COM_CMN_IPTRIM 0x1050 +#define USB3_DP_QSERDES_COM_EP_CLOCK_DETECT_CTRL 0x1054 +#define USB3_DP_QSERDES_COM_SYSCLK_DET_COMP_STATUS 0x1058 +#define USB3_DP_QSERDES_COM_CLK_EP_DIV 0x105c +#define USB3_DP_QSERDES_COM_CP_CTRL_MODE0 0x1060 +#define USB3_DP_QSERDES_COM_CP_CTRL_MODE1 0x1064 +#define USB3_DP_QSERDES_COM_PLL_RCTRL_MODE0 0x1068 +#define USB3_DP_QSERDES_COM_PLL_RCTRL_MODE1 0x106c +#define USB3_DP_QSERDES_COM_PLL_CCTRL_MODE0 0x1070 +#define USB3_DP_QSERDES_COM_PLL_CCTRL_MODE1 0x1074 +#define USB3_DP_QSERDES_COM_PLL_CNTRL 0x1078 +#define USB3_DP_QSERDES_COM_BIAS_EN_CTRL_BY_PSM 0x107c +#define USB3_DP_QSERDES_COM_SYSCLK_EN_SEL 0x1080 +#define USB3_DP_QSERDES_COM_CML_SYSCLK_SEL 0x1084 +#define USB3_DP_QSERDES_COM_RESETSM_CNTRL 0x1088 +#define USB3_DP_QSERDES_COM_RESETSM_CNTRL2 0x108c +#define USB3_DP_QSERDES_COM_LOCK_CMP_EN 0x1090 +#define USB3_DP_QSERDES_COM_LOCK_CMP_CFG 0x1094 +#define USB3_DP_QSERDES_COM_LOCK_CMP1_MODE0 0x1098 +#define USB3_DP_QSERDES_COM_LOCK_CMP2_MODE0 0x109c +#define USB3_DP_QSERDES_COM_LOCK_CMP3_MODE0 0x10a0 +#define USB3_DP_QSERDES_COM_LOCK_CMP1_MODE1 0x10a4 +#define USB3_DP_QSERDES_COM_LOCK_CMP2_MODE1 0x10a8 +#define USB3_DP_QSERDES_COM_LOCK_CMP3_MODE1 0x10ac +#define USB3_DP_QSERDES_COM_DEC_START_MODE0 0x10b0 +#define USB3_DP_QSERDES_COM_DEC_START_MODE1 0x10b4 +#define USB3_DP_QSERDES_COM_DIV_FRAC_START1_MODE0 0x10b8 +#define USB3_DP_QSERDES_COM_DIV_FRAC_START2_MODE0 0x10bc +#define USB3_DP_QSERDES_COM_DIV_FRAC_START3_MODE0 0x10c0 +#define USB3_DP_QSERDES_COM_DIV_FRAC_START1_MODE1 0x10c4 +#define USB3_DP_QSERDES_COM_DIV_FRAC_START2_MODE1 0x10c8 +#define USB3_DP_QSERDES_COM_DIV_FRAC_START3_MODE1 0x10cc +#define USB3_DP_QSERDES_COM_INTEGLOOP_INITVAL 0x10d0 +#define USB3_DP_QSERDES_COM_INTEGLOOP_EN 0x10d4 +#define USB3_DP_QSERDES_COM_INTEGLOOP_GAIN0_MODE0 0x10d8 +#define USB3_DP_QSERDES_COM_INTEGLOOP_GAIN1_MODE0 0x10dc +#define USB3_DP_QSERDES_COM_INTEGLOOP_GAIN0_MODE1 0x10e0 +#define USB3_DP_QSERDES_COM_INTEGLOOP_GAIN1_MODE1 0x10e4 +#define USB3_DP_QSERDES_COM_VCOCAL_DEADMAN_CTRL 0x10e8 +#define USB3_DP_QSERDES_COM_VCO_TUNE_CTRL 0x10ec +#define USB3_DP_QSERDES_COM_VCO_TUNE_MAP 0x10f0 +#define USB3_DP_QSERDES_COM_VCO_TUNE1_MODE0 0x10f4 +#define USB3_DP_QSERDES_COM_VCO_TUNE2_MODE0 0x10f8 +#define USB3_DP_QSERDES_COM_VCO_TUNE1_MODE1 0x10fc +#define USB3_DP_QSERDES_COM_VCO_TUNE2_MODE1 0x1100 +#define USB3_DP_QSERDES_COM_VCO_TUNE_INITVAL1 0x1104 +#define USB3_DP_QSERDES_COM_VCO_TUNE_INITVAL2 0x1108 +#define USB3_DP_QSERDES_COM_VCO_TUNE_MINVAL1 0x110c +#define USB3_DP_QSERDES_COM_VCO_TUNE_MINVAL2 0x1110 +#define USB3_DP_QSERDES_COM_VCO_TUNE_MAXVAL1 0x1114 +#define USB3_DP_QSERDES_COM_VCO_TUNE_MAXVAL2 0x1118 +#define USB3_DP_QSERDES_COM_VCO_TUNE_TIMER1 0x111c +#define USB3_DP_QSERDES_COM_VCO_TUNE_TIMER2 0x1120 +#define USB3_DP_QSERDES_COM_CMN_STATUS 0x1124 +#define USB3_DP_QSERDES_COM_RESET_SM_STATUS 0x1128 +#define USB3_DP_QSERDES_COM_RESTRIM_CODE_STATUS 0x112c +#define USB3_DP_QSERDES_COM_PLLCAL_CODE1_STATUS 0x1130 +#define USB3_DP_QSERDES_COM_PLLCAL_CODE2_STATUS 0x1134 +#define USB3_DP_QSERDES_COM_CLK_SELECT 0x1138 +#define USB3_DP_QSERDES_COM_HSCLK_SEL 0x113c +#define USB3_DP_QSERDES_COM_INTEGLOOP_BINCODE_STATUS 0x1140 +#define USB3_DP_QSERDES_COM_PLL_ANALOG 0x1144 +#define USB3_DP_QSERDES_COM_CORECLK_DIV_MODE0 0x1148 +#define USB3_DP_QSERDES_COM_CORECLK_DIV_MODE1 0x114c +#define USB3_DP_QSERDES_COM_SW_RESET 0x1150 +#define USB3_DP_QSERDES_COM_CORE_CLK_EN 0x1154 +#define USB3_DP_QSERDES_COM_C_READY_STATUS 0x1158 +#define USB3_DP_QSERDES_COM_CMN_CONFIG 0x115c +#define USB3_DP_QSERDES_COM_CMN_RATE_OVERRIDE 0x1160 +#define USB3_DP_QSERDES_COM_SVS_MODE_CLK_SEL 0x1164 +#define USB3_DP_QSERDES_COM_DEBUG_BUS0 0x1168 +#define USB3_DP_QSERDES_COM_DEBUG_BUS1 0x116c +#define USB3_DP_QSERDES_COM_DEBUG_BUS2 0x1170 +#define USB3_DP_QSERDES_COM_DEBUG_BUS3 0x1174 +#define USB3_DP_QSERDES_COM_DEBUG_BUS_SEL 0x1178 +#define USB3_DP_QSERDES_COM_CMN_MISC1 0x117c +#define USB3_DP_QSERDES_COM_CMN_MISC2 0x1180 +#define USB3_DP_QSERDES_COM_CMN_MODE 0x1184 +#define USB3_DP_QSERDES_COM_CMN_VREG_SEL 0x1188 +#define USB3_DP_QSERDES_TXA_BIST_MODE_LANENO 0x1200 +#define USB3_DP_QSERDES_TXA_BIST_INVERT 0x1204 +#define USB3_DP_QSERDES_TXA_CLKBUF_ENABLE 0x1208 +#define USB3_DP_QSERDES_TXA_TX_EMP_POST1_LVL 0x120c +#define USB3_DP_QSERDES_TXA_TX_POST2_EMPH 0x1210 +#define USB3_DP_QSERDES_TXA_TX_BOOST_LVL_UP_DN 0x1214 +#define USB3_DP_QSERDES_TXA_TX_IDLE_LVL_LARGE_AMP 0x1218 +#define USB3_DP_QSERDES_TXA_TX_DRV_LVL 0x121c +#define USB3_DP_QSERDES_TXA_TX_DRV_LVL_OFFSET 0x1220 +#define USB3_DP_QSERDES_TXA_RESET_TSYNC_EN 0x1224 +#define USB3_DP_QSERDES_TXA_PRE_STALL_LDO_BOOST_EN 0x1228 +#define USB3_DP_QSERDES_TXA_TX_BAND 0x122c +#define USB3_DP_QSERDES_TXA_SLEW_CNTL 0x1230 +#define USB3_DP_QSERDES_TXA_INTERFACE_SELECT 0x1234 +#define USB3_DP_QSERDES_TXA_LPB_EN 0x1238 +#define USB3_DP_QSERDES_TXA_RES_CODE_LANE_TX 0x123c +#define USB3_DP_QSERDES_TXA_RES_CODE_LANE_RX 0x1240 +#define USB3_DP_QSERDES_TXA_RES_CODE_LANE_OFFSET_TX 0x1244 +#define USB3_DP_QSERDES_TXA_RES_CODE_LANE_OFFSET_RX 0x1248 +#define USB3_DP_QSERDES_TXA_PERL_LENGTH1 0x124c +#define USB3_DP_QSERDES_TXA_PERL_LENGTH2 0x1250 +#define USB3_DP_QSERDES_TXA_SERDES_BYP_EN_OUT 0x1254 +#define USB3_DP_QSERDES_TXA_DEBUG_BUS_SEL 0x1258 +#define USB3_DP_QSERDES_TXA_TRANSCEIVER_BIAS_EN 0x125c +#define USB3_DP_QSERDES_TXA_HIGHZ_DRVR_EN 0x1260 +#define USB3_DP_QSERDES_TXA_TX_POL_INV 0x1264 +#define USB3_DP_QSERDES_TXA_PARRATE_REC_DETECT_IDLE_EN 0x1268 +#define USB3_DP_QSERDES_TXA_BIST_PATTERN1 0x126c +#define USB3_DP_QSERDES_TXA_BIST_PATTERN2 0x1270 +#define USB3_DP_QSERDES_TXA_BIST_PATTERN3 0x1274 +#define USB3_DP_QSERDES_TXA_BIST_PATTERN4 0x1278 +#define USB3_DP_QSERDES_TXA_BIST_PATTERN5 0x127c +#define USB3_DP_QSERDES_TXA_BIST_PATTERN6 0x1280 +#define USB3_DP_QSERDES_TXA_BIST_PATTERN7 0x1284 +#define USB3_DP_QSERDES_TXA_BIST_PATTERN8 0x1288 +#define USB3_DP_QSERDES_TXA_LANE_MODE_1 0x128c +#define USB3_DP_QSERDES_TXA_LANE_MODE_2 0x1290 +#define USB3_DP_QSERDES_TXA_LANE_MODE_3 0x1294 +#define USB3_DP_QSERDES_TXA_ATB_SEL1 0x1298 +#define USB3_DP_QSERDES_TXA_ATB_SEL2 0x129c +#define USB3_DP_QSERDES_TXA_RCV_DETECT_LVL 0x12a0 +#define USB3_DP_QSERDES_TXA_RCV_DETECT_LVL_2 0x12a4 +#define USB3_DP_QSERDES_TXA_PRBS_SEED1 0x12a8 +#define USB3_DP_QSERDES_TXA_PRBS_SEED2 0x12ac +#define USB3_DP_QSERDES_TXA_PRBS_SEED3 0x12b0 +#define USB3_DP_QSERDES_TXA_PRBS_SEED4 0x12b4 +#define USB3_DP_QSERDES_TXA_RESET_GEN 0x12b8 +#define USB3_DP_QSERDES_TXA_RESET_GEN_MUXES 0x12bc +#define USB3_DP_QSERDES_TXA_TRAN_DRVR_EMP_EN 0x12c0 +#define USB3_DP_QSERDES_TXA_TX_INTERFACE_MODE 0x12c4 +#define USB3_DP_QSERDES_TXA_PWM_CTRL 0x12c8 +#define USB3_DP_QSERDES_TXA_PWM_ENCODED_OR_DATA 0x12cc +#define USB3_DP_QSERDES_TXA_PWM_GEAR_1_DIVIDER_BAND2 0x12d0 +#define USB3_DP_QSERDES_TXA_PWM_GEAR_2_DIVIDER_BAND2 0x12d4 +#define USB3_DP_QSERDES_TXA_PWM_GEAR_3_DIVIDER_BAND2 0x12d8 +#define USB3_DP_QSERDES_TXA_PWM_GEAR_4_DIVIDER_BAND2 0x12dc +#define USB3_DP_QSERDES_TXA_PWM_GEAR_1_DIVIDER_BAND0_1 0x12e0 +#define USB3_DP_QSERDES_TXA_PWM_GEAR_2_DIVIDER_BAND0_1 0x12e4 +#define USB3_DP_QSERDES_TXA_PWM_GEAR_3_DIVIDER_BAND0_1 0x12e8 +#define USB3_DP_QSERDES_TXA_PWM_GEAR_4_DIVIDER_BAND0_1 0x12ec +#define USB3_DP_QSERDES_TXA_VMODE_CTRL1 0x12f0 +#define USB3_DP_QSERDES_TXA_ALOG_OBSV_BUS_CTRL_1 0x12f4 +#define USB3_DP_QSERDES_TXA_BIST_STATUS 0x12f8 +#define USB3_DP_QSERDES_TXA_BIST_ERROR_COUNT1 0x12fc +#define USB3_DP_QSERDES_TXA_BIST_ERROR_COUNT2 0x1300 +#define USB3_DP_QSERDES_TXA_ALOG_OBSV_BUS_STATUS_1 0x1304 +#define USB3_DP_QSERDES_RXA_UCDR_FO_GAIN_HALF 0x1400 +#define USB3_DP_QSERDES_RXA_UCDR_FO_GAIN_QUARTER 0x1404 +#define USB3_DP_QSERDES_RXA_UCDR_FO_GAIN 0x1408 +#define USB3_DP_QSERDES_RXA_UCDR_SO_GAIN_HALF 0x140c +#define USB3_DP_QSERDES_RXA_UCDR_SO_GAIN_QUARTER 0x1410 +#define USB3_DP_QSERDES_RXA_UCDR_SO_GAIN 0x1414 +#define USB3_DP_QSERDES_RXA_UCDR_SVS_FO_GAIN_HALF 0x1418 +#define USB3_DP_QSERDES_RXA_UCDR_SVS_FO_GAIN_QUARTER 0x141c +#define USB3_DP_QSERDES_RXA_UCDR_SVS_FO_GAIN 0x1420 +#define USB3_DP_QSERDES_RXA_UCDR_SVS_SO_GAIN_HALF 0x1424 +#define USB3_DP_QSERDES_RXA_UCDR_SVS_SO_GAIN_QUARTER 0x1428 +#define USB3_DP_QSERDES_RXA_UCDR_SVS_SO_GAIN 0x142c +#define USB3_DP_QSERDES_RXA_UCDR_FASTLOCK_FO_GAIN 0x1430 +#define USB3_DP_QSERDES_RXA_UCDR_SO_SATURATION_AND_ENABLE 0x1434 +#define USB3_DP_QSERDES_RXA_UCDR_FO_TO_SO_DELAY 0x1438 +#define USB3_DP_QSERDES_RXA_UCDR_FASTLOCK_COUNT_LOW 0x143c +#define USB3_DP_QSERDES_RXA_UCDR_FASTLOCK_COUNT_HIGH 0x1440 +#define USB3_DP_QSERDES_RXA_UCDR_PI_CONTROLS 0x1444 +#define USB3_DP_QSERDES_RXA_UCDR_SB2_THRESH1 0x1448 +#define USB3_DP_QSERDES_RXA_UCDR_SB2_THRESH2 0x144c +#define USB3_DP_QSERDES_RXA_UCDR_SB2_GAIN1 0x1450 +#define USB3_DP_QSERDES_RXA_UCDR_SB2_GAIN2 0x1454 +#define USB3_DP_QSERDES_RXA_AUX_CONTROL 0x1458 +#define USB3_DP_QSERDES_RXA_AUX_DATA_TCOARSE_TFINE 0x145c +#define USB3_DP_QSERDES_RXA_RCLK_AUXDATA_SEL 0x1460 +#define USB3_DP_QSERDES_RXA_AC_JTAG_ENABLE 0x1464 +#define USB3_DP_QSERDES_RXA_AC_JTAG_INITP 0x1468 +#define USB3_DP_QSERDES_RXA_AC_JTAG_INITN 0x146c +#define USB3_DP_QSERDES_RXA_AC_JTAG_LVL 0x1470 +#define USB3_DP_QSERDES_RXA_AC_JTAG_MODE 0x1474 +#define USB3_DP_QSERDES_RXA_AC_JTAG_RESET 0x1478 +#define USB3_DP_QSERDES_RXA_RX_TERM_BW 0x147c +#define USB3_DP_QSERDES_RXA_RX_RCVR_IQ_EN 0x1480 +#define USB3_DP_QSERDES_RXA_RX_IDAC_I_DC_OFFSETS 0x1484 +#define USB3_DP_QSERDES_RXA_RX_IDAC_IBAR_DC_OFFSETS 0x1488 +#define USB3_DP_QSERDES_RXA_RX_IDAC_Q_DC_OFFSETS 0x148c +#define USB3_DP_QSERDES_RXA_RX_IDAC_QBAR_DC_OFFSETS 0x1490 +#define USB3_DP_QSERDES_RXA_RX_IDAC_A_DC_OFFSETS 0x1494 +#define USB3_DP_QSERDES_RXA_RX_IDAC_ABAR_DC_OFFSETS 0x1498 +#define USB3_DP_QSERDES_RXA_RX_IDAC_EN 0x149c +#define USB3_DP_QSERDES_RXA_RX_IDAC_ENABLES 0x14a0 +#define USB3_DP_QSERDES_RXA_RX_IDAC_SIGN 0x14a4 +#define USB3_DP_QSERDES_RXA_RX_HIGHZ_HIGHRATE 0x14a8 +#define USB3_DP_QSERDES_RXA_RX_TERM_AC_BYPASS_DC_COUPLE_OFFSET 0x14ac +#define USB3_DP_QSERDES_RXA_DFE_1 0x14b0 +#define USB3_DP_QSERDES_RXA_DFE_2 0x14b4 +#define USB3_DP_QSERDES_RXA_DFE_3 0x14b8 +#define USB3_DP_QSERDES_RXA_VGA_CAL_CNTRL1 0x14bc +#define USB3_DP_QSERDES_RXA_VGA_CAL_CNTRL2 0x14c0 +#define USB3_DP_QSERDES_RXA_GM_CAL 0x14c4 +#define USB3_DP_QSERDES_RXA_RX_EQ_GAIN2_LSB 0x14c8 +#define USB3_DP_QSERDES_RXA_RX_EQ_GAIN2_MSB 0x14cc +#define USB3_DP_QSERDES_RXA_RX_EQU_ADAPTOR_CNTRL1 0x14d0 +#define USB3_DP_QSERDES_RXA_RX_EQU_ADAPTOR_CNTRL2 0x14d4 +#define USB3_DP_QSERDES_RXA_RX_EQU_ADAPTOR_CNTRL3 0x14d8 +#define USB3_DP_QSERDES_RXA_RX_EQU_ADAPTOR_CNTRL4 0x14dc +#define USB3_DP_QSERDES_RXA_RX_IDAC_TSETTLE_LOW 0x14e0 +#define USB3_DP_QSERDES_RXA_RX_IDAC_TSETTLE_HIGH 0x14e4 +#define USB3_DP_QSERDES_RXA_RX_IDAC_MEASURE_TIME 0x14e8 +#define USB3_DP_QSERDES_RXA_RX_IDAC_ACCUMULATOR 0x14ec +#define USB3_DP_QSERDES_RXA_RX_EQ_OFFSET_LSB 0x14f0 +#define USB3_DP_QSERDES_RXA_RX_EQ_OFFSET_MSB 0x14f4 +#define USB3_DP_QSERDES_RXA_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x14f8 +#define USB3_DP_QSERDES_RXA_RX_OFFSET_ADAPTOR_CNTRL2 0x14fc +#define USB3_DP_QSERDES_RXA_SIGDET_ENABLES 0x1500 +#define USB3_DP_QSERDES_RXA_SIGDET_CNTRL 0x1504 +#define USB3_DP_QSERDES_RXA_SIGDET_LVL 0x1508 +#define USB3_DP_QSERDES_RXA_SIGDET_DEGLITCH_CNTRL 0x150c +#define USB3_DP_QSERDES_RXA_RX_BAND 0x1510 +#define USB3_DP_QSERDES_RXA_CDR_FREEZE_UP_DN 0x1514 +#define USB3_DP_QSERDES_RXA_CDR_RESET_OVERRIDE 0x1518 +#define USB3_DP_QSERDES_RXA_RX_INTERFACE_MODE 0x151c +#define USB3_DP_QSERDES_RXA_JITTER_GEN_MODE 0x1520 +#define USB3_DP_QSERDES_RXA_BUJ_AMP 0x1524 +#define USB3_DP_QSERDES_RXA_SJ_AMP1 0x1528 +#define USB3_DP_QSERDES_RXA_SJ_AMP2 0x152c +#define USB3_DP_QSERDES_RXA_SJ_PER1 0x1530 +#define USB3_DP_QSERDES_RXA_SJ_PER2 0x1534 +#define USB3_DP_QSERDES_RXA_BUJ_STEP_FREQ1 0x1538 +#define USB3_DP_QSERDES_RXA_BUJ_STEP_FREQ2 0x153c +#define USB3_DP_QSERDES_RXA_PPM_OFFSET1 0x1540 +#define USB3_DP_QSERDES_RXA_PPM_OFFSET2 0x1544 +#define USB3_DP_QSERDES_RXA_SIGN_PPM_PERIOD1 0x1548 +#define USB3_DP_QSERDES_RXA_SIGN_PPM_PERIOD2 0x154c +#define USB3_DP_QSERDES_RXA_RX_PWM_ENABLE_AND_DATA 0x1550 +#define USB3_DP_QSERDES_RXA_RX_PWM_GEAR1_TIMEOUT_COUNT 0x1554 +#define USB3_DP_QSERDES_RXA_RX_PWM_GEAR2_TIMEOUT_COUNT 0x1558 +#define USB3_DP_QSERDES_RXA_RX_PWM_GEAR3_TIMEOUT_COUNT 0x155c +#define USB3_DP_QSERDES_RXA_RX_PWM_GEAR4_TIMEOUT_COUNT 0x1560 +#define USB3_DP_QSERDES_RXA_RX_MODE_00 0x1564 +#define USB3_DP_QSERDES_RXA_RX_MODE_01 0x1568 +#define USB3_DP_QSERDES_RXA_RX_MODE_10 0x156c +#define USB3_DP_QSERDES_RXA_ALOG_OBSV_BUS_CTRL_1 0x1570 +#define USB3_DP_QSERDES_RXA_PI_CTRL1 0x1574 +#define USB3_DP_QSERDES_RXA_PI_CTRL2 0x1578 +#define USB3_DP_QSERDES_RXA_PI_QUAD 0x157c +#define USB3_DP_QSERDES_RXA_IDATA1 0x1580 +#define USB3_DP_QSERDES_RXA_IDATA2 0x1584 +#define USB3_DP_QSERDES_RXA_AUX_DATA1 0x1588 +#define USB3_DP_QSERDES_RXA_AUX_DATA2 0x158c +#define USB3_DP_QSERDES_RXA_AC_JTAG_OUTP 0x1590 +#define USB3_DP_QSERDES_RXA_AC_JTAG_OUTN 0x1594 +#define USB3_DP_QSERDES_RXA_RX_SIGDET 0x1598 +#define USB3_DP_QSERDES_RXA_IDAC_STATUS_I 0x159c +#define USB3_DP_QSERDES_RXA_IDAC_STATUS_IBAR 0x15a0 +#define USB3_DP_QSERDES_RXA_IDAC_STATUS_Q 0x15a4 +#define USB3_DP_QSERDES_RXA_IDAC_STATUS_QBAR 0x15a8 +#define USB3_DP_QSERDES_RXA_IDAC_STATUS_A 0x15ac +#define USB3_DP_QSERDES_RXA_IDAC_STATUS_ABAR 0x15b0 +#define USB3_DP_QSERDES_RXA_IDAC_STATUS_SM_ON 0x15b4 +#define USB3_DP_QSERDES_RXA_IDAC_STATUS_CAL_DONE 0x15b8 +#define USB3_DP_QSERDES_RXA_IDAC_STATUS_SIGNERROR 0x15bc +#define USB3_DP_QSERDES_RXA_READ_EQCODE 0x15c0 +#define USB3_DP_QSERDES_RXA_READ_OFFSETCODE 0x15c4 +#define USB3_DP_QSERDES_RXA_IA_ERROR_COUNTER_LOW 0x15c8 +#define USB3_DP_QSERDES_RXA_IA_ERROR_COUNTER_HIGH 0x15cc +#define USB3_DP_QSERDES_RXA_VGA_READ_CODE 0x15d0 +#define USB3_DP_QSERDES_RXA_DFE_TAP1_READ_CODE 0x15d4 +#define USB3_DP_QSERDES_RXA_DFE_TAP2_READ_CODE 0x15d8 +#define USB3_DP_QSERDES_RXA_ALOG_OBSV_BUS_STATUS_1 0x15dc +#define USB3_DP_QSERDES_TXB_BIST_MODE_LANENO 0x1600 +#define USB3_DP_QSERDES_TXB_BIST_INVERT 0x1604 +#define USB3_DP_QSERDES_TXB_CLKBUF_ENABLE 0x1608 +#define USB3_DP_QSERDES_TXB_TX_EMP_POST1_LVL 0x160c +#define USB3_DP_QSERDES_TXB_TX_POST2_EMPH 0x1610 +#define USB3_DP_QSERDES_TXB_TX_BOOST_LVL_UP_DN 0x1614 +#define USB3_DP_QSERDES_TXB_TX_IDLE_LVL_LARGE_AMP 0x1618 +#define USB3_DP_QSERDES_TXB_TX_DRV_LVL 0x161c +#define USB3_DP_QSERDES_TXB_TX_DRV_LVL_OFFSET 0x1620 +#define USB3_DP_QSERDES_TXB_RESET_TSYNC_EN 0x1624 +#define USB3_DP_QSERDES_TXB_PRE_STALL_LDO_BOOST_EN 0x1628 +#define USB3_DP_QSERDES_TXB_TX_BAND 0x162c +#define USB3_DP_QSERDES_TXB_SLEW_CNTL 0x1630 +#define USB3_DP_QSERDES_TXB_INTERFACE_SELECT 0x1634 +#define USB3_DP_QSERDES_TXB_LPB_EN 0x1638 +#define USB3_DP_QSERDES_TXB_RES_CODE_LANE_TX 0x163c +#define USB3_DP_QSERDES_TXB_RES_CODE_LANE_RX 0x1640 +#define USB3_DP_QSERDES_TXB_RES_CODE_LANE_OFFSET_TX 0x1644 +#define USB3_DP_QSERDES_TXB_RES_CODE_LANE_OFFSET_RX 0x1648 +#define USB3_DP_QSERDES_TXB_PERL_LENGTH1 0x164c +#define USB3_DP_QSERDES_TXB_PERL_LENGTH2 0x1650 +#define USB3_DP_QSERDES_TXB_SERDES_BYP_EN_OUT 0x1654 +#define USB3_DP_QSERDES_TXB_DEBUG_BUS_SEL 0x1658 +#define USB3_DP_QSERDES_TXB_TRANSCEIVER_BIAS_EN 0x165c +#define USB3_DP_QSERDES_TXB_HIGHZ_DRVR_EN 0x1660 +#define USB3_DP_QSERDES_TXB_TX_POL_INV 0x1664 +#define USB3_DP_QSERDES_TXB_PARRATE_REC_DETECT_IDLE_EN 0x1668 +#define USB3_DP_QSERDES_TXB_BIST_PATTERN1 0x166c +#define USB3_DP_QSERDES_TXB_BIST_PATTERN2 0x1670 +#define USB3_DP_QSERDES_TXB_BIST_PATTERN3 0x1674 +#define USB3_DP_QSERDES_TXB_BIST_PATTERN4 0x1678 +#define USB3_DP_QSERDES_TXB_BIST_PATTERN5 0x167c +#define USB3_DP_QSERDES_TXB_BIST_PATTERN6 0x1680 +#define USB3_DP_QSERDES_TXB_BIST_PATTERN7 0x1684 +#define USB3_DP_QSERDES_TXB_BIST_PATTERN8 0x1688 +#define USB3_DP_QSERDES_TXB_LANE_MODE_1 0x168c +#define USB3_DP_QSERDES_TXB_LANE_MODE_2 0x1690 +#define USB3_DP_QSERDES_TXB_LANE_MODE_3 0x1694 +#define USB3_DP_QSERDES_TXB_ATB_SEL1 0x1698 +#define USB3_DP_QSERDES_TXB_ATB_SEL2 0x169c +#define USB3_DP_QSERDES_TXB_RCV_DETECT_LVL 0x16a0 +#define USB3_DP_QSERDES_TXB_RCV_DETECT_LVL_2 0x16a4 +#define USB3_DP_QSERDES_TXB_PRBS_SEED1 0x16a8 +#define USB3_DP_QSERDES_TXB_PRBS_SEED2 0x16ac +#define USB3_DP_QSERDES_TXB_PRBS_SEED3 0x16b0 +#define USB3_DP_QSERDES_TXB_PRBS_SEED4 0x16b4 +#define USB3_DP_QSERDES_TXB_RESET_GEN 0x16b8 +#define USB3_DP_QSERDES_TXB_RESET_GEN_MUXES 0x16bc +#define USB3_DP_QSERDES_TXB_TRAN_DRVR_EMP_EN 0x16c0 +#define USB3_DP_QSERDES_TXB_TX_INTERFACE_MODE 0x16c4 +#define USB3_DP_QSERDES_TXB_PWM_CTRL 0x16c8 +#define USB3_DP_QSERDES_TXB_PWM_ENCODED_OR_DATA 0x16cc +#define USB3_DP_QSERDES_TXB_PWM_GEAR_1_DIVIDER_BAND2 0x16d0 +#define USB3_DP_QSERDES_TXB_PWM_GEAR_2_DIVIDER_BAND2 0x16d4 +#define USB3_DP_QSERDES_TXB_PWM_GEAR_3_DIVIDER_BAND2 0x16d8 +#define USB3_DP_QSERDES_TXB_PWM_GEAR_4_DIVIDER_BAND2 0x16dc +#define USB3_DP_QSERDES_TXB_PWM_GEAR_1_DIVIDER_BAND0_1 0x16e0 +#define USB3_DP_QSERDES_TXB_PWM_GEAR_2_DIVIDER_BAND0_1 0x16e4 +#define USB3_DP_QSERDES_TXB_PWM_GEAR_3_DIVIDER_BAND0_1 0x16e8 +#define USB3_DP_QSERDES_TXB_PWM_GEAR_4_DIVIDER_BAND0_1 0x16ec +#define USB3_DP_QSERDES_TXB_VMODE_CTRL1 0x16f0 +#define USB3_DP_QSERDES_TXB_ALOG_OBSV_BUS_CTRL_1 0x16f4 +#define USB3_DP_QSERDES_TXB_BIST_STATUS 0x16f8 +#define USB3_DP_QSERDES_TXB_BIST_ERROR_COUNT1 0x16fc +#define USB3_DP_QSERDES_TXB_BIST_ERROR_COUNT2 0x1700 +#define USB3_DP_QSERDES_TXB_ALOG_OBSV_BUS_STATUS_1 0x1704 +#define USB3_DP_QSERDES_RXB_UCDR_FO_GAIN_HALF 0x1800 +#define USB3_DP_QSERDES_RXB_UCDR_FO_GAIN_QUARTER 0x1804 +#define USB3_DP_QSERDES_RXB_UCDR_FO_GAIN 0x1808 +#define USB3_DP_QSERDES_RXB_UCDR_SO_GAIN_HALF 0x180c +#define USB3_DP_QSERDES_RXB_UCDR_SO_GAIN_QUARTER 0x1810 +#define USB3_DP_QSERDES_RXB_UCDR_SO_GAIN 0x1814 +#define USB3_DP_QSERDES_RXB_UCDR_SVS_FO_GAIN_HALF 0x1818 +#define USB3_DP_QSERDES_RXB_UCDR_SVS_FO_GAIN_QUARTER 0x181c +#define USB3_DP_QSERDES_RXB_UCDR_SVS_FO_GAIN 0x1820 +#define USB3_DP_QSERDES_RXB_UCDR_SVS_SO_GAIN_HALF 0x1824 +#define USB3_DP_QSERDES_RXB_UCDR_SVS_SO_GAIN_QUARTER 0x1828 +#define USB3_DP_QSERDES_RXB_UCDR_SVS_SO_GAIN 0x182c +#define USB3_DP_QSERDES_RXB_UCDR_FASTLOCK_FO_GAIN 0x1830 +#define USB3_DP_QSERDES_RXB_UCDR_SO_SATURATION_AND_ENABLE 0x1834 +#define USB3_DP_QSERDES_RXB_UCDR_FO_TO_SO_DELAY 0x1838 +#define USB3_DP_QSERDES_RXB_UCDR_FASTLOCK_COUNT_LOW 0x183c +#define USB3_DP_QSERDES_RXB_UCDR_FASTLOCK_COUNT_HIGH 0x1840 +#define USB3_DP_QSERDES_RXB_UCDR_PI_CONTROLS 0x1844 +#define USB3_DP_QSERDES_RXB_UCDR_SB2_THRESH1 0x1848 +#define USB3_DP_QSERDES_RXB_UCDR_SB2_THRESH2 0x184c +#define USB3_DP_QSERDES_RXB_UCDR_SB2_GAIN1 0x1850 +#define USB3_DP_QSERDES_RXB_UCDR_SB2_GAIN2 0x1854 +#define USB3_DP_QSERDES_RXB_AUX_CONTROL 0x1858 +#define USB3_DP_QSERDES_RXB_AUX_DATA_TCOARSE_TFINE 0x185c +#define USB3_DP_QSERDES_RXB_RCLK_AUXDATA_SEL 0x1860 +#define USB3_DP_QSERDES_RXB_AC_JTAG_ENABLE 0x1864 +#define USB3_DP_QSERDES_RXB_AC_JTAG_INITP 0x1868 +#define USB3_DP_QSERDES_RXB_AC_JTAG_INITN 0x186c +#define USB3_DP_QSERDES_RXB_AC_JTAG_LVL 0x1870 +#define USB3_DP_QSERDES_RXB_AC_JTAG_MODE 0x1874 +#define USB3_DP_QSERDES_RXB_AC_JTAG_RESET 0x1878 +#define USB3_DP_QSERDES_RXB_RX_TERM_BW 0x187c +#define USB3_DP_QSERDES_RXB_RX_RCVR_IQ_EN 0x1880 +#define USB3_DP_QSERDES_RXB_RX_IDAC_I_DC_OFFSETS 0x1884 +#define USB3_DP_QSERDES_RXB_RX_IDAC_IBAR_DC_OFFSETS 0x1888 +#define USB3_DP_QSERDES_RXB_RX_IDAC_Q_DC_OFFSETS 0x188c +#define USB3_DP_QSERDES_RXB_RX_IDAC_QBAR_DC_OFFSETS 0x1890 +#define USB3_DP_QSERDES_RXB_RX_IDAC_A_DC_OFFSETS 0x1894 +#define USB3_DP_QSERDES_RXB_RX_IDAC_ABAR_DC_OFFSETS 0x1898 +#define USB3_DP_QSERDES_RXB_RX_IDAC_EN 0x189c +#define USB3_DP_QSERDES_RXB_RX_IDAC_ENABLES 0x18a0 +#define USB3_DP_QSERDES_RXB_RX_IDAC_SIGN 0x18a4 +#define USB3_DP_QSERDES_RXB_RX_HIGHZ_HIGHRATE 0x18a8 +#define USB3_DP_QSERDES_RXB_RX_TERM_AC_BYPASS_DC_COUPLE_OFFSET 0x18ac +#define USB3_DP_QSERDES_RXB_DFE_1 0x18b0 +#define USB3_DP_QSERDES_RXB_DFE_2 0x18b4 +#define USB3_DP_QSERDES_RXB_DFE_3 0x18b8 +#define USB3_DP_QSERDES_RXB_VGA_CAL_CNTRL1 0x18bc +#define USB3_DP_QSERDES_RXB_VGA_CAL_CNTRL2 0x18c0 +#define USB3_DP_QSERDES_RXB_GM_CAL 0x18c4 +#define USB3_DP_QSERDES_RXB_RX_EQ_GAIN2_LSB 0x18c8 +#define USB3_DP_QSERDES_RXB_RX_EQ_GAIN2_MSB 0x18cc +#define USB3_DP_QSERDES_RXB_RX_EQU_ADAPTOR_CNTRL1 0x18d0 +#define USB3_DP_QSERDES_RXB_RX_EQU_ADAPTOR_CNTRL2 0x18d4 +#define USB3_DP_QSERDES_RXB_RX_EQU_ADAPTOR_CNTRL3 0x18d8 +#define USB3_DP_QSERDES_RXB_RX_EQU_ADAPTOR_CNTRL4 0x18dc +#define USB3_DP_QSERDES_RXB_RX_IDAC_TSETTLE_LOW 0x18e0 +#define USB3_DP_QSERDES_RXB_RX_IDAC_TSETTLE_HIGH 0x18e4 +#define USB3_DP_QSERDES_RXB_RX_IDAC_MEASURE_TIME 0x18e8 +#define USB3_DP_QSERDES_RXB_RX_IDAC_ACCUMULATOR 0x18ec +#define USB3_DP_QSERDES_RXB_RX_EQ_OFFSET_LSB 0x18f0 +#define USB3_DP_QSERDES_RXB_RX_EQ_OFFSET_MSB 0x18f4 +#define USB3_DP_QSERDES_RXB_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x18f8 +#define USB3_DP_QSERDES_RXB_RX_OFFSET_ADAPTOR_CNTRL2 0x18fc +#define USB3_DP_QSERDES_RXB_SIGDET_ENABLES 0x1900 +#define USB3_DP_QSERDES_RXB_SIGDET_CNTRL 0x1904 +#define USB3_DP_QSERDES_RXB_SIGDET_LVL 0x1908 +#define USB3_DP_QSERDES_RXB_SIGDET_DEGLITCH_CNTRL 0x190c +#define USB3_DP_QSERDES_RXB_RX_BAND 0x1910 +#define USB3_DP_QSERDES_RXB_CDR_FREEZE_UP_DN 0x1914 +#define USB3_DP_QSERDES_RXB_CDR_RESET_OVERRIDE 0x1918 +#define USB3_DP_QSERDES_RXB_RX_INTERFACE_MODE 0x191c +#define USB3_DP_QSERDES_RXB_JITTER_GEN_MODE 0x1920 +#define USB3_DP_QSERDES_RXB_BUJ_AMP 0x1924 +#define USB3_DP_QSERDES_RXB_SJ_AMP1 0x1928 +#define USB3_DP_QSERDES_RXB_SJ_AMP2 0x192c +#define USB3_DP_QSERDES_RXB_SJ_PER1 0x1930 +#define USB3_DP_QSERDES_RXB_SJ_PER2 0x1934 +#define USB3_DP_QSERDES_RXB_BUJ_STEP_FREQ1 0x1938 +#define USB3_DP_QSERDES_RXB_BUJ_STEP_FREQ2 0x193c +#define USB3_DP_QSERDES_RXB_PPM_OFFSET1 0x1940 +#define USB3_DP_QSERDES_RXB_PPM_OFFSET2 0x1944 +#define USB3_DP_QSERDES_RXB_SIGN_PPM_PERIOD1 0x1948 +#define USB3_DP_QSERDES_RXB_SIGN_PPM_PERIOD2 0x194c +#define USB3_DP_QSERDES_RXB_RX_PWM_ENABLE_AND_DATA 0x1950 +#define USB3_DP_QSERDES_RXB_RX_PWM_GEAR1_TIMEOUT_COUNT 0x1954 +#define USB3_DP_QSERDES_RXB_RX_PWM_GEAR2_TIMEOUT_COUNT 0x1958 +#define USB3_DP_QSERDES_RXB_RX_PWM_GEAR3_TIMEOUT_COUNT 0x195c +#define USB3_DP_QSERDES_RXB_RX_PWM_GEAR4_TIMEOUT_COUNT 0x1960 +#define USB3_DP_QSERDES_RXB_RX_MODE_00 0x1964 +#define USB3_DP_QSERDES_RXB_RX_MODE_01 0x1968 +#define USB3_DP_QSERDES_RXB_RX_MODE_10 0x196c +#define USB3_DP_QSERDES_RXB_ALOG_OBSV_BUS_CTRL_1 0x1970 +#define USB3_DP_QSERDES_RXB_PI_CTRL1 0x1974 +#define USB3_DP_QSERDES_RXB_PI_CTRL2 0x1978 +#define USB3_DP_QSERDES_RXB_PI_QUAD 0x197c +#define USB3_DP_QSERDES_RXB_IDATA1 0x1980 +#define USB3_DP_QSERDES_RXB_IDATA2 0x1984 +#define USB3_DP_QSERDES_RXB_AUX_DATA1 0x1988 +#define USB3_DP_QSERDES_RXB_AUX_DATA2 0x198c +#define USB3_DP_QSERDES_RXB_AC_JTAG_OUTP 0x1990 +#define USB3_DP_QSERDES_RXB_AC_JTAG_OUTN 0x1994 +#define USB3_DP_QSERDES_RXB_RX_SIGDET 0x1998 +#define USB3_DP_QSERDES_RXB_IDAC_STATUS_I 0x199c +#define USB3_DP_QSERDES_RXB_IDAC_STATUS_IBAR 0x19a0 +#define USB3_DP_QSERDES_RXB_IDAC_STATUS_Q 0x19a4 +#define USB3_DP_QSERDES_RXB_IDAC_STATUS_QBAR 0x19a8 +#define USB3_DP_QSERDES_RXB_IDAC_STATUS_A 0x19ac +#define USB3_DP_QSERDES_RXB_IDAC_STATUS_ABAR 0x19b0 +#define USB3_DP_QSERDES_RXB_IDAC_STATUS_SM_ON 0x19b4 +#define USB3_DP_QSERDES_RXB_IDAC_STATUS_CAL_DONE 0x19b8 +#define USB3_DP_QSERDES_RXB_IDAC_STATUS_SIGNERROR 0x19bc +#define USB3_DP_QSERDES_RXB_READ_EQCODE 0x19c0 +#define USB3_DP_QSERDES_RXB_READ_OFFSETCODE 0x19c4 +#define USB3_DP_QSERDES_RXB_IA_ERROR_COUNTER_LOW 0x19c8 +#define USB3_DP_QSERDES_RXB_IA_ERROR_COUNTER_HIGH 0x19cc +#define USB3_DP_QSERDES_RXB_VGA_READ_CODE 0x19d0 +#define USB3_DP_QSERDES_RXB_DFE_TAP1_READ_CODE 0x19d4 +#define USB3_DP_QSERDES_RXB_DFE_TAP2_READ_CODE 0x19d8 +#define USB3_DP_QSERDES_RXB_ALOG_OBSV_BUS_STATUS_1 0x19dc +#define USB3_DP_PCS_MISC_TYPEC_CTRL 0x1a00 +#define USB3_DP_PCS_MISC_TYPEC_PWRDN_CTRL 0x1a04 +#define USB3_DP_PCS_MISC_PCS_MISC_CONFIG1 0x1a08 +#define USB3_DP_PCS_MISC_CLAMP_ENABLE 0x1a0c +#define USB3_DP_PCS_MISC_TYPEC_STATUS 0x1a10 +#define USB3_DP_PCS_MISC_PLACEHOLDER_STATUS 0x1a14 +#define USB3_DP_PCS_SW_RESET 0x1c00 +#define USB3_DP_PCS_POWER_DOWN_CONTROL 0x1c04 +#define USB3_DP_PCS_START_CONTROL 0x1c08 +#define USB3_DP_PCS_TXMGN_V0 0x1c0c +#define USB3_DP_PCS_TXMGN_V1 0x1c10 +#define USB3_DP_PCS_TXMGN_V2 0x1c14 +#define USB3_DP_PCS_TXMGN_V3 0x1c18 +#define USB3_DP_PCS_TXMGN_V4 0x1c1c +#define USB3_DP_PCS_TXMGN_LS 0x1c20 +#define USB3_DP_PCS_TXDEEMPH_M6DB_V0 0x1c24 +#define USB3_DP_PCS_TXDEEMPH_M3P5DB_V0 0x1c28 +#define USB3_DP_PCS_TXDEEMPH_M6DB_V1 0x1c2c +#define USB3_DP_PCS_TXDEEMPH_M3P5DB_V1 0x1c30 +#define USB3_DP_PCS_TXDEEMPH_M6DB_V2 0x1c34 +#define USB3_DP_PCS_TXDEEMPH_M3P5DB_V2 0x1c38 +#define USB3_DP_PCS_TXDEEMPH_M6DB_V3 0x1c3c +#define USB3_DP_PCS_TXDEEMPH_M3P5DB_V3 0x1c40 +#define USB3_DP_PCS_TXDEEMPH_M6DB_V4 0x1c44 +#define USB3_DP_PCS_TXDEEMPH_M3P5DB_V4 0x1c48 +#define USB3_DP_PCS_TXDEEMPH_M6DB_LS 0x1c4c +#define USB3_DP_PCS_TXDEEMPH_M3P5DB_LS 0x1c50 +#define USB3_DP_PCS_ENDPOINT_REFCLK_DRIVE 0x1c54 +#define USB3_DP_PCS_RX_IDLE_DTCT_CNTRL 0x1c58 +#define USB3_DP_PCS_RATE_SLEW_CNTRL 0x1c5c +#define USB3_DP_PCS_POWER_STATE_CONFIG1 0x1c60 +#define USB3_DP_PCS_POWER_STATE_CONFIG2 0x1c64 +#define USB3_DP_PCS_POWER_STATE_CONFIG3 0x1c68 +#define USB3_DP_PCS_POWER_STATE_CONFIG4 0x1c6c +#define USB3_DP_PCS_RCVR_DTCT_DLY_P1U2_L 0x1c70 +#define USB3_DP_PCS_RCVR_DTCT_DLY_P1U2_H 0x1c74 +#define USB3_DP_PCS_RCVR_DTCT_DLY_U3_L 0x1c78 +#define USB3_DP_PCS_RCVR_DTCT_DLY_U3_H 0x1c7c +#define USB3_DP_PCS_LOCK_DETECT_CONFIG1 0x1c80 +#define USB3_DP_PCS_LOCK_DETECT_CONFIG2 0x1c84 +#define USB3_DP_PCS_LOCK_DETECT_CONFIG3 0x1c88 +#define USB3_DP_PCS_TSYNC_RSYNC_TIME 0x1c8c +#define USB3_DP_PCS_SIGDET_LOW_2_IDLE_TIME 0x1c90 +#define USB3_DP_PCS_BEACON_2_IDLE_TIME_L 0x1c94 +#define USB3_DP_PCS_BEACON_2_IDLE_TIME_H 0x1c98 +#define USB3_DP_PCS_PWRUP_RESET_DLY_TIME_SYSCLK 0x1c9c +#define USB3_DP_PCS_PWRUP_RESET_DLY_TIME_AUXCLK 0x1ca0 +#define USB3_DP_PCS_LP_WAKEUP_DLY_TIME_AUXCLK 0x1ca4 +#define USB3_DP_PCS_PLL_LOCK_CHK_DLY_TIME 0x1ca8 +#define USB3_DP_PCS_LFPS_DET_HIGH_COUNT_VAL 0x1cac +#define USB3_DP_PCS_LFPS_TX_ECSTART_EQTLOCK 0x1cb0 +#define USB3_DP_PCS_LFPS_TX_END_CNT_P2U3_START 0x1cb4 +#define USB3_DP_PCS_RXEQTRAINING_WAIT_TIME 0x1cb8 +#define USB3_DP_PCS_RXEQTRAINING_RUN_TIME 0x1cbc +#define USB3_DP_PCS_TXONESZEROS_RUN_LENGTH 0x1cc0 +#define USB3_DP_PCS_FLL_CNTRL1 0x1cc4 +#define USB3_DP_PCS_FLL_CNTRL2 0x1cc8 +#define USB3_DP_PCS_FLL_CNT_VAL_L 0x1ccc +#define USB3_DP_PCS_FLL_CNT_VAL_H_TOL 0x1cd0 +#define USB3_DP_PCS_FLL_MAN_CODE 0x1cd4 +#define USB3_DP_PCS_AUTONOMOUS_MODE_CTRL 0x1cd8 +#define USB3_DP_PCS_LFPS_RXTERM_IRQ_CLEAR 0x1cdc +#define USB3_DP_PCS_ARCVR_DTCT_EN_PERIOD 0x1ce0 +#define USB3_DP_PCS_ARCVR_DTCT_CM_DLY 0x1ce4 +#define USB3_DP_PCS_ALFPS_DEGLITCH_VAL 0x1ce8 +#define USB3_DP_PCS_INSIG_SW_CTRL1 0x1cec +#define USB3_DP_PCS_INSIG_SW_CTRL2 0x1cf0 +#define USB3_DP_PCS_INSIG_SW_CTRL3 0x1cf4 +#define USB3_DP_PCS_INSIG_MX_CTRL1 0x1cf8 +#define USB3_DP_PCS_INSIG_MX_CTRL2 0x1cfc +#define USB3_DP_PCS_INSIG_MX_CTRL3 0x1d00 +#define USB3_DP_PCS_OUTSIG_SW_CTRL1 0x1d04 +#define USB3_DP_PCS_OUTSIG_MX_CTRL1 0x1d08 +#define USB3_DP_PCS_CLK_DEBUG_BYPASS_CTRL 0x1d0c +#define USB3_DP_PCS_TEST_CONTROL 0x1d10 +#define USB3_DP_PCS_TEST_CONTROL2 0x1d14 +#define USB3_DP_PCS_TEST_CONTROL3 0x1d18 +#define USB3_DP_PCS_TEST_CONTROL4 0x1d1c +#define USB3_DP_PCS_TEST_CONTROL5 0x1d20 +#define USB3_DP_PCS_TEST_CONTROL6 0x1d24 +#define USB3_DP_PCS_TEST_CONTROL7 0x1d28 +#define USB3_DP_PCS_COM_RESET_CONTROL 0x1d2c +#define USB3_DP_PCS_BIST_CTRL 0x1d30 +#define USB3_DP_PCS_PRBS_POLY0 0x1d34 +#define USB3_DP_PCS_PRBS_POLY1 0x1d38 +#define USB3_DP_PCS_PRBS_SEED0 0x1d3c +#define USB3_DP_PCS_PRBS_SEED1 0x1d40 +#define USB3_DP_PCS_FIXED_PAT_CTRL 0x1d44 +#define USB3_DP_PCS_FIXED_PAT0 0x1d48 +#define USB3_DP_PCS_FIXED_PAT1 0x1d4c +#define USB3_DP_PCS_FIXED_PAT2 0x1d50 +#define USB3_DP_PCS_FIXED_PAT3 0x1d54 +#define USB3_DP_PCS_COM_CLK_SWITCH_CTRL 0x1d58 +#define USB3_DP_PCS_ELECIDLE_DLY_SEL 0x1d5c +#define USB3_DP_PCS_SPARE1 0x1d60 +#define USB3_DP_PCS_BIST_CHK_ERR_CNT_L_STATUS 0x1d64 +#define USB3_DP_PCS_BIST_CHK_ERR_CNT_H_STATUS 0x1d68 +#define USB3_DP_PCS_BIST_CHK_STATUS 0x1d6c +#define USB3_DP_PCS_LFPS_RXTERM_IRQ_SOURCE_STATUS 0x1d70 +#define USB3_DP_PCS_PCS_STATUS 0x1d74 +#define USB3_DP_PCS_PCS_STATUS2 0x1d78 +#define USB3_DP_PCS_PCS_STATUS3 0x1d7c +#define USB3_DP_PCS_COM_RESET_STATUS 0x1d80 +#define USB3_DP_PCS_OSC_DTCT_STATUS 0x1d84 +#define USB3_DP_PCS_REVISION_ID0 0x1d88 +#define USB3_DP_PCS_REVISION_ID1 0x1d8c +#define USB3_DP_PCS_REVISION_ID2 0x1d90 +#define USB3_DP_PCS_REVISION_ID3 0x1d94 +#define USB3_DP_PCS_DEBUG_BUS_0_STATUS 0x1d98 +#define USB3_DP_PCS_DEBUG_BUS_1_STATUS 0x1d9c +#define USB3_DP_PCS_DEBUG_BUS_2_STATUS 0x1da0 +#define USB3_DP_PCS_DEBUG_BUS_3_STATUS 0x1da4 +#define USB3_DP_PCS_LP_WAKEUP_DLY_TIME_AUXCLK_MSB 0x1da8 +#define USB3_DP_PCS_OSC_DTCT_ACTIONS 0x1dac +#define USB3_DP_PCS_SIGDET_CNTRL 0x1db0 +#define USB3_DP_PCS_IDAC_CAL_CNTRL 0x1db4 +#define USB3_DP_PCS_CMN_ACK_OUT_SEL 0x1db8 +#define USB3_DP_PCS_PLL_LOCK_CHK_DLY_TIME_SYSCLK 0x1dbc +#define USB3_DP_PCS_AUTONOMOUS_MODE_STATUS 0x1dc0 +#define USB3_DP_PCS_ENDPOINT_REFCLK_CNTRL 0x1dc4 +#define USB3_DP_PCS_EPCLK_PRE_PLL_LOCK_DLY_SYSCLK 0x1dc8 +#define USB3_DP_PCS_EPCLK_PRE_PLL_LOCK_DLY_AUXCLK 0x1dcc +#define USB3_DP_PCS_EPCLK_DLY_COUNT_VAL_L 0x1dd0 +#define USB3_DP_PCS_EPCLK_DLY_COUNT_VAL_H 0x1dd4 +#define USB3_DP_PCS_RX_SIGDET_LVL 0x1dd8 +#define USB3_DP_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB 0x1ddc +#define USB3_DP_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB 0x1de0 +#define USB3_DP_PCS_AUTONOMOUS_MODE_CTRL2 0x1de4 +#define USB3_DP_PCS_RXTERMINATION_DLY_SEL 0x1de8 +#define USB3_DP_PCS_LFPS_PER_TIMER_VAL 0x1dec +#define USB3_DP_PCS_SIGDET_STARTUP_TIMER_VAL 0x1df0 +#define USB3_DP_PCS_LOCK_DETECT_CONFIG4 0x1df4 +#define USB3_DP_PCS_RX_SIGDET_DTCT_CNTRL 0x1df8 +#define USB3_DP_PCS_PCS_STATUS4 0x1dfc +#define USB3_DP_PCS_PCS_STATUS4_CLEAR 0x1e00 +#define USB3_DP_PCS_DEC_ERROR_COUNT_STATUS 0x1e04 +#define USB3_DP_PCS_COMMA_POS_STATUS 0x1e08 +#define USB3_DP_PCS_REFGEN_REQ_CONFIG1 0x1e0c +#define USB3_DP_PCS_REFGEN_REQ_CONFIG2 0x1e10 +#define USB3_DP_PCS_REFGEN_REQ_CONFIG3 0x1e14 +#define USB3_DP_PHY_DP_DP_PHY_PD_CTL 0x2a18 + +#endif /* _DT_BINDINGS_PHY_QCOM_ATOLL_QMP_USB_H */ -- GitLab From 59e9546090de1fdca3e6b04973928eb92078810b Mon Sep 17 00:00:00 2001 From: Ashay Jaiswal Date: Mon, 29 Oct 2018 16:32:17 +0530 Subject: [PATCH 0910/1121] power: battery: handle charging termination at lower float voltage In scenarios when charging terminates at lower vfloat(charger configured to float voltage lower than battery profiles default vfloat), charging doesn't resume when charger is configured back to higher vfloat. Fix this by disabling and re-enabling charging CMD bit to restart charging. Change-Id: I4d20e4dca94705d2773ec91d6eeb5c0d192f6763 Signed-off-by: Ashay Jaiswal --- drivers/power/supply/qcom/battery.c | 48 ++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/drivers/power/supply/qcom/battery.c b/drivers/power/supply/qcom/battery.c index 93c9f520a0db..31fb9e013da0 100644 --- a/drivers/power/supply/qcom/battery.c +++ b/drivers/power/supply/qcom/battery.c @@ -101,6 +101,7 @@ struct pl_data { bool cp_disabled; int taper_entry_fv; int main_fcc_max; + u32 float_voltage_uv; }; struct pl_data *the_chip; @@ -938,6 +939,17 @@ static void fcc_stepper_work(struct work_struct *work) vote(chip->pl_awake_votable, FCC_STEPPER_VOTER, false, 0); } +static bool is_batt_available(struct pl_data *chip) +{ + if (!chip->batt_psy) + chip->batt_psy = power_supply_get_by_name("battery"); + + if (!chip->batt_psy) + return false; + + return true; +} + #define PARALLEL_FLOAT_VOLTAGE_DELTA_UV 50000 static int pl_fv_vote_callback(struct votable *votable, void *data, int fv_uv, const char *client) @@ -971,6 +983,31 @@ static int pl_fv_vote_callback(struct votable *votable, void *data, } } + /* + * check for termination at reduced float voltage and re-trigger + * charging if new float voltage is above last FV. + */ + if ((chip->float_voltage_uv < fv_uv) && is_batt_available(chip)) { + rc = power_supply_get_property(chip->batt_psy, + POWER_SUPPLY_PROP_STATUS, &pval); + if (rc < 0) { + pr_err("Couldn't get battery status rc=%d\n", rc); + } else { + if (pval.intval == POWER_SUPPLY_STATUS_FULL) { + pr_debug("re-triggering charging\n"); + pval.intval = 1; + rc = power_supply_set_property(chip->batt_psy, + POWER_SUPPLY_PROP_FORCE_RECHARGE, + &pval); + if (rc < 0) + pr_err("Couldn't set force recharge rc=%d\n", + rc); + } + } + } + + chip->float_voltage_uv = fv_uv; + return 0; } @@ -1068,17 +1105,6 @@ static void pl_awake_work(struct work_struct *work) vote(chip->pl_awake_votable, PL_VOTER, false, 0); } -static bool is_batt_available(struct pl_data *chip) -{ - if (!chip->batt_psy) - chip->batt_psy = power_supply_get_by_name("battery"); - - if (!chip->batt_psy) - return false; - - return true; -} - static int pl_disable_vote_callback(struct votable *votable, void *data, int pl_disable, const char *client) { -- GitLab From f7677f6150c596f76cf73fcbca1465ed9f41319f Mon Sep 17 00:00:00 2001 From: Avaneesh Kumar Dwivedi Date: Fri, 28 Jun 2019 17:42:14 +0530 Subject: [PATCH 0911/1121] ARM: msm: Add support for new board config qcs403 This change support for new board config arch qcs403. Also removes board config qcs 405 for 32 bit kernel. Change-Id: I66712b5cfa7a1bb252c5205d52bb48db79b2de28 Signed-off-by: Avaneesh Kumar Dwivedi --- arch/arm/mach-qcom/Kconfig | 38 ++++++++++++++++++++++++++++++- arch/arm/mach-qcom/Makefile | 1 + arch/arm/mach-qcom/board-qcs403.c | 33 +++++++++++++++++++++++++++ arch/arm64/Kconfig.platforms | 10 ++++++++ drivers/pinctrl/qcom/Kconfig | 2 +- drivers/soc/qcom/Kconfig | 2 +- 6 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 arch/arm/mach-qcom/board-qcs403.c diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig index fc17977d52a2..8b77bab0f179 100644 --- a/arch/arm/mach-qcom/Kconfig +++ b/arch/arm/mach-qcom/Kconfig @@ -2,7 +2,7 @@ if ARCH_QCOM menu "QCOM SoC Type" config ARCH_QCS405 - bool "Enable Support for QCS405" + bool "Enable Support for QCS405" select CLKDEV_LOOKUP select HAVE_CLK select HAVE_CLK_PREPARE @@ -37,6 +37,42 @@ config ARCH_QCS405 This enables support for the QCS405 chipset. If you do not wish to build a kernel that runs on this chipset, say 'N' here. +config ARCH_QCS403 + bool "Enable Support for QCS403" + select CLKDEV_LOOKUP + select HAVE_CLK + select HAVE_CLK_PREPARE + select PM_OPP + select SOC_BUS + select MSM_IRQ + select THERMAL_WRITABLE_TRIPS + select ARM_GIC + select ARM_AMBA + select SPARSE_IRQ + select MULTI_IRQ_HANDLER + select HAVE_ARM_ARCH_TIMER + select MAY_HAVE_SPARSE_IRQ + select COMMON_CLK + select QCOM_GDSC + select PINCTRL_MSM + select USE_PINCTRL_IRQ + select MSM_PM if PM + select QMI_ENCDEC + select CPU_FREQ + select CPU_FREQ_MSM + select PM_DEVFREQ + select MSM_DEVFREQ_DEVBW + select DEVFREQ_SIMPLE_DEV + select DEVFREQ_GOV_MSM_BW_HWMON + select MSM_BIMC_BWMON + select MSM_QDSP6V2_CODECS + select MSM_AUDIO_QDSP6V2 if SND_SOC + select MSM_RPM_SMD + select MSM_JTAGV8 if CORESIGHT_ETMV4 + help + This enables support for the QCS403 chipset. If you do not + wish to build a kernel that runs on this chipset, say 'N' here. + config ARCH_MSM8X60 bool "Enable support for MSM8X60" select ARCH_SUPPORTS_BIG_ENDIAN diff --git a/arch/arm/mach-qcom/Makefile b/arch/arm/mach-qcom/Makefile index 23af561084b8..27a323e0bee7 100644 --- a/arch/arm/mach-qcom/Makefile +++ b/arch/arm/mach-qcom/Makefile @@ -1,4 +1,5 @@ obj-$(CONFIG_USE_OF) += board-dt.o obj-$(CONFIG_SMP) += platsmp.o obj-$(CONFIG_ARCH_QCS405) += board-qcs405.o +obj-$(CONFIG_ARCH_QCS403) += board-qcs403.o obj-$(CONFIG_ARCH_SDXPRAIRIE) += board-sdxprairie.o diff --git a/arch/arm/mach-qcom/board-qcs403.c b/arch/arm/mach-qcom/board-qcs403.c new file mode 100644 index 000000000000..dec88c6f9742 --- /dev/null +++ b/arch/arm/mach-qcom/board-qcs403.c @@ -0,0 +1,33 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include "board-dt.h" +#include +#include + +static const char *qcs403_dt_match[] __initconst = { + "qcom,qcs403", + "qcom,qcs404", + NULL +}; + +static void __init qcs403_init(void) +{ + board_dt_populate(NULL); +} + +DT_MACHINE_START(QCS403_DT, + "Qualcomm Technologies, Inc. QCS403 (Flattened Device Tree)") + .init_machine = qcs403_init, + .dt_compat = qcs403_dt_match, +MACHINE_END diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index 6ce416f15959..1b524f2c0433 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -186,6 +186,16 @@ config ARCH_QCS405 If you do not wish to build a kernel that runs on this chipset, say 'N' here. +config ARCH_QCS403 + bool "Enable Support for Qualcomm Technologies, Inc. QCS403" + depends on ARCH_QCOM + select COMMON_CLK_QCOM + help + This configuration option enables support to build kernel for + QCS403 SoC. + If you do not wish to build a kernel that runs on this chipset, + say 'N' here. + config ARCH_SDMMAGPIE bool "Enable Support for Qualcomm Technologies, Inc. SDMMAGPIE" depends on ARCH_QCOM diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig index a462ca9acdba..f11e20b42e1f 100644 --- a/drivers/pinctrl/qcom/Kconfig +++ b/drivers/pinctrl/qcom/Kconfig @@ -41,7 +41,7 @@ config PINCTRL_IPQ8064 config PINCTRL_QCS405 tristate "QTI QCS405 pin controller driver" - depends on GPIOLIB && OF && (ARCH_QCS405 || COMPILE_TEST) + depends on GPIOLIB && OF && (ARCH_QCS405 || COMPILE_TEST || ARCH_QCS403) select PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index 91c0f66b44a3..fb54ee455d00 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -629,7 +629,7 @@ config MSM_SPCOM or server is allowed per logical channel. config MSM_TZ_SMMU - depends on ARCH_MSM8953 || ARCH_QCS405 + depends on ARCH_MSM8953 || ARCH_QCS405 || ARCH_QCS403 bool "Helper functions for SMMU configuration through TZ" help Say 'Y' here for targets that need to call into TZ to configure -- GitLab From 16cd8a7692e53cd547780eb6924130f40a73f183 Mon Sep 17 00:00:00 2001 From: Avaneesh Kumar Dwivedi Date: Wed, 17 Jul 2019 13:26:35 +0530 Subject: [PATCH 0912/1121] soc: qcom: socinfo: Add soc information for QCS404 and QCS407 Add socinfo support for QCS404 and QCS407 SoC and update the bindings for the same. Change-Id: I4e94829061cf40544ced774c3dfcf6578b548b35 Signed-off-by: Avaneesh Kumar Dwivedi --- drivers/soc/qcom/socinfo.c | 14 ++++++++++++++ include/soc/qcom/socinfo.h | 8 ++++++++ 2 files changed, 22 insertions(+) diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index f52fc070d56c..5c46e39510e4 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -381,6 +381,12 @@ static struct msm_soc_info cpu_of_id[] = { /* qcs405 ID */ [352] = {MSM_CPU_QCS405, "QCS405"}, + /* qcs404 ID */ + [410] = {MSM_CPU_QCS404, "QCS404"}, + + /* qcs407 ID */ + [411] = {MSM_CPU_QCS407, "QCS407"}, + /* qcs403 ID */ [373] = {MSM_CPU_QCS403, "QCS403"}, @@ -1355,6 +1361,14 @@ static void * __init setup_dummy_socinfo(void) dummy_socinfo.id = 372; strlcpy(dummy_socinfo.build_id, "qcs401 - ", sizeof(dummy_socinfo.build_id)); + } else if (early_machine_is_qcs404()) { + dummy_socinfo.id = 410; + strlcpy(dummy_socinfo.build_id, "qcs404 - ", + sizeof(dummy_socinfo.build_id)); + } else if (early_machine_is_qcs407()) { + dummy_socinfo.id = 411; + strlcpy(dummy_socinfo.build_id, "qcs407 - ", + sizeof(dummy_socinfo.build_id)); } else if (early_machine_is_sdxprairie()) { dummy_socinfo.id = 357; strlcpy(dummy_socinfo.build_id, "sdxprairie - ", diff --git a/include/soc/qcom/socinfo.h b/include/soc/qcom/socinfo.h index ac6791a99527..2797a090d40d 100644 --- a/include/soc/qcom/socinfo.h +++ b/include/soc/qcom/socinfo.h @@ -79,6 +79,10 @@ of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,qcs403") #define early_machine_is_qcs401() \ of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,qcs401") +#define early_machine_is_qcs404() \ + of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,qcs404") +#define early_machine_is_qcs407() \ + of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,qcs407") #define early_machine_is_sdxprairie() \ of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,sdxprairie") #define early_machine_is_sdmmagpie() \ @@ -128,6 +132,8 @@ #define early_machine_is_qcs405() 0 #define early_machine_is_qcs403() 0 #define early_machine_is_qcs401() 0 +#define early_machine_is_qcs404() 0 +#define early_machine_is_qcs407() 0 #define early_machine_is_sdxprairie() 0 #define early_machine_is_sdmmagpie() 0 #define early_machine_is_sdmmagpiep() 0 @@ -169,6 +175,8 @@ enum msm_cpu { MSM_CPU_QCS405, MSM_CPU_QCS403, MSM_CPU_QCS401, + MSM_CPU_QCS404, + MSM_CPU_QCS407, SDX_CPU_SDXPRAIRIE, MSM_CPU_SDMMAGPIE, MSM_CPU_SDMMAGPIEP, -- GitLab From 09c963fc51a1ea53bd9458bd2e2c9b3b9c68acf4 Mon Sep 17 00:00:00 2001 From: Avaneesh Kumar Dwivedi Date: Fri, 28 Jun 2019 17:44:27 +0530 Subject: [PATCH 0913/1121] ARM: dts: msm: Add device tree support for board variants of QCS403 Add board specific dts files of qcs403 variants and while at it also reorganize soc specific changes. Change-Id: I4687fa1b1dae4df932fcee40c7ee7eed5c89b8b8 Signed-off-by: Avaneesh Kumar Dwivedi --- .../devicetree/bindings/arm/msm/msm.txt | 8 ++ arch/arm64/boot/dts/qcom/Makefile | 32 +++--- arch/arm64/boot/dts/qcom/qcs403-iot-sku1.dts | 57 +---------- arch/arm64/boot/dts/qcom/qcs403-iot-sku2.dts | 55 ----------- arch/arm64/boot/dts/qcom/qcs403-iot-sku3.dts | 53 ---------- arch/arm64/boot/dts/qcom/qcs403-iot-sku4.dts | 53 ---------- arch/arm64/boot/dts/qcom/qcs403-iot-sku5.dts | 52 ++++++++++ arch/arm64/boot/dts/qcom/qcs403.dtsi | 52 ++++++++++ arch/arm64/boot/dts/qcom/qcs404-iot-sku3.dts | 97 +++++++++++++++++++ arch/arm64/boot/dts/qcom/qcs404-iot-sku5.dts | 52 ++++++++++ arch/arm64/boot/dts/qcom/qcs404-iot-sku6.dts | 29 ++++++ arch/arm64/boot/dts/qcom/qcs404.dtsi | 35 +++++++ arch/arm64/boot/dts/qcom/qcs407-iot-sku1.dts | 87 +++++++++++++++++ arch/arm64/boot/dts/qcom/qcs407-iot-sku12.dts | 36 +++++++ arch/arm64/boot/dts/qcom/qcs407-iot-sku3.dts | 52 ++++++++++ arch/arm64/boot/dts/qcom/qcs407-iot-sku4.dts | 85 ++++++++++++++++ arch/arm64/boot/dts/qcom/qcs407-iot-sku6.dts | 63 ++++++++++++ arch/arm64/boot/dts/qcom/qcs407-iot-sku9.dts | 73 ++++++++++++++ arch/arm64/boot/dts/qcom/qcs407.dtsi | 21 ++++ 19 files changed, 758 insertions(+), 234 deletions(-) create mode 100644 arch/arm64/boot/dts/qcom/qcs403-iot-sku5.dts create mode 100644 arch/arm64/boot/dts/qcom/qcs404-iot-sku3.dts create mode 100644 arch/arm64/boot/dts/qcom/qcs404-iot-sku5.dts create mode 100644 arch/arm64/boot/dts/qcom/qcs404-iot-sku6.dts create mode 100644 arch/arm64/boot/dts/qcom/qcs404.dtsi create mode 100644 arch/arm64/boot/dts/qcom/qcs407-iot-sku1.dts create mode 100644 arch/arm64/boot/dts/qcom/qcs407-iot-sku12.dts create mode 100644 arch/arm64/boot/dts/qcom/qcs407-iot-sku3.dts create mode 100644 arch/arm64/boot/dts/qcom/qcs407-iot-sku4.dts create mode 100644 arch/arm64/boot/dts/qcom/qcs407-iot-sku6.dts create mode 100644 arch/arm64/boot/dts/qcom/qcs407-iot-sku9.dts create mode 100644 arch/arm64/boot/dts/qcom/qcs407.dtsi diff --git a/Documentation/devicetree/bindings/arm/msm/msm.txt b/Documentation/devicetree/bindings/arm/msm/msm.txt index ed31d3edb60c..7c532a4ac4f8 100644 --- a/Documentation/devicetree/bindings/arm/msm/msm.txt +++ b/Documentation/devicetree/bindings/arm/msm/msm.txt @@ -62,6 +62,12 @@ SoCs: - QCS401 compatible = "qcom,qcs401" +- QCS404 + compatible = "qcom,qcs404" + +- QCS407 + compatible = "qcom,qcs407" + - SDXPRAIRIE compatible = "qcom,sdxprairie" @@ -195,6 +201,8 @@ compatible = "qcom,qcs405-rumi" compatible = "qcom,qcs405-iot" compatible = "qcom,qcs403-iot" compatible = "qcom,qcs401-iot" +compatible = "qcom,qcs404-iot" +compatible = "qcom,qcs407-iot" compatible = "qcom,sa8155-adp-star" compatible = "qcom,sa8155p-adp-star" compatible = "qcom,sa8195p-adp-star" diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index 33ecfef5ebbc..b423da6088a0 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -6,27 +6,25 @@ dtb-$(CONFIG_ARCH_QCOM) += msm8916-mtp.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8992-bullhead-rev-101.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8994-angler-rev-101.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8996-mtp.dtb -ifeq ($(CONFIG_ARM64),y) -dtb-$(CONFIG_ARCH_QCS405) += qcs405-rumi.dtb \ - qcs405-iot-sku1.dtb \ - qcs405-iot-sku2.dtb \ + +dtb-$(CONFIG_ARCH_QCS403) += qcs403-iot-sku1.dtb \ + qcs403-iot-sku3.dtb \ + qcs403-iot-sku5.dtb \ + qcs404-iot-sku3.dtb \ + qcs404-iot-sku5.dtb \ + qcs404-iot-sku6.dtb + +dtb-$(CONFIG_ARCH_QCS405) += qcs405-iot-sku1.dtb \ + qcs407-iot-sku1.dtb \ qcs405-iot-sku3.dtb \ + qcs407-iot-sku3.dtb \ qcs405-iot-sku4.dtb \ - qcs405-iot-sku5.dtb \ + qcs407-iot-sku4.dtb \ qcs405-iot-sku6.dtb \ - qcs405-iot-sku7.dtb \ - qcs405-iot-sku8.dtb \ - qcs405-iot-sku9.dtb \ - qcs405-iot-sku10.dtb \ - qcs405-iot-sku11.dtb \ + qcs407-iot-sku6.dtb \ + qcs407-iot-sku9.dtb \ qcs405-iot-sku12.dtb \ - qcs401-iot-sku1.dtb -else -dtb-$(CONFIG_ARCH_QCS405) += qcs403-iot-sku1.dtb \ - qcs403-iot-sku2.dtb \ - qcs403-iot-sku3.dtb \ - qcs403-iot-sku4.dtb -endif + qcs407-iot-sku12.dtb ifeq ($(CONFIG_BUILD_ARM64_DT_OVERLAY),y) dtbo-$(CONFIG_ARCH_SM8150) += \ diff --git a/arch/arm64/boot/dts/qcom/qcs403-iot-sku1.dts b/arch/arm64/boot/dts/qcom/qcs403-iot-sku1.dts index bcf65cf5aa3e..34de78d0baf6 100644 --- a/arch/arm64/boot/dts/qcom/qcs403-iot-sku1.dts +++ b/arch/arm64/boot/dts/qcom/qcs403-iot-sku1.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -22,61 +22,6 @@ compatible = "qcom,qcs403-iot", "qcom,qcs403", "qcom,iot"; qcom,board-id = <0x010020 0x3>; - cpus { - /delete-node/ cpu@102; - /delete-node/ cpu@103; - - cpu-map { - cluster0 { - /delete-node/ core2; - /delete-node/ core3; - }; - }; - }; -}; - -&soc { - cpuss_dump { - /delete-node/ qcom,l1_i_cache102; - /delete-node/ qcom,l1_i_cache103; - /delete-node/ qcom,l1_d_cache102; - /delete-node/ qcom,l1_d_cache103; - }; - - qcom,spm@b012000 { - qcom,cpu-vctl-list = <&CPU0 &CPU1>; - }; - - qcom,lpm-levels { - qcom,pm-cluster@0{ - qcom,pm-cpu { - qcom,cpu = <&CPU0 &CPU1>; - }; - }; - }; - - /delete-node/ cti@61ba000; - /delete-node/ cti@61bb000; - /delete-node/ etm@61be000; - /delete-node/ etm@61bf000; - funnel@61a1000 { - ports { - /delete-node/ port@3; - /delete-node/ port@4; - }; - }; -}; - -&thermal_zones { - cpuss-max-step { - cooling-maps { - /delete-node/ cpu2_cdev; - /delete-node/ cpu3_cdev; - }; - }; - - /delete-node/ cpuss-2-step; - /delete-node/ cpuss-3-step; }; &qnand_1 { diff --git a/arch/arm64/boot/dts/qcom/qcs403-iot-sku2.dts b/arch/arm64/boot/dts/qcom/qcs403-iot-sku2.dts index 4220f8e48ef5..c782e1d43ca4 100644 --- a/arch/arm64/boot/dts/qcom/qcs403-iot-sku2.dts +++ b/arch/arm64/boot/dts/qcom/qcs403-iot-sku2.dts @@ -22,61 +22,6 @@ compatible = "qcom,qcs403-iot", "qcom,qcs403", "qcom,iot"; qcom,board-id = <0x010015 0x0>; - cpus { - /delete-node/ cpu@102; - /delete-node/ cpu@103; - - cpu-map { - cluster0 { - /delete-node/ core2; - /delete-node/ core3; - }; - }; - }; -}; - -&soc { - cpuss_dump { - /delete-node/ qcom,l1_i_cache102; - /delete-node/ qcom,l1_i_cache103; - /delete-node/ qcom,l1_d_cache102; - /delete-node/ qcom,l1_d_cache103; - }; - - qcom,spm@b012000 { - qcom,cpu-vctl-list = <&CPU0 &CPU1>; - }; - - qcom,lpm-levels { - qcom,pm-cluster@0{ - qcom,pm-cpu { - qcom,cpu = <&CPU0 &CPU1>; - }; - }; - }; - - /delete-node/ cti@61ba000; - /delete-node/ cti@61bb000; - /delete-node/ etm@61be000; - /delete-node/ etm@61bf000; - funnel@61a1000 { - ports { - /delete-node/ port@3; - /delete-node/ port@4; - }; - }; -}; - -&thermal_zones { - cpuss-max-step { - cooling-maps { - /delete-node/ cpu2_cdev; - /delete-node/ cpu3_cdev; - }; - }; - - /delete-node/ cpuss-2-step; - /delete-node/ cpuss-3-step; }; #include "qcs405-mdss-panels.dtsi" diff --git a/arch/arm64/boot/dts/qcom/qcs403-iot-sku3.dts b/arch/arm64/boot/dts/qcom/qcs403-iot-sku3.dts index 637d94ce2e50..7497da5aad38 100644 --- a/arch/arm64/boot/dts/qcom/qcs403-iot-sku3.dts +++ b/arch/arm64/boot/dts/qcom/qcs403-iot-sku3.dts @@ -22,50 +22,9 @@ compatible = "qcom,qcs403-iot", "qcom,qcs403", "qcom,iot"; qcom,board-id = <0x010020 0x4>; - cpus { - /delete-node/ cpu@102; - /delete-node/ cpu@103; - - cpu-map { - cluster0 { - /delete-node/ core2; - /delete-node/ core3; - }; - }; - }; }; &soc { - cpuss_dump { - /delete-node/ qcom,l1_i_cache102; - /delete-node/ qcom,l1_i_cache103; - /delete-node/ qcom,l1_d_cache102; - /delete-node/ qcom,l1_d_cache103; - }; - - qcom,spm@b012000 { - qcom,cpu-vctl-list = <&CPU0 &CPU1>; - }; - - qcom,lpm-levels { - qcom,pm-cluster@0{ - qcom,pm-cpu { - qcom,cpu = <&CPU0 &CPU1>; - }; - }; - }; - - /delete-node/ cti@61ba000; - /delete-node/ cti@61bb000; - /delete-node/ etm@61be000; - /delete-node/ etm@61bf000; - funnel@61a1000 { - ports { - /delete-node/ port@3; - /delete-node/ port@4; - }; - }; - spi@78b5000 { status = "ok"; spi@0 { @@ -82,18 +41,6 @@ }; }; -&thermal_zones { - cpuss-max-step { - cooling-maps { - /delete-node/ cpu2_cdev; - /delete-node/ cpu3_cdev; - }; - }; - - /delete-node/ cpuss-2-step; - /delete-node/ cpuss-3-step; -}; - &qnand_1 { status = "ok"; }; diff --git a/arch/arm64/boot/dts/qcom/qcs403-iot-sku4.dts b/arch/arm64/boot/dts/qcom/qcs403-iot-sku4.dts index 77ac0f29bb32..bbc81eb229ed 100644 --- a/arch/arm64/boot/dts/qcom/qcs403-iot-sku4.dts +++ b/arch/arm64/boot/dts/qcom/qcs403-iot-sku4.dts @@ -22,50 +22,9 @@ compatible = "qcom,qcs403-iot", "qcom,qcs403", "qcom,iot"; qcom,board-id = <0x010020 0x5>; - cpus { - /delete-node/ cpu@102; - /delete-node/ cpu@103; - - cpu-map { - cluster0 { - /delete-node/ core2; - /delete-node/ core3; - }; - }; - }; }; &soc { - cpuss_dump { - /delete-node/ qcom,l1_i_cache102; - /delete-node/ qcom,l1_i_cache103; - /delete-node/ qcom,l1_d_cache102; - /delete-node/ qcom,l1_d_cache103; - }; - - qcom,spm@b012000 { - qcom,cpu-vctl-list = <&CPU0 &CPU1>; - }; - - qcom,lpm-levels { - qcom,pm-cluster@0{ - qcom,pm-cpu { - qcom,cpu = <&CPU0 &CPU1>; - }; - }; - }; - - /delete-node/ cti@61ba000; - /delete-node/ cti@61bb000; - /delete-node/ etm@61be000; - /delete-node/ etm@61bf000; - funnel@61a1000 { - ports { - /delete-node/ port@3; - /delete-node/ port@4; - }; - }; - gpio_keys { vol_mute { gpios = <&tlmm 19 GPIO_ACTIVE_LOW>; @@ -73,18 +32,6 @@ }; }; -&thermal_zones { - cpuss-max-step { - cooling-maps { - /delete-node/ cpu2_cdev; - /delete-node/ cpu3_cdev; - }; - }; - - /delete-node/ cpuss-2-step; - /delete-node/ cpuss-3-step; -}; - &qnand_1 { status = "ok"; }; diff --git a/arch/arm64/boot/dts/qcom/qcs403-iot-sku5.dts b/arch/arm64/boot/dts/qcom/qcs403-iot-sku5.dts new file mode 100644 index 000000000000..f1242404ca81 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs403-iot-sku5.dts @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "qcs403.dtsi" +#include "qcs405-audio-overlay.dtsi" +#include "qcs405-geni-ir-overlay.dtsi" +#include "qcs405-pinctrl.dtsi" +#include "qcs405-circular-pca9956.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. QCS403 sEVB/SLT IOT"; + compatible = "qcom,qcs403-iot", "qcom,qcs403", "qcom,iot"; + qcom,board-id = <0x010020 0x2>; +}; +#include "qcs405-mdss-panels.dtsi" + +&mdss_mdp { + qcom,mdss-pref-prim-intf = "dsi"; +}; + +&mdss_dsi { + hw-config = "single_dsi"; +}; + +&mdss_dsi0 { + qcom,dsi-pref-prim-pan = <&dsi_hx8394d_720_vid>; + pinctrl-names = "mdss_default", "mdss_sleep"; + pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; + pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; + + qcom,platform-te-gpio = <&tlmm 41 0>; + qcom,platform-reset-gpio = <&tlmm 39 0>; + qcom,platform-bklight-en-gpio = <&tlmm 48 0>; +}; + +&dsi_hx8394d_720_vid { + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_tlmm_gpio"; + qcom,mdss-dsi-bl-pmic-bank-select = <0>; + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; +}; diff --git a/arch/arm64/boot/dts/qcom/qcs403.dtsi b/arch/arm64/boot/dts/qcom/qcs403.dtsi index c5058cbaec53..b005e60fb741 100644 --- a/arch/arm64/boot/dts/qcom/qcs403.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs403.dtsi @@ -17,9 +17,50 @@ model = "Qualcomm Technologies, Inc. QCS403"; qcom,msm-name = "QCS403"; qcom,msm-id = <373 0x0>; + + cpus { + /delete-node/ cpu@102; + /delete-node/ cpu@103; + cpu-map { + cluster0 { + /delete-node/ core2; + /delete-node/ core3; + }; + }; + }; + }; &soc { + + cpuss_dump { + /delete-node/ qcom,l1_i_cache102; + /delete-node/ qcom,l1_i_cache103; + /delete-node/ qcom,l1_d_cache102; + /delete-node/ qcom,l1_d_cache103; + }; + qcom,spm@b012000 { + qcom,cpu-vctl-list = <&CPU0 &CPU1>; + }; + qcom,lpm-levels { + qcom,pm-cluster@0{ + qcom,pm-cpu { + qcom,cpu = <&CPU0 &CPU1>; + }; + }; + }; + /delete-node/ cti@61ba000; + /delete-node/ cti@61bb000; + /delete-node/ etm@61be000; + /delete-node/ etm@61bf000; + + funnel@61a1000 { + ports { + /delete-node/ port@3; + /delete-node/ port@4; + }; + }; + /delete-node/ qcom,msm-cpufreq; msm_cpufreq: qcom,msm-cpufreq { @@ -46,6 +87,17 @@ }; }; +&thermal_zones { + cpuss-max-step { + cooling-maps { + /delete-node/ cpu2_cdev; + /delete-node/ cpu3_cdev; + }; + }; + /delete-node/ cpuss-2-step; + /delete-node/ cpuss-3-step; +}; + &adsp_fw_mem { reg = <0x0 0x87400000 0x0 0x1200000>; }; diff --git a/arch/arm64/boot/dts/qcom/qcs404-iot-sku3.dts b/arch/arm64/boot/dts/qcom/qcs404-iot-sku3.dts new file mode 100644 index 000000000000..44178118e543 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs404-iot-sku3.dts @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "qcs404.dtsi" +#include "qcs405-wsa-audio-overlay.dtsi" +#include "qcs405-circular-pca9956.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. QCS403 SSRD IOT"; + compatible = "qcom,qcs403-iot", "qcom,qcs403", "qcom,iot"; + qcom,board-id = <0x010020 0x4>; + +}; + +&soc { + spi@78b5000 { + status = "ok"; + spi@0 { + compatible = "qcom,spi-msm-codec-slave"; + reg = <0>; + spi-max-frequency = <50000000>; + }; + }; + + gpio_keys { + vol_mute { + gpios = <&tlmm 19 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&qnand_1 { + status = "ok"; +}; + +&soc { + usb2_extcon: usb2_extcon { + compatible = "linux,extcon-usb-gpio"; + vbus-gpio = <&tlmm 27 GPIO_ACTIVE_HIGH>; + + pinctrl-names = "default"; + pinctrl-0 = <&usb2_ssrd_det_default>; + }; +}; + +&usb2s { + extcon = <&usb2_extcon>; +}; + +&usb3 { + status = "disabled"; +}; + +&usb_ss_phy { + status = "ok"; + qcom,keep-powerdown; +}; + +&usb2_phy1 { + status = "disabled"; +}; + +&tlmm { + evb_tlmm_gpio_key{ + tlmm_gpio_key_active: tlmm_gpio_key_active { + mux { + pins = "gpio19","gpio52","gpio54","gpio115"; + }; + + config { + pins = "gpio19","gpio52","gpio54","gpio115"; + }; + }; + + tlmm_gpio_key_suspend: tlmm_gpio_key_suspend { + mux { + pins = "gpio19","gpio52","gpio54","gpio115"; + }; + + config { + pins = "gpio19","gpio52","gpio54","gpio115"; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/qcs404-iot-sku5.dts b/arch/arm64/boot/dts/qcom/qcs404-iot-sku5.dts new file mode 100644 index 000000000000..c76b41fc2d37 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs404-iot-sku5.dts @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "qcs404.dtsi" +#include "qcs405-audio-overlay.dtsi" +#include "qcs405-geni-ir-overlay.dtsi" +#include "qcs405-pinctrl.dtsi" +#include "qcs405-circular-pca9956.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. QCS404 sEVB/SLT IOT"; + compatible = "qcom,qcs404-iot", "qcom,qcs404", "qcom,iot"; + qcom,board-id = <0x010020 0x2>; +}; +#include "qcs405-mdss-panels.dtsi" + +&mdss_mdp { + qcom,mdss-pref-prim-intf = "dsi"; +}; + +&mdss_dsi { + hw-config = "single_dsi"; +}; + +&mdss_dsi0 { + qcom,dsi-pref-prim-pan = <&dsi_hx8394d_720_vid>; + pinctrl-names = "mdss_default", "mdss_sleep"; + pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; + pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; + + qcom,platform-te-gpio = <&tlmm 41 0>; + qcom,platform-reset-gpio = <&tlmm 39 0>; + qcom,platform-bklight-en-gpio = <&tlmm 48 0>; +}; + +&dsi_hx8394d_720_vid { + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_tlmm_gpio"; + qcom,mdss-dsi-bl-pmic-bank-select = <0>; + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; +}; diff --git a/arch/arm64/boot/dts/qcom/qcs404-iot-sku6.dts b/arch/arm64/boot/dts/qcom/qcs404-iot-sku6.dts new file mode 100644 index 000000000000..79f4044606e5 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs404-iot-sku6.dts @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "qcs404.dtsi" +#include "qcs405-audio-overlay.dtsi" +#include "qcs405-circular-pca9956.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. QCS404 QCS404 1 CSRA"; + compatible = "qcom,qcs404-iot", "qcom,qcs404", "qcom,iot"; + qcom,board-id = <0x020020 0x4>; + +}; + +&qnand_1 { + status = "ok"; +}; diff --git a/arch/arm64/boot/dts/qcom/qcs404.dtsi b/arch/arm64/boot/dts/qcom/qcs404.dtsi new file mode 100644 index 000000000000..52b9c16ac1af --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs404.dtsi @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "qcs405.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. QCS403"; + qcom,msm-name = "QCS404"; + qcom,msm-id = <410 0x0>; + +}; + +&adsp_fw_mem { + reg = <0x0 0x87400000 0x0 0x1200000>; +}; + +&reserved_mem { + linux,cma { + size = <0 0x400000>; + }; +}; + +&qcom_seecom { + /delete-property/ qcom,appsbl-qseecom-support; +}; diff --git a/arch/arm64/boot/dts/qcom/qcs407-iot-sku1.dts b/arch/arm64/boot/dts/qcom/qcs407-iot-sku1.dts new file mode 100644 index 000000000000..34039bc1f83b --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs407-iot-sku1.dts @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "qcs407.dtsi" +#include "qcs405-wsa-audio-overlay.dtsi" +#include "qcs405-circular-pca9956.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. QCS407 EVB1 1000 IOT"; + compatible = "qcom,qcs407-iot", "qcom,qcs407", "qcom,iot"; + qcom,board-id = <0x010020 0>; +}; + +&i2c_5 { + status = "ok"; +}; + +&smb1351_otg_supply { + status = "ok"; +}; + +&usb2_phy0 { + qcom,snps-hs-phy-init-seq = + <0xc0 0x01 0>, + <0xe8 0x0d 0>, + <0x74 0x12 0>, + <0x98 0x63 0>, + <0x9c 0x83 0>, + <0xa0 0x1d 0>, + <0xa4 0x03 0>, + <0x8c 0x23 0>, + <0x78 0x08 0>, + <0x7c 0xdc 0>, + <0x90 0xe0 20>, + <0x74 0x10 0>, + <0x90 0x60 0>, + <0xffffffff 0xffffffff 0>; +}; + +&usb2s { + extcon = <&smb1351_otg_supply>; + vbus_dwc3-supply = <&smb1351_otg_supply>; +}; + +&soc { + gpio_keys { + vol_mute { + gpios = <&tlmm 19 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&tlmm { + evb_tlmm_gpio_key{ + tlmm_gpio_key_active: tlmm_gpio_key_active { + mux { + pins = "gpio19","gpio52","gpio54","gpio115"; + }; + + config { + pins = "gpio19","gpio52","gpio54","gpio115"; + }; + }; + + tlmm_gpio_key_suspend: tlmm_gpio_key_suspend { + mux { + pins = "gpio19","gpio52","gpio54","gpio115"; + }; + + config { + pins = "gpio19","gpio52","gpio54","gpio115"; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/qcs407-iot-sku12.dts b/arch/arm64/boot/dts/qcom/qcs407-iot-sku12.dts new file mode 100644 index 000000000000..dbaf21baa7c1 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs407-iot-sku12.dts @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "qcs407.dtsi" +#include "qcs405-csra8-audio-overlay.dtsi" +#include "qcs405-geni-ir-overlay.dtsi" +#include "qcs405-linear-pca9956.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. QCS407 EVB1 4K/CSRA8 SPI/LiN"; + compatible = "qcom,qcs407-iot", "qcom,qcs407", "qcom,iot"; + qcom,board-id = <0x080020 0x1>; +}; + +&soc { + spi@78b5000 { + status = "ok"; + spi@0 { + compatible = "qcom,spi-msm-codec-slave"; + reg = <0>; + spi-max-frequency = <50000000>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/qcs407-iot-sku3.dts b/arch/arm64/boot/dts/qcom/qcs407-iot-sku3.dts new file mode 100644 index 000000000000..27e1f9d640f2 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs407-iot-sku3.dts @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "qcs407.dtsi" +#include "qcs405-audio-overlay.dtsi" +#include "qcs405-geni-ir-overlay.dtsi" +#include "qcs405-pinctrl.dtsi" +#include "qcs405-circular-pca9956.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. QCS407 sEVB/SLT IOT"; + compatible = "qcom,qcs407-iot", "qcom,qcs407", "qcom,iot"; + qcom,board-id = <0x010020 0x2>; +}; +#include "qcs405-mdss-panels.dtsi" + +&mdss_mdp { + qcom,mdss-pref-prim-intf = "dsi"; +}; + +&mdss_dsi { + hw-config = "single_dsi"; +}; + +&mdss_dsi0 { + qcom,dsi-pref-prim-pan = <&dsi_hx8394d_720_vid>; + pinctrl-names = "mdss_default", "mdss_sleep"; + pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; + pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; + + qcom,platform-te-gpio = <&tlmm 41 0>; + qcom,platform-reset-gpio = <&tlmm 39 0>; + qcom,platform-bklight-en-gpio = <&tlmm 48 0>; +}; + +&dsi_hx8394d_720_vid { + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_tlmm_gpio"; + qcom,mdss-dsi-bl-pmic-bank-select = <0>; + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; +}; diff --git a/arch/arm64/boot/dts/qcom/qcs407-iot-sku4.dts b/arch/arm64/boot/dts/qcom/qcs407-iot-sku4.dts new file mode 100644 index 000000000000..18c434306d6a --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs407-iot-sku4.dts @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "qcs407.dtsi" +#include "qcs405-audio-overlay.dtsi" +#include "qcs405-geni-ir-overlay.dtsi" +#include "qcs405-circular-pca9956.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. QCS407 EVB1 4000 DSI IOT"; + compatible = "qcom,qcs407-iot", "qcom,qcs407", "qcom,iot"; + qcom,board-id = <0x020020 0x1>; +}; + +#include "qcs405-mdss-panels.dtsi" + +&mdss_hdmi_tx { + pinctrl-names = "hdmi_hpd_active", "hdmi_ddc_active", "hdmi_cec_active", + "hdmi_active", "hdmi_sleep"; + pinctrl-0 = <&mdss_hdmi_5v_active &mdss_hdmi_hpd_active + &mdss_hdmi_ddc_suspend &mdss_hdmi_cec_suspend>; + pinctrl-1 = <&mdss_hdmi_5v_active &mdss_hdmi_hpd_active + &mdss_hdmi_ddc_active &mdss_hdmi_cec_suspend>; + pinctrl-2 = <&mdss_hdmi_5v_active &mdss_hdmi_hpd_active + &mdss_hdmi_cec_active &mdss_hdmi_ddc_suspend>; + pinctrl-3 = <&mdss_hdmi_5v_active &mdss_hdmi_hpd_active + &mdss_hdmi_ddc_active &mdss_hdmi_cec_active>; + pinctrl-4 = <&mdss_hdmi_5v_suspend &mdss_hdmi_hpd_suspend + &mdss_hdmi_ddc_suspend &mdss_hdmi_cec_suspend>; +}; + +&mdss_mdp { + qcom,mdss-pref-prim-intf = "dsi"; +}; + +&mdss_dsi { + hw-config = "single_dsi"; +}; + +&mdss_dsi0 { + qcom,dsi-pref-prim-pan = <&dsi_hx8394d_720_vid>; + pinctrl-names = "mdss_default", "mdss_sleep"; + pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; + pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; + + qcom,platform-te-gpio = <&tlmm 41 0>; + qcom,platform-reset-gpio = <&tlmm 39 0>; + qcom,platform-bklight-en-gpio = <&tlmm 48 0>; +}; + +&dsi_hx8394d_720_vid { + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_tlmm_gpio"; + qcom,mdss-dsi-bl-pmic-bank-select = <0>; + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; +}; + +&i2c_5 { /* BLSP (NTAG) */ + status = "ok"; + nq@55 { + status = "ok"; + }; +}; + +&soc { + spi@78b5000 { + status = "ok"; + spi@0 { + compatible = "qcom,spi-msm-codec-slave"; + reg = <0>; + spi-max-frequency = <50000000>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/qcs407-iot-sku6.dts b/arch/arm64/boot/dts/qcom/qcs407-iot-sku6.dts new file mode 100644 index 000000000000..46d06b57b181 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs407-iot-sku6.dts @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "qcs407.dtsi" +#include "qcs405-csra1-audio-overlay.dtsi" +#include "qcs405-geni-ir-overlay.dtsi" +#include "qcs405-circular-pca9956.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. QCS407 EVB1 4000 CSRA1 IOT"; + compatible = "qcom,qcs407-iot", "qcom,qcs407", "qcom,iot"; + qcom,board-id = <0x040020 0x1>; +}; + +#include "qcs405-mdss-panels.dtsi" + +&mdss_mdp { + qcom,mdss-pref-prim-intf = "dsi"; +}; + +&mdss_dsi { + hw-config = "single_dsi"; +}; + +&mdss_dsi0 { + qcom,dsi-pref-prim-pan = <&dsi_hx8394d_720_vid>; + pinctrl-names = "mdss_default", "mdss_sleep"; + pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; + pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; + + qcom,platform-te-gpio = <&tlmm 41 0>; + qcom,platform-reset-gpio = <&tlmm 39 0>; + qcom,platform-bklight-en-gpio = <&tlmm 48 0>; +}; + +&dsi_hx8394d_720_vid { + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_tlmm_gpio"; + qcom,mdss-dsi-bl-pmic-bank-select = <0>; + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; +}; + +&soc { + spi@78b5000 { + status = "ok"; + spi@0 { + compatible = "qcom,spi-msm-codec-slave"; + reg = <0>; + spi-max-frequency = <50000000>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/qcs407-iot-sku9.dts b/arch/arm64/boot/dts/qcom/qcs407-iot-sku9.dts new file mode 100644 index 000000000000..ffb93e7e053c --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs407-iot-sku9.dts @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "qcs407.dtsi" +#include "qcs405-audio-overlay.dtsi" +#include "qcs405-circular-pca9956.dtsi" +#include "qcs405-pinctrl.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. QCS407 RCM IOT"; + compatible = "qcom,qcs407-iot", "qcom,qcs407", "qcom,iot"; + qcom,board-id = <0x010015 0x0>; +}; + +#include "qcs405-mdss-panels.dtsi" + +&mdss_mdp { + qcom,mdss-pref-prim-intf = "dsi"; +}; + +&mdss_dsi { + hw-config = "single_dsi"; +}; + +&mdss_dsi0 { + qcom,dsi-pref-prim-pan = <&dsi_hx8394d_720_vid>; + pinctrl-names = "mdss_default", "mdss_sleep"; + pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; + pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; + + qcom,platform-te-gpio = <&tlmm 41 0>; + qcom,platform-reset-gpio = <&tlmm 39 0>; + qcom,platform-bklight-en-gpio = <&tlmm 48 0>; +}; + +&dsi_hx8394d_720_vid { + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_tlmm_gpio"; + qcom,mdss-dsi-bl-pmic-bank-select = <0>; + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; +}; + +&smb1351_otg_supply { + status = "disabled"; +}; + +&usb3 { + status = "disabled"; +}; + +&usb_ss_phy { + status = "ok"; + qcom,keep-powerdown; +}; + +&usb2_phy1 { + status = "disabled"; +}; + +&emac_hw { + status = "disabled"; +}; diff --git a/arch/arm64/boot/dts/qcom/qcs407.dtsi b/arch/arm64/boot/dts/qcom/qcs407.dtsi new file mode 100644 index 000000000000..aeb7d3071d6c --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs407.dtsi @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "qcs405.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. QCS407"; + qcom,msm-name = "QCS407"; + qcom,msm-id = <411 0x0>; + +}; -- GitLab From 3acef302b33457d92746aa211cae88ed1c4c4d93 Mon Sep 17 00:00:00 2001 From: Avaneesh Kumar Dwivedi Date: Wed, 17 Jul 2019 14:17:15 +0530 Subject: [PATCH 0914/1121] defconfig: qcs403: Add new defconfig of qcs403 QCS403 was sharing its defconfig with qcs405, separating them out and creating its own defconfig for qcs403. Change-Id: I7a830d407867fcb558c14c1d7b2471c269b29b1a Signed-off-by: Avaneesh Kumar Dwivedi --- arch/arm/configs/vendor/qcs403-perf_defconfig | 369 +++++++++++ arch/arm/configs/vendor/qcs403_defconfig | 571 +++++++++++++++++ .../configs/vendor/qcs403-perf_defconfig | 554 ++++++++++++++++ arch/arm64/configs/vendor/qcs403_defconfig | 604 ++++++++++++++++++ 4 files changed, 2098 insertions(+) create mode 100644 arch/arm/configs/vendor/qcs403-perf_defconfig create mode 100644 arch/arm/configs/vendor/qcs403_defconfig create mode 100644 arch/arm64/configs/vendor/qcs403-perf_defconfig create mode 100644 arch/arm64/configs/vendor/qcs403_defconfig diff --git a/arch/arm/configs/vendor/qcs403-perf_defconfig b/arch/arm/configs/vendor/qcs403-perf_defconfig new file mode 100644 index 000000000000..4c5728f6771c --- /dev/null +++ b/arch/arm/configs/vendor/qcs403-perf_defconfig @@ -0,0 +1,369 @@ +CONFIG_POSIX_MQUEUE=y +CONFIG_AUDIT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_IRQ_TIME_ACCOUNTING=y +CONFIG_SCHED_WALT=y +CONFIG_TASKSTATS=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_RCU_EXPERT=y +CONFIG_RCU_FAST_NO_HZ=y +CONFIG_RCU_NOCB_CPU=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_CGROUPS=y +CONFIG_CGROUP_SCHED=y +CONFIG_RT_GROUP_SCHED=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_PID_NS is not set +CONFIG_DEFAULT_USE_ENERGY_AWARE=y +CONFIG_RELAY=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_KALLSYMS_ALL=y +CONFIG_EMBEDDED=y +# CONFIG_SLUB_DEBUG is not set +CONFIG_PROFILING=y +CONFIG_CC_STACKPROTECTOR_STRONG=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SIG=y +CONFIG_MODULE_SIG_FORCE=y +CONFIG_MODULE_SIG_SHA512=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_ARCH_QCOM=y +CONFIG_ARCH_QCS403=y +# CONFIG_VDSO is not set +CONFIG_SMP=y +CONFIG_ARM_PSCI=y +CONFIG_PREEMPT=y +CONFIG_CMA=y +CONFIG_ZSMALLOC=y +CONFIG_SECCOMP=y +CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y +CONFIG_CPU_IDLE=y +CONFIG_VFP=y +CONFIG_NEON=y +CONFIG_KERNEL_MODE_NEON=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_PM_AUTOSLEEP=y +CONFIG_PM_WAKELOCKS=y +CONFIG_PM_WAKELOCKS_LIMIT=0 +# CONFIG_PM_WAKELOCKS_GC is not set +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET6_XFRM_MODE_TUNNEL is not set +# CONFIG_INET6_XFRM_MODE_BEET is not set +# CONFIG_IPV6_SIT is not set +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_NETFILTER=y +CONFIG_NETFILTER_NETLINK_QUEUE=y +CONFIG_NETFILTER_NETLINK_LOG=y +CONFIG_NF_CONNTRACK=y +# CONFIG_NF_CONNTRACK_PROCFS is not set +CONFIG_NF_CONNTRACK_EVENTS=y +# CONFIG_NF_CT_PROTO_DCCP is not set +# CONFIG_NF_CT_PROTO_SCTP is not set +CONFIG_NF_CONNTRACK_FTP=y +CONFIG_NF_CONNTRACK_TFTP=y +CONFIG_NF_CT_NETLINK=y +CONFIG_NF_CONNTRACK_IPV4=y +CONFIG_NF_LOG_IPV4=y +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_REJECT=y +CONFIG_IP_NF_NAT=y +CONFIG_IP_NF_TARGET_MASQUERADE=y +CONFIG_IP_NF_TARGET_NETMAP=y +CONFIG_IP_NF_TARGET_REDIRECT=y +CONFIG_IP_NF_MANGLE=y +CONFIG_IP_NF_RAW=y +CONFIG_IP_NF_SECURITY=y +CONFIG_IP_NF_ARPTABLES=y +CONFIG_IP_NF_ARPFILTER=y +CONFIG_IP_NF_ARP_MANGLE=y +CONFIG_NF_CONNTRACK_IPV6=y +CONFIG_NF_LOG_IPV6=y +CONFIG_IP6_NF_IPTABLES=y +CONFIG_IP6_NF_FILTER=y +CONFIG_IP6_NF_TARGET_REJECT=y +CONFIG_IP6_NF_MANGLE=y +CONFIG_IP6_NF_RAW=y +CONFIG_BRIDGE_NF_EBTABLES=y +CONFIG_BRIDGE_EBT_BROUTE=y +CONFIG_BRIDGE=y +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_PRIO=y +CONFIG_NET_EMATCH=y +CONFIG_NET_CLS_ACT=y +CONFIG_QRTR=y +CONFIG_QRTR_SMD=y +CONFIG_BT=y +# CONFIG_BT_BREDR is not set +# CONFIG_BT_LE is not set +# CONFIG_BT_DEBUGFS is not set +CONFIG_MSM_BT_POWER=y +CONFIG_CFG80211=y +CONFIG_CFG80211_INTERNAL_REGDB=y +CONFIG_RFKILL=y +CONFIG_NTAG_NQ=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_DMA_CMA=y +CONFIG_MTD=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_MSM_QPIC_NAND=y +CONFIG_MTD_NAND=y +CONFIG_MTD_UBI=y +CONFIG_ZRAM=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_QSEECOM=y +CONFIG_UID_SYS_STATS=y +CONFIG_QPNP_MISC=y +CONFIG_NETDEVICES=y +CONFIG_DUMMY=y +CONFIG_PHYLIB=y +CONFIG_AT803X_PHY=y +CONFIG_PPP=y +CONFIG_PPP_DEFLATE=y +CONFIG_PPP_ASYNC=y +CONFIG_WCNSS_MEM_PRE_ALLOC=y +CONFIG_CLD_LL_CORE=y +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_KEYRESET=y +CONFIG_KEYBOARD_GPIO=y +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_MISC=y +CONFIG_INPUT_QPNP_POWER_ON=y +CONFIG_INPUT_UINPUT=y +CONFIG_INPUT_GPIO=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVMEM is not set +CONFIG_SERIAL_MSM_HS=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_MSM_LEGACY=y +CONFIG_DIAG_CHAR=y +CONFIG_MSM_ADSPRPC=y +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MUX=y +CONFIG_I2C_MSM_V2=y +CONFIG_SPI=y +CONFIG_SPI_QUP=y +CONFIG_SPI_SPIDEV=y +CONFIG_SPMI=y +CONFIG_SLIMBUS_MSM_NGD=y +CONFIG_PTP_1588_CLOCK=y +CONFIG_PINCTRL_QCS405=y +CONFIG_FRAGMENTED_GPIO_ADDRESS_SPACE=y +CONFIG_PINCTRL_QCOM_SPMI_PMIC=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_SYSFS=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_QCOM=y +CONFIG_QCOM_DLOAD_MODE=y +CONFIG_POWER_SUPPLY=y +CONFIG_SMB1351_USB_CHARGER=y +CONFIG_THERMAL=y +CONFIG_THERMAL_GOV_USER_SPACE=y +CONFIG_THERMAL_GOV_LOW_LIMITS=y +CONFIG_CPU_THERMAL=y +CONFIG_DEVFREQ_THERMAL=y +CONFIG_THERMAL_TSENS=y +CONFIG_QTI_VIRTUAL_SENSOR=y +CONFIG_QTI_QMI_COOLING_DEVICE=y +CONFIG_REGULATOR_COOLING_DEVICE=y +CONFIG_QTI_ADC_TM=y +CONFIG_QTI_RPM_SMD_COOLING_DEVICE=y +CONFIG_MFD_SPMI_PMIC=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_FAN53555=y +CONFIG_REGULATOR_CPR=y +CONFIG_REGULATOR_MEM_ACC=y +CONFIG_REGULATOR_RPM_SMD=y +CONFIG_REGULATOR_SPM=y +CONFIG_REGULATOR_STUB=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_USB_AUDIO=y +CONFIG_SND_SOC=y +CONFIG_HIDRAW=y +# CONFIG_USB_HID is not set +CONFIG_USB=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_MSM=y +CONFIG_USB_EHSET_TEST_FIXTURE=y +CONFIG_USB_LINK_LAYER_TEST=y +CONFIG_NOP_USB_XCEIV=y +CONFIG_MSM_SNPS_FEMTO_PHY=y +CONFIG_USB_MSM_SSPHY=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_VBUS_DRAW=900 +CONFIG_USB_CONFIGFS=y +CONFIG_USB_CONFIGFS_F_FS=y +CONFIG_USB_CONFIGFS_UEVENT=y +CONFIG_USB_CONFIGFS_F_DIAG=y +CONFIG_MMC=y +CONFIG_MMC_PERF_PROFILING=y +CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_BLOCK_DEFERRED_RESUME=y +CONFIG_MMC_TEST=m +CONFIG_MMC_PARANOID_SD_INIT=y +CONFIG_MMC_CLKGATE=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_MSM=y +CONFIG_MMC_CQ_HCI=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_PCA9956B=y +CONFIG_LEDS_TRIGGERS=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_QPNP=y +CONFIG_DMADEVICES=y +CONFIG_QCOM_SPS_DMA=y +CONFIG_SYNC_FILE=y +CONFIG_UIO=y +CONFIG_STAGING=y +CONFIG_ASHMEM=y +CONFIG_ION=y +CONFIG_QPNP_REVID=y +CONFIG_SPS=y +CONFIG_SPS_SUPPORT_NDP_BAM=y +CONFIG_COMMON_CLK_QCOM=y +CONFIG_QCOM_CLK_SMD_RPM=y +CONFIG_SPMI_PMIC_CLKDIV=y +CONFIG_MDM_DEBUGCC_QCS405=y +CONFIG_CLOCK_CPU_QCS405=y +CONFIG_QCS_CMN_BLK_PLL=y +CONFIG_HWSPINLOCK=y +CONFIG_HWSPINLOCK_QCOM=y +CONFIG_MAILBOX=y +CONFIG_QCOM_APCS_IPC=y +CONFIG_ARM_SMMU=y +CONFIG_QCOM_LAZY_MAPPING=y +CONFIG_RPMSG_CHAR=y +CONFIG_RPMSG_QCOM_GLINK_RPM=y +CONFIG_RPMSG_QCOM_GLINK_SMEM=y +CONFIG_RPMSG_QCOM_SMD=y +CONFIG_QCOM_QMI_HELPERS=y +CONFIG_QCOM_SMEM=y +CONFIG_QCOM_SMD_RPM=y +CONFIG_MSM_SPM=y +CONFIG_MSM_L2_SPM=y +CONFIG_QCOM_SCM=y +CONFIG_QCOM_MEMORY_DUMP_V2=y +CONFIG_QCOM_WATCHDOG_V2=y +CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y +CONFIG_QCOM_WDOG_IPI_ENABLE=y +CONFIG_QCOM_SMP2P=y +CONFIG_MSM_SERVICE_LOCATOR=y +CONFIG_MSM_SERVICE_NOTIFIER=y +CONFIG_MSM_SUBSYSTEM_RESTART=y +CONFIG_MSM_PIL=y +CONFIG_MSM_SYSMON_QMI_COMM=y +CONFIG_MSM_PIL_SSR_GENERIC=y +CONFIG_MSM_BOOT_STATS=y +CONFIG_QCOM_DCC_V2=y +CONFIG_ICNSS=y +CONFIG_ICNSS_QMI=y +CONFIG_QCOM_BUS_SCALING=y +CONFIG_QCOM_EARLY_RANDOM=y +CONFIG_MSM_TZ_SMMU=y +CONFIG_QCOM_GLINK=y +CONFIG_QCOM_GLINK_PKT=y +CONFIG_QTI_RPM_STATS_LOG=y +CONFIG_MSM_CDSP_LOADER=y +CONFIG_QCOM_SMCINVOKE=y +CONFIG_QCOM_SMP2P_SLEEPSTATE=y +CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y +CONFIG_QCOM_BIMC_BWMON=y +CONFIG_ARM_MEMLAT_MON=y +CONFIG_DEVFREQ_GOV_QCOM_BW_HWMON=y +CONFIG_DEVFREQ_GOV_MEMLAT=y +CONFIG_QCOM_DEVFREQ_DEVBW=y +CONFIG_EXTCON_USB_GPIO=y +CONFIG_IIO=y +CONFIG_QCOM_SPMI_ADC5=y +CONFIG_PWM=y +CONFIG_PWM_QTI_LPG=y +CONFIG_QTI_MPM=y +CONFIG_PHY_QCOM_UFS=y +CONFIG_ANDROID=y +CONFIG_ANDROID_BINDER_IPC=y +CONFIG_DAX=y +CONFIG_MSM_TZ_LOG=y +CONFIG_QUOTA=y +CONFIG_QUOTA_NETLINK_INTERFACE=y +# CONFIG_PRINT_QUOTA_WARNING is not set +CONFIG_QFMT_V2=y +CONFIG_FUSE_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_UBIFS_FS=y +CONFIG_UBIFS_FS_ADVANCED_COMPR=y +CONFIG_SQUASHFS=y +CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y +CONFIG_SQUASHFS_XATTR=y +# CONFIG_SQUASHFS_ZLIB is not set +CONFIG_SQUASHFS_XZ=y +CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y +# CONFIG_NETWORK_FILESYSTEMS is not set +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_FS=y +CONFIG_PANIC_ON_RECURSIVE_FAULT=y +CONFIG_PANIC_ON_OOPS=y +CONFIG_PANIC_TIMEOUT=5 +CONFIG_STACKTRACE=y +# CONFIG_FTRACE is not set +CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y +CONFIG_SECURITY=y +CONFIG_SECURITY_NETWORK=y +CONFIG_LSM_MMAP_MIN_ADDR=4096 +CONFIG_HARDENED_USERCOPY=y +CONFIG_SECURITY_SELINUX=y +CONFIG_CRYPTO_AUTHENC=y +CONFIG_CRYPTO_ECHAINIV=y +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CTR=y +CONFIG_CRYPTO_XCBC=y +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_ARC4=y +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_TWOFISH=y +CONFIG_LIBCRC32C=y diff --git a/arch/arm/configs/vendor/qcs403_defconfig b/arch/arm/configs/vendor/qcs403_defconfig new file mode 100644 index 000000000000..ac217a92deb3 --- /dev/null +++ b/arch/arm/configs/vendor/qcs403_defconfig @@ -0,0 +1,571 @@ +CONFIG_POSIX_MQUEUE=y +CONFIG_AUDIT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_IRQ_TIME_ACCOUNTING=y +CONFIG_SCHED_WALT=y +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_RCU_EXPERT=y +CONFIG_RCU_FAST_NO_HZ=y +CONFIG_RCU_NOCB_CPU=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_CGROUPS=y +CONFIG_CGROUP_SCHED=y +CONFIG_RT_GROUP_SCHED=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_CGROUP_DEBUG=y +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_PID_NS is not set +CONFIG_DEFAULT_USE_ENERGY_AWARE=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_KALLSYMS_ALL=y +CONFIG_EMBEDDED=y +CONFIG_PROFILING=y +CONFIG_CC_STACKPROTECTOR_STRONG=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SIG=y +CONFIG_MODULE_SIG_FORCE=y +CONFIG_MODULE_SIG_SHA512=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_ARCH_QCOM=y +CONFIG_ARCH_QCS403=y +# CONFIG_VDSO is not set +CONFIG_SMP=y +CONFIG_ARM_PSCI=y +CONFIG_PREEMPT=y +CONFIG_HIGHMEM=y +CONFIG_CLEANCACHE=y +CONFIG_CMA=y +CONFIG_CMA_DEBUGFS=y +CONFIG_ZSMALLOC=y +CONFIG_SECCOMP=y +CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y +CONFIG_CPU_IDLE=y +CONFIG_VFP=y +CONFIG_NEON=y +CONFIG_KERNEL_MODE_NEON=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_PM_AUTOSLEEP=y +CONFIG_PM_WAKELOCKS=y +CONFIG_PM_WAKELOCKS_LIMIT=0 +# CONFIG_PM_WAKELOCKS_GC is not set +CONFIG_PM_DEBUG=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_XFRM_USER=y +CONFIG_XFRM_STATISTICS=y +CONFIG_NET_KEY=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_INET_AH=y +CONFIG_INET_ESP=y +CONFIG_INET_IPCOMP=y +# CONFIG_INET_XFRM_MODE_BEET is not set +CONFIG_INET_DIAG_DESTROY=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_INET6_AH=y +CONFIG_INET6_ESP=y +CONFIG_INET6_IPCOMP=y +CONFIG_IPV6_MIP6=y +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_NETFILTER=y +CONFIG_NF_CONNTRACK=y +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_AMANDA=y +CONFIG_NF_CONNTRACK_FTP=y +CONFIG_NF_CONNTRACK_H323=y +CONFIG_NF_CONNTRACK_IRC=y +CONFIG_NF_CONNTRACK_NETBIOS_NS=y +CONFIG_NF_CONNTRACK_PPTP=y +CONFIG_NF_CONNTRACK_SANE=y +CONFIG_NF_CONNTRACK_TFTP=y +CONFIG_NF_CT_NETLINK=y +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y +CONFIG_NETFILTER_XT_TARGET_CONNMARK=y +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y +CONFIG_NETFILTER_XT_TARGET_LOG=y +CONFIG_NETFILTER_XT_TARGET_MARK=y +CONFIG_NETFILTER_XT_TARGET_NFLOG=y +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y +CONFIG_NETFILTER_XT_TARGET_NOTRACK=y +CONFIG_NETFILTER_XT_TARGET_TEE=y +CONFIG_NETFILTER_XT_TARGET_TPROXY=y +CONFIG_NETFILTER_XT_TARGET_TRACE=y +CONFIG_NETFILTER_XT_TARGET_SECMARK=y +CONFIG_NETFILTER_XT_TARGET_TCPMSS=y +CONFIG_NETFILTER_XT_MATCH_COMMENT=y +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y +CONFIG_NETFILTER_XT_MATCH_CONNMARK=y +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y +CONFIG_NETFILTER_XT_MATCH_DSCP=y +CONFIG_NETFILTER_XT_MATCH_ESP=y +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y +CONFIG_NETFILTER_XT_MATCH_HELPER=y +CONFIG_NETFILTER_XT_MATCH_IPRANGE=y +CONFIG_NETFILTER_XT_MATCH_LENGTH=y +CONFIG_NETFILTER_XT_MATCH_LIMIT=y +CONFIG_NETFILTER_XT_MATCH_MAC=y +CONFIG_NETFILTER_XT_MATCH_MARK=y +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y +CONFIG_NETFILTER_XT_MATCH_POLICY=y +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y +CONFIG_NETFILTER_XT_MATCH_QUOTA=y +CONFIG_NETFILTER_XT_MATCH_QUOTA2=y +CONFIG_NETFILTER_XT_MATCH_STATE=y +CONFIG_NETFILTER_XT_MATCH_STATISTIC=y +CONFIG_NETFILTER_XT_MATCH_STRING=y +CONFIG_NETFILTER_XT_MATCH_TIME=y +CONFIG_NETFILTER_XT_MATCH_U32=y +CONFIG_NF_CONNTRACK_IPV4=y +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_MATCH_AH=y +CONFIG_IP_NF_MATCH_ECN=y +CONFIG_IP_NF_MATCH_RPFILTER=y +CONFIG_IP_NF_MATCH_TTL=y +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_REJECT=y +CONFIG_IP_NF_NAT=y +CONFIG_IP_NF_TARGET_MASQUERADE=y +CONFIG_IP_NF_TARGET_NETMAP=y +CONFIG_IP_NF_TARGET_REDIRECT=y +CONFIG_IP_NF_MANGLE=y +CONFIG_IP_NF_RAW=y +CONFIG_IP_NF_SECURITY=y +CONFIG_IP_NF_ARPTABLES=y +CONFIG_IP_NF_ARPFILTER=y +CONFIG_IP_NF_ARP_MANGLE=y +CONFIG_NF_CONNTRACK_IPV6=y +CONFIG_IP6_NF_IPTABLES=y +CONFIG_IP6_NF_MATCH_RPFILTER=y +CONFIG_IP6_NF_FILTER=y +CONFIG_IP6_NF_TARGET_REJECT=y +CONFIG_IP6_NF_MANGLE=y +CONFIG_IP6_NF_RAW=y +CONFIG_BRIDGE_NF_EBTABLES=y +CONFIG_BRIDGE_EBT_BROUTE=y +CONFIG_BRIDGE_EBT_T_FILTER=y +CONFIG_BRIDGE_EBT_T_NAT=y +CONFIG_BRIDGE_EBT_ARP=y +CONFIG_BRIDGE_EBT_IP=y +CONFIG_BRIDGE_EBT_IP6=y +CONFIG_BRIDGE_EBT_ARPREPLY=y +CONFIG_BRIDGE_EBT_DNAT=y +CONFIG_BRIDGE_EBT_SNAT=y +CONFIG_L2TP=y +CONFIG_L2TP_DEBUGFS=y +CONFIG_L2TP_V3=y +CONFIG_L2TP_IP=y +CONFIG_L2TP_ETH=y +CONFIG_BRIDGE=y +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_HTB=y +CONFIG_NET_SCH_PRIO=y +CONFIG_NET_CLS_FW=y +CONFIG_NET_CLS_U32=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_FLOW=y +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_CMP=y +CONFIG_NET_EMATCH_NBYTE=y +CONFIG_NET_EMATCH_U32=y +CONFIG_NET_EMATCH_META=y +CONFIG_NET_EMATCH_TEXT=y +CONFIG_NET_CLS_ACT=y +CONFIG_QRTR=y +CONFIG_QRTR_SMD=y +CONFIG_BT=y +# CONFIG_BT_BREDR is not set +# CONFIG_BT_LE is not set +# CONFIG_BT_DEBUGFS is not set +CONFIG_MSM_BT_POWER=y +CONFIG_CFG80211=y +CONFIG_CFG80211_INTERNAL_REGDB=y +CONFIG_RFKILL=y +CONFIG_NTAG_NQ=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y +CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y +CONFIG_DMA_CMA=y +CONFIG_MTD=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_MSM_QPIC_NAND=y +CONFIG_MTD_NAND=y +CONFIG_MTD_UBI=y +CONFIG_ZRAM=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_QSEECOM=y +CONFIG_UID_SYS_STATS=y +CONFIG_QPNP_MISC=y +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_SG=y +CONFIG_CHR_DEV_SCH=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_UFSHCD=y +CONFIG_SCSI_UFSHCD_PLATFORM=y +CONFIG_SCSI_UFS_QCOM=y +CONFIG_MD=y +CONFIG_BLK_DEV_DM=y +CONFIG_DM_CRYPT=y +CONFIG_DM_VERITY=y +CONFIG_DM_VERITY_FEC=y +CONFIG_NETDEVICES=y +CONFIG_DUMMY=y +CONFIG_TUN=y +CONFIG_AT803X_PHY=y +CONFIG_PPP=y +CONFIG_PPP_BSDCOMP=y +CONFIG_PPP_DEFLATE=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=y +CONFIG_PPP_MULTILINK=y +CONFIG_PPPOE=y +CONFIG_PPPOL2TP=y +CONFIG_PPPOLAC=y +CONFIG_PPPOPNS=y +CONFIG_PPP_ASYNC=y +CONFIG_PPP_SYNC_TTY=y +CONFIG_USB_USBNET=y +CONFIG_USB_NET_SMSC75XX=y +CONFIG_WCNSS_MEM_PRE_ALLOC=y +CONFIG_CLD_LL_CORE=y +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_EVBUG=m +CONFIG_INPUT_KEYRESET=y +CONFIG_KEYBOARD_GPIO=y +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_JOYSTICK=y +CONFIG_JOYSTICK_XPAD=y +CONFIG_INPUT_TABLET=y +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_ATMEL_MXT=y +CONFIG_INPUT_MISC=y +CONFIG_INPUT_HBTP_INPUT=y +CONFIG_INPUT_QPNP_POWER_ON=y +CONFIG_INPUT_UINPUT=y +CONFIG_INPUT_GPIO=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVMEM is not set +CONFIG_SERIAL_MSM=y +CONFIG_SERIAL_MSM_CONSOLE=y +CONFIG_SERIAL_MSM_HS=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_MSM_LEGACY=y +CONFIG_DIAG_CHAR=y +CONFIG_MSM_ADSPRPC=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MSM_V2=y +CONFIG_SPI=y +CONFIG_SPI_DEBUG=y +CONFIG_SPI_QUP=y +CONFIG_SPI_SPIDEV=y +CONFIG_SPMI=y +CONFIG_SPMI_MSM_PMIC_ARB_DEBUG=y +CONFIG_SLIMBUS_MSM_NGD=y +CONFIG_PTP_1588_CLOCK=y +CONFIG_PINCTRL_QCS405=y +CONFIG_FRAGMENTED_GPIO_ADDRESS_SPACE=y +CONFIG_PINCTRL_QCOM_SPMI_PMIC=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_SYSFS=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_QCOM=y +CONFIG_QCOM_DLOAD_MODE=y +CONFIG_POWER_SUPPLY=y +CONFIG_SMB1351_USB_CHARGER=y +CONFIG_THERMAL=y +CONFIG_THERMAL_GOV_USER_SPACE=y +CONFIG_THERMAL_GOV_LOW_LIMITS=y +CONFIG_CPU_THERMAL=y +CONFIG_DEVFREQ_THERMAL=y +CONFIG_QCOM_SPMI_TEMP_ALARM=y +CONFIG_THERMAL_TSENS=y +CONFIG_QTI_VIRTUAL_SENSOR=y +CONFIG_QTI_QMI_COOLING_DEVICE=y +CONFIG_REGULATOR_COOLING_DEVICE=y +CONFIG_QTI_ADC_TM=y +CONFIG_QTI_RPM_SMD_COOLING_DEVICE=y +CONFIG_MFD_SPMI_PMIC=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_FAN53555=y +CONFIG_REGULATOR_CPR=y +CONFIG_REGULATOR_MEM_ACC=y +CONFIG_REGULATOR_RPM_SMD=y +CONFIG_REGULATOR_SPM=y +CONFIG_REGULATOR_STUB=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_RADIO_SUPPORT=y +CONFIG_MEDIA_CONTROLLER=y +CONFIG_VIDEO_V4L2_SUBDEV_API=y +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_SOC_CAMERA=y +CONFIG_SOC_CAMERA_PLATFORM=y +CONFIG_FB=y +CONFIG_FB_MSM=y +CONFIG_FB_MSM_MDSS=y +CONFIG_FB_MSM_MDSS_WRITEBACK=y +CONFIG_FB_MSM_MDSS_DSI_CTRL_STATUS=y +CONFIG_FB_MSM_MDSS_XLOG_DEBUG=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_USB_AUDIO=y +CONFIG_SND_SOC=y +CONFIG_HIDRAW=y +CONFIG_UHID=y +CONFIG_HID_APPLE=y +CONFIG_HID_ELECOM=y +CONFIG_HID_MAGICMOUSE=y +CONFIG_HID_MICROSOFT=y +CONFIG_HID_MULTITOUCH=y +CONFIG_USB_HIDDEV=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +CONFIG_USB_MON=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_ACM=y +CONFIG_USB_STORAGE=y +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_ALAUDA=y +CONFIG_USB_STORAGE_KARMA=y +CONFIG_USB_STORAGE_CYPRESS_ATACB=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_MSM=y +CONFIG_USB_SERIAL=y +CONFIG_USB_EHSET_TEST_FIXTURE=y +CONFIG_USB_LINK_LAYER_TEST=y +CONFIG_NOP_USB_XCEIV=y +CONFIG_MSM_SNPS_FEMTO_PHY=y +CONFIG_USB_MSM_SSPHY=y +CONFIG_USB_QCOM_EMU_PHY=y +CONFIG_DUAL_ROLE_USB_INTF=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_DEBUG_FILES=y +CONFIG_USB_GADGET_DEBUG_FS=y +CONFIG_USB_GADGET_VBUS_DRAW=900 +CONFIG_USB_CONFIGFS=y +CONFIG_USB_CONFIGFS_F_FS=y +CONFIG_USB_CONFIGFS_UEVENT=y +CONFIG_USB_CONFIGFS_F_DIAG=y +CONFIG_MMC=y +CONFIG_MMC_PERF_PROFILING=y +CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_BLOCK_DEFERRED_RESUME=y +CONFIG_MMC_TEST=m +CONFIG_MMC_RING_BUFFER=y +CONFIG_MMC_PARANOID_SD_INIT=y +CONFIG_MMC_CLKGATE=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_MSM=y +CONFIG_MMC_CQ_HCI=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_PCA9956B=y +CONFIG_LEDS_TRIGGERS=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_QPNP=y +CONFIG_DMADEVICES=y +CONFIG_QCOM_SPS_DMA=y +CONFIG_UIO=y +CONFIG_STAGING=y +CONFIG_ASHMEM=y +CONFIG_ION=y +CONFIG_QPNP_REVID=y +CONFIG_SPS=y +CONFIG_SPS_SUPPORT_NDP_BAM=y +CONFIG_QCOM_MDSS_PLL=y +CONFIG_COMMON_CLK_QCOM=y +CONFIG_QCOM_CLK_SMD_RPM=y +CONFIG_SPMI_PMIC_CLKDIV=y +CONFIG_MDM_DEBUGCC_QCS405=y +CONFIG_CLOCK_CPU_QCS405=y +CONFIG_QCS_CMN_BLK_PLL=y +CONFIG_HWSPINLOCK=y +CONFIG_HWSPINLOCK_QCOM=y +CONFIG_MAILBOX=y +CONFIG_QCOM_APCS_IPC=y +CONFIG_ARM_SMMU=y +CONFIG_QCOM_LAZY_MAPPING=y +CONFIG_IOMMU_DEBUG=y +CONFIG_IOMMU_DEBUG_TRACKING=y +CONFIG_IOMMU_TESTS=y +CONFIG_QCOM_IOMMU=y +CONFIG_RPMSG_CHAR=y +CONFIG_RPMSG_QCOM_GLINK_RPM=y +CONFIG_RPMSG_QCOM_GLINK_SMEM=y +CONFIG_RPMSG_QCOM_SMD=y +CONFIG_QCOM_CPUSS_DUMP=y +CONFIG_QCOM_QMI_HELPERS=y +CONFIG_QCOM_SMEM=y +CONFIG_QCOM_SMD_RPM=y +CONFIG_MSM_SPM=y +CONFIG_MSM_L2_SPM=y +CONFIG_QCOM_SCM=y +CONFIG_QCOM_MEMORY_DUMP_V2=y +CONFIG_QCOM_WATCHDOG_V2=y +CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y +CONFIG_QCOM_WDOG_IPI_ENABLE=y +CONFIG_QCOM_SMP2P=y +CONFIG_MSM_SERVICE_LOCATOR=y +CONFIG_MSM_SERVICE_NOTIFIER=y +CONFIG_MSM_SUBSYSTEM_RESTART=y +CONFIG_MSM_PIL=y +CONFIG_MSM_SYSMON_QMI_COMM=y +CONFIG_MSM_PIL_SSR_GENERIC=y +CONFIG_MSM_BOOT_STATS=y +CONFIG_MSM_CORE_HANG_DETECT=y +CONFIG_QCOM_DCC_V2=y +CONFIG_ICNSS=y +CONFIG_ICNSS_DEBUG=y +CONFIG_ICNSS_QMI=y +CONFIG_QCOM_BUS_SCALING=y +CONFIG_QCOM_EARLY_RANDOM=y +CONFIG_MSM_TZ_SMMU=y +CONFIG_QCOM_GLINK=y +CONFIG_QCOM_GLINK_PKT=y +# CONFIG_MSM_JTAGV8 is not set +CONFIG_QTI_RPM_STATS_LOG=y +CONFIG_MSM_CDSP_LOADER=y +CONFIG_QCOM_SMCINVOKE=y +CONFIG_QCOM_SMP2P_SLEEPSTATE=y +CONFIG_QCOM_BIMC_BWMON=y +CONFIG_ARM_MEMLAT_MON=y +CONFIG_DEVFREQ_GOV_QCOM_BW_HWMON=y +CONFIG_DEVFREQ_GOV_MEMLAT=y +CONFIG_QCOM_DEVFREQ_DEVBW=y +CONFIG_EXTCON_USB_GPIO=y +CONFIG_IIO=y +CONFIG_QCOM_SPMI_ADC5=y +CONFIG_PWM=y +CONFIG_PWM_QTI_LPG=y +CONFIG_QTI_MPM=y +CONFIG_ANDROID=y +CONFIG_ANDROID_BINDER_IPC=y +CONFIG_MSM_TZ_LOG=y +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT3_FS=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_QUOTA=y +CONFIG_QUOTA_NETLINK_INTERFACE=y +# CONFIG_PRINT_QUOTA_WARNING is not set +CONFIG_QFMT_V2=y +CONFIG_FUSE_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_UBIFS_FS=y +CONFIG_UBIFS_FS_ADVANCED_COMPR=y +CONFIG_SQUASHFS=y +CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y +CONFIG_SQUASHFS_XATTR=y +# CONFIG_SQUASHFS_ZLIB is not set +CONFIG_SQUASHFS_XZ=y +CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +CONFIG_PRINTK_TIME=y +CONFIG_DYNAMIC_DEBUG=y +CONFIG_DEBUG_INFO=y +CONFIG_PAGE_OWNER=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_PAGEALLOC=y +CONFIG_SLUB_DEBUG_PANIC_ON=y +CONFIG_DEBUG_PAGEALLOC_ENABLE_DEFAULT=y +CONFIG_PAGE_POISONING_ENABLE_DEFAULT=y +CONFIG_DEBUG_OBJECTS=y +CONFIG_DEBUG_OBJECTS_FREE=y +CONFIG_DEBUG_OBJECTS_TIMERS=y +CONFIG_DEBUG_OBJECTS_WORK=y +CONFIG_DEBUG_OBJECTS_RCU_HEAD=y +CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER=y +CONFIG_SLUB_DEBUG_ON=y +CONFIG_DEBUG_KMEMLEAK=y +CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE=4000 +CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y +CONFIG_DEBUG_STACK_USAGE=y +CONFIG_DEBUG_MEMORY_INIT=y +CONFIG_PANIC_ON_RECURSIVE_FAULT=y +CONFIG_PANIC_ON_OOPS=y +CONFIG_PANIC_TIMEOUT=5 +CONFIG_SCHEDSTATS=y +CONFIG_SCHED_STACK_END_CHECK=y +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_MUTEXES=y +CONFIG_DEBUG_ATOMIC_SLEEP=y +CONFIG_DEBUG_LIST=y +CONFIG_FAULT_INJECTION=y +CONFIG_FAIL_PAGE_ALLOC=y +CONFIG_UFS_FAULT_INJECTION=y +CONFIG_FAULT_INJECTION_DEBUG_FS=y +CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y +CONFIG_IPC_LOGGING=y +CONFIG_QCOM_RTB=y +CONFIG_QCOM_RTB_SEPARATE_CPUS=y +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_LKDTM=y +CONFIG_CORESIGHT=y +CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y +CONFIG_CORESIGHT_SOURCE_ETM4X=y +CONFIG_CORESIGHT_DYNAMIC_REPLICATOR=y +CONFIG_CORESIGHT_STM=y +CONFIG_CORESIGHT_CTI=y +CONFIG_CORESIGHT_TPDA=y +CONFIG_CORESIGHT_TPDM=y +CONFIG_CORESIGHT_HWEVENT=y +CONFIG_CORESIGHT_DUMMY=y +CONFIG_CORESIGHT_REMOTE_ETM=y +CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 +CONFIG_CORESIGHT_EVENT=y +CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y +CONFIG_SECURITY=y +CONFIG_SECURITY_NETWORK=y +CONFIG_LSM_MMAP_MIN_ADDR=4096 +CONFIG_HARDENED_USERCOPY=y +CONFIG_SECURITY_SELINUX=y +CONFIG_CRYPTO_CTR=y +CONFIG_CRYPTO_XCBC=y +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_TWOFISH=y diff --git a/arch/arm64/configs/vendor/qcs403-perf_defconfig b/arch/arm64/configs/vendor/qcs403-perf_defconfig new file mode 100644 index 000000000000..cf04736e1c47 --- /dev/null +++ b/arch/arm64/configs/vendor/qcs403-perf_defconfig @@ -0,0 +1,554 @@ +CONFIG_POSIX_MQUEUE=y +CONFIG_AUDIT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_IRQ_TIME_ACCOUNTING=y +CONFIG_SCHED_WALT=y +CONFIG_TASKSTATS=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_RCU_EXPERT=y +CONFIG_RCU_FAST_NO_HZ=y +CONFIG_RCU_NOCB_CPU=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_CGROUPS=y +CONFIG_CGROUP_SCHED=y +CONFIG_RT_GROUP_SCHED=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_PID_NS is not set +CONFIG_DEFAULT_USE_ENERGY_AWARE=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_KALLSYMS_ALL=y +CONFIG_EMBEDDED=y +CONFIG_SLAB_FREELIST_HARDENED=y +CONFIG_PROFILING=y +CONFIG_CC_STACKPROTECTOR_STRONG=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SIG=y +CONFIG_MODULE_SIG_FORCE=y +CONFIG_MODULE_SIG_SHA512=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_ARCH_QCOM=y +CONFIG_ARCH_QCS403=y +CONFIG_PCI=y +CONFIG_PCI_MSM=y +CONFIG_PCI_MSM_MSI=y +CONFIG_NR_CPUS=4 +CONFIG_PREEMPT=y +CONFIG_CMA=y +CONFIG_ZSMALLOC=y +CONFIG_SECCOMP=y +# CONFIG_HARDEN_BRANCH_PREDICTOR is not set +CONFIG_ARMV8_DEPRECATED=y +CONFIG_SWP_EMULATION=y +CONFIG_CP15_BARRIER_EMULATION=y +CONFIG_SETEND_EMULATION=y +CONFIG_ARM64_SW_TTBR0_PAN=y +CONFIG_RANDOMIZE_BASE=y +CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_COMPAT=y +CONFIG_PM_AUTOSLEEP=y +CONFIG_PM_WAKELOCKS=y +CONFIG_PM_WAKELOCKS_LIMIT=0 +# CONFIG_PM_WAKELOCKS_GC is not set +CONFIG_CPU_IDLE=y +CONFIG_ARM_CPUIDLE=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y +CONFIG_CPU_FREQ_MSM=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_XFRM_USER=y +CONFIG_XFRM_STATISTICS=y +CONFIG_NET_KEY=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_INET_AH=y +CONFIG_INET_ESP=y +CONFIG_INET_IPCOMP=y +# CONFIG_INET_XFRM_MODE_BEET is not set +CONFIG_INET_DIAG_DESTROY=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_INET6_AH=y +CONFIG_INET6_ESP=y +CONFIG_INET6_IPCOMP=y +CONFIG_IPV6_MIP6=y +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_NETFILTER=y +CONFIG_NF_CONNTRACK=y +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_AMANDA=y +CONFIG_NF_CONNTRACK_FTP=y +CONFIG_NF_CONNTRACK_H323=y +CONFIG_NF_CONNTRACK_IRC=y +CONFIG_NF_CONNTRACK_NETBIOS_NS=y +CONFIG_NF_CONNTRACK_PPTP=y +CONFIG_NF_CONNTRACK_SANE=y +CONFIG_NF_CONNTRACK_TFTP=y +CONFIG_NF_CT_NETLINK=y +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y +CONFIG_NETFILTER_XT_TARGET_CONNMARK=y +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y +CONFIG_NETFILTER_XT_TARGET_LOG=y +CONFIG_NETFILTER_XT_TARGET_MARK=y +CONFIG_NETFILTER_XT_TARGET_NFLOG=y +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y +CONFIG_NETFILTER_XT_TARGET_NOTRACK=y +CONFIG_NETFILTER_XT_TARGET_TEE=y +CONFIG_NETFILTER_XT_TARGET_TPROXY=y +CONFIG_NETFILTER_XT_TARGET_TRACE=y +CONFIG_NETFILTER_XT_TARGET_SECMARK=y +CONFIG_NETFILTER_XT_TARGET_TCPMSS=y +CONFIG_NETFILTER_XT_MATCH_COMMENT=y +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y +CONFIG_NETFILTER_XT_MATCH_CONNMARK=y +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y +CONFIG_NETFILTER_XT_MATCH_DSCP=y +CONFIG_NETFILTER_XT_MATCH_ESP=y +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y +CONFIG_NETFILTER_XT_MATCH_HELPER=y +CONFIG_NETFILTER_XT_MATCH_IPRANGE=y +CONFIG_NETFILTER_XT_MATCH_LENGTH=y +CONFIG_NETFILTER_XT_MATCH_LIMIT=y +CONFIG_NETFILTER_XT_MATCH_MAC=y +CONFIG_NETFILTER_XT_MATCH_MARK=y +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y +CONFIG_NETFILTER_XT_MATCH_POLICY=y +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y +CONFIG_NETFILTER_XT_MATCH_QUOTA=y +CONFIG_NETFILTER_XT_MATCH_QUOTA2=y +CONFIG_NETFILTER_XT_MATCH_STATE=y +CONFIG_NETFILTER_XT_MATCH_STATISTIC=y +CONFIG_NETFILTER_XT_MATCH_STRING=y +CONFIG_NETFILTER_XT_MATCH_TIME=y +CONFIG_NETFILTER_XT_MATCH_U32=y +CONFIG_NF_CONNTRACK_IPV4=y +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_MATCH_AH=y +CONFIG_IP_NF_MATCH_ECN=y +CONFIG_IP_NF_MATCH_RPFILTER=y +CONFIG_IP_NF_MATCH_TTL=y +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_REJECT=y +CONFIG_IP_NF_NAT=y +CONFIG_IP_NF_TARGET_MASQUERADE=y +CONFIG_IP_NF_TARGET_NETMAP=y +CONFIG_IP_NF_TARGET_REDIRECT=y +CONFIG_IP_NF_MANGLE=y +CONFIG_IP_NF_RAW=y +CONFIG_IP_NF_SECURITY=y +CONFIG_IP_NF_ARPTABLES=y +CONFIG_IP_NF_ARPFILTER=y +CONFIG_IP_NF_ARP_MANGLE=y +CONFIG_NF_CONNTRACK_IPV6=y +CONFIG_IP6_NF_IPTABLES=y +CONFIG_IP6_NF_MATCH_RPFILTER=y +CONFIG_IP6_NF_FILTER=y +CONFIG_IP6_NF_TARGET_REJECT=y +CONFIG_IP6_NF_MANGLE=y +CONFIG_IP6_NF_RAW=y +CONFIG_BRIDGE_NF_EBTABLES=y +CONFIG_BRIDGE_EBT_BROUTE=y +CONFIG_BRIDGE_EBT_T_FILTER=y +CONFIG_BRIDGE_EBT_T_NAT=y +CONFIG_BRIDGE_EBT_ARP=y +CONFIG_BRIDGE_EBT_IP=y +CONFIG_BRIDGE_EBT_IP6=y +CONFIG_BRIDGE_EBT_ARPREPLY=y +CONFIG_BRIDGE_EBT_DNAT=y +CONFIG_BRIDGE_EBT_SNAT=y +CONFIG_L2TP=y +CONFIG_L2TP_V3=y +CONFIG_L2TP_IP=y +CONFIG_L2TP_ETH=y +CONFIG_BRIDGE=y +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_HTB=y +CONFIG_NET_SCH_PRIO=y +CONFIG_NET_CLS_FW=y +CONFIG_NET_CLS_U32=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_FLOW=y +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_CMP=y +CONFIG_NET_EMATCH_NBYTE=y +CONFIG_NET_EMATCH_U32=y +CONFIG_NET_EMATCH_META=y +CONFIG_NET_EMATCH_TEXT=y +CONFIG_NET_CLS_ACT=y +CONFIG_QRTR=y +CONFIG_QRTR_SMD=y +CONFIG_QRTR_USB=y +CONFIG_RMNET_USB=y +CONFIG_BT=y +# CONFIG_BT_BREDR is not set +# CONFIG_BT_LE is not set +# CONFIG_BT_DEBUGFS is not set +CONFIG_MSM_BT_POWER=y +CONFIG_CFG80211=y +CONFIG_CFG80211_INTERNAL_REGDB=y +CONFIG_MAC80211=m +CONFIG_MAC80211_RC_MINSTREL_VHT=y +CONFIG_MAC80211_DEBUGFS=y +CONFIG_RFKILL=y +CONFIG_NTAG_NQ=y +CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y +CONFIG_DMA_CMA=y +CONFIG_MHI_BUS=y +CONFIG_MHI_QCOM=y +CONFIG_MHI_NETDEV=y +CONFIG_MHI_UCI=y +CONFIG_MTD=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_MSM_QPIC_NAND=y +CONFIG_MTD_NAND=y +CONFIG_MTD_UBI=y +CONFIG_ZRAM=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_QSEECOM=y +CONFIG_UID_SYS_STATS=y +CONFIG_QPNP_MISC=y +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_SG=y +CONFIG_CHR_DEV_SCH=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_UFSHCD=y +CONFIG_SCSI_UFSHCD_PLATFORM=y +CONFIG_SCSI_UFS_QCOM=y +CONFIG_SCSI_UFSHCD_CMD_LOGGING=y +CONFIG_MD=y +CONFIG_BLK_DEV_DM=y +CONFIG_DM_CRYPT=y +CONFIG_DM_VERITY=y +CONFIG_DM_VERITY_FEC=y +CONFIG_NETDEVICES=y +CONFIG_DUMMY=y +CONFIG_TUN=y +CONFIG_AT803X_PHY=y +CONFIG_PPP=y +CONFIG_PPP_BSDCOMP=y +CONFIG_PPP_DEFLATE=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=y +CONFIG_PPP_MULTILINK=y +CONFIG_PPPOE=y +CONFIG_PPPOL2TP=y +CONFIG_PPPOLAC=y +CONFIG_PPPOPNS=y +CONFIG_PPP_ASYNC=y +CONFIG_PPP_SYNC_TTY=y +CONFIG_USB_USBNET=y +CONFIG_USB_NET_SMSC75XX=y +CONFIG_ATH10K=m +CONFIG_ATH10K_PCI=m +CONFIG_ATH10K_DEBUG=y +CONFIG_ATH10K_DEBUGFS=y +CONFIG_WCNSS_MEM_PRE_ALLOC=y +CONFIG_CLD_LL_CORE=y +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_EVBUG=m +CONFIG_INPUT_KEYRESET=y +CONFIG_KEYBOARD_GPIO=y +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_JOYSTICK=y +CONFIG_JOYSTICK_XPAD=y +CONFIG_INPUT_TABLET=y +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_ATMEL_MXT=y +CONFIG_INPUT_MISC=y +CONFIG_INPUT_HBTP_INPUT=y +CONFIG_INPUT_QPNP_POWER_ON=y +CONFIG_INPUT_UINPUT=y +CONFIG_INPUT_GPIO=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVMEM is not set +CONFIG_SERIAL_MSM_HS=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_MSM_LEGACY=y +CONFIG_DIAG_CHAR=y +CONFIG_MSM_ADSPRPC=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MSM_V2=y +CONFIG_SPI=y +CONFIG_SPI_QUP=y +CONFIG_SPI_SPIDEV=y +CONFIG_SPMI=y +CONFIG_SLIMBUS_MSM_NGD=y +CONFIG_PTP_1588_CLOCK=y +CONFIG_PINCTRL_QCS405=y +CONFIG_FRAGMENTED_GPIO_ADDRESS_SPACE=y +CONFIG_PINCTRL_QCOM_SPMI_PMIC=y +CONFIG_GPIO_SYSFS=y +CONFIG_POWER_RESET_QCOM=y +CONFIG_QCOM_DLOAD_MODE=y +CONFIG_SMB1351_USB_CHARGER=y +CONFIG_THERMAL=y +CONFIG_THERMAL_WRITABLE_TRIPS=y +CONFIG_THERMAL_GOV_USER_SPACE=y +CONFIG_THERMAL_GOV_LOW_LIMITS=y +CONFIG_CPU_THERMAL=y +CONFIG_DEVFREQ_THERMAL=y +CONFIG_QCOM_SPMI_TEMP_ALARM=y +CONFIG_THERMAL_TSENS=y +CONFIG_QTI_VIRTUAL_SENSOR=y +CONFIG_QTI_QMI_COOLING_DEVICE=y +CONFIG_REGULATOR_COOLING_DEVICE=y +CONFIG_QTI_ADC_TM=y +CONFIG_QTI_RPM_SMD_COOLING_DEVICE=y +CONFIG_MFD_SPMI_PMIC=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_FAN53555=y +CONFIG_REGULATOR_CPR=y +CONFIG_REGULATOR_MEM_ACC=y +CONFIG_REGULATOR_RPM_SMD=y +CONFIG_REGULATOR_SPM=y +CONFIG_REGULATOR_STUB=y +CONFIG_RC_DEVICES=y +CONFIG_IR_MSM_GENI=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_RADIO_SUPPORT=y +CONFIG_MEDIA_CONTROLLER=y +CONFIG_VIDEO_V4L2_SUBDEV_API=y +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_SOC_CAMERA=y +CONFIG_SOC_CAMERA_PLATFORM=y +CONFIG_FB=y +CONFIG_FB_MSM=y +CONFIG_FB_MSM_MDSS=y +CONFIG_FB_MSM_MDSS_WRITEBACK=y +CONFIG_FB_MSM_MDSS_HDMI_PANEL=y +CONFIG_FB_MSM_MDSS_SPI_PANEL=y +CONFIG_FB_MSM_MDSS_RGB_PANEL=y +CONFIG_FB_MSM_MDSS_DSI_CTRL_STATUS=y +CONFIG_FB_MSM_MDSS_XLOG_DEBUG=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_USB_AUDIO=y +CONFIG_SND_SOC=y +CONFIG_HIDRAW=y +CONFIG_UHID=y +CONFIG_HID_APPLE=y +CONFIG_HID_ELECOM=y +CONFIG_HID_MAGICMOUSE=y +CONFIG_HID_MICROSOFT=y +CONFIG_HID_MULTITOUCH=y +CONFIG_USB_HIDDEV=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +CONFIG_USB_MON=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_ACM=y +CONFIG_USB_STORAGE=y +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_ALAUDA=y +CONFIG_USB_STORAGE_KARMA=y +CONFIG_USB_STORAGE_CYPRESS_ATACB=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_MSM=y +CONFIG_USB_SERIAL=y +CONFIG_USB_EHSET_TEST_FIXTURE=y +CONFIG_USB_LINK_LAYER_TEST=y +CONFIG_USB_TYPEC_MUX_NXP5150A=y +CONFIG_USB_QCOM_DIAG_BRIDGE=y +CONFIG_NOP_USB_XCEIV=y +CONFIG_MSM_SNPS_FEMTO_PHY=y +CONFIG_USB_MSM_SSPHY=y +CONFIG_USB_QCOM_EMU_PHY=y +CONFIG_DUAL_ROLE_USB_INTF=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_VBUS_DRAW=900 +CONFIG_USB_CONFIGFS=y +CONFIG_USB_CONFIGFS_F_FS=y +CONFIG_USB_CONFIGFS_UEVENT=y +CONFIG_USB_CONFIGFS_F_DIAG=y +CONFIG_MMC=y +CONFIG_MMC_PERF_PROFILING=y +CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_BLOCK_DEFERRED_RESUME=y +CONFIG_MMC_TEST=m +CONFIG_MMC_PARANOID_SD_INIT=y +CONFIG_MMC_CLKGATE=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_MSM=y +CONFIG_MMC_SDHCI_MSM_ICE=y +CONFIG_MMC_CQ_HCI=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_PCA9956B=y +CONFIG_LEDS_TRIGGERS=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_QPNP=y +CONFIG_DMADEVICES=y +CONFIG_QCOM_SPS_DMA=y +CONFIG_UIO=y +CONFIG_STAGING=y +CONFIG_ASHMEM=y +CONFIG_ION=y +CONFIG_QPNP_REVID=y +CONFIG_SPS=y +CONFIG_SPS_SUPPORT_NDP_BAM=y +CONFIG_QCOM_MDSS_PLL=y +CONFIG_QCOM_CLK_SMD_RPM=y +CONFIG_SPMI_PMIC_CLKDIV=y +CONFIG_MDM_DEBUGCC_QCS405=y +CONFIG_CLOCK_CPU_QCS405=y +CONFIG_QCS_CMN_BLK_PLL=y +CONFIG_HWSPINLOCK=y +CONFIG_HWSPINLOCK_QCOM=y +CONFIG_ARM_ARCH_TIMER_VCT_ACCESS=y +CONFIG_MAILBOX=y +CONFIG_QCOM_APCS_IPC=y +CONFIG_ARM_SMMU=y +CONFIG_QCOM_LAZY_MAPPING=y +CONFIG_IOMMU_DEBUG=y +CONFIG_IOMMU_DEBUG_TRACKING=y +CONFIG_RPMSG_CHAR=y +CONFIG_RPMSG_QCOM_GLINK_RPM=y +CONFIG_RPMSG_QCOM_GLINK_SMEM=y +CONFIG_MSM_RPM_SMD=y +CONFIG_QCOM_QMI_HELPERS=y +CONFIG_QCOM_SMEM=y +CONFIG_QCOM_SMD_RPM=y +CONFIG_MSM_SPM=y +CONFIG_MSM_L2_SPM=y +CONFIG_QCOM_SCM=y +CONFIG_QCOM_MEMORY_DUMP_V2=y +CONFIG_QCOM_WATCHDOG_V2=y +CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y +CONFIG_QCOM_WDOG_IPI_ENABLE=y +CONFIG_QCOM_SMP2P=y +CONFIG_MSM_SERVICE_LOCATOR=y +CONFIG_MSM_SERVICE_NOTIFIER=y +CONFIG_MSM_SUBSYSTEM_RESTART=y +CONFIG_MSM_PIL=y +CONFIG_MSM_SYSMON_QMI_COMM=y +CONFIG_MSM_PIL_SSR_GENERIC=y +CONFIG_MSM_BOOT_STATS=y +CONFIG_QCOM_DCC_V2=y +CONFIG_ICNSS=y +CONFIG_ICNSS_QMI=y +CONFIG_QCOM_BUS_SCALING=y +CONFIG_MSM_TZ_SMMU=y +CONFIG_QCOM_GLINK=y +CONFIG_QCOM_GLINK_PKT=y +CONFIG_MSM_JTAGV8=y +CONFIG_QTI_RPM_STATS_LOG=y +CONFIG_MSM_CDSP_LOADER=y +CONFIG_QCOM_SMCINVOKE=y +CONFIG_MSM_PM=y +CONFIG_QCOM_SMP2P_SLEEPSTATE=y +CONFIG_QCOM_BIMC_BWMON=y +CONFIG_ARM_MEMLAT_MON=y +CONFIG_DEVFREQ_GOV_QCOM_BW_HWMON=y +CONFIG_DEVFREQ_GOV_MEMLAT=y +CONFIG_QCOM_DEVFREQ_DEVBW=y +CONFIG_EXTCON_USB_GPIO=y +CONFIG_IIO=y +CONFIG_QCOM_SPMI_ADC5=y +CONFIG_PWM=y +CONFIG_PWM_QTI_LPG=y +CONFIG_QCOM_KGSL=y +CONFIG_QTI_MPM=y +CONFIG_ANDROID=y +CONFIG_ANDROID_BINDER_IPC=y +CONFIG_MSM_TZ_LOG=y +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT3_FS=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_QUOTA=y +CONFIG_QUOTA_NETLINK_INTERFACE=y +# CONFIG_PRINT_QUOTA_WARNING is not set +CONFIG_QFMT_V2=y +CONFIG_FUSE_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_UBIFS_FS=y +CONFIG_UBIFS_FS_ADVANCED_COMPR=y +CONFIG_SQUASHFS=y +CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y +CONFIG_SQUASHFS_XATTR=y +# CONFIG_SQUASHFS_ZLIB is not set +CONFIG_SQUASHFS_XZ=y +CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_INFO=y +CONFIG_PAGE_OWNER=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_PAGE_POISONING=y +CONFIG_PAGE_POISONING_ENABLE_DEFAULT=y +CONFIG_PANIC_ON_RECURSIVE_FAULT=y +CONFIG_PANIC_ON_OOPS=y +CONFIG_PANIC_TIMEOUT=5 +CONFIG_SCHEDSTATS=y +CONFIG_IPC_LOGGING=y +CONFIG_BUG_ON_DATA_CORRUPTION=y +CONFIG_CORESIGHT=y +CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y +CONFIG_CORESIGHT_DYNAMIC_REPLICATOR=y +CONFIG_CORESIGHT_STM=y +CONFIG_CORESIGHT_CTI=y +CONFIG_CORESIGHT_TPDA=y +CONFIG_CORESIGHT_TPDM=y +CONFIG_CORESIGHT_HWEVENT=y +CONFIG_CORESIGHT_DUMMY=y +CONFIG_CORESIGHT_EVENT=y +CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y +CONFIG_SECURITY=y +CONFIG_SECURITY_NETWORK=y +CONFIG_LSM_MMAP_MIN_ADDR=4096 +CONFIG_HARDENED_USERCOPY=y +CONFIG_HARDENED_USERCOPY_PAGESPAN=y +CONFIG_SECURITY_SELINUX=y +CONFIG_CRYPTO_CTR=y +CONFIG_CRYPTO_XCBC=y +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_TWOFISH=y +CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y +CONFIG_CRYPTO_DEV_QCRYPTO=y +CONFIG_CRYPTO_DEV_QCEDEV=y +CONFIG_CRYPTO_DEV_QCOM_ICE=y +CONFIG_STACK_HASH_ORDER_SHIFT=12 diff --git a/arch/arm64/configs/vendor/qcs403_defconfig b/arch/arm64/configs/vendor/qcs403_defconfig new file mode 100644 index 000000000000..c859d4b29da2 --- /dev/null +++ b/arch/arm64/configs/vendor/qcs403_defconfig @@ -0,0 +1,604 @@ +CONFIG_POSIX_MQUEUE=y +CONFIG_AUDIT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_IRQ_TIME_ACCOUNTING=y +CONFIG_SCHED_WALT=y +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_RCU_EXPERT=y +CONFIG_RCU_FAST_NO_HZ=y +CONFIG_RCU_NOCB_CPU=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_CGROUPS=y +CONFIG_CGROUP_SCHED=y +CONFIG_RT_GROUP_SCHED=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_CGROUP_DEBUG=y +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_PID_NS is not set +CONFIG_DEFAULT_USE_ENERGY_AWARE=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_KALLSYMS_ALL=y +CONFIG_EMBEDDED=y +CONFIG_SLAB_FREELIST_HARDENED=y +CONFIG_PROFILING=y +CONFIG_CC_STACKPROTECTOR_STRONG=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SIG=y +CONFIG_MODULE_SIG_FORCE=y +CONFIG_MODULE_SIG_SHA512=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_ARCH_QCOM=y +CONFIG_ARCH_QCS403=y +CONFIG_PCI=y +CONFIG_PCI_MSM=y +CONFIG_PCI_MSM_MSI=y +CONFIG_NR_CPUS=4 +CONFIG_PREEMPT=y +CONFIG_CLEANCACHE=y +CONFIG_CMA=y +CONFIG_CMA_DEBUGFS=y +CONFIG_ZSMALLOC=y +CONFIG_SECCOMP=y +# CONFIG_HARDEN_BRANCH_PREDICTOR is not set +CONFIG_ARMV8_DEPRECATED=y +CONFIG_SWP_EMULATION=y +CONFIG_CP15_BARRIER_EMULATION=y +CONFIG_SETEND_EMULATION=y +CONFIG_ARM64_SW_TTBR0_PAN=y +CONFIG_RANDOMIZE_BASE=y +CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_COMPAT=y +CONFIG_PM_AUTOSLEEP=y +CONFIG_PM_WAKELOCKS=y +CONFIG_PM_WAKELOCKS_LIMIT=0 +# CONFIG_PM_WAKELOCKS_GC is not set +CONFIG_PM_DEBUG=y +CONFIG_CPU_IDLE=y +CONFIG_ARM_CPUIDLE=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y +CONFIG_CPU_FREQ_MSM=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_XFRM_USER=y +CONFIG_XFRM_STATISTICS=y +CONFIG_NET_KEY=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_INET_AH=y +CONFIG_INET_ESP=y +CONFIG_INET_IPCOMP=y +# CONFIG_INET_XFRM_MODE_BEET is not set +CONFIG_INET_DIAG_DESTROY=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_INET6_AH=y +CONFIG_INET6_ESP=y +CONFIG_INET6_IPCOMP=y +CONFIG_IPV6_MIP6=y +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_NETFILTER=y +CONFIG_NF_CONNTRACK=y +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_AMANDA=y +CONFIG_NF_CONNTRACK_FTP=y +CONFIG_NF_CONNTRACK_H323=y +CONFIG_NF_CONNTRACK_IRC=y +CONFIG_NF_CONNTRACK_NETBIOS_NS=y +CONFIG_NF_CONNTRACK_PPTP=y +CONFIG_NF_CONNTRACK_SANE=y +CONFIG_NF_CONNTRACK_TFTP=y +CONFIG_NF_CT_NETLINK=y +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y +CONFIG_NETFILTER_XT_TARGET_CONNMARK=y +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y +CONFIG_NETFILTER_XT_TARGET_LOG=y +CONFIG_NETFILTER_XT_TARGET_MARK=y +CONFIG_NETFILTER_XT_TARGET_NFLOG=y +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y +CONFIG_NETFILTER_XT_TARGET_NOTRACK=y +CONFIG_NETFILTER_XT_TARGET_TEE=y +CONFIG_NETFILTER_XT_TARGET_TPROXY=y +CONFIG_NETFILTER_XT_TARGET_TRACE=y +CONFIG_NETFILTER_XT_TARGET_SECMARK=y +CONFIG_NETFILTER_XT_TARGET_TCPMSS=y +CONFIG_NETFILTER_XT_MATCH_COMMENT=y +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y +CONFIG_NETFILTER_XT_MATCH_CONNMARK=y +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y +CONFIG_NETFILTER_XT_MATCH_DSCP=y +CONFIG_NETFILTER_XT_MATCH_ESP=y +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y +CONFIG_NETFILTER_XT_MATCH_HELPER=y +CONFIG_NETFILTER_XT_MATCH_IPRANGE=y +CONFIG_NETFILTER_XT_MATCH_LENGTH=y +CONFIG_NETFILTER_XT_MATCH_LIMIT=y +CONFIG_NETFILTER_XT_MATCH_MAC=y +CONFIG_NETFILTER_XT_MATCH_MARK=y +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y +CONFIG_NETFILTER_XT_MATCH_POLICY=y +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y +CONFIG_NETFILTER_XT_MATCH_QUOTA=y +CONFIG_NETFILTER_XT_MATCH_QUOTA2=y +CONFIG_NETFILTER_XT_MATCH_STATE=y +CONFIG_NETFILTER_XT_MATCH_STATISTIC=y +CONFIG_NETFILTER_XT_MATCH_STRING=y +CONFIG_NETFILTER_XT_MATCH_TIME=y +CONFIG_NETFILTER_XT_MATCH_U32=y +CONFIG_NF_CONNTRACK_IPV4=y +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_MATCH_AH=y +CONFIG_IP_NF_MATCH_ECN=y +CONFIG_IP_NF_MATCH_RPFILTER=y +CONFIG_IP_NF_MATCH_TTL=y +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_REJECT=y +CONFIG_IP_NF_NAT=y +CONFIG_IP_NF_TARGET_MASQUERADE=y +CONFIG_IP_NF_TARGET_NETMAP=y +CONFIG_IP_NF_TARGET_REDIRECT=y +CONFIG_IP_NF_MANGLE=y +CONFIG_IP_NF_RAW=y +CONFIG_IP_NF_SECURITY=y +CONFIG_IP_NF_ARPTABLES=y +CONFIG_IP_NF_ARPFILTER=y +CONFIG_IP_NF_ARP_MANGLE=y +CONFIG_NF_CONNTRACK_IPV6=y +CONFIG_IP6_NF_IPTABLES=y +CONFIG_IP6_NF_MATCH_RPFILTER=y +CONFIG_IP6_NF_FILTER=y +CONFIG_IP6_NF_TARGET_REJECT=y +CONFIG_IP6_NF_MANGLE=y +CONFIG_IP6_NF_RAW=y +CONFIG_BRIDGE_NF_EBTABLES=y +CONFIG_BRIDGE_EBT_BROUTE=y +CONFIG_BRIDGE_EBT_T_FILTER=y +CONFIG_BRIDGE_EBT_T_NAT=y +CONFIG_BRIDGE_EBT_ARP=y +CONFIG_BRIDGE_EBT_IP=y +CONFIG_BRIDGE_EBT_IP6=y +CONFIG_BRIDGE_EBT_ARPREPLY=y +CONFIG_BRIDGE_EBT_DNAT=y +CONFIG_BRIDGE_EBT_SNAT=y +CONFIG_L2TP=y +CONFIG_L2TP_DEBUGFS=y +CONFIG_L2TP_V3=y +CONFIG_L2TP_IP=y +CONFIG_L2TP_ETH=y +CONFIG_BRIDGE=y +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_HTB=y +CONFIG_NET_SCH_PRIO=y +CONFIG_NET_CLS_FW=y +CONFIG_NET_CLS_U32=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_FLOW=y +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_CMP=y +CONFIG_NET_EMATCH_NBYTE=y +CONFIG_NET_EMATCH_U32=y +CONFIG_NET_EMATCH_META=y +CONFIG_NET_EMATCH_TEXT=y +CONFIG_NET_CLS_ACT=y +CONFIG_QRTR=y +CONFIG_QRTR_SMD=y +CONFIG_QRTR_USB=y +CONFIG_RMNET_USB=y +CONFIG_BT=y +# CONFIG_BT_BREDR is not set +# CONFIG_BT_LE is not set +# CONFIG_BT_DEBUGFS is not set +CONFIG_MSM_BT_POWER=y +CONFIG_CFG80211=y +CONFIG_CFG80211_INTERNAL_REGDB=y +CONFIG_MAC80211=m +CONFIG_MAC80211_RC_MINSTREL_VHT=y +CONFIG_MAC80211_DEBUGFS=y +CONFIG_RFKILL=y +CONFIG_NTAG_NQ=y +CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y +CONFIG_DMA_CMA=y +CONFIG_MHI_BUS=y +CONFIG_MHI_DEBUG=y +CONFIG_MHI_QCOM=y +CONFIG_MHI_NETDEV=y +CONFIG_MHI_UCI=y +CONFIG_MTD=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_MSM_QPIC_NAND=y +CONFIG_MTD_NAND=y +CONFIG_MTD_UBI=y +CONFIG_ZRAM=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_QSEECOM=y +CONFIG_UID_SYS_STATS=y +CONFIG_QPNP_MISC=y +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_SG=y +CONFIG_CHR_DEV_SCH=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_UFSHCD=y +CONFIG_SCSI_UFSHCD_PLATFORM=y +CONFIG_SCSI_UFS_QCOM=y +CONFIG_SCSI_UFSHCD_CMD_LOGGING=y +CONFIG_MD=y +CONFIG_BLK_DEV_DM=y +CONFIG_DM_CRYPT=y +CONFIG_DM_VERITY=y +CONFIG_DM_VERITY_FEC=y +CONFIG_NETDEVICES=y +CONFIG_DUMMY=y +CONFIG_TUN=y +CONFIG_AT803X_PHY=y +CONFIG_PPP=y +CONFIG_PPP_BSDCOMP=y +CONFIG_PPP_DEFLATE=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=y +CONFIG_PPP_MULTILINK=y +CONFIG_PPPOE=y +CONFIG_PPPOL2TP=y +CONFIG_PPPOLAC=y +CONFIG_PPPOPNS=y +CONFIG_PPP_ASYNC=y +CONFIG_PPP_SYNC_TTY=y +CONFIG_USB_USBNET=y +CONFIG_USB_NET_SMSC75XX=y +CONFIG_ATH10K=m +CONFIG_ATH10K_PCI=m +CONFIG_ATH10K_DEBUG=y +CONFIG_ATH10K_DEBUGFS=y +CONFIG_WCNSS_MEM_PRE_ALLOC=y +CONFIG_CLD_LL_CORE=y +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_EVBUG=m +CONFIG_INPUT_KEYRESET=y +CONFIG_KEYBOARD_GPIO=y +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_JOYSTICK=y +CONFIG_JOYSTICK_XPAD=y +CONFIG_INPUT_TABLET=y +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_ATMEL_MXT=y +CONFIG_INPUT_MISC=y +CONFIG_INPUT_HBTP_INPUT=y +CONFIG_INPUT_QPNP_POWER_ON=y +CONFIG_INPUT_UINPUT=y +CONFIG_INPUT_GPIO=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVMEM is not set +CONFIG_SERIAL_MSM=y +CONFIG_SERIAL_MSM_CONSOLE=y +CONFIG_SERIAL_MSM_HS=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_MSM_LEGACY=y +CONFIG_DIAG_CHAR=y +CONFIG_MSM_ADSPRPC=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MSM_V2=y +CONFIG_SPI=y +CONFIG_SPI_DEBUG=y +CONFIG_SPI_QUP=y +CONFIG_SPI_SPIDEV=y +CONFIG_SPMI=y +CONFIG_SPMI_MSM_PMIC_ARB_DEBUG=y +CONFIG_SLIMBUS_MSM_NGD=y +CONFIG_PTP_1588_CLOCK=y +CONFIG_PINCTRL_QCS405=y +CONFIG_FRAGMENTED_GPIO_ADDRESS_SPACE=y +CONFIG_PINCTRL_QCOM_SPMI_PMIC=y +CONFIG_GPIO_SYSFS=y +CONFIG_POWER_RESET_QCOM=y +CONFIG_QCOM_DLOAD_MODE=y +CONFIG_SMB1351_USB_CHARGER=y +CONFIG_THERMAL=y +CONFIG_THERMAL_WRITABLE_TRIPS=y +CONFIG_THERMAL_GOV_USER_SPACE=y +CONFIG_THERMAL_GOV_LOW_LIMITS=y +CONFIG_CPU_THERMAL=y +CONFIG_DEVFREQ_THERMAL=y +CONFIG_QCOM_SPMI_TEMP_ALARM=y +CONFIG_THERMAL_TSENS=y +CONFIG_QTI_VIRTUAL_SENSOR=y +CONFIG_QTI_QMI_COOLING_DEVICE=y +CONFIG_REGULATOR_COOLING_DEVICE=y +CONFIG_QTI_ADC_TM=y +CONFIG_QTI_RPM_SMD_COOLING_DEVICE=y +CONFIG_MFD_SPMI_PMIC=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_FAN53555=y +CONFIG_REGULATOR_CPR=y +CONFIG_REGULATOR_MEM_ACC=y +CONFIG_REGULATOR_RPM_SMD=y +CONFIG_REGULATOR_SPM=y +CONFIG_REGULATOR_STUB=y +CONFIG_RC_DEVICES=y +CONFIG_IR_MSM_GENI=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_RADIO_SUPPORT=y +CONFIG_MEDIA_CONTROLLER=y +CONFIG_VIDEO_V4L2_SUBDEV_API=y +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_SOC_CAMERA=y +CONFIG_SOC_CAMERA_PLATFORM=y +CONFIG_FB=y +CONFIG_FB_MSM=y +CONFIG_FB_MSM_MDSS=y +CONFIG_FB_MSM_MDSS_WRITEBACK=y +CONFIG_FB_MSM_MDSS_HDMI_PANEL=y +CONFIG_FB_MSM_MDSS_SPI_PANEL=y +CONFIG_FB_MSM_MDSS_RGB_PANEL=y +CONFIG_FB_MSM_MDSS_DSI_CTRL_STATUS=y +CONFIG_FB_MSM_MDSS_XLOG_DEBUG=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_USB_AUDIO=y +CONFIG_SND_SOC=y +CONFIG_HIDRAW=y +CONFIG_UHID=y +CONFIG_HID_APPLE=y +CONFIG_HID_ELECOM=y +CONFIG_HID_MAGICMOUSE=y +CONFIG_HID_MICROSOFT=y +CONFIG_HID_MULTITOUCH=y +CONFIG_USB_HIDDEV=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +CONFIG_USB_MON=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_ACM=y +CONFIG_USB_STORAGE=y +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_ALAUDA=y +CONFIG_USB_STORAGE_KARMA=y +CONFIG_USB_STORAGE_CYPRESS_ATACB=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_MSM=y +CONFIG_USB_SERIAL=y +CONFIG_USB_EHSET_TEST_FIXTURE=y +CONFIG_USB_LINK_LAYER_TEST=y +CONFIG_USB_TYPEC_MUX_NXP5150A=y +CONFIG_USB_QCOM_DIAG_BRIDGE=y +CONFIG_NOP_USB_XCEIV=y +CONFIG_MSM_SNPS_FEMTO_PHY=y +CONFIG_USB_MSM_SSPHY=y +CONFIG_USB_QCOM_EMU_PHY=y +CONFIG_DUAL_ROLE_USB_INTF=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_DEBUG_FILES=y +CONFIG_USB_GADGET_DEBUG_FS=y +CONFIG_USB_GADGET_VBUS_DRAW=900 +CONFIG_USB_CONFIGFS=y +CONFIG_USB_CONFIGFS_F_FS=y +CONFIG_USB_CONFIGFS_UEVENT=y +CONFIG_USB_CONFIGFS_F_DIAG=y +CONFIG_MMC=y +CONFIG_MMC_PERF_PROFILING=y +CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_BLOCK_DEFERRED_RESUME=y +CONFIG_MMC_TEST=m +CONFIG_MMC_RING_BUFFER=y +CONFIG_MMC_PARANOID_SD_INIT=y +CONFIG_MMC_CLKGATE=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_MSM=y +CONFIG_MMC_SDHCI_MSM_ICE=y +CONFIG_MMC_CQ_HCI=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_PCA9956B=y +CONFIG_LEDS_TRIGGERS=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_QPNP=y +CONFIG_DMADEVICES=y +CONFIG_QCOM_SPS_DMA=y +CONFIG_UIO=y +CONFIG_STAGING=y +CONFIG_ASHMEM=y +CONFIG_ION=y +CONFIG_QPNP_REVID=y +CONFIG_SPS=y +CONFIG_SPS_SUPPORT_NDP_BAM=y +CONFIG_QCOM_MDSS_PLL=y +CONFIG_QCOM_CLK_SMD_RPM=y +CONFIG_SPMI_PMIC_CLKDIV=y +CONFIG_MDM_DEBUGCC_QCS405=y +CONFIG_CLOCK_CPU_QCS405=y +CONFIG_QCS_CMN_BLK_PLL=y +CONFIG_HWSPINLOCK=y +CONFIG_HWSPINLOCK_QCOM=y +CONFIG_ARM_ARCH_TIMER_VCT_ACCESS=y +CONFIG_MAILBOX=y +CONFIG_QCOM_APCS_IPC=y +CONFIG_ARM_SMMU=y +CONFIG_QCOM_LAZY_MAPPING=y +CONFIG_IOMMU_DEBUG=y +CONFIG_IOMMU_DEBUG_TRACKING=y +CONFIG_IOMMU_TESTS=y +CONFIG_RPMSG_CHAR=y +CONFIG_RPMSG_QCOM_GLINK_RPM=y +CONFIG_RPMSG_QCOM_GLINK_SMEM=y +CONFIG_MSM_RPM_SMD=y +CONFIG_QCOM_CPUSS_DUMP=y +CONFIG_QCOM_QMI_HELPERS=y +CONFIG_QCOM_SMEM=y +CONFIG_QCOM_SMD_RPM=y +CONFIG_MSM_SPM=y +CONFIG_MSM_L2_SPM=y +CONFIG_QCOM_SCM=y +CONFIG_QCOM_MEMORY_DUMP_V2=y +CONFIG_MSM_DEBUG_LAR_UNLOCK=y +CONFIG_QCOM_WATCHDOG_V2=y +CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y +CONFIG_QCOM_WDOG_IPI_ENABLE=y +CONFIG_QCOM_SMP2P=y +CONFIG_MSM_SERVICE_LOCATOR=y +CONFIG_MSM_SERVICE_NOTIFIER=y +CONFIG_MSM_SUBSYSTEM_RESTART=y +CONFIG_MSM_PIL=y +CONFIG_MSM_SYSMON_QMI_COMM=y +CONFIG_MSM_PIL_SSR_GENERIC=y +CONFIG_MSM_BOOT_STATS=y +CONFIG_MSM_CORE_HANG_DETECT=y +CONFIG_QCOM_DCC_V2=y +CONFIG_ICNSS=y +CONFIG_ICNSS_DEBUG=y +CONFIG_ICNSS_QMI=y +CONFIG_QCOM_BUS_SCALING=y +CONFIG_MSM_TZ_SMMU=y +CONFIG_QCOM_GLINK=y +CONFIG_QCOM_GLINK_PKT=y +CONFIG_QTI_RPM_STATS_LOG=y +CONFIG_MSM_CDSP_LOADER=y +CONFIG_QCOM_SMCINVOKE=y +CONFIG_MSM_PM=y +CONFIG_QCOM_SMP2P_SLEEPSTATE=y +CONFIG_QCOM_BIMC_BWMON=y +CONFIG_ARM_MEMLAT_MON=y +CONFIG_DEVFREQ_GOV_QCOM_BW_HWMON=y +CONFIG_DEVFREQ_GOV_MEMLAT=y +CONFIG_QCOM_DEVFREQ_DEVBW=y +CONFIG_EXTCON_USB_GPIO=y +CONFIG_IIO=y +CONFIG_QCOM_SPMI_ADC5=y +CONFIG_PWM=y +CONFIG_PWM_QTI_LPG=y +CONFIG_QCOM_KGSL=y +CONFIG_QTI_MPM=y +CONFIG_ANDROID=y +CONFIG_ANDROID_BINDER_IPC=y +CONFIG_MSM_TZ_LOG=y +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT3_FS=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_QUOTA=y +CONFIG_QUOTA_NETLINK_INTERFACE=y +# CONFIG_PRINT_QUOTA_WARNING is not set +CONFIG_QFMT_V2=y +CONFIG_FUSE_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_UBIFS_FS=y +CONFIG_UBIFS_FS_ADVANCED_COMPR=y +CONFIG_SQUASHFS=y +CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y +CONFIG_SQUASHFS_XATTR=y +# CONFIG_SQUASHFS_ZLIB is not set +CONFIG_SQUASHFS_XZ=y +CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +CONFIG_PRINTK_TIME=y +CONFIG_DYNAMIC_DEBUG=y +CONFIG_DEBUG_INFO=y +CONFIG_PAGE_OWNER=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_PAGEALLOC=y +CONFIG_SLUB_DEBUG_PANIC_ON=y +CONFIG_DEBUG_PAGEALLOC_ENABLE_DEFAULT=y +CONFIG_PAGE_POISONING=y +CONFIG_PAGE_POISONING_ENABLE_DEFAULT=y +CONFIG_DEBUG_OBJECTS=y +CONFIG_DEBUG_OBJECTS_FREE=y +CONFIG_DEBUG_OBJECTS_TIMERS=y +CONFIG_DEBUG_OBJECTS_WORK=y +CONFIG_DEBUG_OBJECTS_RCU_HEAD=y +CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER=y +CONFIG_SLUB_DEBUG_ON=y +CONFIG_DEBUG_KMEMLEAK=y +CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE=4000 +CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y +CONFIG_DEBUG_STACK_USAGE=y +CONFIG_DEBUG_MEMORY_INIT=y +CONFIG_PANIC_ON_RECURSIVE_FAULT=y +CONFIG_PANIC_ON_OOPS=y +CONFIG_PANIC_TIMEOUT=5 +CONFIG_SCHEDSTATS=y +CONFIG_SCHED_STACK_END_CHECK=y +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_MUTEXES=y +CONFIG_DEBUG_ATOMIC_SLEEP=y +CONFIG_FAULT_INJECTION=y +CONFIG_FAIL_PAGE_ALLOC=y +CONFIG_UFS_FAULT_INJECTION=y +CONFIG_FAULT_INJECTION_DEBUG_FS=y +CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y +CONFIG_IPC_LOGGING=y +CONFIG_QCOM_RTB=y +CONFIG_QCOM_RTB_SEPARATE_CPUS=y +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_LKDTM=y +CONFIG_BUG_ON_DATA_CORRUPTION=y +CONFIG_CORESIGHT=y +CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y +CONFIG_CORESIGHT_SOURCE_ETM4X=y +CONFIG_CORESIGHT_DYNAMIC_REPLICATOR=y +CONFIG_CORESIGHT_STM=y +CONFIG_CORESIGHT_CTI=y +CONFIG_CORESIGHT_TPDA=y +CONFIG_CORESIGHT_TPDM=y +CONFIG_CORESIGHT_HWEVENT=y +CONFIG_CORESIGHT_DUMMY=y +CONFIG_CORESIGHT_REMOTE_ETM=y +CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 +CONFIG_CORESIGHT_EVENT=y +CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y +CONFIG_SECURITY=y +CONFIG_SECURITY_NETWORK=y +CONFIG_LSM_MMAP_MIN_ADDR=4096 +CONFIG_HARDENED_USERCOPY=y +CONFIG_HARDENED_USERCOPY_PAGESPAN=y +CONFIG_SECURITY_SELINUX=y +CONFIG_CRYPTO_CTR=y +CONFIG_CRYPTO_XCBC=y +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_TWOFISH=y +CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y +CONFIG_CRYPTO_DEV_QCRYPTO=y +CONFIG_CRYPTO_DEV_QCEDEV=y +CONFIG_CRYPTO_DEV_QCOM_ICE=y -- GitLab From 9c7d2fa902ec94f33d72cb0ac93d96b3ce82f567 Mon Sep 17 00:00:00 2001 From: Hardik Arya Date: Thu, 18 Jul 2019 14:53:59 +0530 Subject: [PATCH 0915/1121] diag: Prevent possible use-after-free while updating event mask There is a possibility of use-after-free while populating response for update event mask because of using mask_info without holding md_session_lock. The patch fixes this issue by using source buffer for populating command response. Change-Id: I45558a9cb628ec075e1e03e55e840121769c7660 Signed-off-by: Hardik Arya --- drivers/char/diag/diag_masks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c index e2b022affbee..362597bceba8 100644 --- a/drivers/char/diag/diag_masks.c +++ b/drivers/char/diag/diag_masks.c @@ -1109,7 +1109,7 @@ static int diag_cmd_update_event_mask(unsigned char *src_buf, int src_len, rsp.num_bits = driver->last_event_id + 1; memcpy(dest_buf, &rsp, header_len); write_len += header_len; - memcpy(dest_buf + write_len, mask_info->ptr, mask_len); + memcpy(dest_buf + write_len, src_buf + header_len, mask_len); write_len += mask_len; for (i = 0; i < NUM_MD_SESSIONS; i++) { -- GitLab From c38c34b6078057dd75ae400444ce557d79fe5382 Mon Sep 17 00:00:00 2001 From: Dave Martin Date: Tue, 31 Oct 2017 15:51:00 +0000 Subject: [PATCH 0916/1121] arm64/sve: System register and exception syndrome definitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SVE architecture adds some system registers, ID register fields and a dedicated ESR exception class. This patch adds the appropriate definitions that will be needed by the kernel. Change-Id: I717a862853dd2f756552179490225517eb19dbd5 Signed-off-by: Dave Martin Reviewed-by: Alex BennĂ©e Reviewed-by: Catalin Marinas Signed-off-by: Will Deacon Git-commit: 672365649ccac68cf6fafecad1a7913951e7493b Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git [groverm@codeaurora: Resolve trivial merge conflicts] Signed-off-by: Mayank Grover --- arch/arm64/include/asm/esr.h | 3 ++- arch/arm64/include/asm/kvm_arm.h | 1 + arch/arm64/include/asm/sysreg.h | 21 +++++++++++++++++++++ arch/arm64/kernel/traps.c | 1 + 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h index fd740b045113..a576942f8b76 100644 --- a/arch/arm64/include/asm/esr.h +++ b/arch/arm64/include/asm/esr.h @@ -43,7 +43,8 @@ #define ESR_ELx_EC_HVC64 (0x16) #define ESR_ELx_EC_SMC64 (0x17) #define ESR_ELx_EC_SYS64 (0x18) -/* Unallocated EC: 0x19 - 0x1E */ +#define ESR_ELx_EC_SVE (0x19) +/* Unallocated EC: 0x1A - 0x1E */ #define ESR_ELx_EC_IMP_DEF (0x1f) #define ESR_ELx_EC_IABT_LOW (0x20) #define ESR_ELx_EC_IABT_CUR (0x21) diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h index 1d6d980f80ac..99e75847606c 100644 --- a/arch/arm64/include/asm/kvm_arm.h +++ b/arch/arm64/include/asm/kvm_arm.h @@ -187,6 +187,7 @@ #define CPTR_EL2_TCPAC (1 << 31) #define CPTR_EL2_TTA (1 << 20) #define CPTR_EL2_TFP (1 << CPTR_EL2_TFP_SHIFT) +#define CPTR_EL2_TZ (1 << 8) #define CPTR_EL2_DEFAULT 0x000033ff /* Hyp Debug Configuration Register bits */ diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index 7bbbba5ae681..642333e9ba63 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -145,6 +145,7 @@ #define SYS_ID_AA64PFR0_EL1 sys_reg(3, 0, 0, 4, 0) #define SYS_ID_AA64PFR1_EL1 sys_reg(3, 0, 0, 4, 1) +#define SYS_ID_AA64ZFR0_EL1 sys_reg(3, 0, 0, 4, 4) #define SYS_ID_AA64DFR0_EL1 sys_reg(3, 0, 0, 5, 0) #define SYS_ID_AA64DFR1_EL1 sys_reg(3, 0, 0, 5, 1) @@ -160,6 +161,8 @@ #define SYS_ACTLR_EL1 sys_reg(3, 0, 1, 0, 1) #define SYS_CPACR_EL1 sys_reg(3, 0, 1, 0, 2) +#define SYS_ZCR_EL1 sys_reg(3, 0, 1, 2, 0) + #define SYS_TTBR0_EL1 sys_reg(3, 0, 2, 0, 0) #define SYS_TTBR1_EL1 sys_reg(3, 0, 2, 0, 1) #define SYS_TCR_EL1 sys_reg(3, 0, 2, 0, 2) @@ -250,6 +253,8 @@ #define SYS_PMCCFILTR_EL0 sys_reg (3, 3, 14, 15, 7) +#define SYS_ZCR_EL2 sys_reg(3, 4, 1, 2, 0) + #define SYS_DACR32_EL2 sys_reg(3, 4, 3, 0, 0) #define SYS_IFSR32_EL2 sys_reg(3, 4, 5, 0, 1) #define SYS_FPEXC32_EL2 sys_reg(3, 4, 5, 3, 0) @@ -338,6 +343,7 @@ /* id_aa64pfr0 */ #define ID_AA64PFR0_CSV3_SHIFT 60 #define ID_AA64PFR0_CSV2_SHIFT 56 +#define ID_AA64PFR0_SVE_SHIFT 32 #define ID_AA64PFR0_GIC_SHIFT 24 #define ID_AA64PFR0_ASIMD_SHIFT 20 #define ID_AA64PFR0_FP_SHIFT 16 @@ -346,6 +352,7 @@ #define ID_AA64PFR0_EL1_SHIFT 4 #define ID_AA64PFR0_EL0_SHIFT 0 +#define ID_AA64PFR0_SVE 0x1 #define ID_AA64PFR0_FP_NI 0xf #define ID_AA64PFR0_FP_SUPPORTED 0x0 #define ID_AA64PFR0_ASIMD_NI 0xf @@ -447,6 +454,20 @@ #endif +/* + * The ZCR_ELx_LEN_* definitions intentionally include bits [8:4] which + * are reserved by the SVE architecture for future expansion of the LEN + * field, with compatible semantics. + */ +#define ZCR_ELx_LEN_SHIFT 0 +#define ZCR_ELx_LEN_SIZE 9 +#define ZCR_ELx_LEN_MASK 0x1ff + +#define CPACR_EL1_ZEN_EL1EN (1 << 16) /* enable EL1 access */ +#define CPACR_EL1_ZEN_EL0EN (1 << 17) /* enable EL0 access, if EL1EN set */ +#define CPACR_EL1_ZEN (CPACR_EL1_ZEN_EL1EN | CPACR_EL1_ZEN_EL0EN) + + /* Safe value for MPIDR_EL1: Bit31:RES1, Bit30:U:0, Bit24:MT:0 */ #define SYS_MPIDR_SAFE_VAL (1UL << 31) diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index 9fbb35dfc059..a4ec8da34d53 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -699,6 +699,7 @@ static const char *esr_class_str[] = { [ESR_ELx_EC_HVC64] = "HVC (AArch64)", [ESR_ELx_EC_SMC64] = "SMC (AArch64)", [ESR_ELx_EC_SYS64] = "MSR/MRS (AArch64)", + [ESR_ELx_EC_SVE] = "SVE", [ESR_ELx_EC_IMP_DEF] = "EL3 IMP DEF", [ESR_ELx_EC_IABT_LOW] = "IABT (lower EL)", [ESR_ELx_EC_IABT_CUR] = "IABT (current EL)", -- GitLab From f7bb6f3a5d8aab9e12474e14f8af85630830f559 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Tue, 7 Aug 2018 13:43:06 +0100 Subject: [PATCH 0917/1121] arm64: entry: Allow handling of undefined instructions from EL1 [ Upstream commit 0bf0f444b2c49241b2b39aa3cf210d7c95ef6c34 ] Rather than panic() when taking an undefined instruction exception from EL1, allow a hook to be registered in case we want to emulate the instruction, like we will for the SSBS PSTATE manipulation instructions. Change-Id: I283fa8f4e8f4ebb078b4455342a6cd3501447157 Signed-off-by: Will Deacon Signed-off-by: Catalin Marinas Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Git-commit: 0bf0f444b2c49241b2b39aa3cf210d7c95ef6c34 Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git [groverm@codeaurora: Resolve merge conflicts] Signed-off-by: Mayank Grover --- arch/arm64/kernel/entry.S | 2 +- arch/arm64/kernel/traps.c | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index 7e50aec45858..de16794fd64c 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -602,7 +602,7 @@ el1_undef: enable_dbg mov x0, sp bl do_undefinstr - ASM_BUG() + kernel_exit 1 el1_dbg: /* * Debug exception handling diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index a4ec8da34d53..d1a891023b10 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -303,10 +303,12 @@ static int call_undef_hook(struct pt_regs *regs) int (*fn)(struct pt_regs *regs, u32 instr) = NULL; void __user *pc = (void __user *)instruction_pointer(regs); - if (!user_mode(regs)) - return 1; - - if (compat_thumb_mode(regs)) { + if (!user_mode(regs)) { + __le32 instr_le; + if (probe_kernel_address((__force __le32 *)pc, instr_le)) + goto exit; + instr = le32_to_cpu(instr_le); + } else if (compat_thumb_mode(regs)) { /* 16-bit Thumb instruction */ __le16 instr_le; if (get_user(instr_le, (__le16 __user *)pc)) @@ -404,6 +406,7 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs) trace_undef_instr(regs, pc); force_signal_inject(SIGILL, ILL_ILLOPC, regs, 0); + BUG_ON(!user_mode(regs)); } int cpu_enable_cache_maint_trap(void *__unused) -- GitLab From 6044ba2f01ffa990c2d5269c1b76aadc51d71964 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 15 Jun 2018 11:37:34 +0100 Subject: [PATCH 0918/1121] arm64: cpufeature: Detect SSBS and advertise to userspace Armv8.5 introduces a new PSTATE bit known as Speculative Store Bypass Safe (SSBS) which can be used as a mitigation against Spectre variant 4. Additionally, a CPU may provide instructions to manipulate PSTATE.SSBS directly, so that userspace can toggle the SSBS control without trapping to the kernel. This patch probes for the existence of SSBS and advertise the new instructions to userspace if they exist. Change-Id: Ieeb4f8d70afcc1d610716f0d1306a73093ff2660 Reviewed-by: Suzuki K Poulose Signed-off-by: Will Deacon Signed-off-by: Catalin Marinas Git-commit: d71be2b6c0e19180b5f80a6d42039cc074a693a2 Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git [neeraju@codeaurora: Resolve trivial merge conflicts] Signed-off-by: Neeraj Upadhyay [groverm@codeaurora: Resolve merge conflicts] Signed-off-by: Mayank Grover --- arch/arm64/include/asm/cpucaps.h | 3 ++- arch/arm64/include/asm/sysreg.h | 8 ++++++++ arch/arm64/include/uapi/asm/hwcap.h | 1 + arch/arm64/kernel/cpufeature.c | 19 +++++++++++++++++-- arch/arm64/kernel/cpuinfo.c | 1 + 5 files changed, 29 insertions(+), 3 deletions(-) diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h index ab1149efda43..8bd1be2f4d79 100644 --- a/arch/arm64/include/asm/cpucaps.h +++ b/arch/arm64/include/asm/cpucaps.h @@ -46,7 +46,8 @@ #define ARM64_HW_DBM 26 #define ARM64_SSBD 27 #define ARM64_MISMATCHED_CACHE_TYPE 28 +#define ARM64_SSBS 29 -#define ARM64_NCAPS 29 +#define ARM64_NCAPS 30 #endif /* __ASM_CPUCAPS_H */ diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index 642333e9ba63..cee5da219528 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -301,6 +301,7 @@ #define SYS_ICH_LR15_EL2 __SYS__LR8_EL2(7) /* Common SCTLR_ELx flags. */ +#define SCTLR_ELx_DSSBS (1UL << 44) #define SCTLR_ELx_EE (1 << 25) #define SCTLR_ELx_I (1 << 12) #define SCTLR_ELx_SA (1 << 3) @@ -361,6 +362,13 @@ #define ID_AA64PFR0_EL0_64BIT_ONLY 0x1 #define ID_AA64PFR0_EL0_32BIT_64BIT 0x2 +/* id_aa64pfr1 */ +#define ID_AA64PFR1_SSBS_SHIFT 4 + +#define ID_AA64PFR1_SSBS_PSTATE_NI 0 +#define ID_AA64PFR1_SSBS_PSTATE_ONLY 1 +#define ID_AA64PFR1_SSBS_PSTATE_INSNS 2 + /* id_aa64mmfr0 */ #define ID_AA64MMFR0_TGRAN4_SHIFT 28 #define ID_AA64MMFR0_TGRAN64_SHIFT 24 diff --git a/arch/arm64/include/uapi/asm/hwcap.h b/arch/arm64/include/uapi/asm/hwcap.h index f243c57d1670..eed4600efdad 100644 --- a/arch/arm64/include/uapi/asm/hwcap.h +++ b/arch/arm64/include/uapi/asm/hwcap.h @@ -42,5 +42,6 @@ #define HWCAP_SM4 (1 << 19) #define HWCAP_ASIMDDP (1 << 20) #define HWCAP_SHA512 (1 << 21) +#define HWCAP_SSBS (1 << 22) #endif /* _UAPI__ASM_HWCAP_H */ diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 152fda8b9cbc..d45cc4da0295 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -142,6 +142,11 @@ static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = { ARM64_FTR_END, }; +static const struct arm64_ftr_bits ftr_id_aa64pfr1[] = { + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR1_SSBS_SHIFT, 4, ID_AA64PFR1_SSBS_PSTATE_NI), + ARM64_FTR_END, +}; + static const struct arm64_ftr_bits ftr_id_aa64mmfr0[] = { S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, ID_AA64MMFR0_TGRAN4_SHIFT, 4, ID_AA64MMFR0_TGRAN4_NI), S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, ID_AA64MMFR0_TGRAN64_SHIFT, 4, ID_AA64MMFR0_TGRAN64_NI), @@ -341,7 +346,8 @@ static const struct __ftr_reg_entry { /* Op1 = 0, CRn = 0, CRm = 4 */ ARM64_FTR_REG(SYS_ID_AA64PFR0_EL1, ftr_id_aa64pfr0), - ARM64_FTR_REG(SYS_ID_AA64PFR1_EL1, ftr_raz), + ARM64_FTR_REG(SYS_ID_AA64PFR1_EL1, ftr_id_aa64pfr1), + ARM64_FTR_REG(SYS_ID_AA64ZFR0_EL1, ftr_raz), /* Op1 = 0, CRn = 0, CRm = 5 */ ARM64_FTR_REG(SYS_ID_AA64DFR0_EL1, ftr_id_aa64dfr0), @@ -609,7 +615,6 @@ void update_cpu_features(int cpu, /* * EL3 is not our concern. - * ID_AA64PFR1 is currently RES0. */ taint |= check_update_ftr_reg(SYS_ID_AA64PFR0_EL1, cpu, info->reg_id_aa64pfr0, boot->reg_id_aa64pfr0); @@ -1111,6 +1116,15 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .enable = cpu_enable_hw_dbm, }, #endif + { + .desc = "Speculative Store Bypassing Safe (SSBS)", + .capability = ARM64_SSBS, + .matches = has_cpuid_feature, + .sys_reg = SYS_ID_AA64PFR1_EL1, + .field_pos = ID_AA64PFR1_SSBS_SHIFT, + .sign = FTR_UNSIGNED, + .min_field_value = ID_AA64PFR1_SSBS_PSTATE_ONLY, + }, {}, }; @@ -1148,6 +1162,7 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = { HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_JSCVT_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_JSCVT), HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_FCMA_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_FCMA), HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_LRCPC_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_LRCPC), + HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_SSBS_SHIFT, FTR_UNSIGNED, ID_AA64PFR1_SSBS_PSTATE_INSNS, CAP_HWCAP, HWCAP_SSBS), {}, }; diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c index 5bca95fcdfe9..1e3fbfb2b977 100644 --- a/arch/arm64/kernel/cpuinfo.c +++ b/arch/arm64/kernel/cpuinfo.c @@ -81,6 +81,7 @@ static const char *const hwcap_str[] = { "sm4", "asimddp", "sha512", + "ssbs", NULL }; -- GitLab From ad1c713924b46344a456dc4add0afda15d3eb82b Mon Sep 17 00:00:00 2001 From: Anirudh Ghayal Date: Mon, 8 Jul 2019 16:31:45 +0530 Subject: [PATCH 0919/1121] power: qpnp-qg: Add sleep-mode configuration for QG Add support for updating the S2 state configuration in sleep. This allows modifying the fifo-length, accumulator interval and accumulator length when the device enters suspend. Change-Id: I3e51dc34cea5c97a7f901d9981f908e35b8b0fb3 Signed-off-by: Anirudh Ghayal --- drivers/power/supply/qcom/qg-core.h | 13 ++ drivers/power/supply/qcom/qg-defs.h | 4 +- drivers/power/supply/qcom/qpnp-qg.c | 236 +++++++++++++++++++++++----- 3 files changed, 215 insertions(+), 38 deletions(-) diff --git a/drivers/power/supply/qcom/qg-core.h b/drivers/power/supply/qcom/qg-core.h index 2d4ff77044ab..46cbd384083d 100644 --- a/drivers/power/supply/qcom/qg-core.h +++ b/drivers/power/supply/qcom/qg-core.h @@ -42,6 +42,9 @@ struct qg_dt { int s2_vbat_low_fifo_length; int s2_acc_length; int s2_acc_intvl_ms; + int sleep_s2_fifo_length; + int sleep_s2_acc_length; + int sleep_s2_acc_intvl_ms; int ocv_timer_expiry_min; int ocv_tol_threshold_uv; int s3_entry_fifo_length; @@ -67,6 +70,7 @@ struct qg_dt { bool esr_discharge_enable; bool qg_ext_sense; bool use_s7_ocv; + bool qg_sleep_config; }; struct qg_esr_data { @@ -91,6 +95,7 @@ struct qpnp_qg { struct work_struct udata_work; struct work_struct scale_soc_work; struct work_struct qg_status_change_work; + struct delayed_work qg_sleep_exit_work; struct notifier_block nb; struct mutex bus_lock; struct mutex data_lock; @@ -141,6 +146,8 @@ struct qpnp_qg { u32 charge_counter_uah; u32 esr_avg; u32 esr_last; + u32 s2_state; + u32 s2_state_mask; ktime_t last_user_update_time; ktime_t last_fifo_update_time; unsigned long last_maint_soc_update_time; @@ -187,6 +194,12 @@ enum ocv_type { PON_OCV_MAX, }; +enum s2_state { + S2_LOW_VBAT = BIT(0), + S2_SLEEP = BIT(1), + S2_DEFAULT = BIT(2), +}; + enum debug_mask { QG_DEBUG_PON = BIT(0), QG_DEBUG_PROFILE = BIT(1), diff --git a/drivers/power/supply/qcom/qg-defs.h b/drivers/power/supply/qcom/qg-defs.h index c398c697e014..ed6a2ce25e61 100644 --- a/drivers/power/supply/qcom/qg-defs.h +++ b/drivers/power/supply/qcom/qg-defs.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2018 The Linux Foundation. All rights reserved. +/* Copyright (c) 2018,2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -35,6 +35,8 @@ #define PROFILE_IRQ_DISABLE "NO_PROFILE_IRQ_DISABLE" #define QG_INIT_STATE_IRQ_DISABLE "QG_INIT_STATE_IRQ_DISABLE" #define TTF_AWAKE_VOTER "TTF_AWAKE_VOTER" +#define SLEEP_EXIT_DATA_VOTER "SLEEP_EXIT_DATA_VOTER" +#define SLEEP_EXIT_VOTER "SLEEP_EXIT_VOTER" #define V_RAW_TO_UV(V_RAW) div_u64(194637ULL * (u64)V_RAW, 1000) #define FIFO_V_RESET_VAL 0x8000 diff --git a/drivers/power/supply/qcom/qpnp-qg.c b/drivers/power/supply/qcom/qpnp-qg.c index 81e70b0250df..a2f117c4f896 100644 --- a/drivers/power/supply/qcom/qpnp-qg.c +++ b/drivers/power/supply/qcom/qpnp-qg.c @@ -56,6 +56,8 @@ module_param_named( esr_count, qg_esr_count, int, 0600 ); +static int qg_process_rt_fifo(struct qpnp_qg *chip); + static bool is_battery_present(struct qpnp_qg *chip) { u8 reg = 0; @@ -146,7 +148,7 @@ static int qg_update_fifo_length(struct qpnp_qg *chip, u8 length) pr_err("Failed to write S2 FIFO length, rc=%d\n", rc); /* update the S3 FIFO length, when S2 length is updated */ - if (length > 3) + if (length > 3 && !chip->dt.qg_sleep_config) s3_entry_fifo_length = (chip->dt.s3_entry_fifo_length > 0) ? chip->dt.s3_entry_fifo_length : DEFAULT_S3_FIFO_LENGTH; else /* Use S3 length as 1 for any S2 length <= 3 */ @@ -275,6 +277,104 @@ static int qg_store_soc_params(struct qpnp_qg *chip) return rc; } +static int qg_config_s2_state(struct qpnp_qg *chip, + enum s2_state requested_state, bool state_enable, + bool process_fifo) +{ + int rc, acc_interval, acc_length; + u8 fifo_length, reg = 0, state = S2_DEFAULT; + + if ((chip->s2_state_mask & requested_state) && (state_enable == true)) + return 0; /* No change in state */ + + if (!(chip->s2_state_mask & requested_state) && (state_enable == false)) + return 0; /* No change in state */ + + if (state_enable) + chip->s2_state_mask |= requested_state; + else + chip->s2_state_mask &= ~requested_state; + + /* define the priority of the states */ + if (chip->s2_state_mask & S2_LOW_VBAT) + state = S2_LOW_VBAT; + else if (chip->s2_state_mask & S2_SLEEP) + state = S2_SLEEP; + else + state = S2_DEFAULT; + + if (state == chip->s2_state) + return 0; + + switch (state) { + case S2_LOW_VBAT: + fifo_length = chip->dt.s2_vbat_low_fifo_length; + acc_interval = chip->dt.s2_acc_intvl_ms; + acc_length = chip->dt.s2_acc_length; + break; + case S2_SLEEP: + fifo_length = chip->dt.sleep_s2_fifo_length; + acc_interval = chip->dt.sleep_s2_acc_intvl_ms; + acc_length = chip->dt.sleep_s2_acc_length; + break; + case S2_DEFAULT: + fifo_length = chip->dt.s2_fifo_length; + acc_interval = chip->dt.s2_acc_intvl_ms; + acc_length = chip->dt.s2_acc_length; + break; + default: + pr_err("Invalid S2 state %d\n", state); + return -EINVAL; + } + + rc = qg_master_hold(chip, true); + if (rc < 0) { + pr_err("Failed to hold master, rc=%d\n", rc); + return rc; + } + + if (process_fifo) { + rc = qg_process_rt_fifo(chip); + if (rc < 0) { + pr_err("Failed to process FIFO real-time, rc=%d\n", rc); + goto done; + } + } + + rc = qg_update_fifo_length(chip, fifo_length); + if (rc < 0) { + pr_err("Failed to update S2 fifo-length, rc=%d\n", rc); + goto done; + } + + reg = acc_interval / 10; + rc = qg_write(chip, chip->qg_base + QG_S2_NORMAL_MEAS_CTL3_REG, + ®, 1); + if (rc < 0) { + pr_err("Failed to update S2 acc intrvl, rc=%d\n", rc); + goto done; + } + + reg = ilog2(acc_length) - 1; + rc = qg_masked_write(chip, chip->qg_base + QG_S2_NORMAL_MEAS_CTL2_REG, + NUM_OF_ACCUM_MASK, reg); + if (rc < 0) { + pr_err("Failed to update S2 ACC length, rc=%d\n", rc); + goto done; + } + + chip->s2_state = state; + + qg_dbg(chip, QG_DEBUG_STATUS, "S2 New state=%x fifo_length=%d interval=%d acc_length=%d\n", + state, fifo_length, acc_interval, acc_length); + +done: + qg_master_hold(chip, false); + /* FIFO restarted */ + chip->last_fifo_update_time = ktime_get(); + return rc; +} + static int qg_process_fifo(struct qpnp_qg *chip, u32 fifo_length) { int rc = 0, i, j = 0, temp; @@ -526,7 +626,7 @@ static int process_rt_fifo_data(struct qpnp_qg *chip, bool update_smb) static int qg_vbat_low_wa(struct qpnp_qg *chip) { int rc, i, temp = 0; - u32 vbat_low_uv = 0, fifo_length = 0; + u32 vbat_low_uv = 0; if ((chip->wa_flags & QG_VBAT_LOW_WA) && chip->vbat_low) { rc = qg_get_battery_temp(chip, &temp); @@ -556,37 +656,11 @@ static int qg_vbat_low_wa(struct qpnp_qg *chip) } } - rc = get_fifo_length(chip, &fifo_length, false); - if (rc < 0) { - pr_err("Failed to get FIFO length, rc=%d\n", rc); - return rc; - } - - if (chip->vbat_low && fifo_length == chip->dt.s2_vbat_low_fifo_length) - return 0; - - if (!chip->vbat_low && fifo_length == chip->dt.s2_fifo_length) - return 0; - - rc = qg_master_hold(chip, true); - if (rc < 0) { - pr_err("Failed to hold master, rc=%d\n", rc); - goto done; - } - - fifo_length = chip->vbat_low ? chip->dt.s2_vbat_low_fifo_length : - chip->dt.s2_fifo_length; - - rc = qg_update_fifo_length(chip, fifo_length); + rc = qg_config_s2_state(chip, S2_LOW_VBAT, + chip->vbat_low ? true : false, false); if (rc < 0) - goto done; + pr_err("Failed to configure for VBAT_LOW rc=%d\n", rc); - qg_dbg(chip, QG_DEBUG_STATUS, "FIFO length updated to %d vbat_low=%d\n", - fifo_length, chip->vbat_low); -done: - qg_master_hold(chip, false); - /* FIFOs restarted */ - chip->last_fifo_update_time = ktime_get(); return rc; } @@ -2275,6 +2349,33 @@ static int qg_battery_status_update(struct qpnp_qg *chip) return rc; } +static void qg_sleep_exit_work(struct work_struct *work) +{ + int rc; + struct qpnp_qg *chip = container_of(work, + struct qpnp_qg, qg_sleep_exit_work.work); + + vote(chip->awake_votable, SLEEP_EXIT_VOTER, true, 0); + + mutex_lock(&chip->data_lock); + /* + * if this work is executing, the system has been active + * for a while. So, force back the S2 active configuration + */ + qg_dbg(chip, QG_DEBUG_STATUS, "sleep_exit_work: exit S2_SLEEP\n"); + rc = qg_config_s2_state(chip, S2_SLEEP, false, true); + if (rc < 0) + pr_err("Failed to exit S2_SLEEP rc=%d\n", rc); + + vote(chip->awake_votable, SLEEP_EXIT_DATA_VOTER, true, 0); + /* signal the read thread */ + chip->data_ready = true; + wake_up_interruptible(&chip->qg_wait_q); + + mutex_unlock(&chip->data_lock); + + vote(chip->awake_votable, SLEEP_EXIT_VOTER, false, 0); +} static void qg_status_change_work(struct work_struct *work) { @@ -2449,6 +2550,7 @@ static ssize_t qg_device_read(struct file *file, char __user *buf, size_t count, vote(chip->awake_votable, FIFO_DONE_VOTER, false, 0); vote(chip->awake_votable, FIFO_RT_DONE_VOTER, false, 0); vote(chip->awake_votable, SUSPEND_DATA_VOTER, false, 0); + vote(chip->awake_votable, SLEEP_EXIT_DATA_VOTER, false, 0); qg_dbg(chip, QG_DEBUG_DEVICE, "QG device read complete Seq_no=%u Size=%ld\n", @@ -3064,6 +3166,8 @@ static int qg_hw_init(struct qpnp_qg *chip) } } + chip->s2_state = S2_DEFAULT; + chip->s2_state_mask |= S2_DEFAULT; /* signal the read thread */ chip->data_ready = true; wake_up_interruptible(&chip->qg_wait_q); @@ -3399,6 +3503,9 @@ static int qg_alg_init(struct qpnp_qg *chip) #define DEFAULT_S2_VBAT_LOW_LENGTH 2 #define DEFAULT_S2_ACC_LENGTH 128 #define DEFAULT_S2_ACC_INTVL_MS 100 +#define DEFAULT_SLEEP_S2_FIFO_LENGTH 8 +#define DEFAULT_SLEEP_S2_ACC_LENGTH 256 +#define DEFAULT_SLEEP_S2_ACC_INTVL_MS 200 #define DEFAULT_DELTA_SOC 1 #define DEFAULT_SHUTDOWN_SOC_SECS 360 #define DEFAULT_COLD_TEMP_THRESHOLD 0 @@ -3660,6 +3767,35 @@ static int qg_parse_dt(struct qpnp_qg *chip) else chip->dt.sys_min_volt_mv = temp; + if (of_property_read_bool(node, "qcom,qg-sleep-config")) { + + chip->dt.qg_sleep_config = true; + + rc = of_property_read_u32(node, + "qcom,sleep-s2-fifo-length", &temp); + if (rc < 0) + chip->dt.sleep_s2_fifo_length = + DEFAULT_SLEEP_S2_FIFO_LENGTH; + else + chip->dt.sleep_s2_fifo_length = temp; + + rc = of_property_read_u32(node, + "qcom,sleep-s2-acc-length", &temp); + if (rc < 0) + chip->dt.sleep_s2_acc_length = + DEFAULT_SLEEP_S2_ACC_LENGTH; + else + chip->dt.sleep_s2_acc_length = temp; + + rc = of_property_read_u32(node, + "qcom,sleep-s2-acc-intvl-ms", &temp); + if (rc < 0) + chip->dt.sleep_s2_acc_intvl_ms = + DEFAULT_SLEEP_S2_ACC_INTVL_MS; + else + chip->dt.sleep_s2_acc_intvl_ms = temp; + } + chip->dt.qg_ext_sense = of_property_read_bool(node, "qcom,qg-ext-sns"); chip->dt.use_s7_ocv = of_property_read_bool(node, "qcom,qg-use-s7-ocv"); @@ -3755,6 +3891,7 @@ static int process_suspend(struct qpnp_qg *chip) return 0; cancel_delayed_work_sync(&chip->ttf->ttf_work); + cancel_delayed_work_sync(&chip->qg_sleep_exit_work); chip->suspend_data = false; @@ -3763,6 +3900,13 @@ static int process_suspend(struct qpnp_qg *chip) /* ignore any suspend processing if we are charging */ if (chip->charge_status == POWER_SUPPLY_STATUS_CHARGING) { + /* Reset the sleep config if we are charging */ + if (chip->dt.qg_sleep_config) { + qg_dbg(chip, QG_DEBUG_STATUS, "Suspend: Charging - Exit S2_SLEEP\n"); + rc = qg_config_s2_state(chip, S2_SLEEP, false, true); + if (rc < 0) + pr_err("Failed to exit S2-sleep rc=%d\n", rc); + } qg_dbg(chip, QG_DEBUG_PM, "Charging @ suspend - ignore processing\n"); return 0; } @@ -3780,12 +3924,23 @@ static int process_suspend(struct qpnp_qg *chip) return rc; } sleep_fifo_length &= SLEEP_IBAT_QUALIFIED_LENGTH_MASK; - /* - * If the real-time FIFO count is greater than - * the the #fifo to enter sleep, save the FIFO data - * and reset the fifo count. - */ - if (fifo_rt_length >= (chip->dt.s2_fifo_length - sleep_fifo_length)) { + + if (chip->dt.qg_sleep_config) { + qg_dbg(chip, QG_DEBUG_STATUS, "Suspend: Forcing S2_SLEEP\n"); + rc = qg_config_s2_state(chip, S2_SLEEP, true, true); + if (rc < 0) + pr_err("Failed to config S2_SLEEP rc=%d\n", rc); + if (chip->kdata.fifo_length > 0) + chip->suspend_data = true; + } else if (fifo_rt_length >= + (chip->dt.s2_fifo_length - sleep_fifo_length)) { + /* + * If the real-time FIFO count is greater than + * the the #fifo to enter sleep, save the FIFO data + * and reset the fifo count. This is avoid a gauranteed wakeup + * due to fifo_done event as the curent FIFO length is already + * beyond the sleep length. + */ rc = qg_master_hold(chip, true); if (rc < 0) { pr_err("Failed to hold master, rc=%d\n", rc); @@ -3820,6 +3975,7 @@ static int process_suspend(struct qpnp_qg *chip) return rc; } +#define QG_SLEEP_EXIT_TIME_MS 15000 /* 15 secs */ static int process_resume(struct qpnp_qg *chip) { u8 status2 = 0, rt_status = 0; @@ -3834,6 +3990,10 @@ static int process_resume(struct qpnp_qg *chip) get_rtc_time(&rtc_sec); sleep_time_secs = rtc_sec - chip->suspend_time; + if (chip->dt.qg_sleep_config) + schedule_delayed_work(&chip->qg_sleep_exit_work, + msecs_to_jiffies(QG_SLEEP_EXIT_TIME_MS)); + rc = qg_read(chip, chip->qg_base + QG_STATUS2_REG, &status2, 1); if (rc < 0) { pr_err("Failed to read status2 register, rc=%d\n", rc); @@ -4001,6 +4161,7 @@ static int qpnp_qg_probe(struct platform_device *pdev) platform_set_drvdata(pdev, chip); INIT_WORK(&chip->udata_work, process_udata_work); INIT_WORK(&chip->qg_status_change_work, qg_status_change_work); + INIT_DELAYED_WORK(&chip->qg_sleep_exit_work, qg_sleep_exit_work); mutex_init(&chip->bus_lock); mutex_init(&chip->soc_lock); mutex_init(&chip->data_lock); @@ -4161,6 +4322,7 @@ static int qpnp_qg_remove(struct platform_device *pdev) qg_batterydata_exit(); qg_soc_exit(chip); + cancel_delayed_work_sync(&chip->qg_sleep_exit_work); cancel_work_sync(&chip->udata_work); cancel_work_sync(&chip->qg_status_change_work); device_destroy(chip->qg_class, chip->dev_no); -- GitLab From fe0d70526cbbc4163a300203dd8efd1b329adf4c Mon Sep 17 00:00:00 2001 From: Anirudh Ghayal Date: Mon, 8 Jul 2019 16:32:12 +0530 Subject: [PATCH 0920/1121] dt-bindings: qpnp-qg: Add properties for fast-charge config Allow configuring the FIFO length during fast-charging. Change-Id: I8018f8033d05273320fd92cc7d21fcdce0885df7 Signed-off-by: Anirudh Ghayal --- .../bindings/power/supply/qcom/qpnp-qg.txt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-qg.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-qg.txt index b00d7c7534d2..3daca154bb52 100644 --- a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-qg.txt +++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-qg.txt @@ -389,6 +389,21 @@ First Level Node - QGAUGE device 'qcom,qg-sleep-config' is enabled. the default value if not specified is 200ms. +- qcom,qg-fast-chg-config + Usage: optional + Value type: bool + Definition: Enables fast-charge configurtion for QG. This + allows configuring the FIFO length during + fast charge. + +- qcom,fast-chg-s2-fifo-length + Usage: optional + Value type: + Definition: The FIFO length to be applied when system enters + fast-chargging. Takes effect only if + 'qcom,qg-fast-chg-config' is enabled. The + default value if not specified is 1. + ========================================================== Second Level Nodes - Peripherals managed by QGAUGE driver ========================================================== -- GitLab From 884f2b3999d1fdfa9c088144151a3022747750ba Mon Sep 17 00:00:00 2001 From: Anirudh Ghayal Date: Mon, 8 Jul 2019 16:08:26 +0530 Subject: [PATCH 0921/1121] power: qpnp-qg: Add support for fast-charge config Add logic to allow re-configuring the FIFO length based on charging status. This may be required for fast-charging cases where SOC needs to be tracked fine-grain. Change-Id: I3e51dc34cea5c97a7f901d9981f908e35b8b0fb4 Signed-off-by: Anirudh Ghayal --- drivers/power/supply/qcom/qg-core.h | 9 ++++-- drivers/power/supply/qcom/qpnp-qg.c | 43 ++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/drivers/power/supply/qcom/qg-core.h b/drivers/power/supply/qcom/qg-core.h index 46cbd384083d..eb85b4e1ee36 100644 --- a/drivers/power/supply/qcom/qg-core.h +++ b/drivers/power/supply/qcom/qg-core.h @@ -45,6 +45,7 @@ struct qg_dt { int sleep_s2_fifo_length; int sleep_s2_acc_length; int sleep_s2_acc_intvl_ms; + int fast_chg_s2_fifo_length; int ocv_timer_expiry_min; int ocv_tol_threshold_uv; int s3_entry_fifo_length; @@ -71,6 +72,7 @@ struct qg_dt { bool qg_ext_sense; bool use_s7_ocv; bool qg_sleep_config; + bool qg_fast_chg_cfg; }; struct qg_esr_data { @@ -195,9 +197,10 @@ enum ocv_type { }; enum s2_state { - S2_LOW_VBAT = BIT(0), - S2_SLEEP = BIT(1), - S2_DEFAULT = BIT(2), + S2_FAST_CHARGING = BIT(0), + S2_LOW_VBAT = BIT(1), + S2_SLEEP = BIT(2), + S2_DEFAULT = BIT(3), }; enum debug_mask { diff --git a/drivers/power/supply/qcom/qpnp-qg.c b/drivers/power/supply/qcom/qpnp-qg.c index a2f117c4f896..f789b9aeebf5 100644 --- a/drivers/power/supply/qcom/qpnp-qg.c +++ b/drivers/power/supply/qcom/qpnp-qg.c @@ -296,7 +296,9 @@ static int qg_config_s2_state(struct qpnp_qg *chip, chip->s2_state_mask &= ~requested_state; /* define the priority of the states */ - if (chip->s2_state_mask & S2_LOW_VBAT) + if (chip->s2_state_mask & S2_FAST_CHARGING) + state = S2_FAST_CHARGING; + else if (chip->s2_state_mask & S2_LOW_VBAT) state = S2_LOW_VBAT; else if (chip->s2_state_mask & S2_SLEEP) state = S2_SLEEP; @@ -307,6 +309,11 @@ static int qg_config_s2_state(struct qpnp_qg *chip, return 0; switch (state) { + case S2_FAST_CHARGING: + fifo_length = chip->dt.fast_chg_s2_fifo_length; + acc_interval = chip->dt.s2_acc_intvl_ms; + acc_length = chip->dt.s2_acc_length; + break; case S2_LOW_VBAT: fifo_length = chip->dt.s2_vbat_low_fifo_length; acc_interval = chip->dt.s2_acc_intvl_ms; @@ -731,6 +738,22 @@ static int qg_vbat_thresholds_config(struct qpnp_qg *chip) return rc; } +static int qg_fast_charge_config(struct qpnp_qg *chip) +{ + int rc = 0; + + if (!chip->dt.qg_fast_chg_cfg) + return 0; + + rc = qg_config_s2_state(chip, S2_FAST_CHARGING, + (chip->charge_status == POWER_SUPPLY_STATUS_CHARGING) + ? true : false, false); + if (rc < 0) + pr_err("Failed to exit S2_SLEEP rc=%d\n", rc); + + return rc; +} + static void qg_retrieve_esr_params(struct qpnp_qg *chip) { u32 data = 0; @@ -1194,6 +1217,10 @@ static irqreturn_t qg_fifo_update_done_handler(int irq, void *data) if (rc < 0) pr_err("Failed to apply VBAT EMPTY config rc=%d\n", rc); + rc = qg_fast_charge_config(chip); + if (rc < 0) + pr_err("Failed to apply fast-charge config rc=%d\n", rc); + rc = qg_vbat_low_wa(chip); if (rc < 0) { pr_err("Failed to apply VBAT LOW WA, rc=%d\n", rc); @@ -3525,6 +3552,7 @@ static int qg_alg_init(struct qpnp_qg *chip) #define ESR_CHG_MIN_IBAT_UA (-450000) #define DEFAULT_SLEEP_TIME_SECS 1800 /* 30 mins */ #define DEFAULT_SYS_MIN_VOLT_MV 2800 +#define DEFAULT_FAST_CHG_S2_FIFO_LENGTH 1 static int qg_parse_dt(struct qpnp_qg *chip) { int rc = 0; @@ -3796,6 +3824,19 @@ static int qg_parse_dt(struct qpnp_qg *chip) chip->dt.sleep_s2_acc_intvl_ms = temp; } + if (of_property_read_bool(node, "qcom,qg-fast-chg-config")) { + + chip->dt.qg_fast_chg_cfg = true; + + rc = of_property_read_u32(node, + "qcom,fast-chg-s2-fifo-length", &temp); + if (rc < 0) + chip->dt.fast_chg_s2_fifo_length = + DEFAULT_FAST_CHG_S2_FIFO_LENGTH; + else + chip->dt.fast_chg_s2_fifo_length = temp; + } + chip->dt.qg_ext_sense = of_property_read_bool(node, "qcom,qg-ext-sns"); chip->dt.use_s7_ocv = of_property_read_bool(node, "qcom,qg-use-s7-ocv"); -- GitLab From 11ca41ac50e6388c356516f7e7eb67d8dce2e657 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Tue, 7 Aug 2018 13:47:06 +0100 Subject: [PATCH 0922/1121] arm64: ssbd: Add support for PSTATE.SSBS rather than trapping to EL3 On CPUs with support for PSTATE.SSBS, the kernel can toggle the SSBD state without needing to call into firmware. This patch hooks into the existing SSBD infrastructure so that SSBS is used on CPUs that support it, but it's all made horribly complicated by the very real possibility of big/little systems that don't uniformly provide the new capability. Change-Id: I4d195d50bdb04fbd42ad12cf0f9b3d990b686b5a Signed-off-by: Will Deacon Signed-off-by: Catalin Marinas Git-commit: 8f04e8e6e29c93421a95b61cad62e3918425eac7 Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git Signed-off-by: Neeraj Upadhyay Signed-off-by: Mayank Grover --- arch/arm64/include/asm/processor.h | 7 +++++ arch/arm64/include/asm/ptrace.h | 1 + arch/arm64/include/asm/sysreg.h | 3 ++ arch/arm64/include/uapi/asm/ptrace.h | 1 + arch/arm64/kernel/cpu_errata.c | 26 +++++++++++++-- arch/arm64/kernel/cpufeature.c | 47 ++++++++++++++++++++++++++++ arch/arm64/kernel/process.c | 4 +++ arch/arm64/kernel/ssbd.c | 21 +++++++++++++ 8 files changed, 108 insertions(+), 2 deletions(-) diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h index e02c4bd7c68f..87653c86b2e6 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h @@ -147,6 +147,10 @@ static inline void start_thread(struct pt_regs *regs, unsigned long pc, { start_thread_common(regs, pc); regs->pstate = PSR_MODE_EL0t; + + if (arm64_get_ssbd_state() != ARM64_SSBD_FORCE_ENABLE) + regs->pstate |= PSR_SSBS_BIT; + regs->sp = sp; } @@ -163,6 +167,9 @@ static inline void compat_start_thread(struct pt_regs *regs, unsigned long pc, regs->pstate |= COMPAT_PSR_E_BIT; #endif + if (arm64_get_ssbd_state() != ARM64_SSBD_FORCE_ENABLE) + regs->pstate |= COMPAT_PSR_SSBS_BIT; + regs->compat_sp = sp; } #endif diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h index 9faaba0064a2..17c7e949e42c 100644 --- a/arch/arm64/include/asm/ptrace.h +++ b/arch/arm64/include/asm/ptrace.h @@ -50,6 +50,7 @@ #define COMPAT_PSR_I_BIT 0x00000080 #define COMPAT_PSR_A_BIT 0x00000100 #define COMPAT_PSR_E_BIT 0x00000200 +#define COMPAT_PSR_SSBS_BIT 0x00800000 #define COMPAT_PSR_J_BIT 0x01000000 #define COMPAT_PSR_Q_BIT 0x08000000 #define COMPAT_PSR_V_BIT 0x10000000 diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index cee5da219528..a50a0cae58f7 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -85,11 +85,14 @@ #define REG_PSTATE_PAN_IMM sys_reg(0, 0, 4, 0, 4) #define REG_PSTATE_UAO_IMM sys_reg(0, 0, 4, 0, 3) +#define REG_PSTATE_SSBS_IMM sys_reg(0, 3, 4, 0, 1) #define SET_PSTATE_PAN(x) __emit_inst(0xd5000000 | REG_PSTATE_PAN_IMM | \ (!!x)<<8 | 0x1f) #define SET_PSTATE_UAO(x) __emit_inst(0xd5000000 | REG_PSTATE_UAO_IMM | \ (!!x)<<8 | 0x1f) +#define SET_PSTATE_SSBS(x) __emit_inst(0xd5000000 | REG_PSTATE_SSBS_IMM | \ + (!!x)<<8 | 0x1f) #define SYS_DC_ISW sys_insn(1, 0, 7, 6, 2) #define SYS_DC_CSW sys_insn(1, 0, 7, 10, 2) diff --git a/arch/arm64/include/uapi/asm/ptrace.h b/arch/arm64/include/uapi/asm/ptrace.h index 67d4c33974e8..eea58f8ec355 100644 --- a/arch/arm64/include/uapi/asm/ptrace.h +++ b/arch/arm64/include/uapi/asm/ptrace.h @@ -45,6 +45,7 @@ #define PSR_I_BIT 0x00000080 #define PSR_A_BIT 0x00000100 #define PSR_D_BIT 0x00000200 +#define PSR_SSBS_BIT 0x00001000 #define PSR_PAN_BIT 0x00400000 #define PSR_UAO_BIT 0x00800000 #define PSR_Q_BIT 0x08000000 diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index 7617215b8ffc..4aa42be3fa2c 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -271,6 +271,14 @@ early_param("ssbd", ssbd_cfg); void arm64_set_ssbd_mitigation(bool state) { + if (this_cpu_has_cap(ARM64_SSBS)) { + if (state) + asm volatile(SET_PSTATE_SSBS(0)); + else + asm volatile(SET_PSTATE_SSBS(1)); + return; + } + switch (psci_ops.conduit) { case PSCI_CONDUIT_HVC: arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_WORKAROUND_2, state, NULL); @@ -295,6 +303,11 @@ static bool has_ssbd_mitigation(const struct arm64_cpu_capabilities *entry, WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible()); + if (this_cpu_has_cap(ARM64_SSBS)) { + required = false; + goto out_printmsg; + } + if (psci_ops.smccc_version == SMCCC_VERSION_1_0) { ssbd_state = ARM64_SSBD_UNKNOWN; return false; @@ -343,7 +356,6 @@ static bool has_ssbd_mitigation(const struct arm64_cpu_capabilities *entry, switch (ssbd_state) { case ARM64_SSBD_FORCE_DISABLE: - pr_info_once("%s disabled from command-line\n", entry->desc); arm64_set_ssbd_mitigation(false); required = false; break; @@ -356,7 +368,6 @@ static bool has_ssbd_mitigation(const struct arm64_cpu_capabilities *entry, break; case ARM64_SSBD_FORCE_ENABLE: - pr_info_once("%s forced from command-line\n", entry->desc); arm64_set_ssbd_mitigation(true); required = true; break; @@ -366,6 +377,17 @@ static bool has_ssbd_mitigation(const struct arm64_cpu_capabilities *entry, break; } +out_printmsg: + switch (ssbd_state) { + case ARM64_SSBD_FORCE_DISABLE: + pr_info_once("%s disabled from command-line\n", entry->desc); + break; + + case ARM64_SSBD_FORCE_ENABLE: + pr_info_once("%s forced from command-line\n", entry->desc); + break; + } + return required; } #endif /* CONFIG_ARM64_SSBD */ diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index d45cc4da0295..742c8b3244a6 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -983,6 +983,50 @@ static int cpu_copy_el2regs(void *__unused) return 0; } +#ifdef CONFIG_ARM64_SSBD +static int ssbs_emulation_handler(struct pt_regs *regs, u32 instr) +{ + if (user_mode(regs)) + return 1; + + if (instr & BIT(CRm_shift)) + regs->pstate |= PSR_SSBS_BIT; + else + regs->pstate &= ~PSR_SSBS_BIT; + + regs->pc += 4; + return 0; +} + +static struct undef_hook ssbs_emulation_hook = { + .instr_mask = ~(1U << CRm_shift), + .instr_val = 0xd500001f | REG_PSTATE_SSBS_IMM, + .fn = ssbs_emulation_handler, +}; + +static int cpu_enable_ssbs(void *__unsused) +{ + static bool undef_hook_registered = false; + static DEFINE_SPINLOCK(hook_lock); + + spin_lock(&hook_lock); + if (!undef_hook_registered) { + register_undef_hook(&ssbs_emulation_hook); + undef_hook_registered = true; + } + spin_unlock(&hook_lock); + + if (arm64_get_ssbd_state() == ARM64_SSBD_FORCE_DISABLE) { + write_sysreg((read_sysreg(sctlr_el1) | SCTLR_ELx_DSSBS), + sctlr_el1); + arm64_set_ssbd_mitigation(false); + } else { + arm64_set_ssbd_mitigation(true); + } + return 0; +} +#endif /* CONFIG_ARM64_SSBD */ + static const struct arm64_cpu_capabilities arm64_features[] = { { .desc = "GIC system register CPU interface", @@ -1116,6 +1160,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .enable = cpu_enable_hw_dbm, }, #endif +#ifdef CONFIG_ARM64_SSBD { .desc = "Speculative Store Bypassing Safe (SSBS)", .capability = ARM64_SSBS, @@ -1124,7 +1169,9 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .field_pos = ID_AA64PFR1_SSBS_SHIFT, .sign = FTR_UNSIGNED, .min_field_value = ID_AA64PFR1_SSBS_PSTATE_ONLY, + .enable = cpu_enable_ssbs, }, +#endif {}, }; diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index e31f59db9397..6f3258a9d0eb 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -365,6 +365,10 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start, if (IS_ENABLED(CONFIG_ARM64_UAO) && cpus_have_const_cap(ARM64_HAS_UAO)) childregs->pstate |= PSR_UAO_BIT; + + if (arm64_get_ssbd_state() == ARM64_SSBD_FORCE_DISABLE) + childregs->pstate |= PSR_SSBS_BIT; + p->thread.cpu_context.x19 = stack_start; p->thread.cpu_context.x20 = stk_sz; } diff --git a/arch/arm64/kernel/ssbd.c b/arch/arm64/kernel/ssbd.c index 0560738c1d5c..477ede8809c8 100644 --- a/arch/arm64/kernel/ssbd.c +++ b/arch/arm64/kernel/ssbd.c @@ -3,13 +3,31 @@ * Copyright (C) 2018 ARM Ltd, All Rights Reserved. */ +#include #include #include #include +#include #include #include +static void ssbd_ssbs_enable(struct task_struct *task) +{ + u64 val = is_compat_thread(task_thread_info(task)) ? + COMPAT_PSR_SSBS_BIT : PSR_SSBS_BIT; + + task_pt_regs(task)->pstate |= val; +} + +static void ssbd_ssbs_disable(struct task_struct *task) +{ + u64 val = is_compat_thread(task_thread_info(task)) ? + COMPAT_PSR_SSBS_BIT : PSR_SSBS_BIT; + + task_pt_regs(task)->pstate &= ~val; +} + /* * prctl interface for SSBD */ @@ -45,12 +63,14 @@ static int ssbd_prctl_set(struct task_struct *task, unsigned long ctrl) return -EPERM; task_clear_spec_ssb_disable(task); clear_tsk_thread_flag(task, TIF_SSBD); + ssbd_ssbs_enable(task); break; case PR_SPEC_DISABLE: if (state == ARM64_SSBD_FORCE_DISABLE) return -EPERM; task_set_spec_ssb_disable(task); set_tsk_thread_flag(task, TIF_SSBD); + ssbd_ssbs_disable(task); break; case PR_SPEC_FORCE_DISABLE: if (state == ARM64_SSBD_FORCE_DISABLE) @@ -58,6 +78,7 @@ static int ssbd_prctl_set(struct task_struct *task, unsigned long ctrl) task_set_spec_ssb_disable(task); task_set_spec_ssb_force_disable(task); set_tsk_thread_flag(task, TIF_SSBD); + ssbd_ssbs_disable(task); break; default: return -ERANGE; -- GitLab From 32a57e795d759d6b2329aa89f1f2b1d16370fe22 Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Sun, 16 Sep 2018 23:17:23 +0100 Subject: [PATCH 0923/1121] arm64: sysreg: Clean up instructions for modifying PSTATE fields Instructions for modifying the PSTATE fields which were not supported in the older toolchains (e.g, PAN, UAO) are generated using macros. We have so far used the normal sys_reg() helper for defining the PSTATE fields. While this works fine, it is really difficult to correlate the code with the Arm ARM definition. As per Arm ARM, the PSTATE fields are defined only using Op1, Op2 fields, with fixed values for Op0, CRn. Also the CRm field has been reserved for the Immediate value for the instruction. So using the sys_reg() looks quite confusing. This patch cleans up the instruction helpers by bringing them in line with the Arm ARM definitions to make it easier to correlate code with the document. No functional changes. Change-Id: I7454c137730ff0b444eac08f84cda937d208557e Cc: Will Deacon Cc: Mark Rutland Signed-off-by: Suzuki K Poulose Signed-off-by: Catalin Marinas Git-commit: 74e248286e1d04b0d9bfdd002450ef0211f6f29f Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git Signed-off-by: Neeraj Upadhyay Signed-off-by: Mayank Grover --- arch/arm64/include/asm/sysreg.h | 30 ++++++++++++++++++++---------- arch/arm64/kernel/cpufeature.c | 6 +++--- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index a50a0cae58f7..82e4c7eea8cf 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -83,16 +83,26 @@ #endif /* CONFIG_BROKEN_GAS_INST */ -#define REG_PSTATE_PAN_IMM sys_reg(0, 0, 4, 0, 4) -#define REG_PSTATE_UAO_IMM sys_reg(0, 0, 4, 0, 3) -#define REG_PSTATE_SSBS_IMM sys_reg(0, 3, 4, 0, 1) - -#define SET_PSTATE_PAN(x) __emit_inst(0xd5000000 | REG_PSTATE_PAN_IMM | \ - (!!x)<<8 | 0x1f) -#define SET_PSTATE_UAO(x) __emit_inst(0xd5000000 | REG_PSTATE_UAO_IMM | \ - (!!x)<<8 | 0x1f) -#define SET_PSTATE_SSBS(x) __emit_inst(0xd5000000 | REG_PSTATE_SSBS_IMM | \ - (!!x)<<8 | 0x1f) +/* + * Instructions for modifying PSTATE fields. + * As per Arm ARM for v8-A, Section "C.5.1.3 op0 == 0b00, architectural hints, + * barriers and CLREX, and PSTATE access", ARM DDI 0487 C.a, system instructions + * for accessing PSTATE fields have the following encoding: + * Op0 = 0, CRn = 4 + * Op1, Op2 encodes the PSTATE field modified and defines the constraints. + * CRm = Imm4 for the instruction. + * Rt = 0x1f + */ +#define pstate_field(op1, op2) ((op1) << Op1_shift | (op2) << Op2_shift) +#define PSTATE_Imm_shift CRm_shift + +#define PSTATE_PAN pstate_field(0, 4) +#define PSTATE_UAO pstate_field(0, 3) +#define PSTATE_SSBS pstate_field(3, 1) + +#define SET_PSTATE_PAN(x) __emit_inst(0xd500401f | PSTATE_PAN | ((!!x) << PSTATE_Imm_shift)) +#define SET_PSTATE_UAO(x) __emit_inst(0xd500401f | PSTATE_UAO | ((!!x) << PSTATE_Imm_shift)) +#define SET_PSTATE_SSBS(x) __emit_inst(0xd500401f | PSTATE_SSBS | ((!!x) << PSTATE_Imm_shift)) #define SYS_DC_ISW sys_insn(1, 0, 7, 6, 2) #define SYS_DC_CSW sys_insn(1, 0, 7, 10, 2) diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 742c8b3244a6..fa4924bad290 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -989,7 +989,7 @@ static int ssbs_emulation_handler(struct pt_regs *regs, u32 instr) if (user_mode(regs)) return 1; - if (instr & BIT(CRm_shift)) + if (instr & BIT(PSTATE_Imm_shift)) regs->pstate |= PSR_SSBS_BIT; else regs->pstate &= ~PSR_SSBS_BIT; @@ -999,8 +999,8 @@ static int ssbs_emulation_handler(struct pt_regs *regs, u32 instr) } static struct undef_hook ssbs_emulation_hook = { - .instr_mask = ~(1U << CRm_shift), - .instr_val = 0xd500001f | REG_PSTATE_SSBS_IMM, + .instr_mask = ~(1U << PSTATE_Imm_shift), + .instr_val = 0xd500401f | PSTATE_SSBS, .fn = ssbs_emulation_handler, }; -- GitLab From bc129607664a260a6fbb18454006a462c5f4e3c9 Mon Sep 17 00:00:00 2001 From: Mayank Grover Date: Mon, 15 Jul 2019 14:00:00 +0530 Subject: [PATCH 0924/1121] defconfig: msm: Enable SSBD config for Atoll Enable Speculative Store Bypass Disable config for Atoll, so that the mitigation can be used for its impacted cores. Enabling this config is required, to ensure that PSTATE.SSBS is set for EL0, so that speculation is enabled for it. Change-Id: I886d2b383bc6247e854ce8cfa3f8948881544e82 Signed-off-by: Mayank Grover --- arch/arm64/configs/vendor/atoll-perf_defconfig | 1 + arch/arm64/configs/vendor/atoll_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm64/configs/vendor/atoll-perf_defconfig b/arch/arm64/configs/vendor/atoll-perf_defconfig index 0a1d220d5122..3257015246d7 100644 --- a/arch/arm64/configs/vendor/atoll-perf_defconfig +++ b/arch/arm64/configs/vendor/atoll-perf_defconfig @@ -67,6 +67,7 @@ CONFIG_ZSMALLOC=y CONFIG_BALANCE_ANON_FILE_RECLAIM=y CONFIG_SECCOMP=y # CONFIG_UNMAP_KERNEL_AT_EL0 is not set +CONFIG_ARM64_SSBD=y CONFIG_ARMV8_DEPRECATED=y CONFIG_SWP_EMULATION=y CONFIG_CP15_BARRIER_EMULATION=y diff --git a/arch/arm64/configs/vendor/atoll_defconfig b/arch/arm64/configs/vendor/atoll_defconfig index f27b39732be8..d7694e7d1d38 100644 --- a/arch/arm64/configs/vendor/atoll_defconfig +++ b/arch/arm64/configs/vendor/atoll_defconfig @@ -72,6 +72,7 @@ CONFIG_BALANCE_ANON_FILE_RECLAIM=y CONFIG_SECCOMP=y # CONFIG_UNMAP_KERNEL_AT_EL0 is not set CONFIG_PRINT_VMEMLAYOUT=y +CONFIG_ARM64_SSBD=y CONFIG_ARMV8_DEPRECATED=y CONFIG_SWP_EMULATION=y CONFIG_CP15_BARRIER_EMULATION=y -- GitLab From 63f6e6d4ca345b1225057d49f8dba72a1e23d447 Mon Sep 17 00:00:00 2001 From: Mao Jinlong Date: Thu, 18 Jul 2019 16:33:16 +0530 Subject: [PATCH 0925/1121] ARM: dts: msm: add cti trig_out gpio for atoll Add pinctil setting to cti trig_out gpio and configure trig_out gpio for atoll. Change-Id: Ib3219cce33f7f3245faea39efcc9b699c562a2b7 Signed-off-by: Mao Jinlong --- arch/arm64/boot/dts/qcom/atoll-coresight.dtsi | 4 ++++ arch/arm64/boot/dts/qcom/atoll-pinctrl.dtsi | 13 +++++++++++++ 2 files changed, 17 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/atoll-coresight.dtsi b/arch/arm64/boot/dts/qcom/atoll-coresight.dtsi index c9367930754e..1cd3070a7918 100644 --- a/arch/arm64/boot/dts/qcom/atoll-coresight.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll-coresight.dtsi @@ -2415,6 +2415,10 @@ clocks = <&clock_aop QDSS_CLK>; clock-names = "apb_pclk"; + + qcom,cti-gpio-trigout = <4>; + pinctrl-names = "cti-trigout-pctrl"; + pinctrl-0 = <&trigout_a>; }; cti3: cti@6013000 { diff --git a/arch/arm64/boot/dts/qcom/atoll-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/atoll-pinctrl.dtsi index 506a18623dba..328f975d136b 100644 --- a/arch/arm64/boot/dts/qcom/atoll-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll-pinctrl.dtsi @@ -205,6 +205,19 @@ }; }; + trigout_a: trigout_a { + mux { + pins = "gpio72"; + function = "qdss_cti"; + }; + + config { + pins = "gpio72"; + drive-strength = <2>; + bias-disable; + }; + }; + qupv3_se8_2uart_pins: qupv3_se8_2uart_pins { qupv3_se8_2uart_active: qupv3_se8_2uart_active { mux { -- GitLab From 820a58b7f02f936393b2dd490702dac4346b7869 Mon Sep 17 00:00:00 2001 From: Konstantin Dorfman Date: Thu, 18 Jul 2019 14:36:30 +0300 Subject: [PATCH 0926/1121] soc: qcom: spcom: fix error code on create existing channel This change fixes the error code, on an attempt to create a channel that already exists. Change-Id: If8e8aafed725488c88a40777600fcfedc10bb60e Signed-off-by: Konstantin Dorfman --- drivers/soc/qcom/spcom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/soc/qcom/spcom.c b/drivers/soc/qcom/spcom.c index 723ca904ae9a..3306cc12f7a4 100644 --- a/drivers/soc/qcom/spcom.c +++ b/drivers/soc/qcom/spcom.c @@ -1684,7 +1684,7 @@ static int spcom_create_channel_chardev(const char *name) ch = spcom_find_channel_by_name(name); if (ch) { pr_err("channel [%s] already exist.\n", name); - return -EINVAL; + return -EBUSY; } ch = spcom_find_channel_by_name(""); /* find reserved channel */ -- GitLab From f9a13118a0391427c2c40aa47eb93d82c4c13144 Mon Sep 17 00:00:00 2001 From: Rajesh Kemisetti Date: Thu, 18 Jul 2019 20:31:08 +0530 Subject: [PATCH 0927/1121] msm: kgsl: Fix race condition between drawobj and context destroy drawobj_destroy_sync() tries to cancel all pending sync events by taking local copy of pending list. In case of sync point timestamp event, it goes ahead and accesses context's events list assuming that event's context would be alive. But at the same time, if the other context, which is of interest for these sync point events, can be destroyed by cancelling all events in its group. This leads to use-after-free in drawobj_destroy_sync() path. Fix is to give the responsibility of putting the context's ref count to the thread which clears the pending mask. Change-Id: I8d08ef6ddb38ca917f75088071c04727bced11d2 Signed-off-by: Rajesh Kemisetti --- drivers/gpu/msm/kgsl_drawobj.c | 37 +++++++++++++++++----------------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/msm/kgsl_drawobj.c b/drivers/gpu/msm/kgsl_drawobj.c index dc6d835867f8..c927fdccb66d 100644 --- a/drivers/gpu/msm/kgsl_drawobj.c +++ b/drivers/gpu/msm/kgsl_drawobj.c @@ -223,8 +223,13 @@ static void drawobj_sync_func(struct kgsl_device *device, trace_syncpoint_timestamp_expire(event->syncobj, event->context, event->timestamp); - drawobj_sync_expire(device, event); - kgsl_context_put(event->context); + /* + * Put down the context ref count only if + * this thread successfully clears the pending bit mask. + */ + if (drawobj_sync_expire(device, event)) + kgsl_context_put(event->context); + kgsl_drawobj_put(&event->syncobj->base); } @@ -254,24 +259,11 @@ static void drawobj_destroy_sparse(struct kgsl_drawobj *drawobj) static void drawobj_destroy_sync(struct kgsl_drawobj *drawobj) { struct kgsl_drawobj_sync *syncobj = SYNCOBJ(drawobj); - unsigned long pending = 0; unsigned int i; /* Zap the canary timer */ del_timer_sync(&syncobj->timer); - /* - * Copy off the pending list and clear each pending event atomically - - * this will render any subsequent asynchronous callback harmless. - * This marks each event for deletion. If any pending fence callbacks - * run between now and the actual cancel, the associated structures - * are kfreed only in the cancel call. - */ - for_each_set_bit(i, &syncobj->pending, KGSL_MAX_SYNCPOINTS) { - if (test_and_clear_bit(i, &syncobj->pending)) - __set_bit(i, &pending); - } - /* * Clear all pending events - this will render any subsequent async * callbacks harmless @@ -279,8 +271,12 @@ static void drawobj_destroy_sync(struct kgsl_drawobj *drawobj) for (i = 0; i < syncobj->numsyncs; i++) { struct kgsl_drawobj_sync_event *event = &syncobj->synclist[i]; - /* Don't do anything if the event has already expired */ - if (!test_bit(i, &pending)) + /* + * Don't do anything if the event has already expired. + * If this thread clears the pending bit mask then it is + * responsible for doing context put. + */ + if (!test_and_clear_bit(i, &syncobj->pending)) continue; switch (event->type) { @@ -288,6 +284,11 @@ static void drawobj_destroy_sync(struct kgsl_drawobj *drawobj) kgsl_cancel_event(drawobj->device, &event->context->events, event->timestamp, drawobj_sync_func, event); + /* + * Do context put here to make sure the context is alive + * till this thread cancels kgsl event. + */ + kgsl_context_put(event->context); break; case KGSL_CMD_SYNCPOINT_TYPE_FENCE: kgsl_sync_fence_async_cancel(event->handle); @@ -300,7 +301,7 @@ static void drawobj_destroy_sync(struct kgsl_drawobj *drawobj) * If we cancelled an event, there's a good chance that the context is * on a dispatcher queue, so schedule to get it removed. */ - if (!bitmap_empty(&pending, KGSL_MAX_SYNCPOINTS) && + if (!bitmap_empty(&syncobj->pending, KGSL_MAX_SYNCPOINTS) && drawobj->device->ftbl->drawctxt_sched) drawobj->device->ftbl->drawctxt_sched(drawobj->device, drawobj->context); -- GitLab From 035eb1f641f7173a5453fef35625513f26af01a9 Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Thu, 11 Jul 2019 15:51:51 -0700 Subject: [PATCH 0928/1121] drivers: soc: qcom: Add snapshot of virtual subsystem notification driver This is a snapshot of the virtual subsystem notification driver as of msm-4.4 commit <36e8e9585f4b10> (soc: qcom: subsystem_notif_virt: Only initialize work for virtual systems). Change-Id: Ic8bb9ac740d0590432ad8f9ec1a131299b22831a Signed-off-by: Anant Goel --- .../bindings/arm/msm/subsystem_notif_virt.txt | 49 ++++ drivers/soc/qcom/subsystem_notif_virt.c | 251 ++++++++++++++++++ 2 files changed, 300 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/msm/subsystem_notif_virt.txt create mode 100644 drivers/soc/qcom/subsystem_notif_virt.c diff --git a/Documentation/devicetree/bindings/arm/msm/subsystem_notif_virt.txt b/Documentation/devicetree/bindings/arm/msm/subsystem_notif_virt.txt new file mode 100644 index 000000000000..38e997797a04 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/msm/subsystem_notif_virt.txt @@ -0,0 +1,49 @@ +Subsystem Notification Virtual Driver + +The guest VM uses this driver to communicate +subsystem state notifications to a backend driver +via the virtual device's registers. + +[Root level node] +Required Properties: +-compatible : Should be "qcom,subsys-notif-virt" +-reg : The start and size of the virtual device's + register set. +-reg-names : Should be "vdev_base" for virtual device's + base address. + +[Child nodes] +-subsys-names : The name of the subsystem that the + driver is registering to notifications for. +-offset : The offset from the virtual device's register + base where the subsystem state will be written. +-type : The type of the subsystem. + "virtual" - When the subsystem is loaded by the host VM + "native" - When the subsystem is loaded by the guest VM + +Required Property for "virtual" subsystem types: +-interrupts : Tuple defining the interrupt which the driver must + register for to receive subsystem state notifications + from the backend. +-interrupt-names: Must be "state-irq" + +Example: + + subsys_notif_virt: qcom,subsys_notif_virt@2D000000 { + compatible = "qcom,subsys-notif-virt"; + reg = <0x2D000000 0x400>; + reg-names = "vdev_base"; + adsp { + subsys-name = "adsp"; + interrupts = <0 43 0>; + interrupt-names = "state-irq"; + type = "virtual"; + offset = <0>; + }; + mpss { + subsys-name = "modem"; + type = "native"; + offset = <256>; + }; + }; + diff --git a/drivers/soc/qcom/subsystem_notif_virt.c b/drivers/soc/qcom/subsystem_notif_virt.c new file mode 100644 index 000000000000..99ad94744653 --- /dev/null +++ b/drivers/soc/qcom/subsystem_notif_virt.c @@ -0,0 +1,251 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CLIENT_STATE_OFFSET 4 +#define SUBSYS_STATE_OFFSET 8 + +static void __iomem *base_reg; + +enum subsystem_type { + VIRTUAL, + NATIVE, +}; + +struct subsystem_descriptor { + const char *name; + u32 offset; + enum subsystem_type type; + struct notifier_block nb; + void *handle; + int ssr_irq; + struct list_head subsystem_list; + struct work_struct work; +}; + +static LIST_HEAD(subsystem_descriptor_list); +static struct workqueue_struct *ssr_wq; + +static void subsystem_notif_wq_func(struct work_struct *work) +{ + struct subsystem_descriptor *subsystem = + container_of(work, struct subsystem_descriptor, work); + void *subsystem_handle; + int state, ret; + + state = readl_relaxed(base_reg + subsystem->offset); + subsystem_handle = subsys_notif_add_subsys(subsystem->name); + ret = subsys_notif_queue_notification(subsystem_handle, state, NULL); + writel_relaxed(ret, base_reg + subsystem->offset + CLIENT_STATE_OFFSET); +} + +static int subsystem_state_callback(struct notifier_block *this, + unsigned long value, void *priv) +{ + struct subsystem_descriptor *subsystem = + container_of(this, struct subsystem_descriptor, nb); + + writel_relaxed(value, base_reg + subsystem->offset + + SUBSYS_STATE_OFFSET); + + return NOTIFY_OK; +} + +static irqreturn_t subsystem_restart_irq_handler(int irq, void *dev_id) +{ + struct subsystem_descriptor *subsystem = dev_id; + + queue_work(ssr_wq, &subsystem->work); + + return IRQ_HANDLED; +} + +static int get_resources(struct platform_device *pdev) +{ + struct device_node *node; + struct device_node *child = NULL; + const char *ss_type; + struct resource *res; + struct subsystem_descriptor *subsystem = NULL; + int ret = 0; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vdev_base"); + base_reg = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR_OR_NULL(base_reg)) { + dev_err(&pdev->dev, "Memory mapping failed\n"); + return -ENOMEM; + } + + node = pdev->dev.of_node; + for_each_child_of_node(node, child) { + + subsystem = devm_kmalloc(&pdev->dev, + sizeof(struct subsystem_descriptor), + GFP_KERNEL); + if (!subsystem) + return -ENOMEM; + + subsystem->name = + of_get_property(child, "subsys-name", NULL); + if (IS_ERR_OR_NULL(subsystem->name)) { + dev_err(&pdev->dev, "Could not find subsystem name\n"); + return -EINVAL; + } + + ret = of_property_read_u32(child, "offset", + &subsystem->offset); + if (ret) { + dev_err(&pdev->dev, "offset reading for %s failed\n", + subsystem->name); + return -EINVAL; + } + + ret = of_property_read_string(child, "type", + &ss_type); + if (ret) { + dev_err(&pdev->dev, "type reading for %s failed\n", + subsystem->name); + return -EINVAL; + } + + if (!strcmp(ss_type, "virtual")) + subsystem->type = VIRTUAL; + + if (!strcmp(ss_type, "native")) + subsystem->type = NATIVE; + + switch (subsystem->type) { + case NATIVE: + subsystem->nb.notifier_call = + subsystem_state_callback; + + subsystem->handle = + subsys_notif_register_notifier( + subsystem->name, &subsystem->nb); + if (IS_ERR_OR_NULL(subsystem->handle)) { + dev_err(&pdev->dev, + "Could not register SSR notifier cb\n"); + return -EINVAL; + } + list_add_tail(&subsystem->subsystem_list, + &subsystem_descriptor_list); + break; + case VIRTUAL: + subsystem->ssr_irq = + of_irq_get_byname(child, "state-irq"); + if (subsystem->ssr_irq < 0) { + dev_err(&pdev->dev, "Could not find IRQ\n"); + return -EINVAL; + } + ret = devm_request_threaded_irq(&pdev->dev, + subsystem->ssr_irq, NULL, + subsystem_restart_irq_handler, + IRQF_ONESHOT | IRQF_TRIGGER_RISING, + subsystem->name, subsystem); + INIT_WORK(&subsystem->work, subsystem_notif_wq_func); + break; + default: + dev_err(&pdev->dev, "Unsupported type %d\n", + subsystem->type); + } + } + + return 0; +} + +static void release_resources(void) +{ + struct subsystem_descriptor *subsystem, *node; + + list_for_each_entry_safe(subsystem, node, &subsystem_descriptor_list, + subsystem_list) { + subsys_notif_unregister_notifier(subsystem->handle, + &subsystem->nb); + list_del(&subsystem->subsystem_list); + } +} + +static int subsys_notif_virt_probe(struct platform_device *pdev) +{ + int ret = 0; + + if (!pdev) { + dev_err(&pdev->dev, "pdev is NULL\n"); + return -EINVAL; + } + + ssr_wq = create_singlethread_workqueue("ssr_wq"); + if (!ssr_wq) { + dev_err(&pdev->dev, "Workqueue creation failed\n"); + return -ENOMEM; + } + + ret = get_resources(pdev); + if (ret) + destroy_workqueue(ssr_wq); + + return ret; +} + +static int subsys_notif_virt_remove(struct platform_device *pdev) +{ + destroy_workqueue(ssr_wq); + release_resources(); + + return 0; +} + +static const struct of_device_id match_table[] = { + { .compatible = "qcom,subsys-notif-virt" }, + {}, +}; + +static struct platform_driver subsys_notif_virt_driver = { + .probe = subsys_notif_virt_probe, + .remove = subsys_notif_virt_remove, + .driver = { + .name = "subsys_notif_virt", + .owner = THIS_MODULE, + .of_match_table = match_table, + }, +}; + +static int __init subsys_notif_virt_init(void) +{ + return platform_driver_register(&subsys_notif_virt_driver); +} +module_init(subsys_notif_virt_init); + +static void __exit subsys_notif_virt_exit(void) +{ + platform_driver_unregister(&subsys_notif_virt_driver); +} +module_exit(subsys_notif_virt_exit); + +MODULE_DESCRIPTION("Subsystem Notification Virtual Driver"); +MODULE_LICENSE("GPL v2"); -- GitLab From 40dee15fadf527c50a95a7becd7c2925ab02c5e6 Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Tue, 16 Jul 2019 11:11:40 -0700 Subject: [PATCH 0929/1121] ARM: dts: msm: Update SSC entries for SA8195P Enable the sensors TLMM block, disable the SSC sensors node for SA8195P, and use PM8195 regulators for the SSC. Change-Id: Id02e131df2fbd8296258150abd5c939270abd379 Signed-off-by: Anant Goel --- arch/arm64/boot/dts/qcom/sa8195p.dtsi | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sa8195p.dtsi b/arch/arm64/boot/dts/qcom/sa8195p.dtsi index 6dfcaa300047..c704cdcbead0 100644 --- a/arch/arm64/boot/dts/qcom/sa8195p.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8195p.dtsi @@ -111,3 +111,17 @@ qcom,default-mode-host; status = "ok"; }; + +&slpi_tlmm { + status = "ok"; +}; + +&pil_ssc { + vdd_cx-supply = <&VDD_CX_LEVEL>; + vdd_mx-supply = <&VDD_MX_LEVEL>; + status = "ok"; +}; + +&ssc_sensors { + status = "disabled"; +}; -- GitLab From 9c8e3332e3d47212800dd2ea1711296a66a9222d Mon Sep 17 00:00:00 2001 From: Gustavo Solaira Date: Mon, 8 Jul 2019 14:47:25 -0700 Subject: [PATCH 0930/1121] ARM: dts: msm: Enable RGMII for SA515M CCARD Enable RGMII in 1.8V mode for SA515M CCARD boards. Change-Id: I38738278124a48006fb2a3cbb243a2e095d798f2 Signed-off-by: Gustavo Solaira --- arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi | 11 +++++++++++ arch/arm64/boot/dts/qcom/sdxprairie-pmic-overlay.dtsi | 11 +++++++++++ arch/arm64/boot/dts/qcom/sdxprairie-regulator.dtsi | 4 ++-- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi b/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi index 3033eba9f683..6eb3f9aa57b7 100644 --- a/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi +++ b/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi @@ -119,3 +119,14 @@ &i2c_4 { status = "okay"; }; + +&emac_hw { + /delete-property/ vreg_rgmii-supply; + pinctrl-names = "default"; + pinctrl-0 = <&vreg_rgmii_off_default>; +}; + +&vreg_rgmii_io_pads { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; +}; diff --git a/arch/arm64/boot/dts/qcom/sdxprairie-pmic-overlay.dtsi b/arch/arm64/boot/dts/qcom/sdxprairie-pmic-overlay.dtsi index a523e7ab6b47..fc9bb5b6f7f3 100644 --- a/arch/arm64/boot/dts/qcom/sdxprairie-pmic-overlay.dtsi +++ b/arch/arm64/boot/dts/qcom/sdxprairie-pmic-overlay.dtsi @@ -38,3 +38,14 @@ &usb { extcon = <&pm8150b_pdphy>; }; + +&pmxprairie_gpios { + vreg_rgmii_off { + vreg_rgmii_off_default: vreg_rgmii_off_default { + pins = "gpio9"; + bias-pull-down; + output-disable; + input-enable; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/sdxprairie-regulator.dtsi b/arch/arm64/boot/dts/qcom/sdxprairie-regulator.dtsi index c863b3243228..817bef3db90a 100644 --- a/arch/arm64/boot/dts/qcom/sdxprairie-regulator.dtsi +++ b/arch/arm64/boot/dts/qcom/sdxprairie-regulator.dtsi @@ -502,8 +502,8 @@ vreg_rgmii_io_pads: rgmii_io_pads_regulator { compatible = "regulator-fixed"; regulator-name = "rgmii_io_pads"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; regulator-enable-ramp-delay = <100>; gpio = <&tlmm 102 GPIO_ACTIVE_HIGH>; enable-active-high; -- GitLab From 80647ca90d34a9357e5b317804e9df7d12124b24 Mon Sep 17 00:00:00 2001 From: Gustavo Solaira Date: Mon, 15 Jul 2019 14:33:31 -0700 Subject: [PATCH 0931/1121] defconfig: sa515m: Enable the AT24 EEPROM for SA515M Enable the AT24 I2C EEPROM driver for SA515M devices. Change-Id: I92f2d7b0cf885951c6eb7d3d375d04a2422939b2 Signed-off-by: Gustavo Solaira --- arch/arm/configs/vendor/sdxprairie-auto-perf_defconfig | 1 + arch/arm/configs/vendor/sdxprairie-auto_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm/configs/vendor/sdxprairie-auto-perf_defconfig b/arch/arm/configs/vendor/sdxprairie-auto-perf_defconfig index 8dc781b37772..51486a3ffcef 100644 --- a/arch/arm/configs/vendor/sdxprairie-auto-perf_defconfig +++ b/arch/arm/configs/vendor/sdxprairie-auto-perf_defconfig @@ -186,6 +186,7 @@ CONFIG_MTD_UBI=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_QSEECOM=y +CONFIG_EEPROM_AT24=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_SG=y diff --git a/arch/arm/configs/vendor/sdxprairie-auto_defconfig b/arch/arm/configs/vendor/sdxprairie-auto_defconfig index ae512352a79d..0bee993d7a94 100644 --- a/arch/arm/configs/vendor/sdxprairie-auto_defconfig +++ b/arch/arm/configs/vendor/sdxprairie-auto_defconfig @@ -184,6 +184,7 @@ CONFIG_MTD_UBI=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_QSEECOM=y +CONFIG_EEPROM_AT24=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_SG=y -- GitLab From cd0e77ec519442cefc38d8b5ed48c8278702c855 Mon Sep 17 00:00:00 2001 From: Gustavo Solaira Date: Mon, 15 Jul 2019 14:35:47 -0700 Subject: [PATCH 0932/1121] ARM: dts: msm: Enable EEPROM for SA515M boards Enable the I2C EEPROM device for SA515M CCARD boards. The EEPROM stores the CDT data. Change-Id: Ib37b119cdd93e41e0f5d73386ba1b0c794ed46b0 Signed-off-by: Gustavo Solaira --- arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi b/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi index 6eb3f9aa57b7..09b5c7e03766 100644 --- a/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi +++ b/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi @@ -114,6 +114,12 @@ AVDD-supply = <&codec_vreg>; IOVDD-supply = <&codec_vreg>; }; + + eeprom@52 { + compatible = "atmel,24c128"; + reg = <0x52>; + pagesize = <32>; + }; }; &i2c_4 { -- GitLab From 9d88334403f61a9490ade4b045363073f38ec250 Mon Sep 17 00:00:00 2001 From: Gustavo Solaira Date: Mon, 15 Jul 2019 16:25:15 -0700 Subject: [PATCH 0933/1121] ARM: dts: msm: Change tlmm-central-base base for sdxprairie emac Use the correct tlmm-central-base address for the sdxprairie emac driver. Change-Id: Idd506574ce041c56fb76427669372605b6bd0816 Signed-off-by: Gustavo Solaira --- arch/arm64/boot/dts/qcom/sdxprairie.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sdxprairie.dtsi b/arch/arm64/boot/dts/qcom/sdxprairie.dtsi index 09e144edae38..31bb62859e84 100644 --- a/arch/arm64/boot/dts/qcom/sdxprairie.dtsi +++ b/arch/arm64/boot/dts/qcom/sdxprairie.dtsi @@ -1406,7 +1406,7 @@ qcom,arm-smmu; reg = <0x20000 0x10000>, <0x36000 0x100>, - <0x3900000 0x300000>; + <0xf100000 0x300000>; reg-names = "emac-base", "rgmii-base", "tlmm-central-base"; interrupts-extended = <&pdc 0 62 4>, <&pdc 0 60 4>, <&tlmm 90 2>, <&pdc 0 49 4>, -- GitLab From a0484921a4fff9ab007f4563c2a7e1b1be3529c3 Mon Sep 17 00:00:00 2001 From: Gustavo Solaira Date: Wed, 17 Jul 2019 12:23:02 -0700 Subject: [PATCH 0934/1121] defconfig: msm: Enable PPS for sdxprairie-auto platforms Enable PPS support for sdxprairie-auto platforms. This enables time synchronization based on pulse per second interrupt. Change-Id: Ia1fc3073d1b3199df7b5e11fc28847cf3b77fb25 Signed-off-by: Gustavo Solaira --- arch/arm/configs/vendor/sdxprairie-auto-perf_defconfig | 2 ++ arch/arm/configs/vendor/sdxprairie-auto_defconfig | 2 ++ 2 files changed, 4 insertions(+) diff --git a/arch/arm/configs/vendor/sdxprairie-auto-perf_defconfig b/arch/arm/configs/vendor/sdxprairie-auto-perf_defconfig index 51486a3ffcef..dbfa32e26312 100644 --- a/arch/arm/configs/vendor/sdxprairie-auto-perf_defconfig +++ b/arch/arm/configs/vendor/sdxprairie-auto-perf_defconfig @@ -243,6 +243,8 @@ CONFIG_SPI_QUP=y CONFIG_SPI_SPIDEV=m CONFIG_SPMI=y CONFIG_SLIMBUS=y +CONFIG_PPS=y +CONFIG_PPS_CLIENT_GPIO=y CONFIG_PINCTRL_QCOM_SPMI_PMIC=y CONFIG_PINCTRL_SDXPRAIRIE=y CONFIG_GPIOLIB=y diff --git a/arch/arm/configs/vendor/sdxprairie-auto_defconfig b/arch/arm/configs/vendor/sdxprairie-auto_defconfig index 0bee993d7a94..f24bfa4d6dec 100644 --- a/arch/arm/configs/vendor/sdxprairie-auto_defconfig +++ b/arch/arm/configs/vendor/sdxprairie-auto_defconfig @@ -243,6 +243,8 @@ CONFIG_SPI_QUP=y CONFIG_SPI_SPIDEV=m CONFIG_SPMI=y CONFIG_SLIMBUS=y +CONFIG_PPS=y +CONFIG_PPS_CLIENT_GPIO=y CONFIG_PINCTRL_QCOM_SPMI_PMIC=y CONFIG_PINCTRL_SDXPRAIRIE=y CONFIG_GPIOLIB=y -- GitLab From ebcd1afa6faf90416b0ea826a89b4513222e1180 Mon Sep 17 00:00:00 2001 From: Sudarshan Rajagopalan Date: Thu, 13 Jun 2019 17:25:00 -0700 Subject: [PATCH 0935/1121] soc: qcom: mem-offline: fix mem online failure notification During MEM_GOING_ONLINE, if the hardware memory online fails, notify the kernel with the failure so that kernel does not online the pages in this block. Also, on such failures, save the memory states so that appropriate actions can be taken when MEM_CANCEL_ONLINE event is received. Change-Id: I9de11b7aeeed857ef7008aff78d19ef237e28a00 Signed-off-by: Sudarshan Rajagopalan --- drivers/soc/qcom/mem-offline.c | 85 ++++++++++++++++++++++++++++------ 1 file changed, 70 insertions(+), 15 deletions(-) diff --git a/drivers/soc/qcom/mem-offline.c b/drivers/soc/qcom/mem-offline.c index 6e720ee93f6a..0c154636d127 100644 --- a/drivers/soc/qcom/mem-offline.c +++ b/drivers/soc/qcom/mem-offline.c @@ -56,6 +56,8 @@ enum memory_states { MAX_STATE, }; +static enum memory_states *mem_hw_state; + static struct mem_offline_mailbox { struct mbox_client cl; struct mbox_chan *mbox; @@ -184,6 +186,29 @@ static int send_msg(struct memory_notify *mn, bool online) return aop_send_msg(__pfn_to_phys(start), online); } +static int mem_change_refresh_state(struct memory_notify *mn, + enum memory_states state) +{ + int start = SECTION_ALIGN_DOWN(mn->start_pfn); + unsigned long sec_nr = pfn_to_section_nr(start); + bool online = (state == MEMORY_ONLINE) ? true : false; + unsigned long idx = (sec_nr - start_section_nr) / sections_per_block; + int ret; + + if (mem_hw_state[idx] == state) { + /* we shouldn't be getting this request */ + pr_warn("mem-offline: hardware state of mem%d block already in %s state. Ignoring refresh state change request\n", + sec_nr, online ? "online" : "offline"); + return 0; + } + ret = send_msg(mn, online); + if (ret) + return -EINVAL; + mem_hw_state[idx] = state; + + return 0; +} + static int mem_event_callback(struct notifier_block *self, unsigned long action, void *arg) { @@ -223,10 +248,12 @@ static int mem_event_callback(struct notifier_block *self, idx) / sections_per_block].fail_count; cur = ktime_get(); - if (send_msg(mn, true)) + if (mem_change_refresh_state(mn, MEMORY_ONLINE)) { pr_err("PASR: %s online request addr:0x%llx failed\n", is_rpm_controller ? "RPM" : "AOP", __pfn_to_phys(start)); + return NOTIFY_BAD; + } if (!debug_pagealloc_enabled()) { /* Create kernel page-tables */ create_pgtable_mapping(start_addr, end_addr); @@ -252,10 +279,15 @@ static int mem_event_callback(struct notifier_block *self, /* Clear kernel page-tables */ clear_pgtable_mapping(start_addr, end_addr); } - if (send_msg(mn, false)) + if (mem_change_refresh_state(mn, MEMORY_OFFLINE)) { pr_err("PASR: %s offline request addr:0x%llx failed\n", is_rpm_controller ? "RPM" : "AOP", __pfn_to_phys(start)); + /* + * Notifying that something went bad at this stage won't + * help since this is the last stage of memory hotplug. + */ + } delay = ktime_ms_delta(ktime_get(), cur); record_stat(sec_nr, delay, MEMORY_OFFLINE); @@ -266,7 +298,7 @@ static int mem_event_callback(struct notifier_block *self, case MEM_CANCEL_ONLINE: pr_info("mem-offline: MEM_CANCEL_ONLINE: start = 0x%lx end = 0x%lx", start_addr, end_addr); - if (send_msg(mn, false)) + if (mem_change_refresh_state(mn, MEMORY_OFFLINE)) pr_err("PASR: %s online request addr:0x%llx failed\n", is_rpm_controller ? "RPM" : "AOP", __pfn_to_phys(start)); @@ -401,9 +433,6 @@ static struct attribute_group mem_attr_group = { static int mem_sysfs_init(void) { - unsigned int total_blks = (end_section_nr - start_section_nr + 1) / - sections_per_block; - if (start_section_nr == end_section_nr) return -EINVAL; @@ -414,11 +443,6 @@ static int mem_sysfs_init(void) if (sysfs_create_group(kobj, &mem_attr_group)) kobject_put(kobj); - mem_info = kzalloc(sizeof(*mem_info) * total_blks * MAX_STATE, - GFP_KERNEL); - if (!mem_info) - return -ENOMEM; - return 0; } @@ -470,7 +494,8 @@ static struct notifier_block hotplug_memory_callback_nb = { static int mem_offline_driver_probe(struct platform_device *pdev) { - int ret; + unsigned int total_blks; + int ret, i; if (mem_parse_dt(pdev)) return -ENODEV; @@ -482,16 +507,46 @@ static int mem_offline_driver_probe(struct platform_device *pdev) if (ret > 0) pr_err("mem-offline: !!ERROR!! Auto onlining some memory blocks failed. System could run with less RAM\n"); - if (mem_sysfs_init()) - return -ENODEV; + total_blks = (end_section_nr - start_section_nr + 1) / + sections_per_block; + mem_info = kcalloc(total_blks * MAX_STATE, sizeof(*mem_info), + GFP_KERNEL); + if (!mem_info) + return -ENOMEM; + + mem_hw_state = kcalloc(total_blks, sizeof(*mem_hw_state), GFP_KERNEL); + if (!mem_hw_state) { + ret = -ENOMEM; + goto err_free_mem_info; + } + + /* we assume that hardware state of mem blocks are online after boot */ + for (i = 0; i < total_blks; i++) + mem_hw_state[i] = MEMORY_ONLINE; + + if (mem_sysfs_init()) { + ret = -ENODEV; + goto err_free_mem_hw_state; + } if (register_hotmemory_notifier(&hotplug_memory_callback_nb)) { pr_err("mem-offline: Registering memory hotplug notifier failed\n"); - return -ENODEV; + ret = -ENODEV; + goto err_sysfs_remove_group; } pr_info("mem-offline: Added memory blocks ranging from mem%lu - mem%lu\n", start_section_nr, end_section_nr); + return 0; + +err_sysfs_remove_group: + sysfs_remove_group(kobj, &mem_attr_group); + kobject_put(kobj); +err_free_mem_hw_state: + kfree(mem_hw_state); +err_free_mem_info: + kfree(mem_info); + return ret; } static const struct of_device_id mem_offline_match_table[] = { -- GitLab From a49479c9bf51bcd7154bd05c30da8d95d23602e2 Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Tue, 16 Jul 2019 11:18:33 -0700 Subject: [PATCH 0936/1121] ARM: dts: msm: Update camera SIDs and clock rates for SA8195P Provide updated nodes for the camera SIDs and clock rates as they have changed for the SA8195P target. Change-Id: I610f8417585451ceb3fdb8eb68662469a054ec8a Signed-off-by: Anant Goel --- arch/arm64/boot/dts/qcom/sa8195p.dtsi | 74 +++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sa8195p.dtsi b/arch/arm64/boot/dts/qcom/sa8195p.dtsi index 237ab398e218..671d3eb4121c 100644 --- a/arch/arm64/boot/dts/qcom/sa8195p.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8195p.dtsi @@ -105,4 +105,78 @@ qcom,iova-mapping = <0x80000000 0x40000000>; }; }; + + qcom,cam_smmu { + msm_cam_smmu_ife { + iommus = <&apps_smmu 0xAA0 0x4E0>, + <&apps_smmu 0xA20 0x4E0>, + <&apps_smmu 0xA00 0x4E0>, + <&apps_smmu 0xA80 0x4E0>, + <&apps_smmu 0xEA0 0x4E0>, + <&apps_smmu 0xE20 0x4E0>, + <&apps_smmu 0xE00 0x4E0>, + <&apps_smmu 0xE80 0x4E0>; + }; + + msm_cam_smmu_jpeg { + iommus = <&apps_smmu 0x2100 0x20>, + <&apps_smmu 0x2120 0x20>; + }; + + msm_cam_smmu_icp { + iommus = <&apps_smmu 0x2042 0x0>, + <&apps_smmu 0x2080 0x320>, + <&apps_smmu 0x20A0 0x320>, + <&apps_smmu 0x2380 0x320>, + <&apps_smmu 0x23A0 0x320>, + <&apps_smmu 0x20C0 0x300>, + <&apps_smmu 0x23C0 0x300>; + }; + + msm_cam_smmu_fd { + iommus = <&apps_smmu 0x2140 0x20>, + <&apps_smmu 0x2160 0x20>; + }; + + msm_cam_smmu_lrme { + iommus = <&apps_smmu 0x20e0 0x300>, + <&apps_smmu 0x23E0 0x300>; + }; + }; + + cam_csid0 { + clock-rates = + <400000000 0 0 0 400000000 0 0>, + <400000000 0 0 0 558000000 0 0>, + <480000000 0 0 0 637000000 0 0>, + <600000000 0 0 0 760000000 0 0>; + clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo"; + }; + + cam_csid1 { + clock-rates = + <400000000 0 0 0 400000000 0 0>, + <400000000 0 0 0 558000000 0 0>, + <480000000 0 0 0 637000000 0 0>, + <600000000 0 0 0 760000000 0 0>; + clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo"; + }; + + cam_vfe0 { + clock-rates = + <400000000 0 0>, + <558000000 0 0>, + <637000000 0 0>, + <760000000 0 0>; + clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo"; + }; + + cam_vfe1 { + clock-rates = + <400000000 0 0>, + <558000000 0 0>, + <637000000 0 0>, + <760000000 0 0>; + clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo"; + }; }; -- GitLab From deaa93690974b5bab6b6668d45a67cf4e90e75f7 Mon Sep 17 00:00:00 2001 From: Bojun Pan Date: Tue, 16 Jul 2019 01:01:51 -0700 Subject: [PATCH 0937/1121] msm: ipa3: Fix spin_unlock_bh warning in wan driver spin_unlock_bh in ipa3_send unconditionally enable IRQ which is causing spin_lock_irqsave(&wwan_ptr->lock, flags) in ipa3_wwan_xmit to be broken. The fix here is to isolate the spin_unlock_bh and spin_lock_irqsave. Change-Id: I777f643f8789876377d26d0a54c28289df064e40 Signed-off-by: Bojun Pan --- drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c index 9e66e5b6f045..cadbc7b3e669 100644 --- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c @@ -1321,7 +1321,14 @@ static int ipa3_wwan_xmit(struct sk_buff *skb, struct net_device *dev) spin_unlock_irqrestore(&wwan_ptr->lock, flags); return NETDEV_TX_OK; } + /* + * increase the outstanding_pkts count first + * to avoid suspend happens in parallel + * after unlock + */ + atomic_inc(&wwan_ptr->outstanding_pkts); /* IPA_RM checking end */ + spin_unlock_irqrestore(&wwan_ptr->lock, flags); /* * both data packets and command will be routed to @@ -1329,19 +1336,18 @@ static int ipa3_wwan_xmit(struct sk_buff *skb, struct net_device *dev) */ ret = ipa3_tx_dp(IPA_CLIENT_APPS_WAN_PROD, skb, NULL); if (ret) { + atomic_dec(&wwan_ptr->outstanding_pkts); if (ret == -EPIPE) { IPAWANERR_RL("[%s] fatal: pipe is not valid\n", dev->name); dev_kfree_skb_any(skb); dev->stats.tx_dropped++; - spin_unlock_irqrestore(&wwan_ptr->lock, flags); return NETDEV_TX_OK; } ret = NETDEV_TX_BUSY; goto out; } - atomic_inc(&wwan_ptr->outstanding_pkts); dev->stats.tx_packets++; dev->stats.tx_bytes += skb->len; ret = NETDEV_TX_OK; @@ -1355,7 +1361,6 @@ static int ipa3_wwan_xmit(struct sk_buff *skb, struct net_device *dev) IPA_RM_RESOURCE_WWAN_0_PROD); } } - spin_unlock_irqrestore(&wwan_ptr->lock, flags); return ret; } -- GitLab From 032075acf3fd6359e03d12306268081754b47ed3 Mon Sep 17 00:00:00 2001 From: Gustavo Solaira Date: Thu, 18 Jul 2019 11:00:58 -0700 Subject: [PATCH 0938/1121] defconfig: msm: Add defconfig files for SA2150P Add defconfig files for Telematics SA2150P platforms. Change-Id: Id383dc95a7029d1ff0c60d8805ddd7ff16eea594 Signed-off-by: Gustavo Solaira --- .../configs/vendor/sa2150p-perf_defconfig | 481 ++++++++++++++++ arch/arm64/configs/vendor/sa2150p_defconfig | 529 ++++++++++++++++++ 2 files changed, 1010 insertions(+) create mode 100644 arch/arm64/configs/vendor/sa2150p-perf_defconfig create mode 100644 arch/arm64/configs/vendor/sa2150p_defconfig diff --git a/arch/arm64/configs/vendor/sa2150p-perf_defconfig b/arch/arm64/configs/vendor/sa2150p-perf_defconfig new file mode 100644 index 000000000000..23107f443800 --- /dev/null +++ b/arch/arm64/configs/vendor/sa2150p-perf_defconfig @@ -0,0 +1,481 @@ +CONFIG_POSIX_MQUEUE=y +CONFIG_AUDIT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_IRQ_TIME_ACCOUNTING=y +CONFIG_SCHED_WALT=y +CONFIG_TASKSTATS=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_RCU_EXPERT=y +CONFIG_RCU_FAST_NO_HZ=y +CONFIG_RCU_NOCB_CPU=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_CGROUPS=y +CONFIG_CGROUP_SCHED=y +CONFIG_RT_GROUP_SCHED=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_PID_NS is not set +CONFIG_DEFAULT_USE_ENERGY_AWARE=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_KALLSYMS_ALL=y +CONFIG_EMBEDDED=y +CONFIG_SLAB_FREELIST_HARDENED=y +CONFIG_PROFILING=y +CONFIG_CC_STACKPROTECTOR_STRONG=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SIG=y +CONFIG_MODULE_SIG_FORCE=y +CONFIG_MODULE_SIG_SHA512=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_ARCH_QCOM=y +CONFIG_ARCH_QCS405=y +CONFIG_PCI=y +CONFIG_PCI_MSM=y +CONFIG_PCI_MSM_MSI=y +CONFIG_NR_CPUS=4 +CONFIG_PREEMPT=y +CONFIG_CMA=y +CONFIG_ZSMALLOC=y +CONFIG_SECCOMP=y +# CONFIG_HARDEN_BRANCH_PREDICTOR is not set +CONFIG_ARMV8_DEPRECATED=y +CONFIG_SWP_EMULATION=y +CONFIG_CP15_BARRIER_EMULATION=y +CONFIG_SETEND_EMULATION=y +CONFIG_ARM64_SW_TTBR0_PAN=y +CONFIG_RANDOMIZE_BASE=y +CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_COMPAT=y +CONFIG_PM_AUTOSLEEP=y +CONFIG_PM_WAKELOCKS=y +CONFIG_PM_WAKELOCKS_LIMIT=0 +# CONFIG_PM_WAKELOCKS_GC is not set +CONFIG_CPU_IDLE=y +CONFIG_ARM_CPUIDLE=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y +CONFIG_CPU_FREQ_MSM=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_XFRM_USER=y +CONFIG_XFRM_STATISTICS=y +CONFIG_NET_KEY=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_INET_AH=y +CONFIG_INET_ESP=y +CONFIG_INET_IPCOMP=y +# CONFIG_INET_XFRM_MODE_BEET is not set +CONFIG_INET_DIAG_DESTROY=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_INET6_AH=y +CONFIG_INET6_ESP=y +CONFIG_INET6_IPCOMP=y +CONFIG_IPV6_MIP6=y +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_NETFILTER=y +CONFIG_NF_CONNTRACK=y +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_AMANDA=y +CONFIG_NF_CONNTRACK_FTP=y +CONFIG_NF_CONNTRACK_H323=y +CONFIG_NF_CONNTRACK_IRC=y +CONFIG_NF_CONNTRACK_NETBIOS_NS=y +CONFIG_NF_CONNTRACK_PPTP=y +CONFIG_NF_CONNTRACK_SANE=y +CONFIG_NF_CONNTRACK_TFTP=y +CONFIG_NF_CT_NETLINK=y +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y +CONFIG_NETFILTER_XT_TARGET_CONNMARK=y +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y +CONFIG_NETFILTER_XT_TARGET_LOG=y +CONFIG_NETFILTER_XT_TARGET_MARK=y +CONFIG_NETFILTER_XT_TARGET_NFLOG=y +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y +CONFIG_NETFILTER_XT_TARGET_NOTRACK=y +CONFIG_NETFILTER_XT_TARGET_TEE=y +CONFIG_NETFILTER_XT_TARGET_TPROXY=y +CONFIG_NETFILTER_XT_TARGET_TRACE=y +CONFIG_NETFILTER_XT_TARGET_SECMARK=y +CONFIG_NETFILTER_XT_TARGET_TCPMSS=y +CONFIG_NETFILTER_XT_MATCH_COMMENT=y +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y +CONFIG_NETFILTER_XT_MATCH_CONNMARK=y +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y +CONFIG_NETFILTER_XT_MATCH_DSCP=y +CONFIG_NETFILTER_XT_MATCH_ESP=y +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y +CONFIG_NETFILTER_XT_MATCH_HELPER=y +CONFIG_NETFILTER_XT_MATCH_IPRANGE=y +CONFIG_NETFILTER_XT_MATCH_LENGTH=y +CONFIG_NETFILTER_XT_MATCH_LIMIT=y +CONFIG_NETFILTER_XT_MATCH_MAC=y +CONFIG_NETFILTER_XT_MATCH_MARK=y +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y +CONFIG_NETFILTER_XT_MATCH_POLICY=y +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y +CONFIG_NETFILTER_XT_MATCH_QUOTA=y +CONFIG_NETFILTER_XT_MATCH_QUOTA2=y +CONFIG_NETFILTER_XT_MATCH_STATE=y +CONFIG_NETFILTER_XT_MATCH_STATISTIC=y +CONFIG_NETFILTER_XT_MATCH_STRING=y +CONFIG_NETFILTER_XT_MATCH_TIME=y +CONFIG_NETFILTER_XT_MATCH_U32=y +CONFIG_NF_CONNTRACK_IPV4=y +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_MATCH_AH=y +CONFIG_IP_NF_MATCH_ECN=y +CONFIG_IP_NF_MATCH_RPFILTER=y +CONFIG_IP_NF_MATCH_TTL=y +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_REJECT=y +CONFIG_IP_NF_NAT=y +CONFIG_IP_NF_TARGET_MASQUERADE=y +CONFIG_IP_NF_TARGET_NETMAP=y +CONFIG_IP_NF_TARGET_REDIRECT=y +CONFIG_IP_NF_MANGLE=y +CONFIG_IP_NF_RAW=y +CONFIG_IP_NF_SECURITY=y +CONFIG_IP_NF_ARPTABLES=y +CONFIG_IP_NF_ARPFILTER=y +CONFIG_IP_NF_ARP_MANGLE=y +CONFIG_NF_CONNTRACK_IPV6=y +CONFIG_IP6_NF_IPTABLES=y +CONFIG_IP6_NF_MATCH_RPFILTER=y +CONFIG_IP6_NF_FILTER=y +CONFIG_IP6_NF_TARGET_REJECT=y +CONFIG_IP6_NF_MANGLE=y +CONFIG_IP6_NF_RAW=y +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_HTB=y +CONFIG_NET_SCH_PRIO=y +CONFIG_NET_CLS_FW=y +CONFIG_NET_CLS_U32=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_FLOW=y +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_CMP=y +CONFIG_NET_EMATCH_NBYTE=y +CONFIG_NET_EMATCH_U32=y +CONFIG_NET_EMATCH_META=y +CONFIG_NET_EMATCH_TEXT=y +CONFIG_NET_CLS_ACT=y +CONFIG_QRTR=y +CONFIG_NTAG_NQ=y +CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y +CONFIG_DMA_CMA=y +CONFIG_MTD=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_MSM_QPIC_NAND=y +CONFIG_MTD_NAND=y +CONFIG_MTD_UBI=y +CONFIG_ZRAM=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_QSEECOM=y +CONFIG_UID_SYS_STATS=y +CONFIG_QPNP_MISC=y +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_SG=y +CONFIG_CHR_DEV_SCH=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_UFSHCD=y +CONFIG_SCSI_UFSHCD_PLATFORM=y +CONFIG_SCSI_UFS_QCOM=y +CONFIG_SCSI_UFSHCD_CMD_LOGGING=y +CONFIG_MD=y +CONFIG_BLK_DEV_DM=y +CONFIG_DM_CRYPT=y +CONFIG_DM_VERITY=y +CONFIG_DM_VERITY_FEC=y +CONFIG_NETDEVICES=y +CONFIG_DUMMY=y +CONFIG_AT803X_PHY=y +CONFIG_USB_USBNET=y +CONFIG_USB_NET_SMSC75XX=y +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_EVBUG=m +CONFIG_INPUT_KEYRESET=y +CONFIG_KEYBOARD_GPIO=y +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_JOYSTICK=y +CONFIG_JOYSTICK_XPAD=y +CONFIG_INPUT_TABLET=y +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_ATMEL_MXT=y +CONFIG_INPUT_MISC=y +CONFIG_INPUT_QPNP_POWER_ON=y +CONFIG_INPUT_UINPUT=y +CONFIG_INPUT_GPIO=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVMEM is not set +CONFIG_SERIAL_MSM_HS=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_MSM_LEGACY=y +CONFIG_DIAG_CHAR=y +CONFIG_MSM_ADSPRPC=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MSM_V2=y +CONFIG_SPI=y +CONFIG_SPI_QUP=y +CONFIG_SPI_SPIDEV=y +CONFIG_SPMI=y +CONFIG_PTP_1588_CLOCK=y +CONFIG_PINCTRL_QCS405=y +CONFIG_FRAGMENTED_GPIO_ADDRESS_SPACE=y +CONFIG_PINCTRL_QCOM_SPMI_PMIC=y +CONFIG_GPIO_SYSFS=y +CONFIG_POWER_RESET_QCOM=y +CONFIG_QCOM_DLOAD_MODE=y +CONFIG_THERMAL=y +CONFIG_THERMAL_WRITABLE_TRIPS=y +CONFIG_THERMAL_GOV_USER_SPACE=y +CONFIG_THERMAL_GOV_LOW_LIMITS=y +CONFIG_CPU_THERMAL=y +CONFIG_DEVFREQ_THERMAL=y +CONFIG_QCOM_SPMI_TEMP_ALARM=y +CONFIG_THERMAL_TSENS=y +CONFIG_QTI_VIRTUAL_SENSOR=y +CONFIG_QTI_QMI_COOLING_DEVICE=y +CONFIG_REGULATOR_COOLING_DEVICE=y +CONFIG_QTI_ADC_TM=y +CONFIG_QTI_RPM_SMD_COOLING_DEVICE=y +CONFIG_MFD_SPMI_PMIC=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_FAN53555=y +CONFIG_REGULATOR_CPR=y +CONFIG_REGULATOR_MEM_ACC=y +CONFIG_REGULATOR_RPM_SMD=y +CONFIG_REGULATOR_SPM=y +CONFIG_REGULATOR_STUB=y +CONFIG_RC_DEVICES=y +CONFIG_IR_MSM_GENI=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_RADIO_SUPPORT=y +CONFIG_MEDIA_CONTROLLER=y +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_USB_AUDIO=y +CONFIG_SND_SOC=y +CONFIG_HIDRAW=y +CONFIG_UHID=y +CONFIG_HID_APPLE=y +CONFIG_HID_ELECOM=y +CONFIG_HID_MAGICMOUSE=y +CONFIG_HID_MICROSOFT=y +CONFIG_HID_MULTITOUCH=y +CONFIG_USB_HIDDEV=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +CONFIG_USB_MON=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_ACM=y +CONFIG_USB_STORAGE=y +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_ALAUDA=y +CONFIG_USB_STORAGE_KARMA=y +CONFIG_USB_STORAGE_CYPRESS_ATACB=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_MSM=y +CONFIG_USB_SERIAL=y +CONFIG_USB_EHSET_TEST_FIXTURE=y +CONFIG_USB_LINK_LAYER_TEST=y +CONFIG_USB_TYPEC_MUX_NXP5150A=y +CONFIG_USB_QCOM_DIAG_BRIDGE=y +CONFIG_NOP_USB_XCEIV=y +CONFIG_MSM_SNPS_FEMTO_PHY=y +CONFIG_USB_MSM_SSPHY=y +CONFIG_USB_QCOM_EMU_PHY=y +CONFIG_DUAL_ROLE_USB_INTF=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_VBUS_DRAW=900 +CONFIG_USB_CONFIGFS=y +CONFIG_USB_CONFIGFS_F_FS=y +CONFIG_USB_CONFIGFS_UEVENT=y +CONFIG_USB_CONFIGFS_F_DIAG=y +CONFIG_MMC=y +CONFIG_MMC_PERF_PROFILING=y +CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_BLOCK_DEFERRED_RESUME=y +CONFIG_MMC_TEST=m +CONFIG_MMC_PARANOID_SD_INIT=y +CONFIG_MMC_CLKGATE=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_MSM=y +CONFIG_MMC_SDHCI_MSM_ICE=y +CONFIG_MMC_CQ_HCI=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_PCA9956B=y +CONFIG_LEDS_TRIGGERS=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_QPNP=y +CONFIG_DMADEVICES=y +CONFIG_QCOM_SPS_DMA=y +CONFIG_UIO=y +CONFIG_STAGING=y +CONFIG_ASHMEM=y +CONFIG_ION=y +CONFIG_QPNP_REVID=y +CONFIG_SPS=y +CONFIG_SPS_SUPPORT_NDP_BAM=y +CONFIG_QCOM_CLK_SMD_RPM=y +CONFIG_SPMI_PMIC_CLKDIV=y +CONFIG_MDM_DEBUGCC_QCS405=y +CONFIG_CLOCK_CPU_QCS405=y +CONFIG_QCS_CMN_BLK_PLL=y +CONFIG_HWSPINLOCK=y +CONFIG_HWSPINLOCK_QCOM=y +CONFIG_ARM_ARCH_TIMER_VCT_ACCESS=y +CONFIG_MAILBOX=y +CONFIG_QCOM_APCS_IPC=y +CONFIG_ARM_SMMU=y +CONFIG_QCOM_LAZY_MAPPING=y +CONFIG_IOMMU_DEBUG=y +CONFIG_IOMMU_DEBUG_TRACKING=y +CONFIG_RPMSG_CHAR=y +CONFIG_RPMSG_QCOM_GLINK_RPM=y +CONFIG_RPMSG_QCOM_GLINK_SMEM=y +CONFIG_MSM_RPM_SMD=y +CONFIG_QCOM_QMI_HELPERS=y +CONFIG_QCOM_SMEM=y +CONFIG_QCOM_SMD_RPM=y +CONFIG_MSM_SPM=y +CONFIG_MSM_L2_SPM=y +CONFIG_QCOM_SCM=y +CONFIG_QCOM_MEMORY_DUMP_V2=y +CONFIG_QCOM_WATCHDOG_V2=y +CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y +CONFIG_QCOM_WDOG_IPI_ENABLE=y +CONFIG_QCOM_SMP2P=y +CONFIG_MSM_SERVICE_LOCATOR=y +CONFIG_MSM_SERVICE_NOTIFIER=y +CONFIG_MSM_SUBSYSTEM_RESTART=y +CONFIG_MSM_PIL=y +CONFIG_MSM_SYSMON_QMI_COMM=y +CONFIG_MSM_PIL_SSR_GENERIC=y +CONFIG_MSM_BOOT_STATS=y +CONFIG_QCOM_DCC_V2=y +CONFIG_QCOM_BUS_SCALING=y +CONFIG_MSM_TZ_SMMU=y +CONFIG_QCOM_GLINK=y +CONFIG_QCOM_GLINK_PKT=y +CONFIG_QTI_RPM_STATS_LOG=y +CONFIG_MSM_CDSP_LOADER=y +CONFIG_QCOM_SMCINVOKE=y +CONFIG_MSM_PM=y +CONFIG_QCOM_SMP2P_SLEEPSTATE=y +CONFIG_QCOM_BIMC_BWMON=y +CONFIG_ARM_MEMLAT_MON=y +CONFIG_DEVFREQ_GOV_QCOM_BW_HWMON=y +CONFIG_DEVFREQ_GOV_MEMLAT=y +CONFIG_QCOM_DEVFREQ_DEVBW=y +CONFIG_EXTCON_USB_GPIO=y +CONFIG_IIO=y +CONFIG_QCOM_SPMI_ADC5=y +CONFIG_PWM=y +CONFIG_PWM_QTI_LPG=y +CONFIG_QCOM_KGSL=y +CONFIG_QTI_MPM=y +CONFIG_ANDROID=y +CONFIG_ANDROID_BINDER_IPC=y +CONFIG_MSM_TZ_LOG=y +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT3_FS=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_QUOTA=y +CONFIG_QUOTA_NETLINK_INTERFACE=y +# CONFIG_PRINT_QUOTA_WARNING is not set +CONFIG_QFMT_V2=y +CONFIG_FUSE_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_UBIFS_FS=y +CONFIG_UBIFS_FS_ADVANCED_COMPR=y +CONFIG_SQUASHFS=y +CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y +CONFIG_SQUASHFS_XATTR=y +# CONFIG_SQUASHFS_ZLIB is not set +CONFIG_SQUASHFS_XZ=y +CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_INFO=y +CONFIG_PAGE_OWNER=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_PAGE_POISONING=y +CONFIG_PAGE_POISONING_ENABLE_DEFAULT=y +CONFIG_PANIC_ON_RECURSIVE_FAULT=y +CONFIG_PANIC_ON_OOPS=y +CONFIG_PANIC_TIMEOUT=5 +CONFIG_SCHEDSTATS=y +CONFIG_IPC_LOGGING=y +CONFIG_BUG_ON_DATA_CORRUPTION=y +CONFIG_CORESIGHT=y +CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y +CONFIG_CORESIGHT_DYNAMIC_REPLICATOR=y +CONFIG_CORESIGHT_STM=y +CONFIG_CORESIGHT_CTI=y +CONFIG_CORESIGHT_TPDA=y +CONFIG_CORESIGHT_TPDM=y +CONFIG_CORESIGHT_HWEVENT=y +CONFIG_CORESIGHT_DUMMY=y +CONFIG_CORESIGHT_EVENT=y +CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y +CONFIG_SECURITY=y +CONFIG_SECURITY_NETWORK=y +CONFIG_LSM_MMAP_MIN_ADDR=4096 +CONFIG_HARDENED_USERCOPY=y +CONFIG_HARDENED_USERCOPY_PAGESPAN=y +CONFIG_SECURITY_SELINUX=y +CONFIG_CRYPTO_CTR=y +CONFIG_CRYPTO_XCBC=y +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_TWOFISH=y +CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y +CONFIG_CRYPTO_DEV_QCRYPTO=y +CONFIG_CRYPTO_DEV_QCEDEV=y +CONFIG_CRYPTO_DEV_QCOM_ICE=y +CONFIG_STACK_HASH_ORDER_SHIFT=12 diff --git a/arch/arm64/configs/vendor/sa2150p_defconfig b/arch/arm64/configs/vendor/sa2150p_defconfig new file mode 100644 index 000000000000..7a0d2382bf97 --- /dev/null +++ b/arch/arm64/configs/vendor/sa2150p_defconfig @@ -0,0 +1,529 @@ +CONFIG_POSIX_MQUEUE=y +CONFIG_AUDIT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_IRQ_TIME_ACCOUNTING=y +CONFIG_SCHED_WALT=y +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_RCU_EXPERT=y +CONFIG_RCU_FAST_NO_HZ=y +CONFIG_RCU_NOCB_CPU=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_CGROUPS=y +CONFIG_CGROUP_SCHED=y +CONFIG_RT_GROUP_SCHED=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_CGROUP_DEBUG=y +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_PID_NS is not set +CONFIG_DEFAULT_USE_ENERGY_AWARE=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_KALLSYMS_ALL=y +CONFIG_EMBEDDED=y +CONFIG_SLAB_FREELIST_HARDENED=y +CONFIG_PROFILING=y +CONFIG_CC_STACKPROTECTOR_STRONG=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SIG=y +CONFIG_MODULE_SIG_FORCE=y +CONFIG_MODULE_SIG_SHA512=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_ARCH_QCOM=y +CONFIG_ARCH_QCS405=y +CONFIG_PCI=y +CONFIG_PCI_MSM=y +CONFIG_PCI_MSM_MSI=y +CONFIG_NR_CPUS=4 +CONFIG_PREEMPT=y +CONFIG_CLEANCACHE=y +CONFIG_CMA=y +CONFIG_CMA_DEBUGFS=y +CONFIG_ZSMALLOC=y +CONFIG_SECCOMP=y +# CONFIG_HARDEN_BRANCH_PREDICTOR is not set +CONFIG_ARMV8_DEPRECATED=y +CONFIG_SWP_EMULATION=y +CONFIG_CP15_BARRIER_EMULATION=y +CONFIG_SETEND_EMULATION=y +CONFIG_ARM64_SW_TTBR0_PAN=y +CONFIG_RANDOMIZE_BASE=y +CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_COMPAT=y +CONFIG_PM_AUTOSLEEP=y +CONFIG_PM_WAKELOCKS=y +CONFIG_PM_WAKELOCKS_LIMIT=0 +# CONFIG_PM_WAKELOCKS_GC is not set +CONFIG_PM_DEBUG=y +CONFIG_CPU_IDLE=y +CONFIG_ARM_CPUIDLE=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y +CONFIG_CPU_FREQ_MSM=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_XFRM_USER=y +CONFIG_XFRM_STATISTICS=y +CONFIG_NET_KEY=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_INET_AH=y +CONFIG_INET_ESP=y +CONFIG_INET_IPCOMP=y +# CONFIG_INET_XFRM_MODE_BEET is not set +CONFIG_INET_DIAG_DESTROY=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_INET6_AH=y +CONFIG_INET6_ESP=y +CONFIG_INET6_IPCOMP=y +CONFIG_IPV6_MIP6=y +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_NETFILTER=y +CONFIG_NF_CONNTRACK=y +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_AMANDA=y +CONFIG_NF_CONNTRACK_FTP=y +CONFIG_NF_CONNTRACK_H323=y +CONFIG_NF_CONNTRACK_IRC=y +CONFIG_NF_CONNTRACK_NETBIOS_NS=y +CONFIG_NF_CONNTRACK_PPTP=y +CONFIG_NF_CONNTRACK_SANE=y +CONFIG_NF_CONNTRACK_TFTP=y +CONFIG_NF_CT_NETLINK=y +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y +CONFIG_NETFILTER_XT_TARGET_CONNMARK=y +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y +CONFIG_NETFILTER_XT_TARGET_LOG=y +CONFIG_NETFILTER_XT_TARGET_MARK=y +CONFIG_NETFILTER_XT_TARGET_NFLOG=y +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y +CONFIG_NETFILTER_XT_TARGET_NOTRACK=y +CONFIG_NETFILTER_XT_TARGET_TEE=y +CONFIG_NETFILTER_XT_TARGET_TPROXY=y +CONFIG_NETFILTER_XT_TARGET_TRACE=y +CONFIG_NETFILTER_XT_TARGET_SECMARK=y +CONFIG_NETFILTER_XT_TARGET_TCPMSS=y +CONFIG_NETFILTER_XT_MATCH_COMMENT=y +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y +CONFIG_NETFILTER_XT_MATCH_CONNMARK=y +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y +CONFIG_NETFILTER_XT_MATCH_DSCP=y +CONFIG_NETFILTER_XT_MATCH_ESP=y +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y +CONFIG_NETFILTER_XT_MATCH_HELPER=y +CONFIG_NETFILTER_XT_MATCH_IPRANGE=y +CONFIG_NETFILTER_XT_MATCH_LENGTH=y +CONFIG_NETFILTER_XT_MATCH_LIMIT=y +CONFIG_NETFILTER_XT_MATCH_MAC=y +CONFIG_NETFILTER_XT_MATCH_MARK=y +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y +CONFIG_NETFILTER_XT_MATCH_POLICY=y +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y +CONFIG_NETFILTER_XT_MATCH_QUOTA=y +CONFIG_NETFILTER_XT_MATCH_QUOTA2=y +CONFIG_NETFILTER_XT_MATCH_STATE=y +CONFIG_NETFILTER_XT_MATCH_STATISTIC=y +CONFIG_NETFILTER_XT_MATCH_STRING=y +CONFIG_NETFILTER_XT_MATCH_TIME=y +CONFIG_NETFILTER_XT_MATCH_U32=y +CONFIG_NF_CONNTRACK_IPV4=y +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_MATCH_AH=y +CONFIG_IP_NF_MATCH_ECN=y +CONFIG_IP_NF_MATCH_RPFILTER=y +CONFIG_IP_NF_MATCH_TTL=y +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_REJECT=y +CONFIG_IP_NF_NAT=y +CONFIG_IP_NF_TARGET_MASQUERADE=y +CONFIG_IP_NF_TARGET_NETMAP=y +CONFIG_IP_NF_TARGET_REDIRECT=y +CONFIG_IP_NF_MANGLE=y +CONFIG_IP_NF_RAW=y +CONFIG_IP_NF_SECURITY=y +CONFIG_IP_NF_ARPTABLES=y +CONFIG_IP_NF_ARPFILTER=y +CONFIG_IP_NF_ARP_MANGLE=y +CONFIG_NF_CONNTRACK_IPV6=y +CONFIG_IP6_NF_IPTABLES=y +CONFIG_IP6_NF_MATCH_RPFILTER=y +CONFIG_IP6_NF_FILTER=y +CONFIG_IP6_NF_TARGET_REJECT=y +CONFIG_IP6_NF_MANGLE=y +CONFIG_IP6_NF_RAW=y +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_HTB=y +CONFIG_NET_SCH_PRIO=y +CONFIG_NET_CLS_FW=y +CONFIG_NET_CLS_U32=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_FLOW=y +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_CMP=y +CONFIG_NET_EMATCH_NBYTE=y +CONFIG_NET_EMATCH_U32=y +CONFIG_NET_EMATCH_META=y +CONFIG_NET_EMATCH_TEXT=y +CONFIG_NET_CLS_ACT=y +CONFIG_QRTR=y +CONFIG_NTAG_NQ=y +CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y +CONFIG_DMA_CMA=y +CONFIG_MTD=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_MSM_QPIC_NAND=y +CONFIG_MTD_NAND=y +CONFIG_MTD_UBI=y +CONFIG_ZRAM=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_QSEECOM=y +CONFIG_UID_SYS_STATS=y +CONFIG_QPNP_MISC=y +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_SG=y +CONFIG_CHR_DEV_SCH=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_UFSHCD=y +CONFIG_SCSI_UFSHCD_PLATFORM=y +CONFIG_SCSI_UFS_QCOM=y +CONFIG_SCSI_UFSHCD_CMD_LOGGING=y +CONFIG_MD=y +CONFIG_BLK_DEV_DM=y +CONFIG_DM_CRYPT=y +CONFIG_DM_VERITY=y +CONFIG_DM_VERITY_FEC=y +CONFIG_NETDEVICES=y +CONFIG_DUMMY=y +CONFIG_AT803X_PHY=y +CONFIG_USB_USBNET=y +CONFIG_USB_NET_SMSC75XX=y +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_EVBUG=m +CONFIG_INPUT_KEYRESET=y +CONFIG_KEYBOARD_GPIO=y +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_JOYSTICK=y +CONFIG_JOYSTICK_XPAD=y +CONFIG_INPUT_TABLET=y +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_ATMEL_MXT=y +CONFIG_INPUT_MISC=y +CONFIG_INPUT_QPNP_POWER_ON=y +CONFIG_INPUT_UINPUT=y +CONFIG_INPUT_GPIO=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVMEM is not set +CONFIG_SERIAL_MSM=y +CONFIG_SERIAL_MSM_CONSOLE=y +CONFIG_SERIAL_MSM_HS=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_MSM_LEGACY=y +CONFIG_DIAG_CHAR=y +CONFIG_MSM_ADSPRPC=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MSM_V2=y +CONFIG_SPI=y +CONFIG_SPI_DEBUG=y +CONFIG_SPI_QUP=y +CONFIG_SPI_SPIDEV=y +CONFIG_SPMI=y +CONFIG_SPMI_MSM_PMIC_ARB_DEBUG=y +CONFIG_PTP_1588_CLOCK=y +CONFIG_PINCTRL_QCS405=y +CONFIG_FRAGMENTED_GPIO_ADDRESS_SPACE=y +CONFIG_PINCTRL_QCOM_SPMI_PMIC=y +CONFIG_GPIO_SYSFS=y +CONFIG_POWER_RESET_QCOM=y +CONFIG_QCOM_DLOAD_MODE=y +CONFIG_THERMAL=y +CONFIG_THERMAL_WRITABLE_TRIPS=y +CONFIG_THERMAL_GOV_USER_SPACE=y +CONFIG_THERMAL_GOV_LOW_LIMITS=y +CONFIG_CPU_THERMAL=y +CONFIG_DEVFREQ_THERMAL=y +CONFIG_QCOM_SPMI_TEMP_ALARM=y +CONFIG_THERMAL_TSENS=y +CONFIG_QTI_VIRTUAL_SENSOR=y +CONFIG_QTI_QMI_COOLING_DEVICE=y +CONFIG_REGULATOR_COOLING_DEVICE=y +CONFIG_QTI_ADC_TM=y +CONFIG_QTI_RPM_SMD_COOLING_DEVICE=y +CONFIG_MFD_SPMI_PMIC=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_FAN53555=y +CONFIG_REGULATOR_CPR=y +CONFIG_REGULATOR_MEM_ACC=y +CONFIG_REGULATOR_RPM_SMD=y +CONFIG_REGULATOR_SPM=y +CONFIG_REGULATOR_STUB=y +CONFIG_RC_DEVICES=y +CONFIG_IR_MSM_GENI=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_RADIO_SUPPORT=y +CONFIG_MEDIA_CONTROLLER=y +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_USB_AUDIO=y +CONFIG_SND_SOC=y +CONFIG_HIDRAW=y +CONFIG_UHID=y +CONFIG_HID_APPLE=y +CONFIG_HID_ELECOM=y +CONFIG_HID_MAGICMOUSE=y +CONFIG_HID_MICROSOFT=y +CONFIG_HID_MULTITOUCH=y +CONFIG_USB_HIDDEV=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +CONFIG_USB_MON=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_ACM=y +CONFIG_USB_STORAGE=y +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_ALAUDA=y +CONFIG_USB_STORAGE_KARMA=y +CONFIG_USB_STORAGE_CYPRESS_ATACB=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_MSM=y +CONFIG_USB_SERIAL=y +CONFIG_USB_EHSET_TEST_FIXTURE=y +CONFIG_USB_LINK_LAYER_TEST=y +CONFIG_USB_TYPEC_MUX_NXP5150A=y +CONFIG_USB_QCOM_DIAG_BRIDGE=y +CONFIG_NOP_USB_XCEIV=y +CONFIG_MSM_SNPS_FEMTO_PHY=y +CONFIG_USB_MSM_SSPHY=y +CONFIG_USB_QCOM_EMU_PHY=y +CONFIG_DUAL_ROLE_USB_INTF=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_DEBUG_FILES=y +CONFIG_USB_GADGET_DEBUG_FS=y +CONFIG_USB_GADGET_VBUS_DRAW=900 +CONFIG_USB_CONFIGFS=y +CONFIG_USB_CONFIGFS_F_FS=y +CONFIG_USB_CONFIGFS_UEVENT=y +CONFIG_USB_CONFIGFS_F_DIAG=y +CONFIG_MMC=y +CONFIG_MMC_PERF_PROFILING=y +CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_BLOCK_DEFERRED_RESUME=y +CONFIG_MMC_TEST=m +CONFIG_MMC_RING_BUFFER=y +CONFIG_MMC_PARANOID_SD_INIT=y +CONFIG_MMC_CLKGATE=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_MSM=y +CONFIG_MMC_SDHCI_MSM_ICE=y +CONFIG_MMC_CQ_HCI=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_PCA9956B=y +CONFIG_LEDS_TRIGGERS=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_QPNP=y +CONFIG_DMADEVICES=y +CONFIG_QCOM_SPS_DMA=y +CONFIG_UIO=y +CONFIG_STAGING=y +CONFIG_ASHMEM=y +CONFIG_ION=y +CONFIG_QPNP_REVID=y +CONFIG_SPS=y +CONFIG_SPS_SUPPORT_NDP_BAM=y +CONFIG_QCOM_CLK_SMD_RPM=y +CONFIG_SPMI_PMIC_CLKDIV=y +CONFIG_MDM_DEBUGCC_QCS405=y +CONFIG_CLOCK_CPU_QCS405=y +CONFIG_QCS_CMN_BLK_PLL=y +CONFIG_HWSPINLOCK=y +CONFIG_HWSPINLOCK_QCOM=y +CONFIG_ARM_ARCH_TIMER_VCT_ACCESS=y +CONFIG_MAILBOX=y +CONFIG_QCOM_APCS_IPC=y +CONFIG_ARM_SMMU=y +CONFIG_QCOM_LAZY_MAPPING=y +CONFIG_IOMMU_DEBUG=y +CONFIG_IOMMU_DEBUG_TRACKING=y +CONFIG_IOMMU_TESTS=y +CONFIG_RPMSG_CHAR=y +CONFIG_RPMSG_QCOM_GLINK_RPM=y +CONFIG_RPMSG_QCOM_GLINK_SMEM=y +CONFIG_MSM_RPM_SMD=y +CONFIG_QCOM_CPUSS_DUMP=y +CONFIG_QCOM_QMI_HELPERS=y +CONFIG_QCOM_SMEM=y +CONFIG_QCOM_SMD_RPM=y +CONFIG_MSM_SPM=y +CONFIG_MSM_L2_SPM=y +CONFIG_QCOM_SCM=y +CONFIG_QCOM_MEMORY_DUMP_V2=y +CONFIG_MSM_DEBUG_LAR_UNLOCK=y +CONFIG_QCOM_WATCHDOG_V2=y +CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y +CONFIG_QCOM_WDOG_IPI_ENABLE=y +CONFIG_QCOM_SMP2P=y +CONFIG_MSM_SERVICE_LOCATOR=y +CONFIG_MSM_SERVICE_NOTIFIER=y +CONFIG_MSM_SUBSYSTEM_RESTART=y +CONFIG_MSM_PIL=y +CONFIG_MSM_SYSMON_QMI_COMM=y +CONFIG_MSM_PIL_SSR_GENERIC=y +CONFIG_MSM_BOOT_STATS=y +CONFIG_MSM_CORE_HANG_DETECT=y +CONFIG_QCOM_DCC_V2=y +CONFIG_QCOM_BUS_SCALING=y +CONFIG_MSM_TZ_SMMU=y +CONFIG_QCOM_GLINK=y +CONFIG_QCOM_GLINK_PKT=y +CONFIG_QTI_RPM_STATS_LOG=y +CONFIG_MSM_CDSP_LOADER=y +CONFIG_QCOM_SMCINVOKE=y +CONFIG_MSM_PM=y +CONFIG_QCOM_SMP2P_SLEEPSTATE=y +CONFIG_QCOM_BIMC_BWMON=y +CONFIG_ARM_MEMLAT_MON=y +CONFIG_DEVFREQ_GOV_QCOM_BW_HWMON=y +CONFIG_DEVFREQ_GOV_MEMLAT=y +CONFIG_QCOM_DEVFREQ_DEVBW=y +CONFIG_EXTCON_USB_GPIO=y +CONFIG_IIO=y +CONFIG_QCOM_SPMI_ADC5=y +CONFIG_PWM=y +CONFIG_PWM_QTI_LPG=y +CONFIG_QCOM_KGSL=y +CONFIG_QTI_MPM=y +CONFIG_ANDROID=y +CONFIG_ANDROID_BINDER_IPC=y +CONFIG_MSM_TZ_LOG=y +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT3_FS=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_QUOTA=y +CONFIG_QUOTA_NETLINK_INTERFACE=y +# CONFIG_PRINT_QUOTA_WARNING is not set +CONFIG_QFMT_V2=y +CONFIG_FUSE_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_UBIFS_FS=y +CONFIG_UBIFS_FS_ADVANCED_COMPR=y +CONFIG_SQUASHFS=y +CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y +CONFIG_SQUASHFS_XATTR=y +# CONFIG_SQUASHFS_ZLIB is not set +CONFIG_SQUASHFS_XZ=y +CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +CONFIG_PRINTK_TIME=y +CONFIG_DYNAMIC_DEBUG=y +CONFIG_DEBUG_INFO=y +CONFIG_PAGE_OWNER=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_PAGEALLOC=y +CONFIG_SLUB_DEBUG_PANIC_ON=y +CONFIG_DEBUG_PAGEALLOC_ENABLE_DEFAULT=y +CONFIG_PAGE_POISONING=y +CONFIG_PAGE_POISONING_ENABLE_DEFAULT=y +CONFIG_DEBUG_OBJECTS=y +CONFIG_DEBUG_OBJECTS_FREE=y +CONFIG_DEBUG_OBJECTS_TIMERS=y +CONFIG_DEBUG_OBJECTS_WORK=y +CONFIG_DEBUG_OBJECTS_RCU_HEAD=y +CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER=y +CONFIG_SLUB_DEBUG_ON=y +CONFIG_DEBUG_KMEMLEAK=y +CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE=4000 +CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y +CONFIG_DEBUG_STACK_USAGE=y +CONFIG_DEBUG_MEMORY_INIT=y +CONFIG_PANIC_ON_RECURSIVE_FAULT=y +CONFIG_PANIC_ON_OOPS=y +CONFIG_PANIC_TIMEOUT=5 +CONFIG_SCHEDSTATS=y +CONFIG_SCHED_STACK_END_CHECK=y +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_MUTEXES=y +CONFIG_DEBUG_ATOMIC_SLEEP=y +CONFIG_FAULT_INJECTION=y +CONFIG_FAIL_PAGE_ALLOC=y +CONFIG_UFS_FAULT_INJECTION=y +CONFIG_FAULT_INJECTION_DEBUG_FS=y +CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y +CONFIG_IPC_LOGGING=y +CONFIG_QCOM_RTB=y +CONFIG_QCOM_RTB_SEPARATE_CPUS=y +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_LKDTM=y +CONFIG_BUG_ON_DATA_CORRUPTION=y +CONFIG_CORESIGHT=y +CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y +CONFIG_CORESIGHT_SOURCE_ETM4X=y +CONFIG_CORESIGHT_DYNAMIC_REPLICATOR=y +CONFIG_CORESIGHT_STM=y +CONFIG_CORESIGHT_CTI=y +CONFIG_CORESIGHT_TPDA=y +CONFIG_CORESIGHT_TPDM=y +CONFIG_CORESIGHT_HWEVENT=y +CONFIG_CORESIGHT_DUMMY=y +CONFIG_CORESIGHT_REMOTE_ETM=y +CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 +CONFIG_CORESIGHT_EVENT=y +CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y +CONFIG_SECURITY=y +CONFIG_SECURITY_NETWORK=y +CONFIG_LSM_MMAP_MIN_ADDR=4096 +CONFIG_HARDENED_USERCOPY=y +CONFIG_HARDENED_USERCOPY_PAGESPAN=y +CONFIG_SECURITY_SELINUX=y +CONFIG_CRYPTO_CTR=y +CONFIG_CRYPTO_XCBC=y +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_TWOFISH=y +CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y +CONFIG_CRYPTO_DEV_QCRYPTO=y +CONFIG_CRYPTO_DEV_QCEDEV=y +CONFIG_CRYPTO_DEV_QCOM_ICE=y -- GitLab From 1d827b5189ea41ff9a25e35b13cf1a3e050e11af Mon Sep 17 00:00:00 2001 From: Subbaraman Narayanamurthy Date: Wed, 17 Jul 2019 21:08:59 -0700 Subject: [PATCH 0939/1121] power: qpnp-fg-gen4: correct SDAM register used for calibration PBS got changed to use SDAM register 124 instead of 127. Correct it so that calibration can function properly. Change-Id: Ic4393ee4aed0b28d45892cfaf2cf1125e2650237 Signed-off-by: Subbaraman Narayanamurthy --- drivers/power/supply/qcom/qpnp-fg-gen4.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/power/supply/qcom/qpnp-fg-gen4.c b/drivers/power/supply/qcom/qpnp-fg-gen4.c index a1f11bc1eba4..0df0636a034d 100644 --- a/drivers/power/supply/qcom/qpnp-fg-gen4.c +++ b/drivers/power/supply/qcom/qpnp-fg-gen4.c @@ -1029,7 +1029,7 @@ static int fg_gen4_get_prop_soc_scale(struct fg_gen4_chip *chip) return rc; } -#define SDAM1_MEM_127_REG 0xB0BF +#define SDAM1_MEM_124_REG 0xB0BC static int fg_gen4_set_calibrate_level(struct fg_gen4_chip *chip, int val) { struct fg_dev *fg = &chip->fg; @@ -1048,9 +1048,10 @@ static int fg_gen4_set_calibrate_level(struct fg_gen4_chip *chip, int val) return 0; buf = (u8)val; - rc = fg_write(fg, SDAM1_MEM_127_REG, &buf, 1); + rc = fg_write(fg, SDAM1_MEM_124_REG, &buf, 1); if (rc < 0) { - pr_err("Error in writing to 0xB0BF, rc=%d\n", rc); + pr_err("Error in writing to 0x%04X, rc=%d\n", + SDAM1_MEM_124_REG, rc); return rc; } @@ -1061,9 +1062,10 @@ static int fg_gen4_set_calibrate_level(struct fg_gen4_chip *chip, int val) return rc; } - rc = fg_read(fg, SDAM1_MEM_127_REG, &buf, 1); + rc = fg_read(fg, SDAM1_MEM_124_REG, &buf, 1); if (rc < 0) { - pr_err("Error in reading from 0xB0BF, rc=%d\n", rc); + pr_err("Error in reading from 0x%04X, rc=%d\n", + SDAM1_MEM_124_REG, rc); return rc; } -- GitLab From f47a5ae050c25b2a74c2ff0cf1df350fe8cff078 Mon Sep 17 00:00:00 2001 From: Subbaraman Narayanamurthy Date: Fri, 28 Jun 2019 18:44:14 -0700 Subject: [PATCH 0940/1121] ARM: dts: msm: add PBS device for PM8150B Add PBS device for PM8150B and configure PM8150B FG device to obtain it for making specific configurations. Change-Id: I2be74b1dcfb3618ef84a992b575f76406480d010 Signed-off-by: Subbaraman Narayanamurthy --- arch/arm64/boot/dts/qcom/pm8150b.dtsi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/pm8150b.dtsi b/arch/arm64/boot/dts/qcom/pm8150b.dtsi index 6e5d35a6e67c..2c1cea2daef5 100644 --- a/arch/arm64/boot/dts/qcom/pm8150b.dtsi +++ b/arch/arm64/boot/dts/qcom/pm8150b.dtsi @@ -55,6 +55,11 @@ clock-names = "xo"; }; + pm8150b_pbs1: qcom,pbs@7200 { + compatible = "qcom,qpnp-pbs"; + reg = <0x7200 0x100>; + }; + pm8150b_qnovo: qcom,sdam-qnovo@b000 { compatible = "qcom,qpnp-qnovo5"; reg = <0xb000 0x100>; @@ -382,6 +387,7 @@ #address-cells = <1>; #size-cells = <1>; qcom,pmic-revid = <&pm8150b_revid>; + qcom,pmic-pbs = <&pm8150b_pbs1>; status = "okay"; qcom,fg-batt-soc@4000 { -- GitLab From fe8f4c343d5389d34aa5f10e44be26c4513bd2e6 Mon Sep 17 00:00:00 2001 From: Ajay Agarwal Date: Fri, 19 Jul 2019 12:14:13 +0530 Subject: [PATCH 0941/1121] usb: quirk: add no-LPM quirk on Kingston DataTraveler 3.0 drive Kingston DataTraveler drive disconnects on repeated USB2 HW LPM commands from the host PC. Add no-LPM quirk for this drive to get it working seamlessly. Change-Id: I856c49f8ddcea188aa9087379da540b944975f2a Signed-off-by: Ajay Agarwal --- drivers/usb/core/quirks.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 733479ddf8a7..7104cc76d216 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -282,6 +282,9 @@ static const struct usb_device_id usb_quirk_list[] = { /* DJI CineSSD */ { USB_DEVICE(0x2ca3, 0x0031), .driver_info = USB_QUIRK_NO_LPM }, + /* Kingston DataTraveler 3.0 */ + { USB_DEVICE(0x0951, 0x1666), .driver_info = USB_QUIRK_NO_LPM }, + /* INTEL VALUE SSD */ { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, -- GitLab From 96289c798cefec3b8f320f6f7daf5c58726f913a Mon Sep 17 00:00:00 2001 From: Deepak Kumar Singh Date: Wed, 3 Jul 2019 15:22:09 +0530 Subject: [PATCH 0942/1121] rpmsg: glink: Resource cleanup on glink native probe fail When glink probe fails before completion, allocated resources are not freed properly before return. Freeing up allocated resources before return, in case of glink probe failure before completion. CRs-Fixed: 2482441 Change-Id: I65e638b7210117301ba761b63a548f9e0bbf1501 Signed-off-by: Deepak Kumar Singh --- drivers/rpmsg/qcom_glink_native.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c index f121bd9fbc13..ee66de996d33 100644 --- a/drivers/rpmsg/qcom_glink_native.c +++ b/drivers/rpmsg/qcom_glink_native.c @@ -1960,6 +1960,7 @@ struct qcom_glink *qcom_glink_native_probe(struct device *dev, if (IS_ERR(glink->task)) { dev_err(dev, "failed to spawn intent kthread %ld\n", PTR_ERR(glink->task)); + mbox_free_channel(glink->mbox_chan); return ERR_CAST(glink->task); } @@ -2010,6 +2011,8 @@ struct qcom_glink *qcom_glink_native_probe(struct device *dev, unregister: subsys_unregister_early_notifier(glink->name, XPORT_LAYER_NOTIF); + kthread_stop(glink->task); + mbox_free_channel(glink->mbox_chan); return ERR_PTR(ret); } EXPORT_SYMBOL_GPL(qcom_glink_native_probe); -- GitLab From 28b05f5b499d2ef99eb2effdb7585597ee23e1e9 Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Mon, 8 Jul 2019 17:54:39 -0700 Subject: [PATCH 0943/1121] usb: dwc3: Allocate and free TRB buffers from ep ops Move TRB buffer allocation under GSI_EP_OP_PREPARE_TRBS ep operation. Similarly free TRB buffers under GSI_EP_OP_FREE_TRBS ep operation. This simplifies to make decision if TRB and buffer allocation needs to come from cached or non-cached memory region. Change-Id: Ife4203060ea8092c16a9d2cd92016fa7f6afb563 Signed-off-by: Hemant Kumar Signed-off-by: Chandana Kishori Chiluveru --- drivers/usb/dwc3/dwc3-msm.c | 39 ++++++++- drivers/usb/gadget/function/f_gsi.c | 131 ++-------------------------- 2 files changed, 40 insertions(+), 130 deletions(-) diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index dca0673a5f2a..670ffffdf6d1 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -1121,7 +1121,7 @@ static void gsi_endxfer_for_ep(struct usb_ep *ep) } /** - * Allocates and configures TRBs for GSI EPs. + * Allocates Buffers and TRBs. Configures TRBs for GSI EPs. * * @usb_ep - pointer to usb_ep instance. * @request - pointer to GSI request. @@ -1131,7 +1131,8 @@ static void gsi_endxfer_for_ep(struct usb_ep *ep) static int gsi_prepare_trbs(struct usb_ep *ep, struct usb_gsi_request *req) { int i = 0; - dma_addr_t buffer_addr = req->dma; + size_t len; + dma_addr_t buffer_addr; struct dwc3_ep *dep = to_dwc3_ep(ep); struct dwc3 *dwc = dep->dwc; struct dwc3_trb *trb; @@ -1145,6 +1146,24 @@ static int gsi_prepare_trbs(struct usb_ep *ep, struct usb_gsi_request *req) return -ESHUTDOWN; } + /* Allocate TRB buffers */ + + len = req->buf_len * req->num_bufs; + req->buf_base_addr = dma_zalloc_coherent(dwc->sysdev, len, &req->dma, + GFP_KERNEL); + if (!req->buf_base_addr) { + dev_err(dwc->dev, "%s: buf_base_addr allocate failed %s\n", + dep->name); + return -ENOMEM; + } + + dma_get_sgtable(dwc->sysdev, &req->sgt_data_buff, req->buf_base_addr, + req->dma, len); + + buffer_addr = req->dma; + + /* Allocate and configgure TRBs */ + dep->trb_pool = dma_zalloc_coherent(dwc->sysdev, num_trbs * sizeof(struct dwc3_trb), &dep->trb_pool_dma, GFP_KERNEL); @@ -1152,7 +1171,7 @@ static int gsi_prepare_trbs(struct usb_ep *ep, struct usb_gsi_request *req) if (!dep->trb_pool) { dev_err(dep->dwc->dev, "failed to alloc trb dma pool for %s\n", dep->name); - return -ENOMEM; + goto free_trb_buffer; } dep->num_trbs = num_trbs; @@ -1249,10 +1268,16 @@ static int gsi_prepare_trbs(struct usb_ep *ep, struct usb_gsi_request *req) } return 0; + +free_trb_buffer: + dma_free_coherent(dwc->sysdev, len, req->buf_base_addr, req->dma); + req->buf_base_addr = NULL; + sg_free_table(&req->sgt_data_buff); + return -ENOMEM; } /** - * Frees TRBs for GSI EPs. + * Frees TRBs and buffers for GSI EPs. * * @usb_ep - pointer to usb_ep instance. * @@ -1275,6 +1300,12 @@ static void gsi_free_trbs(struct usb_ep *ep, struct usb_gsi_request *req) dep->trb_pool_dma = 0; } sg_free_table(&req->sgt_trb_xfer_ring); + + /* free TRB buffers */ + dma_free_coherent(dwc->sysdev, req->buf_len * req->num_bufs, + req->buf_base_addr, req->dma); + req->buf_base_addr = NULL; + sg_free_table(&req->sgt_data_buff); } /** * Configures GSI EPs. For GSI EPs we need to set interrupter numbers. diff --git a/drivers/usb/gadget/function/f_gsi.c b/drivers/usb/gadget/function/f_gsi.c index b7569bdfa89a..cb955bd3c1bd 100644 --- a/drivers/usb/gadget/function/f_gsi.c +++ b/drivers/usb/gadget/function/f_gsi.c @@ -74,8 +74,6 @@ static DEFINE_IDA(gsi_ida); static void gsi_rndis_ipa_reset_trigger(struct gsi_data_port *d_port); static void ipa_disconnect_handler(struct gsi_data_port *d_port); static int gsi_ctrl_send_notification(struct f_gsi *gsi); -static int gsi_alloc_trb_buffer(struct f_gsi *gsi); -static void gsi_free_trb_buffer(struct f_gsi *gsi); static struct gsi_ctrl_pkt *gsi_ctrl_pkt_alloc(unsigned int len, gfp_t flags); static void gsi_ctrl_pkt_free(struct gsi_ctrl_pkt *pkt); @@ -551,7 +549,8 @@ static int ipa_connect_channels(struct gsi_data_port *d_port) struct ipa_req_chan_out_params ipa_in_channel_out_params; struct ipa_req_chan_out_params ipa_out_channel_out_params; - log_event_dbg("%s: USB GSI IN OPS", __func__); + log_event_dbg("IN: num_bufs:=%zu, buf_len=%zu\n", + d_port->in_request.num_bufs, d_port->in_request.buf_len); ret = usb_gsi_ep_op(d_port->in_ep, &d_port->in_request, GSI_EP_OP_PREPARE_TRBS); if (ret) { @@ -607,7 +606,9 @@ static int ipa_connect_channels(struct gsi_data_port *d_port) gsi_channel_info.depcmd_hi_addr; if (d_port->out_ep) { - log_event_dbg("%s: USB GSI OUT OPS", __func__); + log_event_dbg("OUT: num_bufs:=%zu, buf_len=%zu\n", + d_port->out_request.num_bufs, + d_port->out_request.buf_len); ret = usb_gsi_ep_op(d_port->out_ep, &d_port->out_request, GSI_EP_OP_PREPARE_TRBS); if (ret) { @@ -836,9 +837,6 @@ static void ipa_disconnect_work_handler(struct gsi_data_port *d_port) if (gsi->d_port.out_ep) usb_gsi_ep_op(gsi->d_port.out_ep, &gsi->d_port.out_request, GSI_EP_OP_FREE_TRBS); - - /* free buffers allocated with each TRB */ - gsi_free_trb_buffer(gsi); } static int ipa_suspend_work_handler(struct gsi_data_port *d_port) @@ -946,14 +944,6 @@ static void ipa_work_handler(struct work_struct *w) usb_gadget_autopm_get(d_port->gadget); log_event_dbg("%s: get = %d", __func__, atomic_read(&gad_dev->power.usage_count)); - /* allocate buffers used with each TRB */ - ret = gsi_alloc_trb_buffer(gsi); - if (ret) { - log_event_err("%s: gsi_alloc_trb_failed\n", - __func__); - usb_gadget_autopm_put_async(d_port->gadget); - break; - } d_port->sm_state = STATE_CONNECT_IN_PROGRESS; log_event_dbg("%s: ST_INIT_EVT_CONN_IN_PROG", @@ -963,7 +953,6 @@ static void ipa_work_handler(struct work_struct *w) if (ret) { log_event_err("%s: ipa_connect_channels failed\n", __func__); - gsi_free_trb_buffer(gsi); usb_gadget_autopm_put_async( d_port->gadget); d_port->sm_state = STATE_INITIALIZED; @@ -985,20 +974,10 @@ static void ipa_work_handler(struct work_struct *w) usb_gadget_autopm_get(d_port->gadget); log_event_dbg("%s: get = %d", __func__, atomic_read(&gad_dev->power.usage_count)); - /* allocate buffers used with each TRB */ - ret = gsi_alloc_trb_buffer(gsi); - if (ret) { - log_event_err("%s: gsi_alloc_trb_failed\n", - __func__); - usb_gadget_autopm_put_async(d_port->gadget); - break; - } - ret = ipa_connect_channels(d_port); if (ret) { log_event_err("%s: ipa_connect_channels failed\n", __func__); - gsi_free_trb_buffer(gsi); usb_gadget_autopm_put_async(d_port->gadget); break; } @@ -2336,106 +2315,6 @@ static int gsi_get_alt(struct usb_function *f, unsigned int intf) return -EINVAL; } -static int gsi_alloc_trb_buffer(struct f_gsi *gsi) -{ - u32 len_in = 0, len_out = 0; - int ret = 0; - struct device *dev; - - log_event_dbg("allocate trb's buffer\n"); - - dev = gsi->d_port.gadget->dev.parent; - if (gsi->d_port.in_ep && !gsi->d_port.in_request.buf_base_addr) { - log_event_dbg("IN: num_bufs:=%zu, buf_len=%zu\n", - gsi->d_port.in_request.num_bufs, - gsi->d_port.in_request.buf_len); - - len_in = gsi->d_port.in_request.buf_len * - gsi->d_port.in_request.num_bufs; - gsi->d_port.in_request.buf_base_addr = - dma_zalloc_coherent(dev->parent, - len_in, &gsi->d_port.in_request.dma, GFP_KERNEL); - if (!gsi->d_port.in_request.buf_base_addr) { - dev_err(&gsi->d_port.gadget->dev, - "IN buf_base_addr allocate failed %s\n", - gsi->function.name); - ret = -ENOMEM; - goto fail1; - } - - dma_get_sgtable(dev->parent, - &gsi->d_port.in_request.sgt_data_buff, - gsi->d_port.in_request.buf_base_addr, - gsi->d_port.in_request.dma, len_in); - } - - if (gsi->d_port.out_ep && !gsi->d_port.out_request.buf_base_addr) { - log_event_dbg("OUT: num_bufs:=%zu, buf_len=%zu\n", - gsi->d_port.out_request.num_bufs, - gsi->d_port.out_request.buf_len); - - len_out = gsi->d_port.out_request.buf_len * - gsi->d_port.out_request.num_bufs; - gsi->d_port.out_request.buf_base_addr = - dma_zalloc_coherent(dev->parent, - len_out, &gsi->d_port.out_request.dma, GFP_KERNEL); - if (!gsi->d_port.out_request.buf_base_addr) { - dev_err(&gsi->d_port.gadget->dev, - "OUT buf_base_addr allocate failed %s\n", - gsi->function.name); - ret = -ENOMEM; - goto fail; - } - - dma_get_sgtable(dev->parent, - &gsi->d_port.out_request.sgt_data_buff, - gsi->d_port.out_request.buf_base_addr, - gsi->d_port.out_request.dma, len_out); - } - - log_event_dbg("finished allocating trb's buffer\n"); - return ret; - -fail: - if (len_in && gsi->d_port.in_request.buf_base_addr) { - dma_free_coherent(dev->parent, len_in, - gsi->d_port.in_request.buf_base_addr, - gsi->d_port.in_request.dma); - gsi->d_port.in_request.buf_base_addr = NULL; - } -fail1: - return ret; -} - -static void gsi_free_trb_buffer(struct f_gsi *gsi) -{ - u32 len; - - log_event_dbg("freeing trb's buffer\n"); - - if (gsi->d_port.out_ep && - gsi->d_port.out_request.buf_base_addr) { - len = gsi->d_port.out_request.buf_len * - gsi->d_port.out_request.num_bufs; - dma_free_coherent(gsi->d_port.gadget->dev.parent->parent, len, - gsi->d_port.out_request.buf_base_addr, - gsi->d_port.out_request.dma); - gsi->d_port.out_request.buf_base_addr = NULL; - sg_free_table(&gsi->d_port.out_request.sgt_data_buff); - } - - if (gsi->d_port.in_ep && - gsi->d_port.in_request.buf_base_addr) { - len = gsi->d_port.in_request.buf_len * - gsi->d_port.in_request.num_bufs; - dma_free_coherent(gsi->d_port.gadget->dev.parent->parent, len, - gsi->d_port.in_request.buf_base_addr, - gsi->d_port.in_request.dma); - gsi->d_port.in_request.buf_base_addr = NULL; - sg_free_table(&gsi->d_port.in_request.sgt_data_buff); - } -} - static int gsi_set_alt(struct usb_function *f, unsigned int intf, unsigned int alt) { -- GitLab From 627a1ad8e587d29a087f9fb9c4355b847b308ed3 Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Mon, 1 Jul 2019 11:44:19 -0700 Subject: [PATCH 0944/1121] usb: gadget: Mark usb gsi driver dma memory as cached With this change usb gsi driver specific context bank is marked as cached. This is needed to be in sync with IPA context bank used to map usb iova to PA which is marked as non-cached. Otherwise IPA is accessing the cached memory of USB transfer ring which resulting in to SMMU page fault as the contents of the memory is invalid. IO-Coherency is enabled by default in driver. Change-Id: I04790e155f8e82425d98a3bc1a9d558fccd88bcb Signed-off-by: Hemant Kumar Signed-off-by: Chandana Kishori Chiluveru --- drivers/usb/dwc3/dwc3-msm.c | 39 +++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index 670ffffdf6d1..2d731c3e1a11 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -323,6 +323,7 @@ struct dwc3_msm { enum usb_device_speed override_usb_speed; u32 *gsi_reg; int gsi_reg_offset_cnt; + bool gsi_io_coherency_disabled; struct notifier_block dpdm_nb; struct regulator *dpdm_reg; @@ -1132,9 +1133,11 @@ static int gsi_prepare_trbs(struct usb_ep *ep, struct usb_gsi_request *req) { int i = 0; size_t len; + unsigned long dma_attr; dma_addr_t buffer_addr; struct dwc3_ep *dep = to_dwc3_ep(ep); struct dwc3 *dwc = dep->dwc; + struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent); struct dwc3_trb *trb; int num_trbs = (dep->direction) ? (2 * (req->num_bufs) + 2) : (req->num_bufs + 2); @@ -1146,11 +1149,16 @@ static int gsi_prepare_trbs(struct usb_ep *ep, struct usb_gsi_request *req) return -ESHUTDOWN; } + if (mdwc->gsi_io_coherency_disabled) + dma_attr = DMA_ATTR_FORCE_NON_COHERENT; + else + dma_attr = DMA_ATTR_FORCE_COHERENT; + /* Allocate TRB buffers */ len = req->buf_len * req->num_bufs; - req->buf_base_addr = dma_zalloc_coherent(dwc->sysdev, len, &req->dma, - GFP_KERNEL); + req->buf_base_addr = dma_alloc_attrs(dwc->sysdev, len, &req->dma, + GFP_KERNEL, dma_attr); if (!req->buf_base_addr) { dev_err(dwc->dev, "%s: buf_base_addr allocate failed %s\n", dep->name); @@ -1164,9 +1172,9 @@ static int gsi_prepare_trbs(struct usb_ep *ep, struct usb_gsi_request *req) /* Allocate and configgure TRBs */ - dep->trb_pool = dma_zalloc_coherent(dwc->sysdev, + dep->trb_pool = dma_alloc_attrs(dwc->sysdev, num_trbs * sizeof(struct dwc3_trb), - &dep->trb_pool_dma, GFP_KERNEL); + &dep->trb_pool_dma, GFP_KERNEL, dma_attr); if (!dep->trb_pool) { dev_err(dep->dwc->dev, "failed to alloc trb dma pool for %s\n", @@ -1270,7 +1278,8 @@ static int gsi_prepare_trbs(struct usb_ep *ep, struct usb_gsi_request *req) return 0; free_trb_buffer: - dma_free_coherent(dwc->sysdev, len, req->buf_base_addr, req->dma); + dma_free_attrs(dwc->sysdev, len, req->buf_base_addr, req->dma, + dma_attr); req->buf_base_addr = NULL; sg_free_table(&req->sgt_data_buff); return -ENOMEM; @@ -1286,24 +1295,30 @@ static void gsi_free_trbs(struct usb_ep *ep, struct usb_gsi_request *req) { struct dwc3_ep *dep = to_dwc3_ep(ep); struct dwc3 *dwc = dep->dwc; + struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent); + unsigned long dma_attr; if (dep->endpoint.ep_type == EP_TYPE_NORMAL) return; + if (mdwc->gsi_io_coherency_disabled) + dma_attr = DMA_ATTR_FORCE_NON_COHERENT; + else + dma_attr = DMA_ATTR_FORCE_COHERENT; + /* Free TRBs and TRB pool for EP */ if (dep->trb_pool_dma) { - dma_free_coherent(dwc->sysdev, + dma_free_attrs(dwc->sysdev, dep->num_trbs * sizeof(struct dwc3_trb), - dep->trb_pool, - dep->trb_pool_dma); + dep->trb_pool, dep->trb_pool_dma, dma_attr); dep->trb_pool = NULL; dep->trb_pool_dma = 0; } sg_free_table(&req->sgt_trb_xfer_ring); /* free TRB buffers */ - dma_free_coherent(dwc->sysdev, req->buf_len * req->num_bufs, - req->buf_base_addr, req->dma); + dma_free_attrs(dwc->sysdev, req->buf_len * req->num_bufs, + req->buf_base_addr, req->dma, dma_attr); req->buf_base_addr = NULL; sg_free_table(&req->sgt_data_buff); } @@ -3732,6 +3747,10 @@ static int dwc3_msm_probe(struct platform_device *pdev) mdwc->use_pdc_interrupts = of_property_read_bool(node, "qcom,use-pdc-interrupts"); + + mdwc->gsi_io_coherency_disabled = of_property_read_bool(node, + "qcom,gsi-disable-io-coherency"); + dwc3_set_notifier(&dwc3_msm_notify_event); ret = dwc3_msm_init_iommu(mdwc); -- GitLab From 813fe8a08840908334fe44450ec9916e27e37844 Mon Sep 17 00:00:00 2001 From: Chandana Kishori Chiluveru Date: Fri, 19 Jul 2019 12:32:00 +0530 Subject: [PATCH 0945/1121] dt-bindings: usb: Add gsi-disable-io-coherency to driver bindings This allows to disable io-coherency in usb gsi for msm-ssusb driver. Change-Id: I63278351f65ce9b117d5e85d783ccb9873a2a0ae Signed-off-by: Chandana Kishori Chiluveru --- Documentation/devicetree/bindings/usb/msm-ssusb.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/msm-ssusb.txt b/Documentation/devicetree/bindings/usb/msm-ssusb.txt index 2beaa9b8dc3e..0c451273a926 100644 --- a/Documentation/devicetree/bindings/usb/msm-ssusb.txt +++ b/Documentation/devicetree/bindings/usb/msm-ssusb.txt @@ -75,6 +75,8 @@ Optional properties : - qcom,gsi-reg-offset: USB GSI wrapper registers offset. It is must to provide this if qcom,num-gsi-evt-buffs property is specified. Check dwc3-msm driver for order and name of register offset need to provide. +- qcom,gsi-disable-io-coherency: IO-coherency is enabled by default in usb gsi driver. + This property disables io-coherency in usb gsi driver. - qcom,pm-qos-latency: This represents max tolerable CPU latency in microsecs, which is used as a vote by driver to get max performance in perf mode. - qcom,smmu-s1-bypass: If present, configure SMMU to bypass stage 1 translation. -- GitLab From e30487306f5af69c62179d560086521e7302e86c Mon Sep 17 00:00:00 2001 From: Rama Aparna Mallavarapu Date: Fri, 15 Mar 2019 16:25:07 -0700 Subject: [PATCH 0946/1121] devfreq: Do not round up bandwidth on BWMON4 devices Currently only BWMON5 devices increment the count for non-zero bandwidth while BWMON4 devices increment the count all the time. This results in a non-zero bandwidth report even when the count is zero for BWMON4 devices leading to unnecessarily higher bandwidth votes. Apply checks similar to BWMON5 devices for BWMON4 monitors as well. Change-Id: I0a2d1c0ed979973966668391a32f63bf2711f981 Signed-off-by: Rama Aparna Mallavarapu --- drivers/devfreq/bimc-bwmon.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/devfreq/bimc-bwmon.c b/drivers/devfreq/bimc-bwmon.c index 698c60000fe8..1c9f77fac738 100644 --- a/drivers/devfreq/bimc-bwmon.c +++ b/drivers/devfreq/bimc-bwmon.c @@ -588,15 +588,16 @@ unsigned long get_zone_count(struct bwmon *m, unsigned int zone, WARN(1, "Invalid\n"); return 0; case MON2: - count = readl_relaxed(MON2_ZONE_MAX(m, zone)) + 1; + count = readl_relaxed(MON2_ZONE_MAX(m, zone)); break; case MON3: count = readl_relaxed(MON3_ZONE_MAX(m, zone)); - if (count) - count++; break; } + if (count) + count++; + return count; } -- GitLab From 792585ff34abd4752c6379c11b7748c422a74179 Mon Sep 17 00:00:00 2001 From: Anirudh Ghayal Date: Thu, 11 Jul 2019 15:58:40 +0530 Subject: [PATCH 0947/1121] power: qpnp-qg: Report SOC in centi-percentage CAPACITY_RAW reports SOC in centi-percentage. In QG use the system SOC as CAPACITY_RAW. Change-Id: I3e51dc34cea5c97a7f901d9981f908e35b8b0fb5 Signed-off-by: Anirudh Ghayal --- drivers/power/supply/qcom/qpnp-qg.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/power/supply/qcom/qpnp-qg.c b/drivers/power/supply/qcom/qpnp-qg.c index f789b9aeebf5..1806d279d84b 100644 --- a/drivers/power/supply/qcom/qpnp-qg.c +++ b/drivers/power/supply/qcom/qpnp-qg.c @@ -1961,6 +1961,9 @@ static int qg_psy_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_CAPACITY: rc = qg_get_battery_capacity(chip, &pval->intval); break; + case POWER_SUPPLY_PROP_CAPACITY_RAW: + pval->intval = chip->sys_soc; + break; case POWER_SUPPLY_PROP_REAL_CAPACITY: rc = qg_get_battery_capacity_real(chip, &pval->intval); break; @@ -2090,6 +2093,7 @@ static int qg_property_is_writeable(struct power_supply *psy, static enum power_supply_property qg_psy_props[] = { POWER_SUPPLY_PROP_CAPACITY, + POWER_SUPPLY_PROP_CAPACITY_RAW, POWER_SUPPLY_PROP_REAL_CAPACITY, POWER_SUPPLY_PROP_TEMP, POWER_SUPPLY_PROP_VOLTAGE_NOW, @@ -2920,7 +2924,7 @@ static int qg_determine_pon_soc(struct qpnp_qg *chip) bool use_pon_ocv = true; unsigned long rtc_sec = 0; u32 ocv_uv = 0, soc = 0, pon_soc = 0, full_soc = 0, cutoff_soc = 0; - u32 shutdown[SDAM_MAX] = {0}; + u32 shutdown[SDAM_MAX] = {0}, soc_raw = 0; char ocv_type[20] = "NONE"; if (!chip->profile_loaded) { @@ -2999,6 +3003,7 @@ static int qg_determine_pon_soc(struct qpnp_qg *chip) use_pon_ocv = false; ocv_uv = shutdown[SDAM_OCV_UV]; soc = shutdown[SDAM_SOC]; + soc_raw = shutdown[SDAM_SOC] * 100; strlcpy(ocv_type, "SHUTDOWN_SOC", 20); qg_dbg(chip, QG_DEBUG_PON, "Using SHUTDOWN_SOC @ PON\n"); @@ -3066,7 +3071,9 @@ static int qg_determine_pon_soc(struct qpnp_qg *chip) soc = DIV_ROUND_UP(((pon_soc - cutoff_soc) * 100), (full_soc - cutoff_soc)); soc = CAP(0, 100, soc); + soc_raw = soc * 100; } else { + soc_raw = pon_soc * 100; soc = pon_soc; } @@ -3080,6 +3087,7 @@ static int qg_determine_pon_soc(struct qpnp_qg *chip) return rc; } + chip->cc_soc = chip->sys_soc = soc_raw; chip->last_adj_ssoc = chip->catch_up_soc = chip->msoc = soc; chip->kdata.param[QG_PON_OCV_UV].data = ocv_uv; chip->kdata.param[QG_PON_OCV_UV].valid = true; -- GitLab From 05b2f9c778022a29c7409645969c45b996e18de0 Mon Sep 17 00:00:00 2001 From: Anirudh Ghayal Date: Thu, 18 Jul 2019 08:45:22 +0530 Subject: [PATCH 0948/1121] power: qpnp-qg: Replace ktime_get with ktime_get_boottime ktime_get_boottime reports the time elapsed across suspend. This is a required for QG where the system can go to suspend across FIFO done events. Change-Id: I3e51dc34cea5c97a7f901d9981f908e35b8b0fb8 Signed-off-by: Anirudh Ghayal --- drivers/power/supply/qcom/qpnp-qg.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/power/supply/qcom/qpnp-qg.c b/drivers/power/supply/qcom/qpnp-qg.c index 1806d279d84b..e9005c457470 100644 --- a/drivers/power/supply/qcom/qpnp-qg.c +++ b/drivers/power/supply/qcom/qpnp-qg.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -378,7 +379,7 @@ static int qg_config_s2_state(struct qpnp_qg *chip, done: qg_master_hold(chip, false); /* FIFO restarted */ - chip->last_fifo_update_time = ktime_get(); + chip->last_fifo_update_time = ktime_get_boottime(); return rc; } @@ -566,7 +567,7 @@ static int qg_process_rt_fifo(struct qpnp_qg *chip) static int process_rt_fifo_data(struct qpnp_qg *chip, bool update_smb) { int rc = 0; - ktime_t now = ktime_get(); + ktime_t now = ktime_get_boottime(); s64 time_delta; /* @@ -611,7 +612,7 @@ static int process_rt_fifo_data(struct qpnp_qg *chip, bool update_smb) goto done; } /* FIFOs restarted */ - chip->last_fifo_update_time = ktime_get(); + chip->last_fifo_update_time = ktime_get_boottime(); /* signal the read thread */ chip->data_ready = true; @@ -1099,7 +1100,7 @@ static int qg_esr_estimate(struct qpnp_qg *chip) goto done; } /* FIFOs restarted */ - chip->last_fifo_update_time = ktime_get(); + chip->last_fifo_update_time = ktime_get_boottime(); if (chip->esr_avg) { chip->kdata.param[QG_ESR].data = chip->esr_avg; @@ -1186,7 +1187,7 @@ static void process_udata_work(struct work_struct *work) #define MAX_FIFO_DELTA_PERCENT 10 static irqreturn_t qg_fifo_update_done_handler(int irq, void *data) { - ktime_t now = ktime_get(); + ktime_t now = ktime_get_boottime(); int rc, hw_delta_ms = 0, margin_ms = 0; u32 fifo_length = 0; s64 time_delta_ms = 0; @@ -3213,7 +3214,7 @@ static int qg_hw_init(struct qpnp_qg *chip) pr_err("Failed to release master, rc=%d\n", rc); return rc; } - chip->last_fifo_update_time = ktime_get(); + chip->last_fifo_update_time = ktime_get_boottime(); if (chip->dt.ocv_timer_expiry_min != -EINVAL) { if (chip->dt.ocv_timer_expiry_min < 2) @@ -4009,7 +4010,7 @@ static int process_suspend(struct qpnp_qg *chip) return rc; } /* FIFOs restarted */ - chip->last_fifo_update_time = ktime_get(); + chip->last_fifo_update_time = ktime_get_boottime(); chip->suspend_data = true; } -- GitLab From b56fde2f9abd44937b0720d1c5937f8e99654b1e Mon Sep 17 00:00:00 2001 From: hangtian Date: Wed, 10 Jul 2019 15:28:14 +0800 Subject: [PATCH 0949/1121] cnss: Add cnss driver to msm-4.14 This is the snapshot of the cnss driver from msm-4.9 commit 7524a2. Change-Id: I1d45b978d6302c28f32777f5a80e313464c0a47a CRs-Fixed: 2487159 Signed-off-by: hangtian --- drivers/net/wireless/Kconfig | 1 + drivers/net/wireless/Makefile | 1 + drivers/net/wireless/cnss/Kconfig | 129 + drivers/net/wireless/cnss/Makefile | 6 + drivers/net/wireless/cnss/cnss_common.c | 450 ++ drivers/net/wireless/cnss/cnss_common.h | 65 + drivers/net/wireless/cnss/cnss_pci.c | 3925 +++++++++++++++++ drivers/net/wireless/cnss/cnss_sdio.c | 1607 +++++++ drivers/net/wireless/cnss/logger/Kconfig | 6 + drivers/net/wireless/cnss/logger/Makefile | 6 + drivers/net/wireless/cnss/logger/debugfs.c | 134 + drivers/net/wireless/cnss/logger/logger.h | 102 + drivers/net/wireless/cnss/logger/main.c | 55 + drivers/net/wireless/cnss/logger/nl_service.c | 476 ++ include/linux/qcomwlan_secif.h | 41 + include/net/cnss.h | 271 ++ 16 files changed, 7275 insertions(+) create mode 100644 drivers/net/wireless/cnss/Kconfig create mode 100644 drivers/net/wireless/cnss/Makefile create mode 100644 drivers/net/wireless/cnss/cnss_common.c create mode 100644 drivers/net/wireless/cnss/cnss_common.h create mode 100644 drivers/net/wireless/cnss/cnss_pci.c create mode 100644 drivers/net/wireless/cnss/cnss_sdio.c create mode 100644 drivers/net/wireless/cnss/logger/Kconfig create mode 100644 drivers/net/wireless/cnss/logger/Makefile create mode 100644 drivers/net/wireless/cnss/logger/debugfs.c create mode 100644 drivers/net/wireless/cnss/logger/logger.h create mode 100644 drivers/net/wireless/cnss/logger/main.c create mode 100644 drivers/net/wireless/cnss/logger/nl_service.c create mode 100644 include/linux/qcomwlan_secif.h create mode 100644 include/net/cnss.h diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index 36144d4eefa0..a368a44232be 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -136,6 +136,7 @@ config CLD_LL_CORE support. source "drivers/net/wireless/cnss2/Kconfig" +source "drivers/net/wireless/cnss/Kconfig" source "drivers/net/wireless/cnss_utils/Kconfig" source "drivers/net/wireless/cnss_genl/Kconfig" diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile index 5386709a8b63..a199c9e037f6 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o obj-$(CONFIG_CNSS2) += cnss2/ +obj-$(CONFIG_CNSS) += cnss/ obj-$(CONFIG_WCNSS_MEM_PRE_ALLOC) += cnss_prealloc/ obj-$(CONFIG_CNSS_UTILS) += cnss_utils/ obj-$(CONFIG_CNSS_GENL) += cnss_genl/ diff --git a/drivers/net/wireless/cnss/Kconfig b/drivers/net/wireless/cnss/Kconfig new file mode 100644 index 000000000000..c18cea7be491 --- /dev/null +++ b/drivers/net/wireless/cnss/Kconfig @@ -0,0 +1,129 @@ +config CNSS + tristate "CNSS driver for wifi module" + select CNSS_UTILS + select CRYPTO + select CRYPTO_HASH + select CRYPTO_BLKCIPHER + ---help--- + This module adds support for the CNSS connectivity subsystem used + for wifi devices based on the QCA AR6320 chipset. + This driver also adds support to integrate WLAN module to subsystem + restart framework. + +config CNSS_SDIO + bool "Enable/disable cnss sdio platform driver for wifi module" + depends on CNSS + depends on MMC + ---help--- + This module adds support for the CNSS wlan module interfaced + with SDIO bus. + This driver also adds support to integrate WLAN module to subsystem + restart framework, power on WLAN chip and registered the WLAN module + as a SDIO client device. + +config CNSS_PCI + bool "Enable/disable cnss pci platform driver for wifi module" + depends on CNSS + depends on PCI + ---help--- + This module adds support for the CNSS wlan module interfaced + with PCIe bus. + This driver also adds support to integrate WLAN module to subsystem + restart framework, power on WLAN chip and registered the WLAN module + as a PCIe client device. + +config CNSS_ASYNC + bool "Enable/disable cnss pci platform driver asynchronous probe" + depends on CNSS_PCI + ---help--- + If enabled, CNSS PCI platform driver would do asynchronous probe. + Using asynchronous probe will allow CNSS PCI platform driver to + probe in parallel with other device drivers and will help to + reduce kernel boot time. + +config CNSS_MAC_BUG + bool "Enable/disable 0-4K memory initialization for QCA6174" + depends on CNSS + ---help--- + If enabled, 0-4K memory is reserved for QCA6174 to address + a MAC HW bug. MAC would do an invalid pointer fetch based on + the data, that was read from 0 to 4K. So fill it with zero's; + to an address for which PCIe root complex would honor the read + without any errors. + +config CLD_DEBUG + bool "Enable/disable CLD debug features" + help + WLAN CLD driver uses this config to enable certain debug features. + Some of the debug features may affect performance or may compromise + on security. + + Say N, if you are building a release kernel for production use. + Only say Y, if you are building a kernel with debug support. + +config CLD_USB_CORE + tristate "Qualcomm Technologies Inc. Core wlan driver for QCA USB interface" + select WIRELESS_EXT + select WEXT_PRIV + select WEXT_CORE + select WEXT_SPY + select NL80211_TESTMODE + ---help--- + This section contains the necessary modules needed to enable the + core WLAN driver for Qualcomm Technologies Inc USB wlan chipset. + Select Y to compile the driver in order to have WLAN functionality + support. + +config CLD_HL_SDIO_CORE + tristate "Qualcomm Technologies Inc. Core wlan driver for QCA SDIO interface" + select WIRELESS_EXT + select WEXT_PRIV + select WEXT_CORE + select WEXT_SPY + select NL80211_TESTMODE + depends on ARCH_QCOM + depends on MMC + +config CLD_LL_CORE + tristate "Qualcomm Technologies Inc. Core wlan driver" + select NL80211_TESTMODE + select WEXT_CORE + select WEXT_PRIV + select WEXT_SPY + select WIRELESS_EXT + ---help--- + This section contains the necessary modules needed to enable the + core WLAN driver for Qualcomm Technologies Inc QCA6174 chipset. + Select Y to compile the driver in order to have WLAN functionality + support. + +config CNSS_SECURE_FW + bool "Enable/Disable Memory Allocation for Secure Firmware Feature" + depends on CNSS + ---help--- + CLD Driver can use this for holding local copy of firmware + binaries which is used for sha crypto computation. + The Memory Allocation is done only if this Config Parameter is + enabled + +config BUS_AUTO_SUSPEND + bool "Enable/Disable Runtime PM support for PCIe based WLAN Drivers" + depends on CNSS + depends on PCI + ---help--- + Runtime Power Management is supported for PCIe based WLAN Drivers. + The features enable cld wlan driver to suspend pcie bus when APPS + is awake based on the driver inactivity with the Firmware. + The Feature uses runtime power management framework from kernel to + track bus access clients and to synchronize the driver activity + during system pm. + This config flag controls the feature per target based. The feature + requires CNSS driver support. + +source "drivers/net/wireless/cnss/logger/Kconfig" + +config WLAN_FEATURE_RX_WAKELOCK + bool "Enable RX wake lock feature" + help + Enable WLAN_FEATURE_HOLD_RX_WAKELOCK which is required to take rx + wakelock when driver receives packets from fw. diff --git a/drivers/net/wireless/cnss/Makefile b/drivers/net/wireless/cnss/Makefile new file mode 100644 index 000000000000..38ad5625ea00 --- /dev/null +++ b/drivers/net/wireless/cnss/Makefile @@ -0,0 +1,6 @@ +# Makefile for CNSS platform driver + +obj-$(CONFIG_CNSS_PCI) += cnss_pci.o +obj-$(CONFIG_CNSS_SDIO) += cnss_sdio.o +obj-$(CONFIG_CNSS) += cnss_common.o +obj-$(CONFIG_CNSS_LOGGER) += logger/ diff --git a/drivers/net/wireless/cnss/cnss_common.c b/drivers/net/wireless/cnss/cnss_common.c new file mode 100644 index 000000000000..c69597ba839c --- /dev/null +++ b/drivers/net/wireless/cnss/cnss_common.c @@ -0,0 +1,450 @@ +/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "cnss_common.h" +#include + +#define AR6320_REV1_VERSION 0x5000000 +#define AR6320_REV1_1_VERSION 0x5000001 +#define AR6320_REV1_3_VERSION 0x5000003 +#define AR6320_REV2_1_VERSION 0x5010000 +#define AR6320_REV3_VERSION 0x5020000 +#define AR6320_REV3_2_VERSION 0x5030000 +#define AR900B_DEV_VERSION 0x1000000 +#define QCA9377_REV1_1_VERSION 0x5020001 + +static struct cnss_fw_files FW_FILES_QCA6174_FW_1_1 = { + "qwlan11.bin", "bdwlan11.bin", "otp11.bin", "utf11.bin", + "utfbd11.bin", "epping11.bin", "evicted11.bin"}; +static struct cnss_fw_files FW_FILES_QCA6174_FW_2_0 = { + "qwlan20.bin", "bdwlan20.bin", "otp20.bin", "utf20.bin", + "utfbd20.bin", "epping20.bin", "evicted20.bin"}; +static struct cnss_fw_files FW_FILES_QCA6174_FW_1_3 = { + "qwlan13.bin", "bdwlan13.bin", "otp13.bin", "utf13.bin", + "utfbd13.bin", "epping13.bin", "evicted13.bin"}; +static struct cnss_fw_files FW_FILES_QCA6174_FW_3_0 = { + "qwlan30.bin", "bdwlan30.bin", "otp30.bin", "utf30.bin", + "utfbd30.bin", "epping30.bin", "evicted30.bin"}; +static struct cnss_fw_files FW_FILES_DEFAULT = { + "qwlan.bin", "bdwlan.bin", "otp.bin", "utf.bin", + "utfbd.bin", "epping.bin", "evicted.bin"}; + +enum cnss_dev_bus_type { + CNSS_BUS_NONE = -1, + CNSS_BUS_PCI, + CNSS_BUS_SDIO +}; + +static DEFINE_MUTEX(unsafe_channel_list_lock); +static DEFINE_MUTEX(dfs_nol_info_lock); + +static struct cnss_unsafe_channel_list { + u16 unsafe_ch_count; + u16 unsafe_ch_list[CNSS_MAX_CH_NUM]; +} unsafe_channel_list; + +static struct cnss_dfs_nol_info { + void *dfs_nol_info; + u16 dfs_nol_info_len; +} dfs_nol_info; + +static enum cnss_cc_src cnss_cc_source = CNSS_SOURCE_CORE; + +int cnss_set_wlan_unsafe_channel(u16 *unsafe_ch_list, u16 ch_count) +{ + mutex_lock(&unsafe_channel_list_lock); + if (!unsafe_ch_list || ch_count > CNSS_MAX_CH_NUM) { + mutex_unlock(&unsafe_channel_list_lock); + return -EINVAL; + } + + unsafe_channel_list.unsafe_ch_count = ch_count; + + if (ch_count != 0) { + memcpy( + (char *)unsafe_channel_list.unsafe_ch_list, + (char *)unsafe_ch_list, ch_count * sizeof(u16)); + } + mutex_unlock(&unsafe_channel_list_lock); + + return 0; +} +EXPORT_SYMBOL(cnss_set_wlan_unsafe_channel); + +int cnss_get_wlan_unsafe_channel( + u16 *unsafe_ch_list, + u16 *ch_count, u16 buf_len) +{ + mutex_lock(&unsafe_channel_list_lock); + if (!unsafe_ch_list || !ch_count) { + mutex_unlock(&unsafe_channel_list_lock); + return -EINVAL; + } + + if (buf_len < (unsafe_channel_list.unsafe_ch_count * sizeof(u16))) { + mutex_unlock(&unsafe_channel_list_lock); + return -ENOMEM; + } + + *ch_count = unsafe_channel_list.unsafe_ch_count; + memcpy( + (char *)unsafe_ch_list, + (char *)unsafe_channel_list.unsafe_ch_list, + unsafe_channel_list.unsafe_ch_count * sizeof(u16)); + mutex_unlock(&unsafe_channel_list_lock); + + return 0; +} +EXPORT_SYMBOL(cnss_get_wlan_unsafe_channel); + +int cnss_wlan_set_dfs_nol(const void *info, u16 info_len) +{ + void *temp; + struct cnss_dfs_nol_info *dfs_info; + + mutex_lock(&dfs_nol_info_lock); + if (!info || !info_len) { + mutex_unlock(&dfs_nol_info_lock); + return -EINVAL; + } + + temp = kmalloc(info_len, GFP_KERNEL); + if (!temp) { + mutex_unlock(&dfs_nol_info_lock); + return -ENOMEM; + } + + memcpy(temp, info, info_len); + dfs_info = &dfs_nol_info; + kfree(dfs_info->dfs_nol_info); + + dfs_info->dfs_nol_info = temp; + dfs_info->dfs_nol_info_len = info_len; + mutex_unlock(&dfs_nol_info_lock); + + return 0; +} +EXPORT_SYMBOL(cnss_wlan_set_dfs_nol); + +int cnss_wlan_get_dfs_nol(void *info, u16 info_len) +{ + int len; + struct cnss_dfs_nol_info *dfs_info; + + mutex_lock(&dfs_nol_info_lock); + if (!info || !info_len) { + mutex_unlock(&dfs_nol_info_lock); + return -EINVAL; + } + + dfs_info = &dfs_nol_info; + + if (!dfs_info->dfs_nol_info || dfs_info->dfs_nol_info_len == 0) { + mutex_unlock(&dfs_nol_info_lock); + return -ENOENT; + } + + len = min(info_len, dfs_info->dfs_nol_info_len); + + memcpy(info, dfs_info->dfs_nol_info, len); + mutex_unlock(&dfs_nol_info_lock); + + return len; +} +EXPORT_SYMBOL(cnss_wlan_get_dfs_nol); + +void cnss_init_work(struct work_struct *work, work_func_t func) +{ + INIT_WORK(work, func); +} +EXPORT_SYMBOL(cnss_init_work); + +void cnss_flush_work(void *work) +{ + struct work_struct *cnss_work = work; + + cancel_work_sync(cnss_work); +} +EXPORT_SYMBOL(cnss_flush_work); + +void cnss_flush_delayed_work(void *dwork) +{ + struct delayed_work *cnss_dwork = dwork; + + cancel_delayed_work_sync(cnss_dwork); +} +EXPORT_SYMBOL(cnss_flush_delayed_work); + +void cnss_pm_wake_lock_init(struct wakeup_source *ws, const char *name) +{ + wakeup_source_init(ws, name); +} +EXPORT_SYMBOL(cnss_pm_wake_lock_init); + +void cnss_pm_wake_lock(struct wakeup_source *ws) +{ + __pm_stay_awake(ws); +} +EXPORT_SYMBOL(cnss_pm_wake_lock); + +void cnss_pm_wake_lock_timeout(struct wakeup_source *ws, ulong msec) +{ + __pm_wakeup_event(ws, msec); +} +EXPORT_SYMBOL(cnss_pm_wake_lock_timeout); + +void cnss_pm_wake_lock_release(struct wakeup_source *ws) +{ + __pm_relax(ws); +} +EXPORT_SYMBOL(cnss_pm_wake_lock_release); + +void cnss_pm_wake_lock_destroy(struct wakeup_source *ws) +{ + wakeup_source_trash(ws); +} +EXPORT_SYMBOL(cnss_pm_wake_lock_destroy); + +void cnss_get_monotonic_boottime(struct timespec *ts) +{ + get_monotonic_boottime(ts); +} +EXPORT_SYMBOL(cnss_get_monotonic_boottime); + +void cnss_get_boottime(struct timespec *ts) +{ + ktime_get_ts(ts); +} +EXPORT_SYMBOL(cnss_get_boottime); + +void cnss_init_delayed_work(struct delayed_work *work, work_func_t func) +{ + INIT_DELAYED_WORK(work, func); +} +EXPORT_SYMBOL(cnss_init_delayed_work); + +int cnss_vendor_cmd_reply(struct sk_buff *skb) +{ + return cfg80211_vendor_cmd_reply(skb); +} +EXPORT_SYMBOL(cnss_vendor_cmd_reply); + +int cnss_set_cpus_allowed_ptr(struct task_struct *task, ulong cpu) +{ + return set_cpus_allowed_ptr(task, cpumask_of(cpu)); +} +EXPORT_SYMBOL(cnss_set_cpus_allowed_ptr); + +/* wlan prop driver cannot invoke show_stack + * function directly, so to invoke this function it + * call wcnss_dump_stack function + */ +void cnss_dump_stack(struct task_struct *task) +{ + show_stack(task, NULL); +} +EXPORT_SYMBOL(cnss_dump_stack); + +struct cnss_dev_platform_ops *cnss_get_platform_ops(struct device *dev) +{ + if (!dev) + return NULL; + else + return dev->platform_data; +} + +int cnss_common_request_bus_bandwidth(struct device *dev, int bandwidth) +{ + struct cnss_dev_platform_ops *pf_ops = cnss_get_platform_ops(dev); + + if (pf_ops && pf_ops->request_bus_bandwidth) + return pf_ops->request_bus_bandwidth(bandwidth); + else + return -EINVAL; +} +EXPORT_SYMBOL(cnss_common_request_bus_bandwidth); + +void *cnss_common_get_virt_ramdump_mem(struct device *dev, unsigned long *size) +{ + struct cnss_dev_platform_ops *pf_ops = cnss_get_platform_ops(dev); + + if (pf_ops && pf_ops->get_virt_ramdump_mem) + return pf_ops->get_virt_ramdump_mem(size); + else + return NULL; +} +EXPORT_SYMBOL(cnss_common_get_virt_ramdump_mem); + +void cnss_common_device_self_recovery(struct device *dev) +{ + struct cnss_dev_platform_ops *pf_ops = cnss_get_platform_ops(dev); + + if (pf_ops && pf_ops->device_self_recovery) + pf_ops->device_self_recovery(); +} +EXPORT_SYMBOL(cnss_common_device_self_recovery); + +void cnss_common_schedule_recovery_work(struct device *dev) +{ + struct cnss_dev_platform_ops *pf_ops = cnss_get_platform_ops(dev); + + if (pf_ops && pf_ops->schedule_recovery_work) + pf_ops->schedule_recovery_work(); +} +EXPORT_SYMBOL(cnss_common_schedule_recovery_work); + +void cnss_common_device_crashed(struct device *dev) +{ + struct cnss_dev_platform_ops *pf_ops = cnss_get_platform_ops(dev); + + if (pf_ops && pf_ops->device_crashed) + pf_ops->device_crashed(); +} +EXPORT_SYMBOL(cnss_common_device_crashed); + +u8 *cnss_common_get_wlan_mac_address(struct device *dev, u32 *num) +{ + struct cnss_dev_platform_ops *pf_ops = cnss_get_platform_ops(dev); + + if (pf_ops && pf_ops->get_wlan_mac_address) + return pf_ops->get_wlan_mac_address(num); + else + return NULL; +} +EXPORT_SYMBOL(cnss_common_get_wlan_mac_address); + +int cnss_common_set_wlan_mac_address( + struct device *dev, const u8 *in, u32 len) +{ + struct cnss_dev_platform_ops *pf_ops = cnss_get_platform_ops(dev); + + if (pf_ops && pf_ops->set_wlan_mac_address) + return pf_ops->set_wlan_mac_address(in, len); + else + return -EINVAL; +} +EXPORT_SYMBOL(cnss_common_set_wlan_mac_address); + +int cnss_power_up(struct device *dev) +{ + struct cnss_dev_platform_ops *pf_ops = cnss_get_platform_ops(dev); + + if (pf_ops && pf_ops->power_up) + return pf_ops->power_up(dev); + else + return -EINVAL; +} +EXPORT_SYMBOL(cnss_power_up); + +int cnss_power_down(struct device *dev) +{ + struct cnss_dev_platform_ops *pf_ops = cnss_get_platform_ops(dev); + + if (pf_ops && pf_ops->power_down) + return pf_ops->power_down(dev); + else + return -EINVAL; +} +EXPORT_SYMBOL(cnss_power_down); + +void cnss_get_qca9377_fw_files(struct cnss_fw_files *pfw_files, + u32 size, u32 tufello_dual_fw) +{ + if (tufello_dual_fw) + memcpy(pfw_files, &FW_FILES_DEFAULT, sizeof(*pfw_files)); + else + memcpy(pfw_files, &FW_FILES_QCA6174_FW_3_0, sizeof(*pfw_files)); +} +EXPORT_SYMBOL(cnss_get_qca9377_fw_files); + +int cnss_get_fw_files_for_target(struct cnss_fw_files *pfw_files, + u32 target_type, u32 target_version) +{ + if (!pfw_files) + return -ENODEV; + + switch (target_version) { + case AR6320_REV1_VERSION: + case AR6320_REV1_1_VERSION: + memcpy(pfw_files, &FW_FILES_QCA6174_FW_1_1, sizeof(*pfw_files)); + break; + case AR6320_REV1_3_VERSION: + memcpy(pfw_files, &FW_FILES_QCA6174_FW_1_3, sizeof(*pfw_files)); + break; + case AR6320_REV2_1_VERSION: + memcpy(pfw_files, &FW_FILES_QCA6174_FW_2_0, sizeof(*pfw_files)); + break; + case AR6320_REV3_VERSION: + case AR6320_REV3_2_VERSION: + memcpy(pfw_files, &FW_FILES_QCA6174_FW_3_0, sizeof(*pfw_files)); + break; + default: + memcpy(pfw_files, &FW_FILES_DEFAULT, sizeof(*pfw_files)); + pr_err("%s default version 0x%X 0x%X", __func__, + target_type, target_version); + break; + } + return 0; +} +EXPORT_SYMBOL(cnss_get_fw_files_for_target); + +void cnss_set_cc_source(enum cnss_cc_src cc_source) +{ + cnss_cc_source = cc_source; +} +EXPORT_SYMBOL(cnss_set_cc_source); + +enum cnss_cc_src cnss_get_cc_source(void) +{ + return cnss_cc_source; +} +EXPORT_SYMBOL(cnss_get_cc_source); + +const char *cnss_wlan_get_evicted_data_file(void) +{ + return FW_FILES_QCA6174_FW_3_0.evicted_data; +} + +int cnss_common_register_tsf_captured_handler(struct device *dev, + irq_handler_t handler, void *ctx) +{ + struct cnss_dev_platform_ops *pf_ops = cnss_get_platform_ops(dev); + + if (pf_ops && pf_ops->register_tsf_captured_handler) + return pf_ops->register_tsf_captured_handler(handler, ctx); + else + return -EINVAL; +} +EXPORT_SYMBOL(cnss_common_register_tsf_captured_handler); + +int cnss_common_unregister_tsf_captured_handler(struct device *dev, + void *ctx) +{ + struct cnss_dev_platform_ops *pf_ops = cnss_get_platform_ops(dev); + + if (pf_ops && pf_ops->unregister_tsf_captured_handler) + return pf_ops->unregister_tsf_captured_handler(ctx); + else + return -EINVAL; +} +EXPORT_SYMBOL(cnss_common_unregister_tsf_captured_handler); diff --git a/drivers/net/wireless/cnss/cnss_common.h b/drivers/net/wireless/cnss/cnss_common.h new file mode 100644 index 000000000000..73c6c19ac000 --- /dev/null +++ b/drivers/net/wireless/cnss/cnss_common.h @@ -0,0 +1,65 @@ +/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _NET_CNSS_COMMON_H_ +#define _NET_CNSS_COMMON_H_ + +/* max 20mhz channel count */ +#define CNSS_MAX_CH_NUM 45 + +struct cnss_cap_tsf_info { + int irq_num; + void *context; + irq_handler_t irq_handler; +}; + +struct cnss_dev_platform_ops { + int (*request_bus_bandwidth)(int bandwidth); + void* (*get_virt_ramdump_mem)(unsigned long *size); + void (*device_self_recovery)(void); + void (*schedule_recovery_work)(void); + void (*device_crashed)(void); + u8 * (*get_wlan_mac_address)(u32 *num); + int (*set_wlan_mac_address)(const u8 *in, u32 len); + int (*power_up)(struct device *dev); + int (*power_down)(struct device *dev); + int (*register_tsf_captured_handler)(irq_handler_t handler, + void *adapter); + int (*unregister_tsf_captured_handler)(void *adapter); +}; + +int cnss_pci_request_bus_bandwidth(int bandwidth); +int cnss_sdio_request_bus_bandwidth(int bandwidth); + +void cnss_sdio_device_crashed(void); +void cnss_pci_device_crashed(void); + +void cnss_pci_device_self_recovery(void); +void cnss_sdio_device_self_recovery(void); + +void *cnss_pci_get_virt_ramdump_mem(unsigned long *size); +void *cnss_sdio_get_virt_ramdump_mem(unsigned long *size); + +void cnss_sdio_schedule_recovery_work(void); +void cnss_pci_schedule_recovery_work(void); + +int cnss_pcie_set_wlan_mac_address(const u8 *in, u32 len); +int cnss_sdio_set_wlan_mac_address(const u8 *in, u32 len); + +u8 *cnss_pci_get_wlan_mac_address(u32 *num); +u8 *cnss_sdio_get_wlan_mac_address(u32 *num); +int cnss_sdio_power_up(struct device *dev); +int cnss_sdio_power_down(struct device *dev); +int cnss_pcie_power_up(struct device *dev); +int cnss_pcie_power_down(struct device *dev); +const char *cnss_wlan_get_evicted_data_file(void); +#endif /* _NET_CNSS_COMMON_H_ */ diff --git a/drivers/net/wireless/cnss/cnss_pci.c b/drivers/net/wireless/cnss/cnss_pci.c new file mode 100644 index 000000000000..05259dd3204a --- /dev/null +++ b/drivers/net/wireless/cnss/cnss_pci.c @@ -0,0 +1,3925 @@ +/* Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "cnss_common.h" + +#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC +#include +#endif + +#define subsys_to_drv(d) container_of(d, struct cnss_data, subsys_desc) + +#define VREG_ON 1 +#define VREG_OFF 0 +#define WLAN_EN_HIGH 1 +#define WLAN_EN_LOW 0 +#define PCIE_LINK_UP 1 +#define PCIE_LINK_DOWN 0 +#define WLAN_BOOTSTRAP_HIGH 1 +#define WLAN_BOOTSTRAP_LOW 0 +#define CNSS_DUMP_FORMAT_VER 0x11 +#define CNSS_DUMP_MAGIC_VER_V2 0x42445953 +#define CNSS_DUMP_NAME "CNSS_WLAN" + +#define QCA6174_VENDOR_ID (0x168C) +#define QCA6174_DEVICE_ID (0x003E) +#define BEELINER_DEVICE_ID (0x0040) +#define QCA6174_REV_ID_OFFSET (0x08) +#define QCA6174_FW_1_1 (0x11) +#define QCA6174_FW_1_3 (0x13) +#define QCA6174_FW_2_0 (0x20) +#define QCA6174_FW_3_0 (0x30) +#define QCA6174_FW_3_2 (0x32) +#define BEELINER_FW (0x00) + +#define QCA6180_VENDOR_ID (0x168C) +#define QCA6180_DEVICE_ID (0x0041) +#define QCA6180_REV_ID_OFFSET (0x08) + +#define WLAN_EN_VREG_NAME "vdd-wlan-en" +#define WLAN_VREG_NAME "vdd-wlan" +#define WLAN_VREG_IO_NAME "vdd-wlan-io" +#define WLAN_VREG_XTAL_NAME "vdd-wlan-xtal" +#define WLAN_VREG_XTAL_AON_NAME "vdd-wlan-xtal-aon" +#define WLAN_VREG_CORE_NAME "vdd-wlan-core" +#define WLAN_VREG_SP2T_NAME "vdd-wlan-sp2t" +#define WLAN_SWREG_NAME "wlan-soc-swreg" +#define WLAN_ANT_SWITCH_NAME "wlan-ant-switch" +#define WLAN_EN_GPIO_NAME "wlan-en-gpio" +#define WLAN_BOOTSTRAP_GPIO_NAME "wlan-bootstrap-gpio" +#define PM_OPTIONS 0 +#define PM_OPTIONS_SUSPEND_LINK_DOWN \ + (MSM_PCIE_CONFIG_NO_CFG_RESTORE | MSM_PCIE_CONFIG_LINKDOWN) +#define PM_OPTIONS_RESUME_LINK_DOWN \ + (MSM_PCIE_CONFIG_NO_CFG_RESTORE) + +#define SOC_SWREG_VOLT_MAX 1200000 +#define SOC_SWREG_VOLT_MIN 1200000 +#define WLAN_ANT_SWITCH_VOLT_MAX 2700000 +#define WLAN_ANT_SWITCH_VOLT_MIN 2700000 +#define WLAN_ANT_SWITCH_CURR 20000 +#define WLAN_VREG_IO_MAX 1800000 +#define WLAN_VREG_IO_MIN 1800000 +#define WLAN_VREG_XTAL_MAX 1800000 +#define WLAN_VREG_XTAL_MIN 1800000 +#define WLAN_VREG_CORE_MAX 1300000 +#define WLAN_VREG_CORE_MIN 1300000 +#define WLAN_VREG_SP2T_MAX 2700000 +#define WLAN_VREG_SP2T_MIN 2700000 + +#define POWER_ON_DELAY 2 +#define WLAN_VREG_IO_DELAY_MIN 100 +#define WLAN_VREG_IO_DELAY_MAX 1000 +#define WLAN_ENABLE_DELAY 10 +#define PCIE_SWITCH_DELAY 20 +#define WLAN_RECOVERY_DELAY 1 +#define PCIE_ENABLE_DELAY 100 +#define WLAN_BOOTSTRAP_DELAY 10 +#define EVICT_BIN_MAX_SIZE (512 * 1024) + +static DEFINE_SPINLOCK(pci_link_down_lock); + +#define FW_NAME_FIXED_LEN (6) +#define MAX_NUM_OF_SEGMENTS (16) +#define MAX_INDEX_FILE_SIZE (512) +#define FW_FILENAME_LENGTH (13) +#define TYPE_LENGTH (4) +#define PER_FILE_DATA (21) +#define MAX_IMAGE_SIZE (2 * 1024 * 1024) +#define FW_IMAGE_FTM (0x01) +#define FW_IMAGE_MISSION (0x02) +#define FW_IMAGE_BDATA (0x03) +#define FW_IMAGE_PRINT (0x04) + +#define SEG_METADATA (0x01) +#define SEG_NON_PAGED (0x02) +#define SEG_LOCKED_PAGE (0x03) +#define SEG_UNLOCKED_PAGE (0x04) +#define SEG_NON_SECURE_DATA (0x05) + +#define BMI_TEST_SETUP (0x09) + +struct cnss_wlan_gpio_info { + char *name; + u32 num; + bool state; + bool init; + bool prop; +}; + +struct cnss_wlan_vreg_info { + struct regulator *wlan_en_reg; + struct regulator *wlan_reg; + struct regulator *soc_swreg; + struct regulator *ant_switch; + struct regulator *wlan_reg_io; + struct regulator *wlan_reg_xtal; + struct regulator *wlan_reg_xtal_aon; + struct regulator *wlan_reg_core; + struct regulator *wlan_reg_sp2t; + bool state; +}; + +struct segment_memory { + dma_addr_t dma_region; + void *cpu_region; + u32 size; +}; + +/* FW image descriptor lists */ +struct image_desc_hdr { + u8 image_id; + u8 reserved[3]; + u32 segments_cnt; +}; + +struct segment_desc { + u8 segment_id; + u8 segment_idx; + u8 flags[2]; + u32 addr_count; + u32 addr_low; + u32 addr_high; +}; + +struct region_desc { + u32 addr_low; + u32 addr_high; + u32 size; + u32 reserved; +}; + +struct index_file { + u32 type; + u32 segment_idx; + u8 file_name[13]; +}; + +struct cnss_dual_wifi { + bool is_dual_wifi_enabled; +}; + +/** + * struct wlan_mac_addr - Structure to hold WLAN MAC Address + * @mac_addr: MAC address + */ +#define MAX_NO_OF_MAC_ADDR 4 +struct cnss_wlan_mac_addr { + u8 mac_addr[MAX_NO_OF_MAC_ADDR][ETH_ALEN]; + u32 no_of_mac_addr_set; +}; + +/* device_info is expected to be fully populated after cnss_config is invoked. + * The function pointer callbacks are expected to be non null as well. + */ +static struct cnss_data { + struct platform_device *pldev; + struct subsys_device *subsys; + struct subsys_desc subsysdesc; + struct cnss_wlan_mac_addr wlan_mac_addr; + bool is_wlan_mac_set; + bool ramdump_dynamic; + struct ramdump_device *ramdump_dev; + unsigned long ramdump_size; + void *ramdump_addr; + phys_addr_t ramdump_phys; + struct msm_dump_data dump_data; + struct cnss_wlan_driver *driver; + struct pci_dev *pdev; + const struct pci_device_id *id; + struct dma_iommu_mapping *smmu_mapping; + bool smmu_s1_bypass; + dma_addr_t smmu_iova_start; + size_t smmu_iova_len; + dma_addr_t smmu_iova_ipa_start; + size_t smmu_iova_ipa_len; + struct cnss_wlan_vreg_info vreg_info; + bool wlan_en_vreg_support; + struct cnss_wlan_gpio_info gpio_info; + bool pcie_link_state; + bool pcie_link_down_ind; + bool pci_register_again; + bool notify_modem_status; + struct pci_saved_state *saved_state; + u16 revision_id; + bool recovery_in_progress; + atomic_t fw_available; + struct codeswap_codeseg_info *cnss_seg_info; + /* Virtual Address of the DMA page */ + void *codeseg_cpuaddr[CODESWAP_MAX_CODESEGS]; + struct cnss_fw_files fw_files; + struct pm_qos_request qos_request; + void *modem_notify_handler; + int modem_current_status; + struct msm_bus_scale_pdata *bus_scale_table; + u32 bus_client; + int current_bandwidth_vote; + void *subsys_handle; + struct esoc_desc *esoc_desc; + struct cnss_platform_cap cap; + struct msm_pcie_register_event event_reg; + struct wakeup_source ws; + u32 recovery_count; + enum cnss_driver_status driver_status; +#ifdef CONFIG_CNSS_SECURE_FW + void *fw_mem; +#endif + u32 device_id; + int fw_image_setup; + u32 bmi_test; + void *fw_cpu; + dma_addr_t fw_dma; + u32 fw_dma_size; + u32 fw_seg_count; + struct segment_memory fw_seg_mem[MAX_NUM_OF_SEGMENTS]; + /* Firmware setup complete lock */ + struct mutex fw_setup_stat_lock; + void *bdata_cpu; + dma_addr_t bdata_dma; + u32 bdata_dma_size; + u32 bdata_seg_count; + struct segment_memory bdata_seg_mem[MAX_NUM_OF_SEGMENTS]; + int wlan_bootstrap_gpio; + atomic_t auto_suspended; + bool monitor_wake_intr; + struct cnss_dual_wifi dual_wifi_info; + struct cnss_dev_platform_ops platform_ops; +} *penv; + +static unsigned int pcie_link_down_panic; +module_param(pcie_link_down_panic, uint, 0600); +MODULE_PARM_DESC(pcie_link_down_panic, + "Trigger kernel panic when PCIe link down is detected"); + +static void cnss_put_wlan_enable_gpio(void) +{ + struct cnss_wlan_gpio_info *gpio_info = &penv->gpio_info; + struct cnss_wlan_vreg_info *vreg_info = &penv->vreg_info; + + if (penv->wlan_en_vreg_support) + regulator_put(vreg_info->wlan_en_reg); + else + gpio_free(gpio_info->num); +} + +static int cnss_wlan_vreg_on(struct cnss_wlan_vreg_info *vreg_info) +{ + int ret; + + if (vreg_info->wlan_reg_core) { + ret = regulator_enable(vreg_info->wlan_reg_core); + if (ret) { + pr_err("%s: regulator enable failed for wlan_reg_core\n", + __func__); + goto error_enable_reg_core; + } + } + + if (vreg_info->wlan_reg_io) { + ret = regulator_enable(vreg_info->wlan_reg_io); + if (ret) { + pr_err("%s: regulator enable failed for wlan_reg_io\n", + __func__); + goto error_enable_reg_io; + } + + usleep_range(WLAN_VREG_IO_DELAY_MIN, WLAN_VREG_IO_DELAY_MAX); + } + + if (vreg_info->wlan_reg_xtal_aon) { + ret = regulator_enable(vreg_info->wlan_reg_xtal_aon); + if (ret) { + pr_err("%s: wlan_reg_xtal_aon enable failed\n", + __func__); + goto error_enable_reg_xtal_aon; + } + } + + if (vreg_info->wlan_reg_xtal) { + ret = regulator_enable(vreg_info->wlan_reg_xtal); + if (ret) { + pr_err("%s: regulator enable failed for wlan_reg_xtal\n", + __func__); + goto error_enable_reg_xtal; + } + } + + ret = regulator_enable(vreg_info->wlan_reg); + if (ret) { + pr_err("%s: regulator enable failed for WLAN power\n", + __func__); + goto error_enable; + } + + if (vreg_info->wlan_reg_sp2t) { + ret = regulator_enable(vreg_info->wlan_reg_sp2t); + if (ret) { + pr_err("%s: regulator enable failed for wlan_reg_sp2t\n", + __func__); + goto error_enable_reg_sp2t; + } + } + + if (vreg_info->ant_switch) { + ret = regulator_enable(vreg_info->ant_switch); + if (ret) { + pr_err("%s: regulator enable failed for ant_switch\n", + __func__); + goto error_enable_ant_switch; + } + } + + if (vreg_info->soc_swreg) { + ret = regulator_enable(vreg_info->soc_swreg); + if (ret) { + pr_err("%s: regulator enable failed for external soc-swreg\n", + __func__); + goto error_enable_soc_swreg; + } + } + + return ret; + +error_enable_soc_swreg: + if (vreg_info->ant_switch) + regulator_disable(vreg_info->ant_switch); +error_enable_ant_switch: + if (vreg_info->wlan_reg_sp2t) + regulator_disable(vreg_info->wlan_reg_sp2t); +error_enable_reg_sp2t: + regulator_disable(vreg_info->wlan_reg); +error_enable: + if (vreg_info->wlan_reg_xtal) + regulator_disable(vreg_info->wlan_reg_xtal); +error_enable_reg_xtal: + if (vreg_info->wlan_reg_xtal_aon) + regulator_disable(vreg_info->wlan_reg_xtal_aon); +error_enable_reg_xtal_aon: + if (vreg_info->wlan_reg_io) + regulator_disable(vreg_info->wlan_reg_io); +error_enable_reg_io: + if (vreg_info->wlan_reg_core) + regulator_disable(vreg_info->wlan_reg_core); +error_enable_reg_core: + return ret; +} + +static int cnss_wlan_vreg_off(struct cnss_wlan_vreg_info *vreg_info) +{ + int ret; + + if (vreg_info->soc_swreg) { + ret = regulator_disable(vreg_info->soc_swreg); + if (ret) { + pr_err("%s: regulator disable failed for external soc-swreg\n", + __func__); + goto error_disable; + } + } + + if (vreg_info->ant_switch) { + ret = regulator_disable(vreg_info->ant_switch); + if (ret) { + pr_err("%s: regulator disable failed for ant_switch\n", + __func__); + goto error_disable; + } + } + + if (vreg_info->wlan_reg_sp2t) { + ret = regulator_disable(vreg_info->wlan_reg_sp2t); + if (ret) { + pr_err("%s: regulator disable failed for wlan_reg_sp2t\n", + __func__); + goto error_disable; + } + } + + ret = regulator_disable(vreg_info->wlan_reg); + if (ret) { + pr_err("%s: regulator disable failed for WLAN power\n", + __func__); + goto error_disable; + } + + if (vreg_info->wlan_reg_xtal) { + ret = regulator_disable(vreg_info->wlan_reg_xtal); + if (ret) { + pr_err("%s: regulator disable failed for wlan_reg_xtal\n", + __func__); + goto error_disable; + } + } + + if (vreg_info->wlan_reg_xtal_aon) { + ret = regulator_disable(vreg_info->wlan_reg_xtal_aon); + if (ret) { + pr_err("%s: wlan_reg_xtal_aon disable failed\n", + __func__); + goto error_disable; + } + } + + if (vreg_info->wlan_reg_io) { + ret = regulator_disable(vreg_info->wlan_reg_io); + if (ret) { + pr_err("%s: regulator disable failed for wlan_reg_io\n", + __func__); + goto error_disable; + } + } + + if (vreg_info->wlan_reg_core) { + ret = regulator_disable(vreg_info->wlan_reg_core); + if (ret) { + pr_err("%s: regulator disable failed for wlan_reg_core\n", + __func__); + goto error_disable; + } + } + +error_disable: + return ret; +} + +static int cnss_wlan_vreg_set(struct cnss_wlan_vreg_info *vreg_info, bool state) +{ + int ret = 0; + + if (vreg_info->state == state) { + pr_debug("Already wlan vreg state is %s\n", + state ? "enabled" : "disabled"); + goto out; + } + + if (state) + ret = cnss_wlan_vreg_on(vreg_info); + else + ret = cnss_wlan_vreg_off(vreg_info); + + if (ret) + goto out; + + pr_debug("%s: wlan vreg is now %s\n", __func__, + state ? "enabled" : "disabled"); + vreg_info->state = state; + +out: + return ret; +} + +static int cnss_wlan_gpio_init(struct cnss_wlan_gpio_info *info) +{ + int ret = 0; + + ret = gpio_request(info->num, info->name); + + if (ret) { + pr_err("can't get gpio %s ret %d\n", info->name, ret); + goto err_gpio_req; + } + + ret = gpio_direction_output(info->num, info->init); + + if (ret) { + pr_err("can't set gpio direction %s ret %d\n", info->name, ret); + goto err_gpio_dir; + } + info->state = info->init; + + return ret; + +err_gpio_dir: + gpio_free(info->num); + +err_gpio_req: + + return ret; +} + +static int cnss_wlan_bootstrap_gpio_init(void) +{ + int ret = 0; + + ret = gpio_request(penv->wlan_bootstrap_gpio, WLAN_BOOTSTRAP_GPIO_NAME); + if (ret) { + pr_err("%s: Can't get GPIO %s, ret = %d\n", + __func__, WLAN_BOOTSTRAP_GPIO_NAME, ret); + goto out; + } + + ret = gpio_direction_output(penv->wlan_bootstrap_gpio, + WLAN_BOOTSTRAP_HIGH); + if (ret) { + pr_err("%s: Can't set GPIO %s direction, ret = %d\n", + __func__, WLAN_BOOTSTRAP_GPIO_NAME, ret); + gpio_free(penv->wlan_bootstrap_gpio); + goto out; + } + + msleep(WLAN_BOOTSTRAP_DELAY); +out: + return ret; +} + +static void cnss_wlan_gpio_set(struct cnss_wlan_gpio_info *info, bool state) +{ + if (!info->prop) + return; + + if (info->state == state) { + pr_debug("Already %s gpio is %s\n", + info->name, state ? "high" : "low"); + return; + } + + gpio_set_value(info->num, state); + info->state = state; + + pr_debug("%s: %s gpio is now %s\n", __func__, + info->name, info->state ? "enabled" : "disabled"); +} + +static int cnss_configure_wlan_en_gpio(bool state) +{ + int ret = 0; + struct cnss_wlan_gpio_info *gpio_info = &penv->gpio_info; + struct cnss_wlan_vreg_info *vreg_info = &penv->vreg_info; + + if (penv->wlan_en_vreg_support) { + if (state) + ret = regulator_enable(vreg_info->wlan_en_reg); + else + ret = regulator_disable(vreg_info->wlan_en_reg); + } else { + cnss_wlan_gpio_set(gpio_info, state); + } + + msleep(WLAN_ENABLE_DELAY); + return ret; +} + +static void cnss_disable_xtal_ldo(struct platform_device *pdev) +{ + struct cnss_wlan_vreg_info *info = &penv->vreg_info; + + if (info->wlan_reg_xtal) { + regulator_disable(info->wlan_reg_xtal); + regulator_put(info->wlan_reg_xtal); + } + + if (info->wlan_reg_xtal_aon) { + regulator_disable(info->wlan_reg_xtal_aon); + regulator_put(info->wlan_reg_xtal_aon); + } +} + +static int cnss_enable_xtal_ldo(struct platform_device *pdev) +{ + int ret = 0; + struct cnss_wlan_vreg_info *info = &penv->vreg_info; + + if (!of_get_property(pdev->dev.of_node, + WLAN_VREG_XTAL_AON_NAME "-supply", NULL)) + goto enable_xtal; + + info->wlan_reg_xtal_aon = regulator_get(&pdev->dev, + WLAN_VREG_XTAL_AON_NAME); + if (IS_ERR(info->wlan_reg_xtal_aon)) { + ret = PTR_ERR(info->wlan_reg_xtal_aon); + pr_err("%s: XTAL AON Regulator get failed err:%d\n", __func__, + ret); + return ret; + } + + ret = regulator_enable(info->wlan_reg_xtal_aon); + if (ret) { + pr_err("%s: VREG_XTAL_ON enable failed\n", __func__); + goto end; + } + +enable_xtal: + + if (!of_get_property(pdev->dev.of_node, + WLAN_VREG_XTAL_NAME "-supply", NULL)) + goto out_disable_xtal_aon; + + info->wlan_reg_xtal = regulator_get(&pdev->dev, WLAN_VREG_XTAL_NAME); + + if (IS_ERR(info->wlan_reg_xtal)) { + ret = PTR_ERR(info->wlan_reg_xtal); + pr_err("%s XTAL Regulator get failed err:%d\n", __func__, ret); + goto out_disable_xtal_aon; + } + + ret = regulator_set_voltage(info->wlan_reg_xtal, WLAN_VREG_XTAL_MIN, + WLAN_VREG_XTAL_MAX); + if (ret) { + pr_err("%s: Set wlan_vreg_xtal failed\n", __func__); + goto out_put_xtal; + } + + ret = regulator_enable(info->wlan_reg_xtal); + if (ret) { + pr_err("%s: Enable wlan_vreg_xtal failed\n", __func__); + goto out_put_xtal; + } + + return 0; + +out_put_xtal: + if (info->wlan_reg_xtal) + regulator_put(info->wlan_reg_xtal); + +out_disable_xtal_aon: + if (info->wlan_reg_xtal_aon) + regulator_disable(info->wlan_reg_xtal_aon); + +end: + if (info->wlan_reg_xtal_aon) + regulator_put(info->wlan_reg_xtal_aon); + + return ret; +} + +static int cnss_get_wlan_enable_gpio( + struct cnss_wlan_gpio_info *gpio_info, + struct platform_device *pdev) +{ + int ret = 0; + struct device *dev = &pdev->dev; + + if (!of_find_property(dev->of_node, gpio_info->name, NULL)) { + gpio_info->prop = false; + return -ENODEV; + } + + gpio_info->prop = true; + ret = of_get_named_gpio(dev->of_node, gpio_info->name, 0); + if (ret >= 0) { + gpio_info->num = ret; + } else { + if (ret == -EPROBE_DEFER) + pr_debug("get WLAN_EN GPIO probe defer\n"); + else + pr_err( + "can't get gpio %s ret %d", gpio_info->name, ret); + } + + ret = cnss_wlan_gpio_init(gpio_info); + if (ret) + pr_err("gpio init failed\n"); + + return ret; +} + +static int cnss_get_wlan_bootstrap_gpio(struct platform_device *pdev) +{ + int ret = 0; + struct device_node *node = (&pdev->dev)->of_node; + + if (!of_find_property(node, WLAN_BOOTSTRAP_GPIO_NAME, NULL)) + return ret; + + penv->wlan_bootstrap_gpio = + of_get_named_gpio(node, WLAN_BOOTSTRAP_GPIO_NAME, 0); + if (penv->wlan_bootstrap_gpio > 0) { + ret = cnss_wlan_bootstrap_gpio_init(); + } else { + ret = penv->wlan_bootstrap_gpio; + pr_err( + "%s: Can't get GPIO %s, ret = %d", + __func__, WLAN_BOOTSTRAP_GPIO_NAME, ret); + } + + return ret; +} + +static int cnss_wlan_get_resources(struct platform_device *pdev) +{ + int ret = 0; + struct cnss_wlan_gpio_info *gpio_info = &penv->gpio_info; + struct cnss_wlan_vreg_info *vreg_info = &penv->vreg_info; + struct device_node *node = pdev->dev.of_node; + + if (of_get_property(node, WLAN_VREG_CORE_NAME "-supply", NULL)) { + vreg_info->wlan_reg_core = regulator_get(&pdev->dev, + WLAN_VREG_CORE_NAME); + if (IS_ERR(vreg_info->wlan_reg_core)) { + ret = PTR_ERR(vreg_info->wlan_reg_core); + + if (ret == -EPROBE_DEFER) { + pr_err("%s: wlan_reg_core probe deferred\n", + __func__); + } else { + pr_err("%s: Get wlan_reg_core failed\n", + __func__); + } + goto err_reg_core_get; + } + + ret = regulator_set_voltage(vreg_info->wlan_reg_core, + WLAN_VREG_CORE_MIN, + WLAN_VREG_CORE_MAX); + if (ret) { + pr_err("%s: Set wlan_reg_core failed\n", __func__); + goto err_reg_core_set; + } + + ret = regulator_enable(vreg_info->wlan_reg_core); + if (ret) { + pr_err("%s: Enable wlan_reg_core failed\n", __func__); + goto err_reg_core_enable; + } + } + + if (of_get_property(node, WLAN_VREG_IO_NAME "-supply", NULL)) { + vreg_info->wlan_reg_io = regulator_get(&pdev->dev, + WLAN_VREG_IO_NAME); + if (!IS_ERR(vreg_info->wlan_reg_io)) { + ret = regulator_set_voltage(vreg_info->wlan_reg_io, + WLAN_VREG_IO_MIN, + WLAN_VREG_IO_MAX); + if (ret) { + pr_err("%s: Set wlan_vreg_io failed\n", + __func__); + goto err_reg_io_set; + } + + ret = regulator_enable(vreg_info->wlan_reg_io); + if (ret) { + pr_err("%s: Enable wlan_vreg_io failed\n", + __func__); + goto err_reg_io_enable; + } + + usleep_range(WLAN_VREG_IO_DELAY_MIN, + WLAN_VREG_IO_DELAY_MAX); + } + } + + if (cnss_enable_xtal_ldo(pdev)) + goto err_reg_xtal_enable; + + vreg_info->wlan_reg = regulator_get(&pdev->dev, WLAN_VREG_NAME); + + if (IS_ERR(vreg_info->wlan_reg)) { + if (PTR_ERR(vreg_info->wlan_reg) == -EPROBE_DEFER) + pr_err("%s: vreg probe defer\n", __func__); + else + pr_err("%s: vreg regulator get failed\n", __func__); + ret = PTR_ERR(vreg_info->wlan_reg); + goto err_reg_get; + } + + ret = regulator_enable(vreg_info->wlan_reg); + + if (ret) { + pr_err("%s: vreg initial vote failed\n", __func__); + goto err_reg_enable; + } + + if (of_get_property(node, WLAN_VREG_SP2T_NAME "-supply", NULL)) { + vreg_info->wlan_reg_sp2t = + regulator_get(&pdev->dev, WLAN_VREG_SP2T_NAME); + if (!IS_ERR(vreg_info->wlan_reg_sp2t)) { + ret = regulator_set_voltage(vreg_info->wlan_reg_sp2t, + WLAN_VREG_SP2T_MIN, + WLAN_VREG_SP2T_MAX); + if (ret) { + pr_err("%s: Set wlan_vreg_sp2t failed\n", + __func__); + goto err_reg_sp2t_set; + } + + ret = regulator_enable(vreg_info->wlan_reg_sp2t); + if (ret) { + pr_err("%s: Enable wlan_vreg_sp2t failed\n", + __func__); + goto err_reg_sp2t_enable; + } + } + } + + if (of_get_property(node, WLAN_ANT_SWITCH_NAME "-supply", NULL)) { + vreg_info->ant_switch = + regulator_get(&pdev->dev, WLAN_ANT_SWITCH_NAME); + if (!IS_ERR(vreg_info->ant_switch)) { + ret = regulator_set_voltage(vreg_info->ant_switch, + WLAN_ANT_SWITCH_VOLT_MIN, + WLAN_ANT_SWITCH_VOLT_MAX); + if (ret < 0) { + pr_err("%s: Set ant_switch voltage failed\n", + __func__); + goto err_ant_switch_set; + } + + ret = regulator_set_load(vreg_info->ant_switch, + WLAN_ANT_SWITCH_CURR); + if (ret < 0) { + pr_err("%s: Set ant_switch current failed\n", + __func__); + goto err_ant_switch_set; + } + + ret = regulator_enable(vreg_info->ant_switch); + if (ret < 0) { + pr_err("%s: Enable ant_switch failed\n", + __func__); + goto err_ant_switch_enable; + } + } + } + + if (of_find_property(node, "qcom,wlan-uart-access", NULL)) + penv->cap.cap_flag |= CNSS_HAS_UART_ACCESS; + + if (of_get_property(node, WLAN_SWREG_NAME "-supply", NULL)) { + vreg_info->soc_swreg = regulator_get(&pdev->dev, + WLAN_SWREG_NAME); + if (IS_ERR(vreg_info->soc_swreg)) { + pr_err("%s: soc-swreg node not found\n", + __func__); + goto err_reg_get2; + } + ret = regulator_set_voltage(vreg_info->soc_swreg, + SOC_SWREG_VOLT_MIN, + SOC_SWREG_VOLT_MAX); + if (ret) { + pr_err("%s: vreg initial voltage set failed on soc-swreg\n", + __func__); + goto err_reg_set; + } + ret = regulator_enable(vreg_info->soc_swreg); + if (ret) { + pr_err("%s: vreg initial vote failed\n", __func__); + goto err_reg_enable2; + } + penv->cap.cap_flag |= CNSS_HAS_EXTERNAL_SWREG; + } + + penv->wlan_en_vreg_support = + of_property_read_bool(node, "qcom,wlan-en-vreg-support"); + if (penv->wlan_en_vreg_support) { + vreg_info->wlan_en_reg = + regulator_get(&pdev->dev, WLAN_EN_VREG_NAME); + if (IS_ERR(vreg_info->wlan_en_reg)) { + pr_err("%s:wlan_en vreg get failed\n", __func__); + ret = PTR_ERR(vreg_info->wlan_en_reg); + goto err_wlan_en_reg_get; + } + } + + if (!penv->wlan_en_vreg_support) { + ret = cnss_get_wlan_enable_gpio(gpio_info, pdev); + if (ret) { + pr_err( + "%s:Failed to config the WLAN_EN gpio\n", __func__); + goto err_gpio_wlan_en; + } + } + vreg_info->state = VREG_ON; + + ret = cnss_get_wlan_bootstrap_gpio(pdev); + if (ret) { + pr_err("%s: Failed to enable wlan bootstrap gpio\n", __func__); + goto err_gpio_wlan_bootstrap; + } + + return ret; + +err_gpio_wlan_bootstrap: + cnss_put_wlan_enable_gpio(); +err_gpio_wlan_en: +err_wlan_en_reg_get: + vreg_info->wlan_en_reg = NULL; + if (vreg_info->soc_swreg) + regulator_disable(vreg_info->soc_swreg); + vreg_info->state = VREG_OFF; + +err_reg_enable2: +err_reg_set: + if (vreg_info->soc_swreg) + regulator_put(vreg_info->soc_swreg); + +err_reg_get2: + if (vreg_info->ant_switch) + regulator_disable(vreg_info->ant_switch); + +err_ant_switch_enable: +err_ant_switch_set: + if (vreg_info->ant_switch) + regulator_put(vreg_info->ant_switch); + if (vreg_info->wlan_reg_sp2t) + regulator_disable(vreg_info->wlan_reg_sp2t); + +err_reg_sp2t_enable: +err_reg_sp2t_set: + if (vreg_info->wlan_reg_sp2t) + regulator_put(vreg_info->wlan_reg_sp2t); + regulator_disable(vreg_info->wlan_reg); + +err_reg_enable: + regulator_put(vreg_info->wlan_reg); +err_reg_get: + cnss_disable_xtal_ldo(pdev); + +err_reg_xtal_enable: + if (vreg_info->wlan_reg_io) + regulator_disable(vreg_info->wlan_reg_io); + +err_reg_io_enable: +err_reg_io_set: + if (vreg_info->wlan_reg_io) + regulator_put(vreg_info->wlan_reg_io); + if (vreg_info->wlan_reg_core) + regulator_disable(vreg_info->wlan_reg_core); + +err_reg_core_enable: +err_reg_core_set: + if (vreg_info->wlan_reg_core) + regulator_put(vreg_info->wlan_reg_core); + +err_reg_core_get: + return ret; +} + +static void cnss_wlan_release_resources(void) +{ + struct cnss_wlan_gpio_info *gpio_info = &penv->gpio_info; + struct cnss_wlan_vreg_info *vreg_info = &penv->vreg_info; + + if (penv->wlan_bootstrap_gpio > 0) + gpio_free(penv->wlan_bootstrap_gpio); + cnss_put_wlan_enable_gpio(); + gpio_info->state = WLAN_EN_LOW; + gpio_info->prop = false; + cnss_wlan_vreg_set(vreg_info, VREG_OFF); + if (vreg_info->soc_swreg) + regulator_put(vreg_info->soc_swreg); + if (vreg_info->ant_switch) + regulator_put(vreg_info->ant_switch); + if (vreg_info->wlan_reg_sp2t) + regulator_put(vreg_info->wlan_reg_sp2t); + regulator_put(vreg_info->wlan_reg); + if (vreg_info->wlan_reg_xtal) + regulator_put(vreg_info->wlan_reg_xtal); + if (vreg_info->wlan_reg_xtal_aon) + regulator_put(vreg_info->wlan_reg_xtal_aon); + if (vreg_info->wlan_reg_io) + regulator_put(vreg_info->wlan_reg_io); + if (vreg_info->wlan_reg_core) + regulator_put(vreg_info->wlan_reg_core); + vreg_info->state = VREG_OFF; +} + +static u8 cnss_get_pci_dev_bus_number(struct pci_dev *pdev) +{ + return pdev->bus->number; +} + +void cnss_setup_fw_files(u16 revision) +{ + switch (revision) { + case QCA6174_FW_1_1: + strlcpy(penv->fw_files.image_file, "qwlan11.bin", + CNSS_MAX_FILE_NAME); + strlcpy(penv->fw_files.board_data, "bdwlan11.bin", + CNSS_MAX_FILE_NAME); + strlcpy(penv->fw_files.otp_data, "otp11.bin", + CNSS_MAX_FILE_NAME); + strlcpy(penv->fw_files.utf_file, "utf11.bin", + CNSS_MAX_FILE_NAME); + strlcpy(penv->fw_files.utf_board_data, "utfbd11.bin", + CNSS_MAX_FILE_NAME); + break; + + case QCA6174_FW_1_3: + strlcpy(penv->fw_files.image_file, "qwlan13.bin", + CNSS_MAX_FILE_NAME); + strlcpy(penv->fw_files.board_data, "bdwlan13.bin", + CNSS_MAX_FILE_NAME); + strlcpy(penv->fw_files.otp_data, "otp13.bin", + CNSS_MAX_FILE_NAME); + strlcpy(penv->fw_files.utf_file, "utf13.bin", + CNSS_MAX_FILE_NAME); + strlcpy(penv->fw_files.utf_board_data, "utfbd13.bin", + CNSS_MAX_FILE_NAME); + break; + + case QCA6174_FW_2_0: + strlcpy(penv->fw_files.image_file, "qwlan20.bin", + CNSS_MAX_FILE_NAME); + strlcpy(penv->fw_files.board_data, "bdwlan20.bin", + CNSS_MAX_FILE_NAME); + strlcpy(penv->fw_files.otp_data, "otp20.bin", + CNSS_MAX_FILE_NAME); + strlcpy(penv->fw_files.utf_file, "utf20.bin", + CNSS_MAX_FILE_NAME); + strlcpy(penv->fw_files.utf_board_data, "utfbd20.bin", + CNSS_MAX_FILE_NAME); + break; + + case QCA6174_FW_3_0: + case QCA6174_FW_3_2: + strlcpy(penv->fw_files.image_file, "qwlan30.bin", + CNSS_MAX_FILE_NAME); + strlcpy(penv->fw_files.board_data, "bdwlan30.bin", + CNSS_MAX_FILE_NAME); + strlcpy(penv->fw_files.otp_data, "otp30.bin", + CNSS_MAX_FILE_NAME); + strlcpy(penv->fw_files.utf_file, "utf30.bin", + CNSS_MAX_FILE_NAME); + strlcpy(penv->fw_files.utf_board_data, "utfbd30.bin", + CNSS_MAX_FILE_NAME); + break; + + default: + strlcpy(penv->fw_files.image_file, "qwlan.bin", + CNSS_MAX_FILE_NAME); + strlcpy(penv->fw_files.board_data, "bdwlan.bin", + CNSS_MAX_FILE_NAME); + strlcpy(penv->fw_files.otp_data, "otp.bin", + CNSS_MAX_FILE_NAME); + strlcpy(penv->fw_files.utf_file, "utf.bin", + CNSS_MAX_FILE_NAME); + strlcpy(penv->fw_files.utf_board_data, "utfbd.bin", + CNSS_MAX_FILE_NAME); + break; + } +} + +int cnss_get_fw_files(struct cnss_fw_files *pfw_files) +{ + if (!penv || !pfw_files) + return -ENODEV; + + *pfw_files = penv->fw_files; + + return 0; +} +EXPORT_SYMBOL(cnss_get_fw_files); + +#ifdef CONFIG_CNSS_SECURE_FW +static void cnss_wlan_fw_mem_alloc(struct pci_dev *pdev) +{ + penv->fw_mem = devm_kzalloc(&pdev->dev, MAX_FIRMWARE_SIZE, GFP_KERNEL); +} +#else +static void cnss_wlan_fw_mem_alloc(struct pci_dev *pdev) +{ +} +#endif + +static int get_image_file(const u8 *index_info, u8 *file_name, + u32 *type, u32 *segment_idx) +{ + if (!file_name || !index_info || !type) + return -EINVAL; + + memcpy(type, index_info, TYPE_LENGTH); + memcpy(segment_idx, index_info + TYPE_LENGTH, TYPE_LENGTH); + memcpy(file_name, index_info + TYPE_LENGTH + TYPE_LENGTH, + FW_FILENAME_LENGTH); + + pr_debug("%u: %u: %s", *type, *segment_idx, file_name); + + return PER_FILE_DATA; +} + +static void print_allocated_image_table(void) +{ + u32 seg = 0, count = 0; + u8 *dump_addr; + struct segment_memory *pseg_mem = penv->fw_seg_mem; + struct segment_memory *p_bdata_seg_mem = penv->bdata_seg_mem; + + pr_debug("%s: Dumping FW IMAGE\n", __func__); + while (seg++ < penv->fw_seg_count) { + dump_addr = (u8 *)pseg_mem->cpu_region + + sizeof(struct region_desc); + for (count = 0; count < pseg_mem->size - + sizeof(struct region_desc); count++) + pr_debug("%02x", dump_addr[count]); + + pseg_mem++; + } + + seg = 0; + pr_debug("%s: Dumping BOARD DATA\n", __func__); + while (seg++ < penv->bdata_seg_count) { + dump_addr = (u8 *)p_bdata_seg_mem->cpu_region + + sizeof(struct region_desc); + for (count = 0; count < p_bdata_seg_mem->size - + sizeof(struct region_desc); count++) + pr_debug("%02x ", dump_addr[count]); + + p_bdata_seg_mem++; + } +} + +static void free_allocated_image_table(void) +{ + struct device *dev = &penv->pdev->dev; + struct segment_memory *pseg_mem; + u32 seg = 0; + + /* free fw memroy */ + pseg_mem = penv->fw_seg_mem; + while (seg++ < penv->fw_seg_count) { + dma_free_coherent(dev, pseg_mem->size, + pseg_mem->cpu_region, pseg_mem->dma_region); + pseg_mem++; + } + if (penv->fw_cpu) + dma_free_coherent(dev, + sizeof(struct segment_desc) * + MAX_NUM_OF_SEGMENTS, + penv->fw_cpu, penv->fw_dma); + penv->fw_seg_count = 0; + penv->fw_dma = 0; + penv->fw_cpu = NULL; + penv->fw_dma_size = 0; + + /* free bdata memory */ + seg = 0; + pseg_mem = penv->bdata_seg_mem; + while (seg++ < penv->bdata_seg_count) { + dma_free_coherent(dev, pseg_mem->size, + pseg_mem->cpu_region, + pseg_mem->dma_region); + pseg_mem++; + } + if (penv->bdata_cpu) + dma_free_coherent(dev, + sizeof(struct segment_desc) * + MAX_NUM_OF_SEGMENTS, + penv->bdata_cpu, penv->bdata_dma); + penv->bdata_seg_count = 0; + penv->bdata_dma = 0; + penv->bdata_cpu = NULL; + penv->bdata_dma_size = 0; +} + +static int cnss_setup_fw_image_table(int mode) +{ + struct image_desc_hdr *image_hdr; + struct segment_desc *pseg = NULL; + const struct firmware *fw_index, *fw_image; + struct device *dev = NULL; + char reserved[3] = ""; + u8 image_file[FW_FILENAME_LENGTH] = ""; + u8 index_file[FW_FILENAME_LENGTH] = ""; + u8 index_info[MAX_INDEX_FILE_SIZE] = ""; + size_t image_desc_size = 0, file_size = 0; + size_t index_pos = 0, image_pos = 0; + struct region_desc *reg_desc = NULL; + u32 type = 0; + u32 segment_idx = 0; + uintptr_t address; + int ret = 0; + dma_addr_t dma_addr; + void *vaddr = NULL; + dma_addr_t paddr; + struct segment_memory *pseg_mem; + u32 *pseg_count; + + if (!penv || !penv->pdev) { + pr_err("cnss: invalid penv or pdev or dev\n"); + ret = -EINVAL; + goto err; + } + dev = &penv->pdev->dev; + + /* meta data file has image details */ + switch (mode) { + case FW_IMAGE_FTM: + ret = scnprintf(index_file, FW_FILENAME_LENGTH, "qftm.bin"); + pseg_mem = penv->fw_seg_mem; + pseg_count = &penv->fw_seg_count; + break; + case FW_IMAGE_MISSION: + ret = scnprintf(index_file, FW_FILENAME_LENGTH, "qwlan.bin"); + pseg_mem = penv->fw_seg_mem; + pseg_count = &penv->fw_seg_count; + break; + case FW_IMAGE_BDATA: + ret = scnprintf(index_file, FW_FILENAME_LENGTH, "bdwlan.bin"); + pseg_mem = penv->bdata_seg_mem; + pseg_count = &penv->bdata_seg_count; + break; + default: + pr_err("%s: Unknown meta data file type 0x%x\n", + __func__, mode); + ret = -EINVAL; + } + if (ret < 0) + goto err; + + image_desc_size = sizeof(struct image_desc_hdr) + + sizeof(struct segment_desc) * MAX_NUM_OF_SEGMENTS; + + vaddr = dma_alloc_coherent(dev, image_desc_size, + &paddr, GFP_KERNEL); + + if (!vaddr) { + pr_err("cnss: image desc allocation failure\n"); + ret = -ENOMEM; + goto err; + } + + memset(vaddr, 0, image_desc_size); + + image_hdr = (struct image_desc_hdr *)vaddr; + image_hdr->image_id = mode; + memcpy(image_hdr->reserved, reserved, 3); + + pr_err("cnss: request meta data file %s\n", index_file); + ret = request_firmware(&fw_index, index_file, dev); + if (ret || !fw_index || !fw_index->data || !fw_index->size) { + pr_err("cnss: meta data file open failure %s\n", index_file); + goto err_free; + } + + if (fw_index->size > MAX_INDEX_FILE_SIZE) { + pr_err("cnss: meta data file has invalid size %s: %zu\n", + index_file, fw_index->size); + release_firmware(fw_index); + goto err_free; + } + + memcpy(index_info, fw_index->data, fw_index->size); + file_size = fw_index->size; + release_firmware(fw_index); + + while (file_size >= PER_FILE_DATA && image_pos < image_desc_size && + image_hdr->segments_cnt < MAX_NUM_OF_SEGMENTS) { + ret = get_image_file(index_info + index_pos, + image_file, &type, &segment_idx); + if (ret == -EINVAL) + goto err_free; + + file_size -= ret; + index_pos += ret; + pseg = vaddr + image_pos + + sizeof(struct image_desc_hdr); + + switch (type) { + case SEG_METADATA: + case SEG_NON_PAGED: + case SEG_LOCKED_PAGE: + case SEG_UNLOCKED_PAGE: + case SEG_NON_SECURE_DATA: + + image_hdr->segments_cnt++; + pseg->segment_id = type; + pseg->segment_idx = (u8)(segment_idx & 0xff); + memcpy(pseg->flags, reserved, 2); + + ret = request_firmware(&fw_image, image_file, dev); + if (ret || !fw_image || !fw_image->data || + !fw_image->size) { + pr_err("cnss: image file read failed %s", + image_file); + goto err_free; + } + if (fw_image->size > MAX_IMAGE_SIZE) { + pr_err("cnss: %s: image file invalid size %zu\n", + image_file, fw_image->size); + release_firmware(fw_image); + ret = -EINVAL; + goto err_free; + } + reg_desc = + dma_alloc_coherent(dev, + sizeof(struct region_desc) + + fw_image->size, + &dma_addr, GFP_KERNEL); + if (!reg_desc) { + pr_err("cnss: region allocation failure\n"); + ret = -ENOMEM; + release_firmware(fw_image); + goto err_free; + } + address = (uintptr_t)dma_addr; + pseg->addr_low = address & 0xFFFFFFFF; + pseg->addr_high = 0x00; + /* one region for one image file */ + pseg->addr_count = 1; + memcpy((u8 *)reg_desc + sizeof(struct region_desc), + fw_image->data, fw_image->size); + address += sizeof(struct region_desc); + reg_desc->addr_low = address & 0xFFFFFFFF; + reg_desc->addr_high = 0x00; + reg_desc->reserved = 0; + reg_desc->size = fw_image->size; + + pseg_mem[*pseg_count].dma_region = dma_addr; + pseg_mem[*pseg_count].cpu_region = reg_desc; + pseg_mem[*pseg_count].size = + sizeof(struct region_desc) + fw_image->size; + + release_firmware(fw_image); + (*pseg_count)++; + break; + + default: + pr_err("cnss: Unknown segment %d", type); + ret = -EINVAL; + goto err_free; + } + image_pos += sizeof(struct segment_desc); + } + if (mode != FW_IMAGE_BDATA) { + penv->fw_cpu = vaddr; + penv->fw_dma = paddr; + penv->fw_dma_size = sizeof(struct image_desc_hdr) + + sizeof(struct segment_desc) * image_hdr->segments_cnt; + } else { + penv->bdata_cpu = vaddr; + penv->bdata_dma = paddr; + penv->bdata_dma_size = sizeof(struct image_desc_hdr) + + sizeof(struct segment_desc) * image_hdr->segments_cnt; + } + pr_info("%s: Mode %d: Image setup table built on host", __func__, mode); + + return file_size; +err_free: + free_allocated_image_table(); +err: + pr_err("cnss: image file setup failed %d\n", ret); + return ret; +} + +int cnss_get_fw_image(struct image_desc_info *image_desc_info) +{ + if (!image_desc_info || !penv || + !penv->fw_seg_count || !penv->bdata_seg_count) + return -EINVAL; + + mutex_lock(&penv->fw_setup_stat_lock); + image_desc_info->fw_addr = penv->fw_dma; + image_desc_info->fw_size = penv->fw_dma_size; + image_desc_info->bdata_addr = penv->bdata_dma; + image_desc_info->bdata_size = penv->bdata_dma_size; + mutex_unlock(&penv->fw_setup_stat_lock); + + return 0; +} +EXPORT_SYMBOL(cnss_get_fw_image); + +static ssize_t wlan_setup_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + if (!penv) + return -ENODEV; + + return scnprintf(buf, PAGE_SIZE, "%u\n", penv->revision_id); +} + +static DEVICE_ATTR(wlan_setup, 0400, + wlan_setup_show, NULL); + +static int cnss_wlan_is_codeswap_supported(u16 revision) +{ + switch (revision) { + case QCA6174_FW_3_0: + case QCA6174_FW_3_2: + return 0; + default: + return 1; + } +} + +static int cnss_smmu_init(struct device *dev) +{ + struct dma_iommu_mapping *mapping; + int atomic_ctx = 1; + int s1_bypass = 1; + int fast = 1; + int ret; + + mapping = arm_iommu_create_mapping(&platform_bus_type, + penv->smmu_iova_start, + penv->smmu_iova_len); + if (IS_ERR(mapping)) { + ret = PTR_ERR(mapping); + pr_err("%s: create mapping failed, err = %d\n", __func__, ret); + goto map_fail; + } + + if (penv->smmu_s1_bypass) { + ret = iommu_domain_set_attr(mapping->domain, + DOMAIN_ATTR_S1_BYPASS, + &s1_bypass); + if (ret) { + pr_err("%s: set s1 bypass attr failed, err = %d\n", + __func__, ret); + goto set_attr_fail; + } + } else { + ret = iommu_domain_set_attr(mapping->domain, + DOMAIN_ATTR_ATOMIC, + &atomic_ctx); + if (ret) { + pr_err("%s: set atomic_ctx attr failed, err = %d\n", + __func__, ret); + goto set_attr_fail; + } + + ret = iommu_domain_set_attr(mapping->domain, + DOMAIN_ATTR_FAST, + &fast); + if (ret) { + pr_err("%s: set fast map attr failed, err = %d\n", + __func__, ret); + goto set_attr_fail; + } + } + + ret = arm_iommu_attach_device(dev, mapping); + if (ret) { + pr_err("%s: attach device failed, err = %d\n", __func__, ret); + goto attach_fail; + } + + penv->smmu_mapping = mapping; + + return ret; + +attach_fail: +set_attr_fail: + arm_iommu_release_mapping(mapping); +map_fail: + return ret; +} + +static void cnss_smmu_remove(struct device *dev) +{ + arm_iommu_detach_device(dev); + arm_iommu_release_mapping(penv->smmu_mapping); + + penv->smmu_mapping = NULL; +} + +#ifdef CONFIG_PCI_MSM +struct pci_saved_state *cnss_pci_store_saved_state(struct pci_dev *dev) +{ + return pci_store_saved_state(dev); +} + +int cnss_msm_pcie_pm_control( + enum msm_pcie_pm_opt pm_opt, u32 bus_num, + struct pci_dev *pdev, u32 options) +{ + return msm_pcie_pm_control(pm_opt, bus_num, pdev, NULL, options); +} + +int cnss_pci_load_and_free_saved_state( + struct pci_dev *dev, struct pci_saved_state **state) +{ + return pci_load_and_free_saved_state(dev, state); +} + +int cnss_msm_pcie_shadow_control(struct pci_dev *dev, bool enable) +{ + return msm_pcie_shadow_control(dev, enable); +} + +int cnss_msm_pcie_deregister_event(struct msm_pcie_register_event *reg) +{ + return msm_pcie_deregister_event(reg); +} + +int cnss_msm_pcie_recover_config(struct pci_dev *dev) +{ + return msm_pcie_recover_config(dev); +} + +int cnss_msm_pcie_register_event(struct msm_pcie_register_event *reg) +{ + return msm_pcie_register_event(reg); +} + +int cnss_msm_pcie_enumerate(u32 rc_idx) +{ + return msm_pcie_enumerate(rc_idx); +} +#else /* !defined CONFIG_PCI_MSM */ + +struct pci_saved_state *cnss_pci_store_saved_state(struct pci_dev *dev) +{ + return NULL; +} + +int cnss_msm_pcie_pm_control( + enum msm_pcie_pm_opt pm_opt, u32 bus_num, + struct pci_dev *pdev, u32 options) +{ + return -ENODEV; +} + +int cnss_pci_load_and_free_saved_state( + struct pci_dev *dev, struct pci_saved_state **state) +{ + return 0; +} + +int cnss_msm_pcie_shadow_control(struct pci_dev *dev, bool enable) +{ + return -ENODEV; +} + +int cnss_msm_pcie_deregister_event(struct msm_pcie_register_event *reg) +{ + return -ENODEV; +} + +int cnss_msm_pcie_recover_config(struct pci_dev *dev) +{ + return -ENODEV; +} + +int cnss_msm_pcie_register_event(struct msm_pcie_register_event *reg) +{ + return -ENODEV; +} + +int cnss_msm_pcie_enumerate(u32 rc_idx) +{ + return -EPROBE_DEFER; +} +#endif + +static void cnss_pcie_set_platform_ops(struct device *dev) +{ + struct cnss_dev_platform_ops *pf_ops = &penv->platform_ops; + + pf_ops->request_bus_bandwidth = cnss_pci_request_bus_bandwidth; + pf_ops->get_virt_ramdump_mem = cnss_pci_get_virt_ramdump_mem; + pf_ops->device_self_recovery = cnss_pci_device_self_recovery; + pf_ops->schedule_recovery_work = cnss_pci_schedule_recovery_work; + pf_ops->device_crashed = cnss_pci_device_crashed; + pf_ops->get_wlan_mac_address = cnss_pci_get_wlan_mac_address; + pf_ops->set_wlan_mac_address = cnss_pcie_set_wlan_mac_address; + pf_ops->power_up = cnss_pcie_power_up; + pf_ops->power_down = cnss_pcie_power_down; + + dev->platform_data = pf_ops; +} + +static void cnss_pcie_reset_platform_ops(struct device *dev) +{ + struct cnss_dev_platform_ops *pf_ops = &penv->platform_ops; + + memset(pf_ops, 0, sizeof(struct cnss_dev_platform_ops)); + dev->platform_data = NULL; +} + +static int cnss_wlan_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + int ret = 0; + struct cnss_wlan_vreg_info *vreg_info = &penv->vreg_info; + void *cpu_addr; + dma_addr_t dma_handle; + struct codeswap_codeseg_info *cnss_seg_info = NULL; + struct device *dev = &pdev->dev; + + cnss_pcie_set_platform_ops(dev); + penv->pdev = pdev; + penv->id = id; + atomic_set(&penv->fw_available, 0); + penv->device_id = pdev->device; + + if (penv->smmu_iova_len) { + ret = cnss_smmu_init(&pdev->dev); + if (ret) { + pr_err("%s: SMMU init failed, err = %d\n", + __func__, ret); + } + } + + if (penv->pci_register_again) { + pr_debug("%s: PCI re-registration complete\n", __func__); + penv->pci_register_again = false; + return 0; + } + + switch (pdev->device) { + case QCA6180_DEVICE_ID: + pci_read_config_word(pdev, QCA6180_REV_ID_OFFSET, + &penv->revision_id); + break; + + case QCA6174_DEVICE_ID: + pci_read_config_word(pdev, QCA6174_REV_ID_OFFSET, + &penv->revision_id); + cnss_setup_fw_files(penv->revision_id); + break; + + default: + pr_err("cnss: unknown device found %d\n", pdev->device); + ret = -EPROBE_DEFER; + goto err_unknown; + } + + if (penv->pcie_link_state) { + pci_save_state(pdev); + penv->saved_state = cnss_pci_store_saved_state(pdev); + + ret = cnss_msm_pcie_pm_control( + MSM_PCIE_SUSPEND, cnss_get_pci_dev_bus_number(pdev), + pdev, PM_OPTIONS); + if (ret) { + pr_err("Failed to shutdown PCIe link\n"); + goto err_pcie_suspend; + } + penv->pcie_link_state = PCIE_LINK_DOWN; + } + + cnss_configure_wlan_en_gpio(WLAN_EN_LOW); + ret = cnss_wlan_vreg_set(vreg_info, VREG_OFF); + + if (ret) { + pr_err("can't turn off wlan vreg\n"); + goto err_pcie_suspend; + } + + mutex_lock(&penv->fw_setup_stat_lock); + cnss_wlan_fw_mem_alloc(pdev); + mutex_unlock(&penv->fw_setup_stat_lock); + + ret = device_create_file(&penv->pldev->dev, &dev_attr_wlan_setup); + + if (ret) { + pr_err("Can't Create Device file\n"); + goto err_pcie_suspend; + } + + if (cnss_wlan_is_codeswap_supported(penv->revision_id)) { + pr_debug("Code-swap not enabled: %d\n", penv->revision_id); + goto err_pcie_suspend; + } + + cpu_addr = dma_alloc_coherent(dev, EVICT_BIN_MAX_SIZE, + &dma_handle, GFP_KERNEL); + if (!cpu_addr || !dma_handle) { + pr_err("cnss: Memory Alloc failed for codeswap feature\n"); + goto err_pcie_suspend; + } + + memset(cpu_addr, 0, EVICT_BIN_MAX_SIZE); + cnss_seg_info = devm_kzalloc(dev, sizeof(*cnss_seg_info), + GFP_KERNEL); + if (!cnss_seg_info) + goto end_dma_alloc; + + memset(cnss_seg_info, 0, sizeof(*cnss_seg_info)); + cnss_seg_info->codeseg_busaddr[0] = (void *)dma_handle; + penv->codeseg_cpuaddr[0] = cpu_addr; + cnss_seg_info->codeseg_size = EVICT_BIN_MAX_SIZE; + cnss_seg_info->codeseg_total_bytes = EVICT_BIN_MAX_SIZE; + cnss_seg_info->num_codesegs = 1; + cnss_seg_info->codeseg_size_log2 = ilog2(EVICT_BIN_MAX_SIZE); + + penv->cnss_seg_info = cnss_seg_info; + pr_debug("%s: Successfully allocated memory for CODESWAP\n", __func__); + + return ret; + +end_dma_alloc: + dma_free_coherent(dev, EVICT_BIN_MAX_SIZE, cpu_addr, dma_handle); +err_unknown: +err_pcie_suspend: + cnss_pcie_reset_platform_ops(dev); + return ret; +} + +static void cnss_wlan_pci_remove(struct pci_dev *pdev) +{ + struct device *dev; + + if (!penv) + return; + + dev = &penv->pldev->dev; + cnss_pcie_reset_platform_ops(dev); + device_remove_file(dev, &dev_attr_wlan_setup); + + if (penv->smmu_mapping) + cnss_smmu_remove(&pdev->dev); +} + +static int cnss_wlan_pci_suspend(struct device *dev) +{ + int ret = 0; + struct cnss_wlan_driver *wdriver; + struct pci_dev *pdev = to_pci_dev(dev); + + pm_message_t state = { .event = PM_EVENT_SUSPEND }; + + if (!penv) + goto out; + + if (!penv->pcie_link_state) + goto out; + + wdriver = penv->driver; + if (!wdriver) + goto out; + + if (wdriver->suspend) { + ret = wdriver->suspend(pdev, state); + + if (penv->pcie_link_state) { + pci_save_state(pdev); + penv->saved_state = cnss_pci_store_saved_state(pdev); + } + } + penv->monitor_wake_intr = false; + +out: + return ret; +} + +static int cnss_wlan_pci_resume(struct device *dev) +{ + int ret = 0; + struct cnss_wlan_driver *wdriver; + struct pci_dev *pdev = to_pci_dev(dev); + + if (!penv) + goto out; + + if (!penv->pcie_link_state) + goto out; + + wdriver = penv->driver; + if (!wdriver) + goto out; + + if (wdriver->resume && !penv->pcie_link_down_ind) { + if (penv->saved_state) + cnss_pci_load_and_free_saved_state( + pdev, &penv->saved_state); + pci_restore_state(pdev); + + ret = wdriver->resume(pdev); + } + +out: + return ret; +} + +static int cnss_wlan_runtime_suspend(struct device *dev) +{ + int ret = 0; + struct cnss_wlan_driver *wdrv; + + if (!penv) + return -EAGAIN; + + if (penv->pcie_link_down_ind) { + pr_debug("PCI link down recovery is in progress\n"); + return -EAGAIN; + } + + pr_debug("cnss: runtime suspend start\n"); + + wdrv = penv->driver; + + if (wdrv && wdrv->runtime_ops && wdrv->runtime_ops->runtime_suspend) + ret = wdrv->runtime_ops->runtime_suspend(to_pci_dev(dev)); + + pr_info("cnss: runtime suspend status: %d\n", ret); + + return ret; +} + +static int cnss_wlan_runtime_resume(struct device *dev) +{ + struct cnss_wlan_driver *wdrv; + int ret = 0; + + if (!penv) + return -EAGAIN; + + if (penv->pcie_link_down_ind) { + pr_debug("PCI link down recovery is in progress\n"); + return -EAGAIN; + } + + pr_debug("cnss: runtime resume start\n"); + + wdrv = penv->driver; + + if (wdrv && wdrv->runtime_ops && wdrv->runtime_ops->runtime_resume) + ret = wdrv->runtime_ops->runtime_resume(to_pci_dev(dev)); + + pr_info("cnss: runtime resume status: %d\n", ret); + + return ret; +} + +static int cnss_wlan_runtime_idle(struct device *dev) +{ + pr_debug("cnss: runtime idle\n"); + + pm_request_autosuspend(dev); + + return -EBUSY; +} + +static DECLARE_RWSEM(cnss_pm_sem); + +static int cnss_pm_notify(struct notifier_block *b, + unsigned long event, void *p) +{ + switch (event) { + case PM_SUSPEND_PREPARE: + down_write(&cnss_pm_sem); + break; + + case PM_POST_SUSPEND: + up_write(&cnss_pm_sem); + break; + } + + return NOTIFY_DONE; +} + +static struct notifier_block cnss_pm_notifier = { + .notifier_call = cnss_pm_notify, +}; + +static const struct pci_device_id cnss_wlan_pci_id_table[] = { + { QCA6174_VENDOR_ID, QCA6174_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { QCA6174_VENDOR_ID, BEELINER_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { QCA6180_VENDOR_ID, QCA6180_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, cnss_wlan_pci_id_table); + +#ifdef CONFIG_PM +static const struct dev_pm_ops cnss_wlan_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(cnss_wlan_pci_suspend, cnss_wlan_pci_resume) + SET_RUNTIME_PM_OPS(cnss_wlan_runtime_suspend, cnss_wlan_runtime_resume, + cnss_wlan_runtime_idle) +}; +#endif + +struct pci_driver cnss_wlan_pci_driver = { + .name = "cnss_wlan_pci", + .id_table = cnss_wlan_pci_id_table, + .probe = cnss_wlan_pci_probe, + .remove = cnss_wlan_pci_remove, +#ifdef CONFIG_PM + .driver = { + .pm = &cnss_wlan_pm_ops, + }, +#endif +}; + +static ssize_t fw_image_setup_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + if (!penv) + return -ENODEV; + + return scnprintf(buf, PAGE_SIZE, "%u\n", penv->fw_image_setup); +} + +static ssize_t fw_image_setup_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int val; + int ret; + + if (!penv) + return -ENODEV; + + mutex_lock(&penv->fw_setup_stat_lock); + pr_info("%s: Firmware setup in progress\n", __func__); + + if (kstrtoint(buf, 0, &val)) { + mutex_unlock(&penv->fw_setup_stat_lock); + return -EINVAL; + } + + if (val == FW_IMAGE_FTM || val == FW_IMAGE_MISSION || + val == FW_IMAGE_BDATA) { + pr_info("%s: fw image setup triggered %d\n", __func__, val); + ret = cnss_setup_fw_image_table(val); + if (ret != 0) { + pr_err("%s: Invalid parsing of FW image files %d\n", + __func__, ret); + mutex_unlock(&penv->fw_setup_stat_lock); + return -EINVAL; + } + penv->fw_image_setup = val; + } else if (val == FW_IMAGE_PRINT) { + print_allocated_image_table(); + } else if (val == BMI_TEST_SETUP) { + penv->bmi_test = val; + } + + pr_info("%s: Firmware setup completed\n", __func__); + mutex_unlock(&penv->fw_setup_stat_lock); + return count; +} + +static DEVICE_ATTR(fw_image_setup, 0600, + fw_image_setup_show, fw_image_setup_store); + +void cnss_pci_recovery_work_handler(struct work_struct *recovery) +{ + cnss_pci_device_self_recovery(); +} + +DECLARE_WORK(cnss_pci_recovery_work, cnss_pci_recovery_work_handler); + +void cnss_schedule_recovery_work(void) +{ + schedule_work(&cnss_pci_recovery_work); +} +EXPORT_SYMBOL(cnss_schedule_recovery_work); + +static inline void __cnss_disable_irq(void *data) +{ + struct pci_dev *pdev = data; + + disable_irq(pdev->irq); +} + +void cnss_pci_events_cb(struct msm_pcie_notify *notify) +{ + unsigned long flags; + + if (!notify) + return; + + switch (notify->event) { + case MSM_PCIE_EVENT_LINKDOWN: + if (pcie_link_down_panic) + panic("PCIe link is down\n"); + + spin_lock_irqsave(&pci_link_down_lock, flags); + if (penv->pcie_link_down_ind) { + pr_debug("PCI link down recovery is in progress, ignore\n"); + spin_unlock_irqrestore(&pci_link_down_lock, flags); + return; + } + penv->pcie_link_down_ind = true; + spin_unlock_irqrestore(&pci_link_down_lock, flags); + + pr_err("PCI link down, schedule recovery\n"); + __cnss_disable_irq(notify->user); + schedule_work(&cnss_pci_recovery_work); + break; + + case MSM_PCIE_EVENT_WAKEUP: + if (penv->monitor_wake_intr && + atomic_read(&penv->auto_suspended)) { + penv->monitor_wake_intr = false; + pm_request_resume(&penv->pdev->dev); + } + break; + + default: + pr_err("cnss: invalid event from PCIe callback %d\n", + notify->event); + } +} + +void cnss_wlan_pci_link_down(void) +{ + unsigned long flags; + + if (pcie_link_down_panic) + panic("PCIe link is down\n"); + + spin_lock_irqsave(&pci_link_down_lock, flags); + if (penv->pcie_link_down_ind) { + pr_debug("PCI link down recovery is in progress, ignore\n"); + spin_unlock_irqrestore(&pci_link_down_lock, flags); + return; + } + penv->pcie_link_down_ind = true; + spin_unlock_irqrestore(&pci_link_down_lock, flags); + + pr_err("PCI link down detected by host driver, schedule recovery\n"); + schedule_work(&cnss_pci_recovery_work); +} +EXPORT_SYMBOL(cnss_wlan_pci_link_down); + +int cnss_pcie_shadow_control(struct pci_dev *dev, bool enable) +{ + return cnss_msm_pcie_shadow_control(dev, enable); +} +EXPORT_SYMBOL(cnss_pcie_shadow_control); + +int cnss_get_codeswap_struct(struct codeswap_codeseg_info *swap_seg) +{ + struct codeswap_codeseg_info *cnss_seg_info = penv->cnss_seg_info; + + mutex_lock(&penv->fw_setup_stat_lock); + if (!cnss_seg_info) { + swap_seg = NULL; + mutex_unlock(&penv->fw_setup_stat_lock); + return -ENOENT; + } + + if (!atomic_read(&penv->fw_available)) { + pr_debug("%s: fw is not available\n", __func__); + mutex_unlock(&penv->fw_setup_stat_lock); + return -ENOENT; + } + + *swap_seg = *cnss_seg_info; + mutex_unlock(&penv->fw_setup_stat_lock); + + return 0; +} +EXPORT_SYMBOL(cnss_get_codeswap_struct); + +static void cnss_wlan_memory_expansion(void) +{ + struct device *dev; + const struct firmware *fw_entry; + const char *filename; + u32 fw_entry_size, size_left, dma_size_left, length; + char *fw_temp; + char *fw_data; + char *dma_virt_addr; + struct codeswap_codeseg_info *cnss_seg_info; + u32 total_length = 0; + struct pci_dev *pdev; + + mutex_lock(&penv->fw_setup_stat_lock); + filename = cnss_wlan_get_evicted_data_file(); + pdev = penv->pdev; + dev = &pdev->dev; + cnss_seg_info = penv->cnss_seg_info; + + if (!cnss_seg_info) { + pr_debug("cnss: cnss_seg_info is NULL\n"); + mutex_unlock(&penv->fw_setup_stat_lock); + goto end; + } + + if (atomic_read(&penv->fw_available)) { + pr_debug("cnss: fw code already copied to host memory\n"); + mutex_unlock(&penv->fw_setup_stat_lock); + goto end; + } + + if (request_firmware(&fw_entry, filename, dev) != 0) { + pr_debug("cnss: failed to get fw: %s\n", filename); + mutex_unlock(&penv->fw_setup_stat_lock); + goto end; + } + + if (!fw_entry || !fw_entry->data) { + pr_err("%s: INVALID FW entries\n", __func__); + mutex_unlock(&penv->fw_setup_stat_lock); + goto release_fw; + } + + dma_virt_addr = (char *)penv->codeseg_cpuaddr[0]; + fw_data = (u8 *)fw_entry->data; + fw_temp = fw_data; + fw_entry_size = fw_entry->size; + if (fw_entry_size > EVICT_BIN_MAX_SIZE) + fw_entry_size = EVICT_BIN_MAX_SIZE; + size_left = fw_entry_size; + dma_size_left = EVICT_BIN_MAX_SIZE; + while ((size_left && fw_temp) && (dma_size_left > 0)) { + fw_temp = fw_temp + 4; + size_left = size_left - 4; + length = *(int *)fw_temp; + if ((length > size_left || length <= 0) || + (dma_size_left <= 0 || length > dma_size_left)) { + pr_err("cnss: wrong length read:%d\n", + length); + break; + } + fw_temp = fw_temp + 4; + size_left = size_left - 4; + memcpy(dma_virt_addr, fw_temp, length); + dma_size_left = dma_size_left - length; + size_left = size_left - length; + fw_temp = fw_temp + length; + dma_virt_addr = dma_virt_addr + length; + total_length += length; + pr_debug("cnss: bytes_left to copy: fw:%d; dma_page:%d\n", + size_left, dma_size_left); + } + pr_debug("cnss: total_bytes copied: %d\n", total_length); + cnss_seg_info->codeseg_total_bytes = total_length; + + atomic_set(&penv->fw_available, 1); + mutex_unlock(&penv->fw_setup_stat_lock); + +release_fw: + release_firmware(fw_entry); +end: + return; +} + +/** + * cnss_get_wlan_mac_address() - API to return MAC addresses buffer + * @dev: struct device pointer + * @num: buffer for number of mac addresses supported + * + * API returns the pointer to the buffer filled with mac addresses and + * updates num with the number of mac addresses the buffer contains. + * + * Return: pointer to mac address buffer. + */ +u8 *cnss_pci_get_wlan_mac_address(u32 *num) +{ + struct cnss_wlan_mac_addr *addr = NULL; + + if (!penv) { + pr_err("%s: Invalid Platform Driver Context\n", __func__); + goto end; + } + + if (!penv->is_wlan_mac_set) { + pr_info("%s: Platform Driver doesn't have any mac address\n", + __func__); + goto end; + } + + addr = &penv->wlan_mac_addr; + *num = addr->no_of_mac_addr_set; + return &addr->mac_addr[0][0]; + +end: + *num = 0; + return NULL; +} + +/** + * cnss_get_wlan_mac_address() - API to return MAC addresses buffer + * @dev: struct device pointer + * @num: buffer for number of mac addresses supported + * + * API returns the pointer to the buffer filled with mac addresses and + * updates num with the number of mac addresses the buffer contains. + * + * Return: pointer to mac address buffer. + */ +u8 *cnss_get_wlan_mac_address(struct device *dev, u32 *num) +{ + struct cnss_wlan_mac_addr *addr = NULL; + + if (!penv) { + pr_err("%s: Invalid Platform Driver Context\n", __func__); + goto end; + } + + if (!penv->is_wlan_mac_set) { + pr_info("%s: Platform Driver doesn't have any mac address\n", + __func__); + goto end; + } + + addr = &penv->wlan_mac_addr; + *num = addr->no_of_mac_addr_set; + return &addr->mac_addr[0][0]; +end: + *num = 0; + return NULL; +} +EXPORT_SYMBOL(cnss_get_wlan_mac_address); + +/** + * cnss_pcie_set_wlan_mac_address() - API to get two wlan mac address + * @in: Input buffer with wlan mac addresses + * @len: Size of the buffer passed + * + * API to store wlan mac address passed by the caller. The stored mac + * addresses are used by the wlan functional driver to program wlan HW. + * + * Return: kernel error code. + */ +int cnss_pcie_set_wlan_mac_address(const u8 *in, u32 len) +{ + u32 no_of_mac_addr; + struct cnss_wlan_mac_addr *addr = NULL; + int iter = 0; + u8 *temp = NULL; + + if (len == 0 || (len % ETH_ALEN) != 0) { + pr_err("%s: Invalid Length:%d\n", __func__, len); + return -EINVAL; + } + + no_of_mac_addr = len / ETH_ALEN; + + if (no_of_mac_addr > MAX_NO_OF_MAC_ADDR) { + pr_err("%s: Num of supported MAC addresses are:%d given:%d\n", + __func__, MAX_NO_OF_MAC_ADDR, no_of_mac_addr); + return -EINVAL; + } + + if (!penv) { + pr_err("%s: Invalid CNSS Platform Context\n", __func__); + return -ENOENT; + } + + if (penv->is_wlan_mac_set) { + pr_info("%s: Already MAC address are configured\n", __func__); + return 0; + } + + penv->is_wlan_mac_set = true; + addr = &penv->wlan_mac_addr; + addr->no_of_mac_addr_set = no_of_mac_addr; + temp = &addr->mac_addr[0][0]; + + for (; iter < no_of_mac_addr; ++iter, temp += ETH_ALEN, in += + ETH_ALEN) { + ether_addr_copy(temp, in); + pr_debug("%s MAC_ADDR:%02x:%02x:%02x:%02x:%02x:%02x\n", + __func__, temp[0], temp[1], temp[2], temp[3], temp[4], + temp[5]); + } + return 0; +} + +int cnss_wlan_register_driver(struct cnss_wlan_driver *driver) +{ + int ret = 0; + int probe_again = 0; + struct cnss_wlan_driver *wdrv; + struct cnss_wlan_vreg_info *vreg_info; + struct cnss_wlan_gpio_info *gpio_info; + struct pci_dev *pdev; + + if (!penv) + return -ENODEV; + + vreg_info = &penv->vreg_info; + gpio_info = &penv->gpio_info; + pdev = penv->pdev; + + if (!penv->driver) { + penv->driver = driver; + wdrv = penv->driver; + } else { + pr_err("driver already registered\n"); + return -EEXIST; + } + +again: + ret = cnss_wlan_vreg_set(vreg_info, VREG_ON); + if (ret) { + pr_err("wlan vreg ON failed\n"); + goto err_wlan_vreg_on; + } + + msleep(POWER_ON_DELAY); + + if (penv->wlan_bootstrap_gpio > 0) { + gpio_set_value(penv->wlan_bootstrap_gpio, WLAN_BOOTSTRAP_HIGH); + msleep(WLAN_BOOTSTRAP_DELAY); + } + + cnss_configure_wlan_en_gpio(WLAN_EN_HIGH); + + if (!pdev) { + pr_debug("%s: invalid pdev. register pci device\n", __func__); + ret = pci_register_driver(&cnss_wlan_pci_driver); + + if (ret) { + pr_err("%s: pci registration failed\n", __func__); + goto err_pcie_reg; + } + pdev = penv->pdev; + if (!pdev) { + pr_err("%s: pdev is still invalid\n", __func__); + goto err_pcie_reg; + } + } + + penv->event_reg.events = MSM_PCIE_EVENT_LINKDOWN | + MSM_PCIE_EVENT_WAKEUP; + penv->event_reg.user = pdev; + penv->event_reg.mode = MSM_PCIE_TRIGGER_CALLBACK; + penv->event_reg.callback = cnss_pci_events_cb; + penv->event_reg.options = MSM_PCIE_CONFIG_NO_RECOVERY; + ret = cnss_msm_pcie_register_event(&penv->event_reg); + if (ret) + pr_err("%s: PCIe event register failed %d\n", __func__, ret); + + if (!penv->pcie_link_state && !penv->pcie_link_down_ind) { + ret = cnss_msm_pcie_pm_control( + MSM_PCIE_RESUME, cnss_get_pci_dev_bus_number(pdev), + pdev, PM_OPTIONS); + if (ret) { + pr_err("PCIe link bring-up failed\n"); + goto err_pcie_link_up; + } + penv->pcie_link_state = PCIE_LINK_UP; + } else if (!penv->pcie_link_state && penv->pcie_link_down_ind) { + ret = cnss_msm_pcie_pm_control( + MSM_PCIE_RESUME, cnss_get_pci_dev_bus_number(pdev), + pdev, PM_OPTIONS_RESUME_LINK_DOWN); + + if (ret) { + pr_err("PCIe link bring-up failed (link down option)\n"); + goto err_pcie_link_up; + } + penv->pcie_link_state = PCIE_LINK_UP; + + ret = cnss_msm_pcie_recover_config(pdev); + if (ret) { + pr_err("cnss: PCI link failed to recover\n"); + goto err_pcie_link_up; + } + penv->pcie_link_down_ind = false; + } + + if (!cnss_wlan_is_codeswap_supported(penv->revision_id)) + cnss_wlan_memory_expansion(); + + if (wdrv->probe) { + if (penv->saved_state) + cnss_pci_load_and_free_saved_state( + pdev, &penv->saved_state); + + pci_restore_state(pdev); + + ret = wdrv->probe(pdev, penv->id); + if (ret) { + wcnss_prealloc_check_memory_leak(); + wcnss_pre_alloc_reset(); + + if (probe_again > 3) { + pr_err("Failed to probe WLAN\n"); + goto err_wlan_probe; + } + pci_save_state(pdev); + penv->saved_state = cnss_pci_store_saved_state(pdev); + cnss_msm_pcie_deregister_event(&penv->event_reg); + cnss_msm_pcie_pm_control( + MSM_PCIE_SUSPEND, + cnss_get_pci_dev_bus_number(pdev), + pdev, PM_OPTIONS); + penv->pcie_link_state = PCIE_LINK_DOWN; + cnss_configure_wlan_en_gpio(WLAN_EN_LOW); + cnss_wlan_vreg_set(vreg_info, VREG_OFF); + msleep(POWER_ON_DELAY); + probe_again++; + goto again; + } + } + + if (penv->notify_modem_status && wdrv->modem_status) + wdrv->modem_status(pdev, penv->modem_current_status); + + return ret; + +err_wlan_probe: + pci_save_state(pdev); + penv->saved_state = cnss_pci_store_saved_state(pdev); + +err_pcie_link_up: + cnss_msm_pcie_deregister_event(&penv->event_reg); + if (penv->pcie_link_state) { + cnss_msm_pcie_pm_control( + MSM_PCIE_SUSPEND, cnss_get_pci_dev_bus_number(pdev), + pdev, PM_OPTIONS); + penv->pcie_link_state = PCIE_LINK_DOWN; + } + +err_pcie_reg: + cnss_configure_wlan_en_gpio(WLAN_EN_LOW); + cnss_wlan_vreg_set(vreg_info, VREG_OFF); + if (penv->pdev) { + pr_err("%d: Unregistering PCI device\n", __LINE__); + pci_unregister_driver(&cnss_wlan_pci_driver); + penv->pdev = NULL; + penv->pci_register_again = true; + } + +err_wlan_vreg_on: + penv->driver = NULL; + + return ret; +} +EXPORT_SYMBOL(cnss_wlan_register_driver); + +void cnss_wlan_unregister_driver(struct cnss_wlan_driver *driver) +{ + struct cnss_wlan_driver *wdrv; + struct cnss_wlan_vreg_info *vreg_info; + struct cnss_wlan_gpio_info *gpio_info; + struct pci_dev *pdev; + + if (!penv) + return; + + wdrv = penv->driver; + vreg_info = &penv->vreg_info; + gpio_info = &penv->gpio_info; + pdev = penv->pdev; + + if (!wdrv) { + pr_err("driver not registered\n"); + return; + } + + if (penv->bus_client) + msm_bus_scale_client_update_request(penv->bus_client, + CNSS_BUS_WIDTH_NONE); + + if (!pdev) { + pr_err("%d: invalid pdev\n", __LINE__); + goto cut_power; + } + + if (wdrv->remove) + wdrv->remove(pdev); + + wcnss_prealloc_check_memory_leak(); + wcnss_pre_alloc_reset(); + + cnss_msm_pcie_deregister_event(&penv->event_reg); + + if (penv->pcie_link_state && !penv->pcie_link_down_ind) { + pci_save_state(pdev); + penv->saved_state = cnss_pci_store_saved_state(pdev); + + if (cnss_msm_pcie_pm_control( + MSM_PCIE_SUSPEND, cnss_get_pci_dev_bus_number(pdev), + pdev, PM_OPTIONS)) { + pr_err("Failed to shutdown PCIe link\n"); + return; + } + } else if (penv->pcie_link_state && penv->pcie_link_down_ind) { + penv->saved_state = NULL; + + if (cnss_msm_pcie_pm_control( + MSM_PCIE_SUSPEND, cnss_get_pci_dev_bus_number(pdev), + pdev, PM_OPTIONS_SUSPEND_LINK_DOWN)) { + pr_err("Failed to shutdown PCIe link (with linkdown option)\n"); + return; + } + } + penv->pcie_link_state = PCIE_LINK_DOWN; + penv->driver_status = CNSS_UNINITIALIZED; + penv->monitor_wake_intr = false; + atomic_set(&penv->auto_suspended, 0); + +cut_power: + penv->driver = NULL; + + cnss_configure_wlan_en_gpio(WLAN_EN_LOW); + if (cnss_wlan_vreg_set(vreg_info, VREG_OFF)) + pr_err("wlan vreg OFF failed\n"); +} +EXPORT_SYMBOL(cnss_wlan_unregister_driver); + +#ifdef CONFIG_PCI_MSM +int cnss_wlan_pm_control(bool vote) +{ + if (!penv || !penv->pdev) + return -ENODEV; + + return cnss_msm_pcie_pm_control( + vote ? MSM_PCIE_DISABLE_PC : MSM_PCIE_ENABLE_PC, + cnss_get_pci_dev_bus_number(penv->pdev), + penv->pdev, PM_OPTIONS); +} +EXPORT_SYMBOL(cnss_wlan_pm_control); +#endif + +void cnss_lock_pm_sem(void) +{ + down_read(&cnss_pm_sem); +} +EXPORT_SYMBOL(cnss_lock_pm_sem); + +void cnss_release_pm_sem(void) +{ + up_read(&cnss_pm_sem); +} +EXPORT_SYMBOL(cnss_release_pm_sem); + +void cnss_pci_schedule_recovery_work(void) +{ + schedule_work(&cnss_pci_recovery_work); +} + +void *cnss_pci_get_virt_ramdump_mem(unsigned long *size) +{ + if (!penv || !penv->pldev) + return NULL; + + *size = penv->ramdump_size; + + return penv->ramdump_addr; +} + +void cnss_pci_device_crashed(void) +{ + if (penv && penv->subsys) { + subsys_set_crash_status(penv->subsys, true); + subsystem_restart_dev(penv->subsys); + } +} + +void *cnss_get_virt_ramdump_mem(unsigned long *size) +{ + if (!penv || !penv->pldev) + return NULL; + + *size = penv->ramdump_size; + + return penv->ramdump_addr; +} +EXPORT_SYMBOL(cnss_get_virt_ramdump_mem); + +void cnss_device_crashed(void) +{ + if (penv && penv->subsys) { + subsys_set_crash_status(penv->subsys, true); + subsystem_restart_dev(penv->subsys); + } +} +EXPORT_SYMBOL(cnss_device_crashed); + +static int cnss_shutdown(const struct subsys_desc *subsys, bool force_stop) +{ + struct cnss_wlan_driver *wdrv; + struct pci_dev *pdev; + struct cnss_wlan_vreg_info *vreg_info; + struct cnss_wlan_gpio_info *gpio_info; + int ret = 0; + + if (!penv) + return -ENODEV; + + penv->recovery_in_progress = true; + wdrv = penv->driver; + pdev = penv->pdev; + vreg_info = &penv->vreg_info; + gpio_info = &penv->gpio_info; + + if (!pdev) { + ret = -EINVAL; + goto cut_power; + } + + if (wdrv && wdrv->shutdown) + wdrv->shutdown(pdev); + + if (penv->pcie_link_state) { + if (cnss_msm_pcie_pm_control( + MSM_PCIE_SUSPEND, cnss_get_pci_dev_bus_number(pdev), + pdev, PM_OPTIONS_SUSPEND_LINK_DOWN)) { + pr_debug("cnss: Failed to shutdown PCIe link\n"); + ret = -EFAULT; + } + penv->saved_state = NULL; + penv->pcie_link_state = PCIE_LINK_DOWN; + } + +cut_power: + cnss_configure_wlan_en_gpio(WLAN_EN_LOW); + if (cnss_wlan_vreg_set(vreg_info, VREG_OFF)) + pr_err("cnss: Failed to set WLAN VREG_OFF\n"); + + return ret; +} + +static int cnss_powerup(const struct subsys_desc *subsys) +{ + struct cnss_wlan_driver *wdrv; + struct pci_dev *pdev; + struct cnss_wlan_vreg_info *vreg_info; + struct cnss_wlan_gpio_info *gpio_info; + int ret = 0; + + if (!penv) + return -ENODEV; + + if (!penv->driver) + goto out; + + wdrv = penv->driver; + pdev = penv->pdev; + vreg_info = &penv->vreg_info; + gpio_info = &penv->gpio_info; + + ret = cnss_wlan_vreg_set(vreg_info, VREG_ON); + if (ret) { + pr_err("cnss: Failed to set WLAN VREG_ON\n"); + goto err_wlan_vreg_on; + } + + msleep(POWER_ON_DELAY); + cnss_configure_wlan_en_gpio(WLAN_EN_HIGH); + /** + * Some platforms have wifi and other PCIE card attached with PCIE + * switch on the same RC like P5459 board(ROME 3.2 PCIE card + Ethernet + * PCI), it will need extra time to stable the signals when do SSR, + * otherwise fail to create the PCIE link, so add PCIE_SWITCH_DELAY. + */ + msleep(PCIE_SWITCH_DELAY); + + if (!pdev) { + pr_err("%d: invalid pdev\n", __LINE__); + goto err_pcie_link_up; + } + + if (!penv->pcie_link_state) { + ret = cnss_msm_pcie_pm_control( + MSM_PCIE_RESUME, + cnss_get_pci_dev_bus_number(pdev), + pdev, PM_OPTIONS_RESUME_LINK_DOWN); + + if (ret) { + pr_err("cnss: Failed to bring-up PCIe link\n"); + goto err_pcie_link_up; + } + penv->pcie_link_state = PCIE_LINK_UP; + ret = cnss_msm_pcie_recover_config(penv->pdev); + if (ret) { + pr_err("cnss: PCI link failed to recover\n"); + goto err_pcie_link_up; + } + penv->pcie_link_down_ind = false; + } + + if (wdrv && wdrv->reinit) { + if (penv->saved_state) + cnss_pci_load_and_free_saved_state( + pdev, &penv->saved_state); + + pci_restore_state(pdev); + + ret = wdrv->reinit(pdev, penv->id); + if (ret) { + pr_err("%d: Failed to do reinit\n", __LINE__); + goto err_wlan_reinit; + } + } else { + pr_err("%d: wdrv->reinit is invalid\n", __LINE__); + goto err_pcie_link_up; + } + + if (penv->notify_modem_status && wdrv->modem_status) + wdrv->modem_status(pdev, penv->modem_current_status); + +out: + penv->recovery_in_progress = false; + return ret; + +err_wlan_reinit: + pci_save_state(pdev); + penv->saved_state = cnss_pci_store_saved_state(pdev); + cnss_msm_pcie_pm_control( + MSM_PCIE_SUSPEND, + cnss_get_pci_dev_bus_number(pdev), + pdev, PM_OPTIONS); + penv->pcie_link_state = PCIE_LINK_DOWN; + +err_pcie_link_up: + cnss_configure_wlan_en_gpio(WLAN_EN_LOW); + cnss_wlan_vreg_set(vreg_info, VREG_OFF); + if (penv->pdev) { + if (wdrv && wdrv->update_status) + wdrv->update_status(penv->pdev, CNSS_SSR_FAIL); + if (!penv->recovery_in_progress) { + pr_err("%d: Unregistering pci device\n", __LINE__); + pci_unregister_driver(&cnss_wlan_pci_driver); + penv->pdev = NULL; + penv->pci_register_again = true; + } + } + +err_wlan_vreg_on: + return ret; +} + +void cnss_pci_device_self_recovery(void) +{ + if (!penv) + return; + + if (penv->recovery_in_progress) { + pr_err("cnss: Recovery already in progress\n"); + return; + } + + if (penv->driver_status == CNSS_LOAD_UNLOAD) { + pr_err("cnss: load unload in progress\n"); + return; + } + + penv->recovery_count++; + penv->recovery_in_progress = true; + cnss_pm_wake_lock(&penv->ws); + cnss_shutdown(NULL, false); + msleep(WLAN_RECOVERY_DELAY); + cnss_powerup(NULL); + cnss_pm_wake_lock_release(&penv->ws); + penv->recovery_in_progress = false; +} + +static int cnss_ramdump(int enable, const struct subsys_desc *subsys) +{ + struct ramdump_segment segment; + + if (!penv) + return -ENODEV; + + if (!penv->ramdump_size) + return -ENOENT; + + if (!enable) + return 0; + + memset(&segment, 0, sizeof(segment)); + segment.v_address = penv->ramdump_addr; + segment.size = penv->ramdump_size; + + return do_ramdump(penv->ramdump_dev, &segment, 1); +} + +static void cnss_crash_shutdown(const struct subsys_desc *subsys) +{ + struct cnss_wlan_driver *wdrv; + struct pci_dev *pdev; + + if (!penv) + return; + + wdrv = penv->driver; + pdev = penv->pdev; + + if (pdev && wdrv && wdrv->crash_shutdown) + wdrv->crash_shutdown(pdev); +} + +void cnss_device_self_recovery(void) +{ + if (!penv) + return; + + if (penv->recovery_in_progress) { + pr_err("cnss: Recovery already in progress\n"); + return; + } + if (penv->driver_status == CNSS_LOAD_UNLOAD) { + pr_err("cnss: load unload in progress\n"); + return; + } + penv->recovery_count++; + penv->recovery_in_progress = true; + cnss_pm_wake_lock(&penv->ws); + cnss_shutdown(NULL, false); + msleep(WLAN_RECOVERY_DELAY); + cnss_powerup(NULL); + cnss_pm_wake_lock_release(&penv->ws); + penv->recovery_in_progress = false; +} +EXPORT_SYMBOL(cnss_device_self_recovery); + +static int cnss_modem_notifier_nb(struct notifier_block *this, + unsigned long code, + void *ss_handle) +{ + struct cnss_wlan_driver *wdrv; + struct pci_dev *pdev; + + pr_debug("%s: Modem-Notify: event %lu\n", __func__, code); + + if (!penv) + return NOTIFY_DONE; + + if (code == SUBSYS_AFTER_POWERUP) + penv->modem_current_status = 1; + else if (code == SUBSYS_BEFORE_SHUTDOWN) + penv->modem_current_status = 0; + else + return NOTIFY_DONE; + + wdrv = penv->driver; + pdev = penv->pdev; + + if (!wdrv || !pdev || !wdrv->modem_status) + return NOTIFY_DONE; + + wdrv->modem_status(pdev, penv->modem_current_status); + + return NOTIFY_OK; +} + +static struct notifier_block mnb = { + .notifier_call = cnss_modem_notifier_nb, +}; + +static int cnss_init_dump_entry(void) +{ + struct msm_dump_entry dump_entry; + + if (!penv) + return -ENODEV; + + if (!penv->ramdump_dynamic) + return 0; + + penv->dump_data.addr = penv->ramdump_phys; + penv->dump_data.len = penv->ramdump_size; + penv->dump_data.version = CNSS_DUMP_FORMAT_VER; + penv->dump_data.magic = CNSS_DUMP_MAGIC_VER_V2; + strlcpy(penv->dump_data.name, CNSS_DUMP_NAME, + sizeof(penv->dump_data.name)); + dump_entry.id = MSM_DUMP_DATA_CNSS_WLAN; + dump_entry.addr = virt_to_phys(&penv->dump_data); + + return msm_dump_data_register(MSM_DUMP_TABLE_APPS, &dump_entry); +} + +struct dma_iommu_mapping *cnss_smmu_get_mapping(void) +{ + if (!penv) { + pr_err("Invalid penv: data %pK\n", penv); + return NULL; + } + + return penv->smmu_mapping; +} +EXPORT_SYMBOL(cnss_smmu_get_mapping); + +int cnss_smmu_map(phys_addr_t paddr, uint32_t *iova_addr, size_t size) +{ + unsigned long iova; + size_t len; + int ret = 0; + + if (!iova_addr) { + pr_err("iova_addr is NULL, paddr %pa, size %zu\n", + &paddr, size); + return -EINVAL; + } + + len = roundup(size + paddr - rounddown(paddr, PAGE_SIZE), PAGE_SIZE); + iova = roundup(penv->smmu_iova_ipa_start, PAGE_SIZE); + + if (iova >= penv->smmu_iova_ipa_start + penv->smmu_iova_ipa_len) { + pr_err("No IOVA space to map, iova %lx, smmu_iova_ipa_start %pad, smmu_iova_ipa_len %zu\n", + iova, + &penv->smmu_iova_ipa_start, + penv->smmu_iova_ipa_len); + return -ENOMEM; + } + + ret = iommu_map(penv->smmu_mapping->domain, iova, + rounddown(paddr, PAGE_SIZE), len, + IOMMU_READ | IOMMU_WRITE); + if (ret) { + pr_err("PA to IOVA mapping failed, ret %d\n", ret); + return ret; + } + + penv->smmu_iova_ipa_start = iova + len; + *iova_addr = (uint32_t)(iova + paddr - rounddown(paddr, PAGE_SIZE)); + + return 0; +} +EXPORT_SYMBOL(cnss_smmu_map); + +static int cnss_probe(struct platform_device *pdev) +{ + int ret = 0; + struct esoc_desc *desc; + const char *client_desc; + struct device *dev = &pdev->dev; + u32 rc_num; + struct resource *res; + u32 ramdump_size = 0; + u32 smmu_iova_address[2]; + u32 smmu_iova_ipa[2]; + + if (penv) + return -ENODEV; + + penv = devm_kzalloc(&pdev->dev, sizeof(*penv), GFP_KERNEL); + if (!penv) + return -ENOMEM; + + penv->pldev = pdev; + penv->esoc_desc = NULL; + + penv->gpio_info.name = WLAN_EN_GPIO_NAME; + penv->gpio_info.num = 0; + penv->gpio_info.state = WLAN_EN_LOW; + penv->gpio_info.init = WLAN_EN_LOW; + penv->gpio_info.prop = false; + penv->vreg_info.wlan_reg = NULL; + penv->vreg_info.state = VREG_OFF; + penv->pci_register_again = false; + mutex_init(&penv->fw_setup_stat_lock); + + ret = cnss_wlan_get_resources(pdev); + if (ret) + goto err_get_wlan_res; + + ret = cnss_configure_wlan_en_gpio(WLAN_EN_HIGH); + if (ret) { + pr_err("%s: Failed to enable WLAN enable gpio\n", __func__); + goto err_get_rc; + } + + ret = of_property_read_u32(dev->of_node, "qcom,wlan-rc-num", &rc_num); + if (ret) { + pr_err("%s: Failed to find PCIe RC number\n", __func__); + goto err_get_rc; + } + + ret = cnss_msm_pcie_enumerate(rc_num); + if (ret) { + pr_err("%s: Failed to enable PCIe RC%x\n", __func__, rc_num); + goto err_pcie_enumerate; + } + + penv->pcie_link_state = PCIE_LINK_UP; + + penv->notify_modem_status = + of_property_read_bool(dev->of_node, + "qcom,notify-modem-status"); + + if (penv->notify_modem_status) { + ret = of_property_read_string_index(dev->of_node, "esoc-names", + 0, &client_desc); + if (ret) { + pr_debug("%s: esoc-names is not defined in DT, SKIP\n", + __func__); + } else { + desc = devm_register_esoc_client(dev, client_desc); + if (IS_ERR_OR_NULL(desc)) { + ret = PTR_RET(desc); + pr_err("%s: can't find esoc desc\n", __func__); + goto err_esoc_reg; + } + penv->esoc_desc = desc; + } + } + + penv->subsysdesc.name = "AR6320"; + penv->subsysdesc.owner = THIS_MODULE; + penv->subsysdesc.shutdown = cnss_shutdown; + penv->subsysdesc.powerup = cnss_powerup; + penv->subsysdesc.ramdump = cnss_ramdump; + penv->subsysdesc.crash_shutdown = cnss_crash_shutdown; + penv->subsysdesc.dev = &pdev->dev; + penv->subsys = subsys_register(&penv->subsysdesc); + if (IS_ERR(penv->subsys)) { + ret = PTR_ERR(penv->subsys); + goto err_subsys_reg; + } + + penv->subsys_handle = subsystem_get(penv->subsysdesc.name); + + if (of_property_read_bool(dev->of_node, "qcom,is-dual-wifi-enabled")) + penv->dual_wifi_info.is_dual_wifi_enabled = true; + + if (of_property_read_u32(dev->of_node, "qcom,wlan-ramdump-dynamic", + &ramdump_size) == 0) { + penv->ramdump_addr = dma_alloc_coherent(&pdev->dev, + ramdump_size, + &penv->ramdump_phys, + GFP_KERNEL); + + if (penv->ramdump_addr) + penv->ramdump_size = ramdump_size; + penv->ramdump_dynamic = true; + } else { + res = platform_get_resource_byname(penv->pldev, + IORESOURCE_MEM, "ramdump"); + if (res) { + penv->ramdump_phys = res->start; + ramdump_size = resource_size(res); + penv->ramdump_addr = ioremap(penv->ramdump_phys, + ramdump_size); + + if (penv->ramdump_addr) + penv->ramdump_size = ramdump_size; + + penv->ramdump_dynamic = false; + } + } + + pr_debug("%s: ramdump addr: %p, phys: %pa\n", __func__, + penv->ramdump_addr, &penv->ramdump_phys); + + if (penv->ramdump_size == 0) { + pr_info("%s: CNSS ramdump will not be collected\n", __func__); + goto skip_ramdump; + } + + ret = cnss_init_dump_entry(); + if (ret) { + pr_err("%s: Dump table setup failed: %d\n", __func__, ret); + goto err_ramdump_create; + } + + penv->ramdump_dev = create_ramdump_device(penv->subsysdesc.name, + penv->subsysdesc.dev); + if (!penv->ramdump_dev) { + ret = -ENOMEM; + goto err_ramdump_create; + } + +skip_ramdump: + penv->modem_current_status = 0; + + if (penv->notify_modem_status) { + penv->modem_notify_handler = + subsys_notif_register_notifier(penv->esoc_desc ? + penv->esoc_desc->name : + "modem", &mnb); + if (IS_ERR(penv->modem_notify_handler)) { + ret = PTR_ERR(penv->modem_notify_handler); + pr_err("%s: Register notifier Failed\n", __func__); + goto err_notif_modem; + } + } + + if (of_property_read_u32_array(dev->of_node, + "qcom,wlan-smmu-iova-address", + smmu_iova_address, 2) == 0) { + penv->smmu_iova_start = smmu_iova_address[0]; + penv->smmu_iova_len = smmu_iova_address[1]; + } + + if (of_property_read_u32_array(dev->of_node, + "qcom,wlan-smmu-iova-ipa", + smmu_iova_ipa, 2) == 0) { + penv->smmu_iova_ipa_start = smmu_iova_ipa[0]; + penv->smmu_iova_ipa_len = smmu_iova_ipa[1]; + } + + if (of_property_read_bool(dev->of_node, + "qcom,smmu-s1-bypass")) + penv->smmu_s1_bypass = true; + + ret = pci_register_driver(&cnss_wlan_pci_driver); + if (ret) + goto err_pci_reg; + + penv->bus_scale_table = 0; + penv->bus_scale_table = msm_bus_cl_get_pdata(pdev); + + if (penv->bus_scale_table) { + penv->bus_client = + msm_bus_scale_register_client(penv->bus_scale_table); + + if (!penv->bus_client) { + pr_err("Failed to register with bus_scale client\n"); + goto err_bus_reg; + } + } + cnss_pm_wake_lock_init(&penv->ws, "cnss_wlock"); + + register_pm_notifier(&cnss_pm_notifier); + +#ifdef CONFIG_CNSS_MAC_BUG + /* 0-4K memory is reserved for QCA6174 to address a MAC HW bug. + * MAC would do an invalid pointer fetch based on the data + * that was read from 0 to 4K. So fill it with zero's (to an + * address for which PCIe RC honored the read without any errors). + */ + memset(phys_to_virt(0), 0, SZ_4K); +#endif + + ret = device_create_file(dev, &dev_attr_fw_image_setup); + if (ret) { + pr_err("cnss: fw_image_setup sys file creation failed\n"); + goto err_bus_reg; + } + pr_debug("cnss: Platform driver probed successfully.\n"); + return ret; + +err_bus_reg: + if (penv->bus_scale_table) + msm_bus_cl_clear_pdata(penv->bus_scale_table); + pci_unregister_driver(&cnss_wlan_pci_driver); + +err_pci_reg: + if (penv->notify_modem_status) + subsys_notif_unregister_notifier + (penv->modem_notify_handler, &mnb); + +err_notif_modem: + if (penv->ramdump_dev) + destroy_ramdump_device(penv->ramdump_dev); + +err_ramdump_create: + if (penv->ramdump_addr) { + if (penv->ramdump_dynamic) { + dma_free_coherent(&pdev->dev, penv->ramdump_size, + penv->ramdump_addr, + penv->ramdump_phys); + } else { + iounmap(penv->ramdump_addr); + } + } + + if (penv->subsys_handle) + subsystem_put(penv->subsys_handle); + + subsys_unregister(penv->subsys); + +err_subsys_reg: + if (penv->esoc_desc) + devm_unregister_esoc_client(&pdev->dev, penv->esoc_desc); + +err_esoc_reg: +err_pcie_enumerate: +err_get_rc: + cnss_configure_wlan_en_gpio(WLAN_EN_LOW); + cnss_wlan_release_resources(); + +err_get_wlan_res: + penv = NULL; + + return ret; +} + +static int cnss_remove(struct platform_device *pdev) +{ + unregister_pm_notifier(&cnss_pm_notifier); + device_remove_file(&pdev->dev, &dev_attr_fw_image_setup); + + cnss_pm_wake_lock_destroy(&penv->ws); + + if (penv->bus_client) + msm_bus_scale_unregister_client(penv->bus_client); + + if (penv->bus_scale_table) + msm_bus_cl_clear_pdata(penv->bus_scale_table); + + if (penv->ramdump_addr) { + if (penv->ramdump_dynamic) { + dma_free_coherent(&pdev->dev, penv->ramdump_size, + penv->ramdump_addr, + penv->ramdump_phys); + } else { + iounmap(penv->ramdump_addr); + } + } + + cnss_configure_wlan_en_gpio(WLAN_EN_LOW); + if (penv->wlan_bootstrap_gpio > 0) + gpio_set_value(penv->wlan_bootstrap_gpio, WLAN_BOOTSTRAP_LOW); + cnss_wlan_release_resources(); + + return 0; +} + +static const struct of_device_id cnss_dt_match[] = { + {.compatible = "qcom,cnss"}, + {} +}; + +MODULE_DEVICE_TABLE(of, cnss_dt_match); + +static struct platform_driver cnss_driver = { + .probe = cnss_probe, + .remove = cnss_remove, + .driver = { + .name = "cnss", + .owner = THIS_MODULE, + .of_match_table = cnss_dt_match, +#ifdef CONFIG_CNSS_ASYNC + .probe_type = PROBE_PREFER_ASYNCHRONOUS, +#endif + }, +}; + +static int __init cnss_initialize(void) +{ + return platform_driver_register(&cnss_driver); +} + +static void __exit cnss_exit(void) +{ + struct platform_device *pdev = penv->pldev; + + if (penv->ramdump_dev) + destroy_ramdump_device(penv->ramdump_dev); + if (penv->notify_modem_status) + subsys_notif_unregister_notifier(penv->modem_notify_handler, + &mnb); + subsys_unregister(penv->subsys); + if (penv->esoc_desc) + devm_unregister_esoc_client(&pdev->dev, penv->esoc_desc); + platform_driver_unregister(&cnss_driver); +} + +void cnss_request_pm_qos_type(int latency_type, u32 qos_val) +{ + if (!penv) { + pr_err("%s: penv is NULL\n", __func__); + return; + } + + pm_qos_add_request(&penv->qos_request, latency_type, qos_val); +} +EXPORT_SYMBOL(cnss_request_pm_qos_type); + +void cnss_request_pm_qos(u32 qos_val) +{ + if (!penv) { + pr_err("%s: penv is NULL\n", __func__); + return; + } + + pm_qos_add_request(&penv->qos_request, PM_QOS_CPU_DMA_LATENCY, qos_val); +} +EXPORT_SYMBOL(cnss_request_pm_qos); + +void cnss_remove_pm_qos(void) +{ + if (!penv) { + pr_err("%s: penv is NULL\n", __func__); + return; + } + + pm_qos_remove_request(&penv->qos_request); +} +EXPORT_SYMBOL(cnss_remove_pm_qos); + +void cnss_pci_request_pm_qos_type(int latency_type, u32 qos_val) +{ + if (!penv) { + pr_err("%s: penv is NULL\n", __func__); + return; + } + + pm_qos_add_request(&penv->qos_request, latency_type, qos_val); +} +EXPORT_SYMBOL(cnss_pci_request_pm_qos_type); + +void cnss_pci_request_pm_qos(u32 qos_val) +{ + if (!penv) { + pr_err("%s: penv is NULL\n", __func__); + return; + } + + pm_qos_add_request(&penv->qos_request, PM_QOS_CPU_DMA_LATENCY, qos_val); +} +EXPORT_SYMBOL(cnss_pci_request_pm_qos); + +void cnss_pci_remove_pm_qos(void) +{ + if (!penv) { + pr_err("%s: penv is NULL\n", __func__); + return; + } + + pm_qos_remove_request(&penv->qos_request); +} +EXPORT_SYMBOL(cnss_pci_remove_pm_qos); + +int cnss_pci_request_bus_bandwidth(int bandwidth) +{ + int ret = 0; + + if (!penv) + return -ENODEV; + + if (!penv->bus_client) + return -EINVAL; + + switch (bandwidth) { + case CNSS_BUS_WIDTH_NONE: + case CNSS_BUS_WIDTH_LOW: + case CNSS_BUS_WIDTH_MEDIUM: + case CNSS_BUS_WIDTH_HIGH: + ret = msm_bus_scale_client_update_request( + penv->bus_client, bandwidth); + if (!ret) { + penv->current_bandwidth_vote = bandwidth; + } else { + pr_err("%s: could not set bus bandwidth %d, ret = %d\n", + __func__, bandwidth, ret); + } + break; + + default: + pr_err("%s: Invalid request %d\n", __func__, bandwidth); + ret = -EINVAL; + } + return ret; +} + +int cnss_request_bus_bandwidth(int bandwidth) +{ + int ret = 0; + + if (!penv) + return -ENODEV; + + if (!penv->bus_client) + return -EINVAL; + + switch (bandwidth) { + case CNSS_BUS_WIDTH_NONE: + case CNSS_BUS_WIDTH_LOW: + case CNSS_BUS_WIDTH_MEDIUM: + case CNSS_BUS_WIDTH_HIGH: + ret = msm_bus_scale_client_update_request( + penv->bus_client, bandwidth); + if (!ret) { + penv->current_bandwidth_vote = bandwidth; + } else { + pr_err("%s: could not set bus bandwidth %d, ret = %d\n", + __func__, bandwidth, ret); + } + break; + + default: + pr_err("%s: Invalid request %d\n", __func__, bandwidth); + ret = -EINVAL; + } + return ret; +} +EXPORT_SYMBOL(cnss_request_bus_bandwidth); + +int cnss_get_platform_cap(struct cnss_platform_cap *cap) +{ + if (!penv) + return -ENODEV; + + if (cap) + *cap = penv->cap; + + return 0; +} +EXPORT_SYMBOL(cnss_get_platform_cap); + +void cnss_set_driver_status(enum cnss_driver_status driver_status) +{ + penv->driver_status = driver_status; +} +EXPORT_SYMBOL(cnss_set_driver_status); + +int cnss_get_bmi_setup(void) +{ + if (!penv) + return -ENODEV; + + return penv->bmi_test; +} +EXPORT_SYMBOL(cnss_get_bmi_setup); + +#ifdef CONFIG_CNSS_SECURE_FW +int cnss_get_sha_hash(const u8 *data, u32 data_len, u8 *hash_idx, u8 *out) +{ + struct scatterlist sg; + struct hash_desc desc; + int ret = 0; + + if (!out) { + pr_err("memory for output buffer is not allocated\n"); + ret = -EINVAL; + goto end; + } + + desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; + desc.tfm = crypto_alloc_hash(hash_idx, 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(desc.tfm)) { + pr_err("crypto_alloc_hash failed:%ld\n", PTR_ERR(desc.tfm)); + ret = PTR_ERR(desc.tfm); + goto end; + } + + sg_init_one(&sg, data, data_len); + ret = crypto_hash_digest(&desc, &sg, sg.length, out); + crypto_free_hash(desc.tfm); +end: + return ret; +} +EXPORT_SYMBOL(cnss_get_sha_hash); + +void *cnss_get_fw_ptr(void) +{ + if (!penv) + return NULL; + + return penv->fw_mem; +} +EXPORT_SYMBOL(cnss_get_fw_ptr); +#endif + +int cnss_auto_suspend(void) +{ + int ret = 0; + struct pci_dev *pdev; + + if (!penv || !penv->driver) + return -ENODEV; + + pdev = penv->pdev; + + if (penv->pcie_link_state) { + pci_save_state(pdev); + penv->saved_state = cnss_pci_store_saved_state(pdev); + pci_disable_device(pdev); + ret = pci_set_power_state(pdev, PCI_D3hot); + if (ret) + pr_err("%s: Set D3Hot failed: %d\n", __func__, ret); + if (cnss_msm_pcie_pm_control( + MSM_PCIE_SUSPEND, + cnss_get_pci_dev_bus_number(pdev), + pdev, PM_OPTIONS)) { + pr_err("%s: Failed to shutdown PCIe link\n", __func__); + ret = -EAGAIN; + goto out; + } + } + atomic_set(&penv->auto_suspended, 1); + penv->monitor_wake_intr = true; + penv->pcie_link_state = PCIE_LINK_DOWN; + + msm_bus_scale_client_update_request(penv->bus_client, + CNSS_BUS_WIDTH_NONE); +out: + return ret; +} +EXPORT_SYMBOL(cnss_auto_suspend); + +int cnss_auto_resume(void) +{ + int ret = 0; + struct pci_dev *pdev; + + if (!penv || !penv->driver) + return -ENODEV; + + pdev = penv->pdev; + if (!penv->pcie_link_state) { + if (cnss_msm_pcie_pm_control( + MSM_PCIE_RESUME, cnss_get_pci_dev_bus_number(pdev), + pdev, PM_OPTIONS)) { + pr_err("%s: Failed to resume PCIe link\n", __func__); + ret = -EAGAIN; + goto out; + } + ret = pci_enable_device(pdev); + if (ret) + pr_err("%s: enable device failed: %d\n", __func__, ret); + penv->pcie_link_state = PCIE_LINK_UP; + } + + if (penv->saved_state) + cnss_pci_load_and_free_saved_state(pdev, &penv->saved_state); + + pci_restore_state(pdev); + pci_set_master(pdev); + + atomic_set(&penv->auto_suspended, 0); + + msm_bus_scale_client_update_request(penv->bus_client, + penv->current_bandwidth_vote); +out: + return ret; +} +EXPORT_SYMBOL(cnss_auto_resume); + +int cnss_pm_runtime_request(struct device *dev, + enum cnss_runtime_request request) +{ + int ret = 0; + + switch (request) { + case CNSS_PM_RUNTIME_GET: + ret = pm_runtime_get(dev); + break; + case CNSS_PM_RUNTIME_PUT: + ret = pm_runtime_put(dev); + break; + case CNSS_PM_RUNTIME_MARK_LAST_BUSY: + pm_runtime_mark_last_busy(dev); + break; + case CNSS_PM_RUNTIME_RESUME: + ret = pm_runtime_resume(dev); + break; + case CNSS_PM_RUNTIME_PUT_AUTO: + ret = pm_runtime_put_autosuspend(dev); + break; + case CNSS_PM_RUNTIME_PUT_NOIDLE: + pm_runtime_put_noidle(dev); + break; + case CNSS_PM_REQUEST_RESUME: + ret = pm_request_resume(dev); + break; + case CNSS_PM_GET_NORESUME: + pm_runtime_get_noresume(dev); + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} +EXPORT_SYMBOL(cnss_pm_runtime_request); + +void cnss_runtime_init(struct device *dev, int auto_delay) +{ + pm_runtime_set_autosuspend_delay(dev, auto_delay); + pm_runtime_use_autosuspend(dev); + pm_runtime_allow(dev); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_noidle(dev); + pm_suspend_ignore_children(dev, true); +} +EXPORT_SYMBOL(cnss_runtime_init); + +void cnss_runtime_exit(struct device *dev) +{ + pm_runtime_get_noresume(dev); + pm_runtime_set_active(dev); +} +EXPORT_SYMBOL(cnss_runtime_exit); + +static void __cnss_set_pcie_monitor_intr(struct device *dev, bool val) +{ + penv->monitor_wake_intr = val; +} + +static void __cnss_set_auto_suspend(struct device *dev, int val) +{ + atomic_set(&penv->auto_suspended, val); +} + +static int __cnss_resume_link(struct device *dev, u32 flags) +{ + int ret; + struct pci_dev *pdev = to_pci_dev(dev); + u8 bus_num = cnss_get_pci_dev_bus_number(pdev); + + ret = cnss_msm_pcie_pm_control(MSM_PCIE_RESUME, bus_num, pdev, flags); + if (ret) + pr_err("%s: PCIe link resume failed with flags:%d bus_num:%d\n", + __func__, flags, bus_num); + + penv->pcie_link_state = PCIE_LINK_UP; + + return ret; +} + +static int __cnss_suspend_link(struct device *dev, u32 flags) +{ + struct pci_dev *pdev = to_pci_dev(dev); + u8 bus_num = cnss_get_pci_dev_bus_number(pdev); + int ret; + + if (!penv->pcie_link_state) + return 0; + + ret = cnss_msm_pcie_pm_control(MSM_PCIE_SUSPEND, bus_num, pdev, flags); + if (ret) { + pr_err("%s: Failed to suspend link\n", __func__); + return ret; + } + + penv->pcie_link_state = PCIE_LINK_DOWN; + + return ret; +} + +static int __cnss_pcie_recover_config(struct device *dev) +{ + int ret; + + ret = cnss_msm_pcie_recover_config(to_pci_dev(dev)); + if (ret) + pr_err("%s: PCIe Recover config failed\n", __func__); + + return ret; +} + +static int __cnss_event_reg(struct device *dev) +{ + int ret; + struct msm_pcie_register_event *event_reg; + + event_reg = &penv->event_reg; + + event_reg->events = MSM_PCIE_EVENT_LINKDOWN | + MSM_PCIE_EVENT_WAKEUP; + event_reg->user = to_pci_dev(dev); + event_reg->mode = MSM_PCIE_TRIGGER_CALLBACK; + event_reg->callback = cnss_pci_events_cb; + event_reg->options = MSM_PCIE_CONFIG_NO_RECOVERY; + + ret = cnss_msm_pcie_register_event(event_reg); + if (ret) + pr_err("%s: PCIe event register failed %d\n", __func__, ret); + + return ret; +} + +static void __cnss_event_dereg(struct device *dev) +{ + cnss_msm_pcie_deregister_event(&penv->event_reg); +} + +static struct pci_dev *__cnss_get_pcie_dev(struct device *dev) +{ + int ret; + struct pci_dev *pdev = penv->pdev; + + if (pdev) + return pdev; + + ret = pci_register_driver(&cnss_wlan_pci_driver); + if (ret) { + pr_err("%s: pci re-registration failed\n", __func__); + return NULL; + } + + pdev = penv->pdev; + + return pdev; +} + +static int __cnss_pcie_power_up(struct device *dev) +{ + struct cnss_wlan_vreg_info *vreg_info; + struct cnss_wlan_gpio_info *gpio_info; + int ret; + + vreg_info = &penv->vreg_info; + gpio_info = &penv->gpio_info; + + ret = cnss_wlan_vreg_set(vreg_info, VREG_ON); + if (ret) { + pr_err("%s: WLAN VREG ON Failed\n", __func__); + return ret; + } + + msleep(POWER_ON_DELAY); + + if (penv->wlan_bootstrap_gpio > 0) { + gpio_set_value(penv->wlan_bootstrap_gpio, WLAN_BOOTSTRAP_HIGH); + msleep(WLAN_BOOTSTRAP_DELAY); + } + + cnss_configure_wlan_en_gpio(WLAN_EN_HIGH); + return 0; +} + +static int __cnss_pcie_power_down(struct device *dev) +{ + struct cnss_wlan_vreg_info *vreg_info; + struct cnss_wlan_gpio_info *gpio_info; + int ret; + + vreg_info = &penv->vreg_info; + gpio_info = &penv->gpio_info; + + cnss_configure_wlan_en_gpio(WLAN_EN_LOW); + if (penv->wlan_bootstrap_gpio > 0) + gpio_set_value(penv->wlan_bootstrap_gpio, WLAN_BOOTSTRAP_LOW); + + ret = cnss_wlan_vreg_set(vreg_info, VREG_OFF); + if (ret) + pr_err("%s: Failed to turn off 3.3V regulator\n", __func__); + + return ret; +} + +static int __cnss_suspend_link_state(struct device *dev) +{ + int ret; + struct pci_dev *pdev = to_pci_dev(dev); + int link_ind; + + if (!penv->pcie_link_state) { + pr_debug("%s: Link is already suspended\n", __func__); + return 0; + } + + link_ind = penv->pcie_link_down_ind; + + if (!link_ind) + pci_save_state(pdev); + + penv->saved_state = link_ind ? NULL : cnss_pci_store_saved_state(pdev); + + ret = link_ind ? __cnss_suspend_link(dev, PM_OPTIONS_SUSPEND_LINK_DOWN) + : __cnss_suspend_link(dev, PM_OPTIONS); + if (ret) { + pr_err("%s: Link Suspend failed in state:%s\n", __func__, + link_ind ? "LINK_DOWN" : "LINK_ACTIVE"); + return ret; + } + + penv->pcie_link_state = PCIE_LINK_DOWN; + + return 0; +} + +static int __cnss_restore_pci_config_space(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + int ret = 0; + + if (penv->saved_state) + ret = cnss_pci_load_and_free_saved_state(pdev, + &penv->saved_state); + pci_restore_state(pdev); + + return ret; +} + +static int __cnss_resume_link_state(struct device *dev) +{ + int ret; + int link_ind; + + if (penv->pcie_link_state) { + pr_debug("%s: Link is already in active state\n", __func__); + return 0; + } + + link_ind = penv->pcie_link_down_ind; + + ret = link_ind ? __cnss_resume_link(dev, PM_OPTIONS_RESUME_LINK_DOWN) : + __cnss_resume_link(dev, PM_OPTIONS); + + if (ret) { + pr_err("%s: Resume Link failed in link state:%s\n", __func__, + link_ind ? "LINK_DOWN" : "LINK_ACTIVE"); + return ret; + } + + penv->pcie_link_state = PCIE_LINK_UP; + + ret = link_ind ? __cnss_pcie_recover_config(dev) : + __cnss_restore_pci_config_space(dev); + + if (ret) { + pr_err("%s: Link Recovery Config Failed link_state:%s\n", + __func__, link_ind ? "LINK_DOWN" : "LINK_ACTIVE"); + penv->pcie_link_state = PCIE_LINK_DOWN; + return ret; + } + + penv->pcie_link_down_ind = false; + return ret; +} + +int cnss_pcie_power_up(struct device *dev) +{ + int ret; + struct pci_dev *pdev; + + if (!penv) { + pr_err("%s: platform data is NULL\n", __func__); + return -ENODEV; + } + + ret = __cnss_pcie_power_up(dev); + if (ret) { + pr_err("%s: Power UP Failed\n", __func__); + return ret; + } + + pdev = __cnss_get_pcie_dev(dev); + if (!pdev) { + pr_err("%s: PCIe Dev is NULL\n", __func__); + goto power_down; + } + + ret = __cnss_event_reg(dev); + + if (ret) + pr_err("%s: PCIe event registration failed\n", __func__); + + ret = __cnss_resume_link_state(dev); + + if (ret) { + pr_err("%s: Link Bring Up Failed\n", __func__); + goto event_dereg; + } + + __cnss_set_pcie_monitor_intr(dev, true); + + return ret; + +event_dereg: + __cnss_event_dereg(dev); +power_down: + __cnss_pcie_power_down(dev); + pr_err("%s: Device Power Up Failed Fatal Error\n", __func__); + return ret; +} + +static void __cnss_vote_bus_width(struct device *dev, u32 option) +{ + if (penv->bus_client) + msm_bus_scale_client_update_request(penv->bus_client, option); +} + +int cnss_pcie_power_down(struct device *dev) +{ + int ret; + struct pci_dev *pdev = to_pci_dev(dev); + + if (!penv) { + pr_err("%s: Invalid Platform data\n", __func__); + return -ENODEV; + } + + if (!pdev) { + pr_err("%s: Invalid Pdev, Cut Power to device\n", __func__); + __cnss_pcie_power_down(dev); + return -ENODEV; + } + + __cnss_vote_bus_width(dev, CNSS_BUS_WIDTH_NONE); + __cnss_event_dereg(dev); + + ret = __cnss_suspend_link_state(dev); + + if (ret) { + pr_err("%s: Suspend Link failed\n", __func__); + return ret; + } + + __cnss_set_pcie_monitor_intr(dev, false); + __cnss_set_auto_suspend(dev, 0); + + ret = __cnss_pcie_power_down(dev); + if (ret) + pr_err("%s: Power Down Failed\n", __func__); + + return ret; +} + +module_init(cnss_initialize); +module_exit(cnss_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION(DEVICE "CNSS Driver"); diff --git a/drivers/net/wireless/cnss/cnss_sdio.c b/drivers/net/wireless/cnss/cnss_sdio.c new file mode 100644 index 000000000000..dd1819271962 --- /dev/null +++ b/drivers/net/wireless/cnss/cnss_sdio.c @@ -0,0 +1,1607 @@ +/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define pr_fmt(fmt) "cnss_sdio:%s:%d:: " fmt, __func__, __LINE__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "cnss_common.h" +#include +#include +#include +#include +#include + +#define WLAN_VREG_NAME "vdd-wlan" +#define WLAN_VREG_DSRC_NAME "vdd-wlan-dsrc" +#define WLAN_VREG_IO_NAME "vdd-wlan-io" +#define WLAN_VREG_XTAL_NAME "vdd-wlan-xtal" +#define WLAN_GPIO_CAPTSF_NAME "qcom,cap-tsf-gpio" + +#define WLAN_VREG_IO_MAX 1800000 +#define WLAN_VREG_IO_MIN 1800000 +#define WLAN_VREG_XTAL_MAX 3465000 +#define WLAN_VREG_XTAL_MIN 1620000 +#define WLAN_VREG_XTAL_TYP 1800000 +#define POWER_ON_DELAY 4 + +/* Values for Dynamic Ramdump Collection*/ +#define CNSS_DUMP_FORMAT_VER 0x11 +#define CNSS_DUMP_MAGIC_VER_V2 0x42445953 +#define CNSS_DUMP_NAME "CNSS_WLAN_SDIO" +#define CNSS_PINCTRL_SLEEP_STATE "sleep" +#define CNSS_PINCTRL_ACTIVE_STATE "active" + +#define CNSS_HW_SLEEP 0 +#define CNSS_HW_ACTIVE 1 + +struct cnss_sdio_regulator { + struct regulator *wlan_io; + struct regulator *wlan_xtal; + struct regulator *wlan_vreg; + struct regulator *wlan_vreg_dsrc; +}; + +struct cnss_sdio_info { + struct cnss_sdio_wlan_driver *wdrv; + struct sdio_func *func; + struct mmc_card *card; + struct mmc_host *host; + struct device *dev; + const struct sdio_device_id *id; + bool skip_wlan_en_toggle; + bool cnss_hw_state; + struct cnss_cap_tsf_info cap_tsf_info; +}; + +struct cnss_ssr_info { + struct subsys_device *subsys; + struct subsys_desc subsysdesc; + void *subsys_handle; + struct ramdump_device *ramdump_dev; + unsigned long ramdump_size; + void *ramdump_addr; + phys_addr_t ramdump_phys; + struct msm_dump_data dump_data; + bool ramdump_dynamic; + char subsys_name[10]; +}; + +struct cnss_wlan_pinctrl_info { + bool is_antenna_shared; + struct pinctrl *pinctrl; + struct pinctrl_state *sleep; + struct pinctrl_state *active; +}; + +struct cnss_sdio_bus_bandwidth { + struct msm_bus_scale_pdata *bus_scale_table; + u32 bus_client; + int current_bandwidth_vote; +}; + +static struct cnss_sdio_data { + struct cnss_sdio_regulator regulator; + struct platform_device *pdev; + struct cnss_sdio_info cnss_sdio_info; + struct cnss_ssr_info ssr_info; + struct pm_qos_request qos_request; + struct cnss_wlan_pinctrl_info pinctrl_info; + struct cnss_sdio_bus_bandwidth bus_bandwidth; + struct cnss_dev_platform_ops platform_ops; +} *cnss_pdata; + +#define WLAN_RECOVERY_DELAY 1 +/* cnss sdio subsytem device name, required property */ +#define CNSS_SUBSYS_NAME_KEY "subsys-name" + +/* SDIO manufacturer ID and Codes */ +#define MANUFACTURER_ID_AR6320_BASE 0x500 +#define MANUFACTURER_ID_QCA9377_BASE 0x700 +#define MANUFACTURER_ID_QCA9379_BASE 0x800 +#define MANUFACTURER_CODE 0x271 + +static const struct sdio_device_id ar6k_id_table[] = { + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x0))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x1))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x2))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x3))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x4))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x5))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x6))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x7))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x8))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x9))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0xA))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0xB))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0xC))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0xD))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0xE))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0xF))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x0))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x1))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x2))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x3))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x4))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x5))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x6))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x7))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x8))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x9))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0xA))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0xB))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0xC))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0xD))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0xE))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0xF))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9379_BASE | 0x0))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9379_BASE | 0x1))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9379_BASE | 0x2))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9379_BASE | 0x3))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9379_BASE | 0x4))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9379_BASE | 0x5))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9379_BASE | 0x6))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9379_BASE | 0x7))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9379_BASE | 0x8))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9379_BASE | 0x9))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9379_BASE | 0xA))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9379_BASE | 0xB))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9379_BASE | 0xC))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9379_BASE | 0xD))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9379_BASE | 0xE))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9379_BASE | 0xF))}, + {}, +}; +MODULE_DEVICE_TABLE(sdio, ar6k_id_table); + +void cnss_sdio_request_pm_qos_type(int latency_type, u32 qos_val) +{ + if (!cnss_pdata) + return; + + pr_debug("PM QoS value: %d\n", qos_val); + pm_qos_add_request(&cnss_pdata->qos_request, latency_type, qos_val); +} +EXPORT_SYMBOL(cnss_sdio_request_pm_qos_type); + +int cnss_sdio_request_bus_bandwidth(int bandwidth) +{ + int ret; + struct cnss_sdio_bus_bandwidth *bus_bandwidth; + + if (!cnss_pdata) + return -ENODEV; + + bus_bandwidth = &cnss_pdata->bus_bandwidth; + if (!bus_bandwidth->bus_client) + return -EINVAL; + + switch (bandwidth) { + case CNSS_BUS_WIDTH_NONE: + case CNSS_BUS_WIDTH_LOW: + case CNSS_BUS_WIDTH_MEDIUM: + case CNSS_BUS_WIDTH_HIGH: + ret = msm_bus_scale_client_update_request( + bus_bandwidth->bus_client, bandwidth); + if (!ret) { + bus_bandwidth->current_bandwidth_vote = bandwidth; + } else { + pr_debug( + "could not set bus bandwidth %d, ret = %d\n", + bandwidth, ret); + } + break; + default: + pr_debug("Invalid request %d\n", bandwidth); + ret = -EINVAL; + } + + return ret; +} + +void cnss_sdio_request_pm_qos(u32 qos_val) +{ + if (!cnss_pdata) + return; + + pr_debug("PM QoS value: %d\n", qos_val); + pm_qos_add_request( + &cnss_pdata->qos_request, + PM_QOS_CPU_DMA_LATENCY, qos_val); +} +EXPORT_SYMBOL(cnss_sdio_request_pm_qos); + +void cnss_sdio_remove_pm_qos(void) +{ + if (!cnss_pdata) + return; + + pm_qos_remove_request(&cnss_pdata->qos_request); + pr_debug("PM QoS removed\n"); +} +EXPORT_SYMBOL(cnss_sdio_remove_pm_qos); + +static int cnss_put_hw_resources(struct device *dev) +{ + int ret = -EINVAL; + struct cnss_sdio_info *info; + struct mmc_host *host; + + if (!cnss_pdata) + return ret; + + info = &cnss_pdata->cnss_sdio_info; + + if (info->skip_wlan_en_toggle) { + pr_debug("HW doesn't support wlan toggling\n"); + return 0; + } + + if (info->cnss_hw_state == CNSS_HW_SLEEP) { + pr_debug("HW resources are already released\n"); + return 0; + } + + host = info->host; + + if (!host) { + pr_err("MMC host is invalid\n"); + return ret; + } + + ret = mmc_power_save_host(host); + if (ret) { + pr_err("Failed to Power Save Host err:%d\n", + ret); + return ret; + } + + if (cnss_pdata->regulator.wlan_vreg) + regulator_disable(cnss_pdata->regulator.wlan_vreg); + else + pr_debug("wlan_vreg regulator is invalid\n"); + + info->cnss_hw_state = CNSS_HW_SLEEP; + + return ret; +} + +static int cnss_get_hw_resources(struct device *dev) +{ + int ret = -EINVAL; + struct mmc_host *host; + struct cnss_sdio_info *info; + + if (!cnss_pdata) + return ret; + + info = &cnss_pdata->cnss_sdio_info; + + if (info->skip_wlan_en_toggle) { + pr_debug("HW doesn't support wlan toggling\n"); + return 0; + } + + if (info->cnss_hw_state == CNSS_HW_ACTIVE) { + pr_debug("HW resources are already active\n"); + return 0; + } + + host = info->host; + + if (!host) { + pr_err("MMC Host is Invalid; Enumeration Failed\n"); + return ret; + } + + if (cnss_pdata->regulator.wlan_vreg) { + ret = regulator_enable(cnss_pdata->regulator.wlan_vreg); + if (ret) { + pr_err("Failed to enable wlan vreg\n"); + return ret; + } + } else { + pr_debug("wlan_vreg regulator is invalid\n"); + } + + ret = mmc_power_restore_host(host); + if (ret) { + pr_err("Failed to restore host power ret:%d\n", + ret); + if (cnss_pdata->regulator.wlan_vreg) + regulator_disable(cnss_pdata->regulator.wlan_vreg); + return ret; + } + + info->cnss_hw_state = CNSS_HW_ACTIVE; + return ret; +} + +static int cnss_sdio_shutdown(const struct subsys_desc *subsys, bool force_stop) +{ + struct cnss_sdio_info *cnss_info; + struct cnss_sdio_wlan_driver *wdrv; + int ret = 0; + + if (!cnss_pdata) + return -ENODEV; + + cnss_info = &cnss_pdata->cnss_sdio_info; + wdrv = cnss_info->wdrv; + if (!wdrv) + return 0; + if (!wdrv->shutdown) + return 0; + + wdrv->shutdown(cnss_info->func); + ret = cnss_put_hw_resources(cnss_info->dev); + + if (ret) + pr_err("Failed to put hw resources\n"); + + return ret; +} + +static int cnss_sdio_powerup(const struct subsys_desc *subsys) +{ + struct cnss_sdio_info *cnss_info; + struct cnss_sdio_wlan_driver *wdrv; + int ret = 0; + + if (!cnss_pdata) + return -ENODEV; + + cnss_info = &cnss_pdata->cnss_sdio_info; + wdrv = cnss_info->wdrv; + + if (!wdrv) + return 0; + + if (!wdrv->reinit) + return 0; + + ret = cnss_get_hw_resources(cnss_info->dev); + if (ret) { + pr_err("Failed to power up HW\n"); + return ret; + } + + ret = wdrv->reinit(cnss_info->func, cnss_info->id); + if (ret) + pr_err("wlan reinit error=%d\n", ret); + + return ret; +} + +static void cnss_sdio_crash_shutdown(const struct subsys_desc *subsys) +{ + struct cnss_sdio_info *cnss_info; + struct cnss_sdio_wlan_driver *wdrv; + + if (!cnss_pdata) + return; + + cnss_info = &cnss_pdata->cnss_sdio_info; + wdrv = cnss_info->wdrv; + if (wdrv && wdrv->crash_shutdown) + wdrv->crash_shutdown(cnss_info->func); +} + +static int cnss_sdio_ramdump(int enable, const struct subsys_desc *subsys) +{ + struct cnss_ssr_info *ssr_info; + struct ramdump_segment segment; + int ret; + + if (!cnss_pdata) + return -ENODEV; + + if (!cnss_pdata->ssr_info.ramdump_size) + return -ENOENT; + + if (!enable) + return 0; + + ssr_info = &cnss_pdata->ssr_info; + + memset(&segment, 0, sizeof(segment)); + segment.v_address = ssr_info->ramdump_addr; + segment.size = ssr_info->ramdump_size; + ret = do_ramdump(ssr_info->ramdump_dev, &segment, 1); + if (ret) + pr_err("do_ramdump failed error=%d\n", ret); + return ret; +} + +static int cnss_subsys_init(void) +{ + struct cnss_ssr_info *ssr_info; + int ret = 0; + + if (!cnss_pdata) + return -ENODEV; + + ssr_info = &cnss_pdata->ssr_info; + ssr_info->subsysdesc.name = ssr_info->subsys_name; + ssr_info->subsysdesc.owner = THIS_MODULE; + ssr_info->subsysdesc.shutdown = cnss_sdio_shutdown; + ssr_info->subsysdesc.powerup = cnss_sdio_powerup; + ssr_info->subsysdesc.ramdump = cnss_sdio_ramdump; + ssr_info->subsysdesc.crash_shutdown = cnss_sdio_crash_shutdown; + ssr_info->subsysdesc.dev = &cnss_pdata->pdev->dev; + ssr_info->subsys = subsys_register(&ssr_info->subsysdesc); + if (IS_ERR(ssr_info->subsys)) { + ret = PTR_ERR(ssr_info->subsys); + ssr_info->subsys = NULL; + dev_err(&cnss_pdata->pdev->dev, "Failed to subsys_register error=%d\n", + ret); + goto err_subsys_reg; + } + ssr_info->subsys_handle = subsystem_get(ssr_info->subsysdesc.name); + if (IS_ERR(ssr_info->subsys_handle)) { + ret = PTR_ERR(ssr_info->subsys_handle); + ssr_info->subsys_handle = NULL; + dev_err(&cnss_pdata->pdev->dev, "Failed to subsystem_get error=%d\n", + ret); + goto err_subsys_get; + } + return 0; +err_subsys_get: + subsys_unregister(ssr_info->subsys); + ssr_info->subsys = NULL; +err_subsys_reg: + return ret; +} + +static void cnss_subsys_exit(void) +{ + struct cnss_ssr_info *ssr_info; + + if (!cnss_pdata) + return; + + ssr_info = &cnss_pdata->ssr_info; + if (ssr_info->subsys_handle) + subsystem_put(ssr_info->subsys_handle); + ssr_info->subsys_handle = NULL; + if (ssr_info->subsys) + subsys_unregister(ssr_info->subsys); + ssr_info->subsys = NULL; +} + +static int cnss_configure_dump_table(struct cnss_ssr_info *ssr_info) +{ + struct msm_dump_entry dump_entry; + int ret; + + ssr_info->dump_data.addr = ssr_info->ramdump_phys; + ssr_info->dump_data.len = ssr_info->ramdump_size; + ssr_info->dump_data.version = CNSS_DUMP_FORMAT_VER; + ssr_info->dump_data.magic = CNSS_DUMP_MAGIC_VER_V2; + strlcpy(ssr_info->dump_data.name, CNSS_DUMP_NAME, + sizeof(ssr_info->dump_data.name)); + + dump_entry.id = MSM_DUMP_DATA_CNSS_WLAN; + dump_entry.addr = virt_to_phys(&ssr_info->dump_data); + + ret = msm_dump_data_register(MSM_DUMP_TABLE_APPS, &dump_entry); + if (ret) + pr_err("Dump table setup failed: %d\n", ret); + + return ret; +} + +static int cnss_configure_ramdump(void) +{ + struct cnss_ssr_info *ssr_info; + int ret = 0; + struct resource *res; + const char *name; + u32 ramdump_size = 0; + struct device *dev; + + if (!cnss_pdata) + return -ENODEV; + + dev = &cnss_pdata->pdev->dev; + + ssr_info = &cnss_pdata->ssr_info; + + ret = of_property_read_string(dev->of_node, CNSS_SUBSYS_NAME_KEY, + &name); + if (ret) { + pr_err("cnss missing DT key '%s'\n", + CNSS_SUBSYS_NAME_KEY); + ret = -ENODEV; + goto err_subsys_name_query; + } + + strlcpy(ssr_info->subsys_name, name, sizeof(ssr_info->subsys_name)); + + if (of_property_read_u32(dev->of_node, "qcom,wlan-ramdump-dynamic", + &ramdump_size) == 0) { + ssr_info->ramdump_addr = + dma_alloc_coherent(dev, ramdump_size, + &ssr_info->ramdump_phys, + GFP_KERNEL); + if (ssr_info->ramdump_addr) + ssr_info->ramdump_size = ramdump_size; + ssr_info->ramdump_dynamic = true; + } else { + res = platform_get_resource_byname(cnss_pdata->pdev, + IORESOURCE_MEM, "ramdump"); + if (res) { + ssr_info->ramdump_phys = res->start; + ramdump_size = resource_size(res); + ssr_info->ramdump_addr = ioremap(ssr_info->ramdump_phys, + ramdump_size); + if (ssr_info->ramdump_addr) + ssr_info->ramdump_size = ramdump_size; + ssr_info->ramdump_dynamic = false; + } + } + + pr_info("ramdump addr: %p, phys: %pa subsys:'%s'\n", + ssr_info->ramdump_addr, &ssr_info->ramdump_phys, + ssr_info->subsys_name); + + if (ssr_info->ramdump_size == 0) { + pr_info("CNSS ramdump will not be collected\n"); + return 0; + } + + if (ssr_info->ramdump_dynamic) { + ret = cnss_configure_dump_table(ssr_info); + if (ret) + goto err_configure_dump_table; + } + + ssr_info->ramdump_dev = create_ramdump_device(ssr_info->subsys_name, + dev); + if (!ssr_info->ramdump_dev) { + ret = -ENOMEM; + pr_err("ramdump dev create failed: error=%d\n", + ret); + goto err_configure_dump_table; + } + + return 0; + +err_configure_dump_table: + if (ssr_info->ramdump_dynamic) + dma_free_coherent(dev, ssr_info->ramdump_size, + ssr_info->ramdump_addr, + ssr_info->ramdump_phys); + else + iounmap(ssr_info->ramdump_addr); + + ssr_info->ramdump_addr = NULL; + ssr_info->ramdump_size = 0; +err_subsys_name_query: + return ret; +} + +static void cnss_ramdump_cleanup(void) +{ + struct cnss_ssr_info *ssr_info; + struct device *dev; + + if (!cnss_pdata) + return; + + dev = &cnss_pdata->pdev->dev; + ssr_info = &cnss_pdata->ssr_info; + if (ssr_info->ramdump_addr) { + if (ssr_info->ramdump_dynamic) + dma_free_coherent(dev, ssr_info->ramdump_size, + ssr_info->ramdump_addr, + ssr_info->ramdump_phys); + else + iounmap(ssr_info->ramdump_addr); + } + + ssr_info->ramdump_addr = NULL; + if (ssr_info->ramdump_dev) + destroy_ramdump_device(ssr_info->ramdump_dev); + ssr_info->ramdump_dev = NULL; +} + +void *cnss_sdio_get_virt_ramdump_mem(unsigned long *size) +{ + if (!cnss_pdata || !cnss_pdata->pdev) + return NULL; + + *size = cnss_pdata->ssr_info.ramdump_size; + + return cnss_pdata->ssr_info.ramdump_addr; +} + +void cnss_sdio_device_self_recovery(void) +{ + cnss_sdio_shutdown(NULL, false); + msleep(WLAN_RECOVERY_DELAY); + cnss_sdio_powerup(NULL); +} + +void cnss_sdio_device_crashed(void) +{ + struct cnss_ssr_info *ssr_info; + + if (!cnss_pdata) + return; + ssr_info = &cnss_pdata->ssr_info; + if (ssr_info->subsys) { + subsys_set_crash_status(ssr_info->subsys, true); + subsystem_restart_dev(ssr_info->subsys); + } +} + +static void cnss_sdio_recovery_work_handler(struct work_struct *recovery) +{ + cnss_sdio_device_self_recovery(); +} + +DECLARE_WORK(cnss_sdio_recovery_work, cnss_sdio_recovery_work_handler); + +void cnss_sdio_schedule_recovery_work(void) +{ + schedule_work(&cnss_sdio_recovery_work); +} + +/** + * cnss_get_restart_level() - cnss get restart level API + * + * Wlan sdio function driver uses this API to get the current + * subsystem restart level. + * + * Return: CNSS_RESET_SOC - "SYSTEM", restart system + * CNSS_RESET_SUBSYS_COUPLED - "RELATED",restart subsystem + */ +int cnss_get_restart_level(void) +{ + struct cnss_ssr_info *ssr_info; + int level; + + if (!cnss_pdata) + return CNSS_RESET_SOC; + ssr_info = &cnss_pdata->ssr_info; + if (!ssr_info->subsys) + return CNSS_RESET_SOC; + level = subsys_get_restart_level(ssr_info->subsys); + switch (level) { + case RESET_SOC: + return CNSS_RESET_SOC; + case RESET_SUBSYS_COUPLED: + return CNSS_RESET_SUBSYS_COUPLED; + default: + return CNSS_RESET_SOC; + } +} +EXPORT_SYMBOL(cnss_get_restart_level); + +static inline int cnss_get_tsf_cap_irq(struct device *dev) +{ + int irq = -EINVAL; + int gpio; + + if (!dev) + return -ENODEV; + + gpio = of_get_named_gpio(dev->of_node, WLAN_GPIO_CAPTSF_NAME, 0); + if (gpio >= 0) + irq = gpio_to_irq(gpio); + + return irq; +} + +static int cnss_sdio_register_tsf_captured_handler(irq_handler_t handler, + void *ctx) +{ + struct cnss_cap_tsf_info *tsf_info; + + if (!cnss_pdata) + return -ENODEV; + + tsf_info = &cnss_pdata->cnss_sdio_info.cap_tsf_info; + if (tsf_info->irq_num < 0) + return -ENOTSUPP; + + tsf_info->irq_handler = handler; + tsf_info->context = ctx; + return 0; +} + +static int cnss_sdio_unregister_tsf_captured_handler(void *ctx) +{ + struct cnss_cap_tsf_info *tsf_info; + + if (!cnss_pdata) + return -ENODEV; + + tsf_info = &cnss_pdata->cnss_sdio_info.cap_tsf_info; + if (tsf_info->irq_num < 0) + return -ENOTSUPP; + + if (ctx == tsf_info->context) { + tsf_info->irq_handler = NULL; + tsf_info->context = NULL; + } + return 0; +} + +static irqreturn_t cnss_sdio_tsf_captured_handler(int irq, void *ctx) +{ + struct cnss_cap_tsf_info *tsf_info; + + if (!cnss_pdata) + return IRQ_HANDLED; + + tsf_info = &cnss_pdata->cnss_sdio_info.cap_tsf_info; + if (tsf_info->irq_num < 0 || tsf_info->irq_num != irq || + !tsf_info->irq_handler || !tsf_info->context) + return IRQ_HANDLED; + + return tsf_info->irq_handler(irq, tsf_info->context); +} + +static void cnss_sdio_tsf_init(struct device *dev, + struct cnss_cap_tsf_info *tsf_info) +{ + int ret, irq; + + tsf_info->irq_num = -EINVAL; + tsf_info->irq_handler = NULL; + tsf_info->context = NULL; + + irq = cnss_get_tsf_cap_irq(dev); + if (irq < 0) { + dev_err(dev, "%s: fail to get irq: %d\n", __func__, irq); + return; + } + + ret = request_irq(irq, cnss_sdio_tsf_captured_handler, + IRQF_SHARED | IRQF_TRIGGER_RISING, dev_name(dev), + (void *)tsf_info); + dev_err(dev, "%s: request irq[%d] for dev: %s, result: %d\n", + __func__, irq, dev_name(dev), ret); + if (!ret) + tsf_info->irq_num = irq; +} + +static void cnss_sdio_tsf_deinit(struct cnss_cap_tsf_info *tsf_info) +{ + int irq = tsf_info->irq_num; + + if (irq < 0) + return; + + free_irq(irq, (void *)tsf_info); + + tsf_info->irq_num = -EINVAL; + tsf_info->irq_handler = NULL; + tsf_info->context = NULL; +} + +static void cnss_sdio_set_platform_ops(struct device *dev) +{ + struct cnss_dev_platform_ops *pf_ops = &cnss_pdata->platform_ops; + + pf_ops->power_up = cnss_sdio_power_up; + pf_ops->power_down = cnss_sdio_power_down; + pf_ops->device_crashed = cnss_sdio_device_crashed; + pf_ops->get_virt_ramdump_mem = cnss_sdio_get_virt_ramdump_mem; + pf_ops->device_self_recovery = cnss_sdio_device_self_recovery; + pf_ops->get_wlan_mac_address = cnss_sdio_get_wlan_mac_address; + pf_ops->set_wlan_mac_address = cnss_sdio_set_wlan_mac_address; + pf_ops->schedule_recovery_work = cnss_sdio_schedule_recovery_work; + pf_ops->request_bus_bandwidth = cnss_sdio_request_bus_bandwidth; + pf_ops->register_tsf_captured_handler = + cnss_sdio_register_tsf_captured_handler; + pf_ops->unregister_tsf_captured_handler = + cnss_sdio_unregister_tsf_captured_handler; + dev->platform_data = pf_ops; +} + +static int cnss_sdio_wlan_inserted(struct sdio_func *func, + const struct sdio_device_id *id) +{ + struct cnss_sdio_info *info; + + if (!cnss_pdata) + return -ENODEV; + + info = &cnss_pdata->cnss_sdio_info; + + info->func = func; + info->card = func->card; + info->host = func->card->host; + info->id = id; + info->dev = &func->dev; + cnss_sdio_set_platform_ops(info->dev); + + cnss_put_hw_resources(cnss_pdata->cnss_sdio_info.dev); + + pr_info("SDIO Device is Probed\n"); + return 0; +} + +static void cnss_sdio_wlan_removed(struct sdio_func *func) +{ + struct cnss_sdio_info *info; + + if (!cnss_pdata) + return; + + info = &cnss_pdata->cnss_sdio_info; + + info->host = NULL; + info->card = NULL; + info->func = NULL; + info->id = NULL; +} + +#if defined(CONFIG_PM) +static int cnss_sdio_wlan_suspend(struct device *dev) +{ + struct cnss_sdio_wlan_driver *wdrv; + struct cnss_sdio_bus_bandwidth *bus_bandwidth; + struct sdio_func *func; + + int error = 0; + + if (!cnss_pdata) + return -ENODEV; + + bus_bandwidth = &cnss_pdata->bus_bandwidth; + if (bus_bandwidth->bus_client) { + msm_bus_scale_client_update_request( + bus_bandwidth->bus_client, CNSS_BUS_WIDTH_NONE); + } + + func = cnss_pdata->cnss_sdio_info.func; + wdrv = cnss_pdata->cnss_sdio_info.wdrv; + if (!wdrv) { + /* This can happen when no wlan driver loaded (no register to + * platform driver). + */ + sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); + pr_debug("wlan driver not registered\n"); + return 0; + } + if (wdrv->suspend) { + error = wdrv->suspend(dev); + if (error) + pr_err("wlan suspend failed error=%d\n", error); + } + + return error; +} + +static int cnss_sdio_wlan_resume(struct device *dev) +{ + struct cnss_sdio_wlan_driver *wdrv; + struct cnss_sdio_bus_bandwidth *bus_bandwidth; + int error = 0; + + if (!cnss_pdata) + return -ENODEV; + + bus_bandwidth = &cnss_pdata->bus_bandwidth; + if (bus_bandwidth->bus_client) { + msm_bus_scale_client_update_request( + bus_bandwidth->bus_client, + bus_bandwidth->current_bandwidth_vote); + } + + wdrv = cnss_pdata->cnss_sdio_info.wdrv; + if (!wdrv) { + /* This can happen when no wlan driver loaded (no register to + * platform driver). + */ + pr_debug("wlan driver not registered\n"); + return 0; + } + if (wdrv->resume) { + error = wdrv->resume(dev); + if (error) + pr_err("wlan resume failed error=%d\n", error); + } + return error; +} +#endif + +#if defined(CONFIG_PM) +static const struct dev_pm_ops cnss_ar6k_device_pm_ops = { + .suspend = cnss_sdio_wlan_suspend, + .resume = cnss_sdio_wlan_resume, +}; +#endif /* CONFIG_PM */ + +static struct sdio_driver cnss_ar6k_driver = { + .name = "cnss_ar6k_wlan", + .id_table = ar6k_id_table, + .probe = cnss_sdio_wlan_inserted, + .remove = cnss_sdio_wlan_removed, +#if defined(CONFIG_PM) + .drv = { + .pm = &cnss_ar6k_device_pm_ops, + } +#endif +}; + +static int cnss_set_pinctrl_state(struct cnss_sdio_data *pdata, bool state) +{ + struct cnss_wlan_pinctrl_info *info = &pdata->pinctrl_info; + + if (!info->is_antenna_shared) + return 0; + + if (!info->pinctrl) + return -EIO; + + return state ? pinctrl_select_state(info->pinctrl, info->active) : + pinctrl_select_state(info->pinctrl, info->sleep); +} + +int cnss_sdio_configure_spdt(bool state) +{ + if (!cnss_pdata) + return -ENODEV; + + return cnss_set_pinctrl_state(cnss_pdata, state); +} +EXPORT_SYMBOL(cnss_sdio_configure_spdt); + +/** + * cnss_sdio_wlan_register_driver() - cnss wlan register API + * @driver: sdio wlan driver interface from wlan driver. + * + * wlan sdio function driver uses this API to register callback + * functions to cnss_sido platform driver. The callback will + * be invoked by corresponding wrapper function of this cnss + * platform driver. + */ +int cnss_sdio_wlan_register_driver(struct cnss_sdio_wlan_driver *driver) +{ + struct cnss_sdio_info *cnss_info; + struct device *dev; + int error = -EINVAL; + + if (!cnss_pdata) + return -ENODEV; + + cnss_info = &cnss_pdata->cnss_sdio_info; + dev = cnss_info->dev; + + if (cnss_info->wdrv) { + pr_debug("wdrv already existed\n"); + return error; + } + + if (!driver) + return error; + + error = cnss_get_hw_resources(dev); + if (error) { + pr_err("Failed to restore power err:%d\n", error); + return error; + } + + error = cnss_set_pinctrl_state(cnss_pdata, PINCTRL_ACTIVE); + if (error) { + pr_err("Fail to set pinctrl to active state\n"); + cnss_put_hw_resources(dev); + goto put_hw; + } + + /* The HW resources are released in unregister logic if probe fails */ + error = driver->probe ? driver->probe(cnss_info->func, + cnss_info->id) : error; + if (error) { + pr_err("wlan probe failed error=%d\n", error); + /** + * Check memory leak in skb pre-alloc memory pool + * Reset the skb memory pool + */ + goto pinctrl_sleep; + } + + cnss_info->wdrv = driver; + + return error; + +pinctrl_sleep: + cnss_set_pinctrl_state(cnss_pdata, PINCTRL_SLEEP); +put_hw: + return error; +} +EXPORT_SYMBOL(cnss_sdio_wlan_register_driver); + +/** + * cnss_sdio_wlan_unregister_driver() - cnss wlan unregister API + * @driver: sdio wlan driver interface from wlan driver. + * + * wlan sdio function driver uses this API to detach it from cnss_sido + * platform driver. + */ +void +cnss_sdio_wlan_unregister_driver(struct cnss_sdio_wlan_driver *driver) +{ + struct cnss_sdio_info *cnss_info; + struct cnss_sdio_bus_bandwidth *bus_bandwidth; + + if (!cnss_pdata) + return; + + bus_bandwidth = &cnss_pdata->bus_bandwidth; + if (bus_bandwidth->bus_client) { + msm_bus_scale_client_update_request( + bus_bandwidth->bus_client, CNSS_BUS_WIDTH_NONE); + } + + cnss_info = &cnss_pdata->cnss_sdio_info; + if (!cnss_info->wdrv) { + pr_err("driver not registered\n"); + return; + } + + if (!driver) + return; + + if (!driver->remove) + return; + + driver->remove(cnss_info->func); + + cnss_info->wdrv = NULL; + cnss_set_pinctrl_state(cnss_pdata, PINCTRL_SLEEP); + cnss_put_hw_resources(cnss_info->dev); +} +EXPORT_SYMBOL(cnss_sdio_wlan_unregister_driver); + +/** + * cnss_wlan_query_oob_status() - cnss wlan query oob status API + * + * Wlan sdio function driver uses this API to check whether oob is + * supported in platform driver. + * + * Return: 0 means oob is supported, others means unsupported. + */ +int cnss_wlan_query_oob_status(void) +{ + return -EINVAL; +} +EXPORT_SYMBOL(cnss_wlan_query_oob_status); + +/** + * cnss_wlan_register_oob_irq_handler() - cnss wlan register oob callback API + * @handler: oob callback function pointer which registered to platform driver. + * @pm_oob : parameter which registered to platform driver. + * + * Wlan sdio function driver uses this API to register oob callback + * function to platform driver. + * + * Return: 0 means register successfully, others means failure. + */ +int cnss_wlan_register_oob_irq_handler(oob_irq_handler_t handler, void *pm_oob) +{ + return -EINVAL; +} +EXPORT_SYMBOL(cnss_wlan_register_oob_irq_handler); + +/** + * cnss_wlan_unregister_oob_irq_handler() - unregister oob callback API + * @pm_oob: parameter which unregistered from platform driver. + * + * Wlan sdio function driver uses this API to unregister oob callback + * function from platform driver. + * + * Return: 0 means unregister successfully, others means failure. + */ +int cnss_wlan_unregister_oob_irq_handler(void *pm_oob) +{ + return -EINVAL; +} +EXPORT_SYMBOL(cnss_wlan_unregister_oob_irq_handler); + +static void cnss_sdio_reset_platform_ops(void) +{ + struct cnss_dev_platform_ops *pf_ops = &cnss_pdata->platform_ops; + struct cnss_sdio_info *sdio_info = &cnss_pdata->cnss_sdio_info; + + memset(pf_ops, 0, sizeof(struct cnss_dev_platform_ops)); + if (sdio_info->dev) + sdio_info->dev->platform_data = NULL; +} + +static int cnss_sdio_wlan_init(void) +{ + int error = 0; + + error = sdio_register_driver(&cnss_ar6k_driver); + if (error) { + cnss_sdio_reset_platform_ops(); + pr_err("registered fail error=%d\n", error); + } else { + pr_debug("registered success\n"); + } + + return error; +} + +static void cnss_sdio_wlan_exit(void) +{ + if (!cnss_pdata) + return; + + cnss_sdio_reset_platform_ops(); + sdio_unregister_driver(&cnss_ar6k_driver); +} + +static void cnss_sdio_deinit_bus_bandwidth(void) +{ + struct cnss_sdio_bus_bandwidth *bus_bandwidth; + + bus_bandwidth = &cnss_pdata->bus_bandwidth; + if (bus_bandwidth->bus_client) { + msm_bus_scale_client_update_request(bus_bandwidth->bus_client, + CNSS_BUS_WIDTH_NONE); + msm_bus_scale_unregister_client(bus_bandwidth->bus_client); + } +} + +static int cnss_sdio_configure_wlan_enable_regulator(void) +{ + int error; + struct device *dev = &cnss_pdata->pdev->dev; + + if (of_get_property( + cnss_pdata->pdev->dev.of_node, + WLAN_VREG_NAME "-supply", NULL)) { + cnss_pdata->regulator.wlan_vreg = regulator_get( + &cnss_pdata->pdev->dev, WLAN_VREG_NAME); + if (IS_ERR(cnss_pdata->regulator.wlan_vreg)) { + error = PTR_ERR(cnss_pdata->regulator.wlan_vreg); + dev_err(dev, "VDD-VREG get failed error=%d\n", error); + return error; + } + + error = regulator_enable(cnss_pdata->regulator.wlan_vreg); + if (error) { + dev_err(dev, "VDD-VREG enable failed error=%d\n", + error); + goto err_vdd_vreg_regulator; + } + } + + return 0; + +err_vdd_vreg_regulator: + regulator_put(cnss_pdata->regulator.wlan_vreg); + + return error; +} + +static int cnss_sdio_configure_wlan_enable_dsrc_regulator(void) +{ + int error; + struct device *dev = &cnss_pdata->pdev->dev; + + if (of_get_property( + cnss_pdata->pdev->dev.of_node, + WLAN_VREG_DSRC_NAME "-supply", NULL)) { + cnss_pdata->regulator.wlan_vreg_dsrc = regulator_get( + &cnss_pdata->pdev->dev, WLAN_VREG_DSRC_NAME); + if (IS_ERR(cnss_pdata->regulator.wlan_vreg_dsrc)) { + error = PTR_ERR(cnss_pdata->regulator.wlan_vreg_dsrc); + dev_err(dev, "VDD-VREG-DSRC get failed error=%d\n", + error); + return error; + } + + error = regulator_enable(cnss_pdata->regulator.wlan_vreg_dsrc); + if (error) { + dev_err(dev, "VDD-VREG-DSRC enable failed error=%d\n", + error); + goto err_vdd_vreg_dsrc_regulator; + } + } + + return 0; + +err_vdd_vreg_dsrc_regulator: + regulator_put(cnss_pdata->regulator.wlan_vreg_dsrc); + + return error; +} + +static int cnss_sdio_configure_regulator(void) +{ + int error; + struct device *dev = &cnss_pdata->pdev->dev; + u32 vdd_xtal_min; + u32 vdd_xtal_max; + + if (of_get_property( + cnss_pdata->pdev->dev.of_node, + WLAN_VREG_IO_NAME "-supply", NULL)) { + cnss_pdata->regulator.wlan_io = regulator_get( + &cnss_pdata->pdev->dev, WLAN_VREG_IO_NAME); + if (IS_ERR(cnss_pdata->regulator.wlan_io)) { + error = PTR_ERR(cnss_pdata->regulator.wlan_io); + dev_err(dev, "VDD-IO get failed error=%d\n", error); + return error; + } + + error = regulator_set_voltage( + cnss_pdata->regulator.wlan_io, + WLAN_VREG_IO_MIN, WLAN_VREG_IO_MAX); + if (error) { + dev_err(dev, "VDD-IO set failed error=%d\n", error); + goto err_vdd_io_regulator; + } else { + error = regulator_enable(cnss_pdata->regulator.wlan_io); + if (error) { + dev_err(dev, "VDD-IO enable failed error=%d\n", + error); + goto err_vdd_io_regulator; + } + } + } + + if (of_get_property( + cnss_pdata->pdev->dev.of_node, + WLAN_VREG_XTAL_NAME "-supply", NULL)) { + cnss_pdata->regulator.wlan_xtal = regulator_get( + &cnss_pdata->pdev->dev, WLAN_VREG_XTAL_NAME); + if (IS_ERR(cnss_pdata->regulator.wlan_xtal)) { + error = PTR_ERR(cnss_pdata->regulator.wlan_xtal); + dev_err(dev, "VDD-XTAL get failed error=%d\n", error); + goto err_vdd_xtal_regulator; + } + + if (!of_property_read_u32(cnss_pdata->pdev->dev.of_node, + WLAN_VREG_XTAL_NAME "-min", + &vdd_xtal_min)) { + if (vdd_xtal_min < WLAN_VREG_XTAL_MIN || + vdd_xtal_min > WLAN_VREG_XTAL_MAX) + vdd_xtal_min = WLAN_VREG_XTAL_TYP; + } else { + vdd_xtal_min = WLAN_VREG_XTAL_TYP; + } + + if (!of_property_read_u32(cnss_pdata->pdev->dev.of_node, + WLAN_VREG_XTAL_NAME "-max", + &vdd_xtal_max)) { + if (vdd_xtal_max < WLAN_VREG_XTAL_MIN || + vdd_xtal_max > WLAN_VREG_XTAL_MAX) + vdd_xtal_max = WLAN_VREG_XTAL_TYP; + } else { + vdd_xtal_max = WLAN_VREG_XTAL_TYP; + } + + if (vdd_xtal_min > vdd_xtal_max) + vdd_xtal_min = vdd_xtal_max; + + error = regulator_set_voltage( + cnss_pdata->regulator.wlan_xtal, + vdd_xtal_min, vdd_xtal_max); + if (error) { + dev_err(dev, "VDD-XTAL set failed error=%d\n", error); + goto err_vdd_xtal_regulator; + } else { + error = regulator_enable( + cnss_pdata->regulator.wlan_xtal); + if (error) { + dev_err(dev, "VDD-XTAL enable failed err=%d\n", + error); + goto err_vdd_xtal_regulator; + } + } + } + + return 0; + +err_vdd_xtal_regulator: + regulator_put(cnss_pdata->regulator.wlan_xtal); +err_vdd_io_regulator: + regulator_put(cnss_pdata->regulator.wlan_io); + return error; +} + +static void cnss_sdio_release_resource(void) +{ + if (cnss_pdata->regulator.wlan_xtal) + regulator_put(cnss_pdata->regulator.wlan_xtal); + if (cnss_pdata->regulator.wlan_vreg) + regulator_put(cnss_pdata->regulator.wlan_vreg); + if (cnss_pdata->regulator.wlan_io) + regulator_put(cnss_pdata->regulator.wlan_io); + if (cnss_pdata->regulator.wlan_vreg_dsrc) + regulator_put(cnss_pdata->regulator.wlan_vreg_dsrc); +} + +static int cnss_sdio_pinctrl_init(struct cnss_sdio_data *pdata, + struct platform_device *pdev) +{ + int ret = 0; + struct device *dev = &pdev->dev; + struct cnss_wlan_pinctrl_info *info = &pdata->pinctrl_info; + + if (!of_find_property(dev->of_node, "qcom,is-antenna-shared", NULL)) + return 0; + + info->is_antenna_shared = true; + info->pinctrl = devm_pinctrl_get(dev); + if ((IS_ERR_OR_NULL(info->pinctrl))) { + dev_err(dev, "%s: Failed to get pinctrl\n", __func__); + return PTR_ERR(info->pinctrl); + } + + info->sleep = pinctrl_lookup_state(info->pinctrl, + CNSS_PINCTRL_SLEEP_STATE); + if (IS_ERR_OR_NULL(info->sleep)) { + dev_err(dev, "%s: Fail to get sleep state for pin\n", __func__); + ret = PTR_ERR(info->sleep); + goto release_pinctrl; + } + + info->active = pinctrl_lookup_state(info->pinctrl, + CNSS_PINCTRL_ACTIVE_STATE); + if (IS_ERR_OR_NULL(info->active)) { + dev_err(dev, "%s: Fail to get active state for pin\n", + __func__); + ret = PTR_ERR(info->active); + goto release_pinctrl; + } + + ret = cnss_set_pinctrl_state(pdata, PINCTRL_SLEEP); + + if (ret) { + dev_err(dev, "%s: Fail to set pin in sleep state\n", __func__); + goto release_pinctrl; + } + + return ret; + +release_pinctrl: + devm_pinctrl_put(info->pinctrl); + info->is_antenna_shared = false; + return ret; +} + +static int cnss_sdio_init_bus_bandwidth(void) +{ + int ret = 0; + struct cnss_sdio_bus_bandwidth *bus_bandwidth; + struct device *dev = &cnss_pdata->pdev->dev; + + bus_bandwidth = &cnss_pdata->bus_bandwidth; + bus_bandwidth->bus_scale_table = msm_bus_cl_get_pdata(cnss_pdata->pdev); + if (!bus_bandwidth->bus_scale_table) { + dev_err(dev, "Failed to get the bus scale platform data\n"); + ret = -EINVAL; + } + + bus_bandwidth->bus_client = msm_bus_scale_register_client( + bus_bandwidth->bus_scale_table); + if (!bus_bandwidth->bus_client) { + dev_err(dev, "Failed to register with bus_scale client\n"); + ret = -EINVAL; + } + + return ret; +} + +static int cnss_sdio_probe(struct platform_device *pdev) +{ + int error; + struct device *dev = &pdev->dev; + struct cnss_sdio_info *info; + + if (pdev->dev.of_node) { + cnss_pdata = devm_kzalloc( + &pdev->dev, sizeof(*cnss_pdata), GFP_KERNEL); + if (!cnss_pdata) + return -ENOMEM; + } else { + cnss_pdata = pdev->dev.platform_data; + } + + if (!cnss_pdata) + return -EINVAL; + + cnss_pdata->pdev = pdev; + info = &cnss_pdata->cnss_sdio_info; + + error = cnss_sdio_pinctrl_init(cnss_pdata, pdev); + if (error) { + dev_err(&pdev->dev, "Fail to configure pinctrl err:%d\n", + error); + return error; + } + + error = cnss_sdio_configure_regulator(); + if (error) { + dev_err(&pdev->dev, "Failed to configure voltage regulator error=%d\n", + error); + return error; + } + + if (of_get_property( + cnss_pdata->pdev->dev.of_node, + WLAN_VREG_NAME "-supply", NULL)) { + error = cnss_sdio_configure_wlan_enable_regulator(); + if (error) { + dev_err(&pdev->dev, + "Failed to enable wlan enable regulator error=%d\n", + error); + goto err_wlan_enable_regulator; + } + } + + if (of_get_property( + cnss_pdata->pdev->dev.of_node, + WLAN_VREG_DSRC_NAME "-supply", NULL)) { + error = cnss_sdio_configure_wlan_enable_dsrc_regulator(); + if (error) { + dev_err(&pdev->dev, + "Failed to enable wlan dsrc enable regulator\n"); + goto err_wlan_dsrc_enable_regulator; + } + } + + info->skip_wlan_en_toggle = of_property_read_bool(dev->of_node, + "qcom,skip-wlan-en-toggle"); + info->cnss_hw_state = CNSS_HW_ACTIVE; + + cnss_sdio_tsf_init(dev, &info->cap_tsf_info); + + error = cnss_sdio_wlan_init(); + if (error) { + dev_err(&pdev->dev, "cnss wlan init failed error=%d\n", error); + goto err_wlan_dsrc_enable_regulator; + } + + error = cnss_configure_ramdump(); + if (error) { + dev_err(&pdev->dev, "Failed to configure ramdump error=%d\n", + error); + goto err_ramdump_create; + } + + error = cnss_subsys_init(); + if (error) { + dev_err(&pdev->dev, "Failed to cnss_subsys_init error=%d\n", + error); + goto err_subsys_init; + } + + if (of_property_read_bool( + pdev->dev.of_node, "qcom,cnss-enable-bus-bandwidth")) { + error = cnss_sdio_init_bus_bandwidth(); + if (error) { + dev_err(&pdev->dev, "Failed to init bus bandwidth\n"); + goto err_bus_bandwidth_init; + } + } + + dev_info(&pdev->dev, "CNSS SDIO Driver registered"); + return 0; + +err_bus_bandwidth_init: + cnss_subsys_exit(); +err_subsys_init: + cnss_ramdump_cleanup(); +err_ramdump_create: + cnss_sdio_wlan_exit(); +err_wlan_dsrc_enable_regulator: + info->cnss_hw_state = CNSS_HW_SLEEP; + regulator_put(cnss_pdata->regulator.wlan_vreg_dsrc); +err_wlan_enable_regulator: + regulator_put(cnss_pdata->regulator.wlan_xtal); + regulator_put(cnss_pdata->regulator.wlan_io); + cnss_pdata = NULL; + return error; +} + +static int cnss_sdio_remove(struct platform_device *pdev) +{ + struct cnss_sdio_info *info; + struct cnss_cap_tsf_info *tsf_info; + + if (!cnss_pdata) + return -ENODEV; + + info = &cnss_pdata->cnss_sdio_info; + tsf_info = &info->cap_tsf_info; + + cnss_sdio_tsf_deinit(tsf_info); + cnss_sdio_deinit_bus_bandwidth(); + cnss_sdio_wlan_exit(); + cnss_subsys_exit(); + cnss_ramdump_cleanup(); + cnss_put_hw_resources(info->dev); + cnss_sdio_release_resource(); + cnss_pdata = NULL; + return 0; +} + +int cnss_sdio_set_wlan_mac_address(const u8 *in, u32 len) +{ + return 0; +} + +u8 *cnss_sdio_get_wlan_mac_address(u32 *num) +{ + *num = 0; + return NULL; +} + +int cnss_sdio_power_down(struct device *dev) +{ + return 0; +} + +int cnss_sdio_power_up(struct device *dev) +{ + return 0; +} + +static const struct of_device_id cnss_sdio_dt_match[] = { + {.compatible = "qcom,cnss_sdio"}, + {} +}; +MODULE_DEVICE_TABLE(of, cnss_sdio_dt_match); + +static struct platform_driver cnss_sdio_driver = { + .probe = cnss_sdio_probe, + .remove = cnss_sdio_remove, + .driver = { + .name = "cnss_sdio", + .owner = THIS_MODULE, + .of_match_table = cnss_sdio_dt_match, + }, +}; + +static int __init cnss_sdio_init(void) +{ + return platform_driver_register(&cnss_sdio_driver); +} + +static void __exit cnss_sdio_exit(void) +{ + platform_driver_unregister(&cnss_sdio_driver); +} + +module_init(cnss_sdio_init); +module_exit(cnss_sdio_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION(DEVICE "CNSS SDIO Driver"); diff --git a/drivers/net/wireless/cnss/logger/Kconfig b/drivers/net/wireless/cnss/logger/Kconfig new file mode 100644 index 000000000000..85b69921a6a4 --- /dev/null +++ b/drivers/net/wireless/cnss/logger/Kconfig @@ -0,0 +1,6 @@ +config CNSS_LOGGER + tristate "CNSS Logging Service Driver" + ---help--- + This module adds support for the CNSS Logging Service for CLD + driver, including the netlink socket service registration, transmit, + event receive. diff --git a/drivers/net/wireless/cnss/logger/Makefile b/drivers/net/wireless/cnss/logger/Makefile new file mode 100644 index 000000000000..1e296a32df16 --- /dev/null +++ b/drivers/net/wireless/cnss/logger/Makefile @@ -0,0 +1,6 @@ +obj-$(CONFIG_CNSS_LOGGER) += logger.o + +logger-y += main.o \ + nl_service.o + +logger-$(CONFIG_DEBUG_FS) += debugfs.o diff --git a/drivers/net/wireless/cnss/logger/debugfs.c b/drivers/net/wireless/cnss/logger/debugfs.c new file mode 100644 index 000000000000..d34dd819e06d --- /dev/null +++ b/drivers/net/wireless/cnss/logger/debugfs.c @@ -0,0 +1,134 @@ +/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include + +#include "logger.h" + +#define CNSS_LOGGER_STATE_DUMP_BUFFER (2 * 1024) /* 2KB */ + +static int logger_state_dump_device(struct logger_device *dev, char *buf, + int buf_len) +{ + int len = 0; + struct logger_event_handler *cur; + + len += scnprintf(buf + len, buf_len - len, + "==============================================\n"); + + len += scnprintf(buf + len, buf_len - len, + "driver [%s] is registered with radio index: %d\n", + dev->name, dev->radio_idx); + + if (list_empty(&dev->event_list)) { + len += scnprintf(buf + len, buf_len - len, + "No event registered\n"); + return len; + } + + list_for_each_entry(cur, &dev->event_list, list) { + len += scnprintf(buf + len, buf_len - len, + "\t event %d\n", cur->event); + } + len += scnprintf(buf + len, buf_len - len, "\n"); + + return len; +} + +static int logger_state_dump(struct logger_context *ctx, char *buf, int buf_len) +{ + int len = 0; + struct logger_device *cur; + + if (list_empty(&ctx->dev_list)) { + len += scnprintf(buf + len, buf_len - len, + "=======================\n"); + len += scnprintf(buf + len, buf_len - len, + "No driver registered\n"); + return 0; + } + + list_for_each_entry(cur, &ctx->dev_list, list) + len += logger_state_dump_device(cur, (buf + len), buf_len); + + return 0; +} + +static int logger_state_open(struct inode *inode, struct file *file) +{ + struct logger_context *ctx = inode->i_private; + void *buf; + int ret; + + mutex_lock(&ctx->con_mutex); + + buf = kmalloc(CNSS_LOGGER_STATE_DUMP_BUFFER, GFP_KERNEL); + if (!buf) { + ret = -ENOMEM; + goto error_unlock; + } + + ret = logger_state_dump(ctx, buf, CNSS_LOGGER_STATE_DUMP_BUFFER); + if (ret) + goto error_free; + + file->private_data = buf; + mutex_unlock(&ctx->con_mutex); + return 0; + +error_free: + kfree(buf); + +error_unlock: + mutex_unlock(&ctx->con_mutex); + + return ret; +} + +static int logger_state_release(struct inode *inode, struct file *file) +{ + kfree(file->private_data); + return 0; +} + +static ssize_t logger_state_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + const char *buf = file->private_data; + unsigned int len = strlen(buf); + + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + +static const struct file_operations fops_logger_state = { + .open = logger_state_open, + .release = logger_state_release, + .read = logger_state_read, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + +void logger_debugfs_init(struct logger_context *ctx) +{ + if (!ctx->debugfs_entry) + ctx->debugfs_entry = debugfs_create_dir("cnss_logger", NULL); + + debugfs_create_file("state", 0400, ctx->debugfs_entry, ctx, + &fops_logger_state); +} + +void logger_debugfs_remove(struct logger_context *ctx) +{ + debugfs_remove(ctx->debugfs_entry); +} + diff --git a/drivers/net/wireless/cnss/logger/logger.h b/drivers/net/wireless/cnss/logger/logger.h new file mode 100644 index 000000000000..2c4060a85aea --- /dev/null +++ b/drivers/net/wireless/cnss/logger/logger.h @@ -0,0 +1,102 @@ +/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef _LOGGER_H_ +#define _LOGGER_H_ + +#include +#include +#include +#include +#include + +#define CNSS_LOGGER_NL_MCAST_GRP_ID 0x01 +#define CNSS_LOGGER_NL_MAX_PAYLOAD 256 +#define CNSS_LOGGER_BROADCAST_ID 255 + +/** + * struct aninlmsg - the wireless service message header + * @nlh: the netlink message header + * @radio: the radio index of this message + * @wmsg: the pointer to the wireless message data + */ +struct aninlmsg { + struct nlmsghdr *nlh; + int radio; + void *wmsg; +}; + +/** + * struct logger_event_handler - the logger event handler structure + * @list: the event list associated to the same device + * @event: the event number + * @radio_idx: the callback handler + */ +struct logger_event_handler { + struct list_head list; + + int event; + int (*cb)(struct sk_buff *skb); +}; + +/** + * struct logger_device - the logger device structure + * @list: the device list registered to logger module + * @event_list: the event list registered to this device + * @ctx: the pointer to the logger context + * @wiphy: the wiphy that associated to the device + * @name: the name of the device driver module + * @radio_idx: the radio index assigned to this device + */ +struct logger_device { + struct list_head list; + struct list_head event_list; + + struct logger_context *ctx; + struct wiphy *wiphy; + char name[MODULE_NAME_LEN]; + int radio_idx; +}; + +/** + * struct logger_context - the main context block for logger module + * @dev_list: this is the list to maintain the devices that registered + * to use the logger module feature + * @nl_sock: the netlink socket to share accros the module + * @con_mutex: the mutex to protect concurrent access + * @data_lock: the lock to protect shared data + * @radio_mask: this mask would maintain the radio index assign and release + */ +struct logger_context { + struct list_head dev_list; + + struct sock *nl_sock; + struct mutex con_mutex; /* concurrent access mutex */ + spinlock_t data_lock; + unsigned long radio_mask; /* support up to 4 drivers registration? */ +#ifdef CONFIG_DEBUG_FS + struct dentry *debugfs_entry; +#endif +}; + +int logger_netlink_init(struct logger_context *ctx); +int logger_netlink_deinit(struct logger_context *ctx); +struct logger_context *logger_get_ctx(void); + +#ifdef CONFIG_DEBUG_FS +void logger_debugfs_init(struct logger_context *ctx); +void logger_debugfs_remove(struct logger_context *ctx); +#else +static inline void logger_debugfs_init(struct logger_context *ctx) {} +static inline void logger_debugfs_remove(struct logger_context *ctx) {} +#endif + +#endif /* _LOGGER_H_ */ diff --git a/drivers/net/wireless/cnss/logger/main.c b/drivers/net/wireless/cnss/logger/main.c new file mode 100644 index 000000000000..fc2c1822c741 --- /dev/null +++ b/drivers/net/wireless/cnss/logger/main.c @@ -0,0 +1,55 @@ +/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include "logger.h" + +static struct logger_context *ctx; + +struct logger_context *logger_get_ctx(void) +{ + return ctx; +} + +static int __init logger_module_init(void) +{ + int ret; + + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return -ENOMEM; + + ret = logger_netlink_init(ctx); + + mutex_init(&ctx->con_mutex); + spin_lock_init(&ctx->data_lock); + logger_debugfs_init(ctx); + + return ret; +} + +static void __exit logger_module_exit(void) +{ + logger_debugfs_remove(ctx); + logger_netlink_deinit(ctx); + + kfree(ctx); +} + +module_init(logger_module_init); +module_exit(logger_module_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("CNSS Logging Service Driver"); diff --git a/drivers/net/wireless/cnss/logger/nl_service.c b/drivers/net/wireless/cnss/logger/nl_service.c new file mode 100644 index 000000000000..a532e1f7c4d0 --- /dev/null +++ b/drivers/net/wireless/cnss/logger/nl_service.c @@ -0,0 +1,476 @@ +/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define pr_fmt(fmt) "cnss_logger: %s: "fmt, __func__ + +#include +#include +#include +#include +#include +#include "logger.h" + +static DEFINE_MUTEX(logger_sem); + +/** + * logger_get_radio_idx() - to get the radio index + * @ctx: the logger context pointer + * + * Return: the first available radio index, otherwise failure code + */ +static int logger_get_radio_idx(struct logger_context *ctx) +{ + int i; + + for (i = 0; i < sizeof(ctx->radio_mask); i++) { + if (!test_and_set_bit(i, &ctx->radio_mask)) + return i; + } + return -EINVAL; +} + +/** + * logger_put_radio_idx() - to release the radio index + * @radio: the radio index to release + * + * Return: None + */ +static void logger_put_radio_idx(struct logger_context *ctx, int radio) +{ + clear_bit(radio, &ctx->radio_mask); +} + +/** + * logger_get_device() - to get the logger device per radio index + * @radio: the radio index + * + * Return: the logger_device pointer, otherwise return NULL. + */ +static struct logger_device *logger_get_device(int radio) +{ + struct logger_device *dev; + struct logger_context *ctx; + + ctx = logger_get_ctx(); + if (!ctx) + return NULL; + + list_for_each_entry(dev, &ctx->dev_list, list) { + if (dev->radio_idx == radio) + return dev; + } + return NULL; +} + +/** + * logger_device_is_registered() - to check if device has been registered + * @dev: pointer to logger device + * @wiphy: the wiphy pointer of the device to register + * + * This helper function is to check if this device has been registered. + * + * Return: NULL if it has not, otherwise return the logger_device pointer. + */ +static struct logger_device *logger_device_is_registered( + struct logger_context *ctx, + struct wiphy *wiphy) +{ + struct logger_device *dev; + + list_for_each_entry(dev, &ctx->dev_list, list) { + if (dev->wiphy == wiphy) + return dev; + } + return NULL; +} + +/** + * logger_dispatch_skb() - to dispatch the skb to devices + * @skb: the socket buffer received and to dispatch + * + * The function will look up the header of the skb, and dispatch the skb + * to the associated event and device that registered. + * + * Return: 0 if successfully dispatch, otherwise failure code + */ +static int logger_dispatch_skb(struct sk_buff *skb) +{ + struct nlmsghdr *nlh; + struct logger_context *ctx; + struct logger_device *cur; + struct logger_event_handler *evt; + int handled = 0; + + ctx = logger_get_ctx(); + if (!ctx) + return -ENOENT; + + pr_info("skb_len: %d, skb_data_len: %d\n", + skb->len, skb->data_len); + + if (skb->len < sizeof(struct nlmsghdr)) + return 0; + + nlh = (struct nlmsghdr *)skb->data; + list_for_each_entry(cur, &ctx->dev_list, list) { + list_for_each_entry(evt, &cur->event_list, list) { + if (nlh->nlmsg_type == evt->event) { + if (evt->cb) { + handled = 1; + evt->cb(skb); + } + /* Break inside loop, next dev */ + break; + } + } + } + + if (!handled) + pr_info("Not handled msg type: %d\n", nlh->nlmsg_type); + + return 0; +} + +/** + * logger_flush_event_handle() - to flush the event handle associate to device + * @dev: pointer to logger device + * + * The function will clean up all the event handle's resource, take it out + * from the list, and free the memory allocated. + * + * Return: None + */ +static void logger_flush_event_handle(struct logger_device *dev) +{ + struct list_head *pos, *temp; + struct logger_event_handler *cur; + + list_for_each_safe(pos, temp, &dev->event_list) { + cur = container_of(pos, struct logger_event_handler, list); + pr_info("radio: %d, event: %d unregistered\n", + dev->radio_idx, cur->event); + list_del(&cur->list); + kfree(cur); + } +} + +/** + * logger_flush_devices() - to flush the devices infomration + * @dev: pointer to logger device + * + * The helper function to flush the device information, all the device clean + * up prcoess should be starting from here. + * + * Return: None + */ +static void logger_flush_devices(struct logger_device *dev) +{ + pr_info("driver: [%s] and radio-%d is unregistered\n", + dev->name, dev->radio_idx); + logger_flush_event_handle(dev); + logger_put_radio_idx(dev->ctx, dev->radio_idx); + list_del(&dev->list); + kfree(dev); +} + +/** + * logger_register_device_event() - register the evet to device + * @dev: pointer to logger device + * @event: the event to register + * @cb: the callback associated to the device and event + * + * Return: 0 if register successfully, otherwise the failure code + */ +static int logger_register_device_event(struct logger_device *dev, int event, + int (*cb)(struct sk_buff *skb)) +{ + struct logger_event_handler *cur; + + list_for_each_entry(cur, &dev->event_list, list) { + if (cur->event == event) { + pr_info("event %d, is already added\n", event); + return 0; + } + } + + cur = kmalloc(sizeof(*cur), GFP_KERNEL); + if (!cur) + return -ENOMEM; + + cur->event = event; + cur->cb = cb; + + pr_info("radio: %d, event: %d\n", dev->radio_idx, cur->event); + list_add_tail(&cur->list, &dev->event_list); + + return 0; +} + +/** + * logger_unregister_device_event() - unregister the evet from device + * @dev: pointer to logger device + * @event: the event to unregister + * @cb: the callback associated to the device and event + * + * Return: 0 if unregister successfully, otherwise the failure code + */ +static int logger_unregister_device_event(struct logger_device *dev, int event, + int (*cb)(struct sk_buff *skb)) +{ + struct list_head *pos, *temp; + struct logger_event_handler *cur; + + list_for_each_safe(pos, temp, &dev->event_list) { + cur = container_of(pos, struct logger_event_handler, list); + if (cur->event == event && cur->cb == cb) { + pr_info("radio: %d, event: %d\n", + dev->radio_idx, cur->event); + list_del(&cur->list); + kfree(cur); + return 0; + } + } + return -ENOENT; +} + +/** + * logger_skb_input() - the callback to receive the skb + * @skb: the receive socket buffer + * + * Return: None + */ +static void logger_skb_input(struct sk_buff *skb) +{ + mutex_lock(&logger_sem); + logger_dispatch_skb(skb); + mutex_unlock(&logger_sem); +} + +/** + * cnss_logger_event_register() - register the event + * @radio: the radio index to register + * @event: the event to register + * @cb: the callback + * + * This function is used to register event associated to the radio index. + * + * Return: 0 if register success, otherwise failure code + */ +int cnss_logger_event_register(int radio, int event, + int (*cb)(struct sk_buff *skb)) +{ + int ret = -ENOENT; + struct logger_device *dev; + + dev = logger_get_device(radio); + if (dev) + ret = logger_register_device_event(dev, event, cb); + + return ret; +} +EXPORT_SYMBOL(cnss_logger_event_register); + +/** + * cnss_logger_event_unregister() - unregister the event + * @radio: the radio index to unregister + * @event: the event to unregister + * @cb: the callback + * + * This function is used to unregister the event from cnss logger module. + * + * Return: 0 if unregister success, otherwise failure code + */ +int cnss_logger_event_unregister(int radio, int event, + int (*cb)(struct sk_buff *skb)) +{ + int ret = -ENOENT; + struct logger_device *dev; + + dev = logger_get_device(radio); + if (dev) + ret = logger_unregister_device_event(dev, event, cb); + + return ret; +} +EXPORT_SYMBOL(cnss_logger_event_unregister); + +/** + * cnss_logger_device_register() - register the driver + * @wiphy: the wiphy device to unregister + * @name: the module name of the driver + * + * This function is used to register the driver to cnss logger module, + * this will indicate the existence of the driver, and also assign the + * radio index for further operation. + * + * Return: the radio index if register successful, otherwise failure code + */ +int cnss_logger_device_register(struct wiphy *wiphy, const char *name) +{ + int radio; + struct logger_context *ctx; + struct logger_device *new; + + ctx = logger_get_ctx(); + if (!ctx) + return -ENOENT; + + /* sanity check, already registered? */ + new = logger_device_is_registered(ctx, wiphy); + if (new) + return new->radio_idx; + + radio = logger_get_radio_idx(ctx); + if (radio < 0) { + pr_err("driver registration is full\n"); + return -ENOMEM; + } + + new = kmalloc(sizeof(*new), GFP_KERNEL); + if (!new) { + logger_put_radio_idx(ctx, radio); + return -ENOMEM; + } + + new->radio_idx = radio; + new->wiphy = wiphy; + new->ctx = ctx; + strlcpy(new->name, name, sizeof(new->name)); + INIT_LIST_HEAD(&new->event_list); + + list_add(&new->list, &ctx->dev_list); + + pr_info("driver: [%s] is registered as radio-%d\n", + new->name, new->radio_idx); + + return new->radio_idx; +} +EXPORT_SYMBOL(cnss_logger_device_register); + +/** + * cnss_logger_device_unregister() - unregister the driver + * @radio: the radio to unregister + * @wiphy: the wiphy device to unregister + * + * This function is used to unregister the driver from cnss logger module. + * This will disable the driver to access the interface in cnss logger, + * and also all the related events that registered will be reset. + * + * Return: 0 if success, otherwise failure code + */ +int cnss_logger_device_unregister(int radio, struct wiphy *wiphy) +{ + struct logger_context *ctx; + struct logger_device *cur; + struct list_head *pos, *temp; + + ctx = logger_get_ctx(); + if (!ctx) + return -ENOENT; + + list_for_each_safe(pos, temp, &ctx->dev_list) { + cur = list_entry(pos, struct logger_device, list); + if (cur->radio_idx == radio && cur->wiphy == wiphy) { + logger_flush_devices(cur); + break; + } + } + return 0; +} +EXPORT_SYMBOL(cnss_logger_device_unregister); + +/** + * cnss_logger_nl_ucast() - nl interface to unicast the buffer + * @skb: the socket buffer to transmit + * @portid: netlink portid of the destination socket + * @flag: the flag to indicate if this is a nonblock call + * + * Return: 0 if success, otherwise failure code + */ +int cnss_logger_nl_ucast(struct sk_buff *skb, int portid, int flag) +{ + struct logger_context *ctx; + + ctx = logger_get_ctx(); + if (!ctx) { + dev_kfree_skb(skb); + return -ENOENT; + } + + return netlink_unicast(ctx->nl_sock, skb, portid, flag); +} +EXPORT_SYMBOL(cnss_logger_nl_ucast); + +/** + * cnss_logger_nl_bcast() - nl interface to broadcast the buffer + * @skb: the socket buffer to transmit + * @portid: netlink portid of the destination socket + * @flag: the gfp_t flag + * + * Return: 0 if success, otherwise failure code + */ +int cnss_logger_nl_bcast(struct sk_buff *skb, int portid, int flag) +{ + struct logger_context *ctx; + + ctx = logger_get_ctx(); + if (!ctx) { + dev_kfree_skb(skb); + return -ENOENT; + } + + return netlink_broadcast(ctx->nl_sock, skb, 0, portid, flag); +} +EXPORT_SYMBOL(cnss_logger_nl_bcast); + +/** + * logger_netlink_init() - initialize the netlink socket + * @ctx: the cnss logger context pointer + * + * Return: the netlink handle if success, otherwise failure code + */ +int logger_netlink_init(struct logger_context *ctx) +{ + struct netlink_kernel_cfg cfg = { + .groups = CNSS_LOGGER_NL_MCAST_GRP_ID, + .input = logger_skb_input, + }; + + ctx->nl_sock = netlink_kernel_create(&init_net, NETLINK_USERSOCK, &cfg); + if (!ctx->nl_sock) { + pr_err("cnss_logger: Cannot create netlink socket"); + return -ENOMEM; + } + + INIT_LIST_HEAD(&ctx->dev_list); + + return 0; +} + +/** + * logger_netlink_deinit() - release the netlink socket and other resource + * @ctx: the cnss logger context pointer + * + * Return: 0 if success, otherwise failure code + */ +int logger_netlink_deinit(struct logger_context *ctx) +{ + struct list_head *pos, *temp; + struct logger_device *dev; + + netlink_kernel_release(ctx->nl_sock); + list_for_each_safe(pos, temp, &ctx->dev_list) { + dev = container_of(pos, struct logger_device, list); + logger_flush_devices(dev); + } + return 0; +} diff --git a/include/linux/qcomwlan_secif.h b/include/linux/qcomwlan_secif.h new file mode 100644 index 000000000000..2d140e845fc2 --- /dev/null +++ b/include/linux/qcomwlan_secif.h @@ -0,0 +1,41 @@ +/* Copyright (c) 2011-2013, 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __QCOM_WLAN_SECIF_H__ +#define __QCOM_WLAN_SECIF_H__ + +#include + +#define CMAC_TLEN 8 /* CMAC TLen = 64 bits (8 octets) */ + +/* + * Prototypes for WLAN Security Interface Functions + */ + +extern struct crypto_ahash * +wcnss_wlan_crypto_alloc_ahash(const char *alg_name, u32 type, u32 mask); + +extern int wcnss_wlan_crypto_ahash_digest(struct ahash_request *req); +extern void wcnss_wlan_crypto_free_ahash(struct crypto_ahash *tfm); +extern int wcnss_wlan_crypto_ahash_setkey(struct crypto_ahash *tfm, + const u8 *key, unsigned int keylen); +extern struct crypto_ablkcipher * +wcnss_wlan_crypto_alloc_ablkcipher(const char *alg_name, u32 type, u32 mask); +extern void wcnss_wlan_ablkcipher_request_free(struct ablkcipher_request *req); +extern void wcnss_wlan_crypto_free_cipher(struct crypto_cipher *tfm); +extern void wcnss_wlan_crypto_free_ablkcipher(struct crypto_ablkcipher *tfm); +extern struct crypto_cipher * +wcnss_wlan_crypto_alloc_cipher(const char *alg_name, u32 type, u32 mask); +extern void wcnss_wlan_cmac_calc_mic(struct crypto_cipher *tfm, u8 *m, + u16 length, u8 *mac); + +#endif /* __QCOM_WLAN_SECIF_H__ */ diff --git a/include/net/cnss.h b/include/net/cnss.h new file mode 100644 index 000000000000..d7b059aa4c1d --- /dev/null +++ b/include/net/cnss.h @@ -0,0 +1,271 @@ +/* Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef _NET_CNSS_H_ +#define _NET_CNSS_H_ + +#include +#include +#include +#include +#include + +#ifdef CONFIG_CNSS +#define MAX_FIRMWARE_SIZE (1 * 1024 * 1024) +#define CNSS_MAX_FILE_NAME 20 +#define PINCTRL_SLEEP 0 +#define PINCTRL_ACTIVE 1 + +enum cnss_bus_width_type { + CNSS_BUS_WIDTH_NONE, + CNSS_BUS_WIDTH_LOW, + CNSS_BUS_WIDTH_MEDIUM, + CNSS_BUS_WIDTH_HIGH +}; + +enum cnss_cc_src { + CNSS_SOURCE_CORE, + CNSS_SOURCE_11D, + CNSS_SOURCE_USER +}; + +/* FW image files */ +struct cnss_fw_files { + char image_file[CNSS_MAX_FILE_NAME]; + char board_data[CNSS_MAX_FILE_NAME]; + char otp_data[CNSS_MAX_FILE_NAME]; + char utf_file[CNSS_MAX_FILE_NAME]; + char utf_board_data[CNSS_MAX_FILE_NAME]; + char epping_file[CNSS_MAX_FILE_NAME]; + char evicted_data[CNSS_MAX_FILE_NAME]; +}; + +struct cnss_wlan_runtime_ops { + int (*runtime_suspend)(struct pci_dev *pdev); + int (*runtime_resume)(struct pci_dev *pdev); +}; + +struct cnss_wlan_driver { + char *name; + int (*probe)(struct pci_dev *pdev, const struct pci_device_id *id); + void (*remove)(struct pci_dev *pdev); + int (*reinit)(struct pci_dev *pdev, const struct pci_device_id *id); + void (*shutdown)(struct pci_dev *pdev); + void (*crash_shutdown)(struct pci_dev *pdev); + int (*suspend)(struct pci_dev *pdev, pm_message_t state); + int (*resume)(struct pci_dev *pdev); + void (*modem_status)(struct pci_dev *, int state); + void (*update_status)(struct pci_dev *pdev, uint32_t status); + struct cnss_wlan_runtime_ops *runtime_ops; + const struct pci_device_id *id_table; +}; + +/* + * codeseg_total_bytes: Total bytes across all the codesegment blocks + * num_codesegs: No of Pages used + * codeseg_size: Size of each segment. Should be power of 2 and multiple of 4K + * codeseg_size_log2: log2(codeseg_size) + * codeseg_busaddr: Physical address of the DMAble memory;4K aligned + */ + +#define CODESWAP_MAX_CODESEGS 16 +struct codeswap_codeseg_info { + u32 codeseg_total_bytes; + u32 num_codesegs; + u32 codeseg_size; + u32 codeseg_size_log2; + void *codeseg_busaddr[CODESWAP_MAX_CODESEGS]; +}; + +struct image_desc_info { + dma_addr_t fw_addr; + u32 fw_size; + dma_addr_t bdata_addr; + u32 bdata_size; +}; + +/* platform capabilities */ +enum cnss_platform_cap_flag { + CNSS_HAS_EXTERNAL_SWREG = 0x01, + CNSS_HAS_UART_ACCESS = 0x02, +}; + +struct cnss_platform_cap { + u32 cap_flag; +}; + +/* WLAN driver status, keep it aligned with cnss2 */ +enum cnss_driver_status { + CNSS_UNINITIALIZED, + CNSS_INITIALIZED, + CNSS_LOAD_UNLOAD, + CNSS_RECOVERY, + CNSS_FW_DOWN, + CNSS_SSR_FAIL, +}; + +enum cnss_runtime_request { + CNSS_PM_RUNTIME_GET, + CNSS_PM_RUNTIME_PUT, + CNSS_PM_RUNTIME_MARK_LAST_BUSY, + CNSS_PM_RUNTIME_RESUME, + CNSS_PM_RUNTIME_PUT_NOIDLE, + CNSS_PM_REQUEST_RESUME, + CNSS_PM_RUNTIME_PUT_AUTO, + CNSS_PM_GET_NORESUME, +}; + +extern struct dma_iommu_mapping *cnss_smmu_get_mapping(void); +extern int cnss_smmu_map(phys_addr_t paddr, uint32_t *iova_addr, size_t size); +extern int cnss_get_fw_image(struct image_desc_info *image_desc_info); +extern void cnss_runtime_init(struct device *dev, int auto_delay); +extern void cnss_runtime_exit(struct device *dev); +extern void cnss_wlan_pci_link_down(void); +extern int cnss_pcie_shadow_control(struct pci_dev *dev, bool enable); +extern int cnss_wlan_register_driver(struct cnss_wlan_driver *driver); +extern void cnss_wlan_unregister_driver(struct cnss_wlan_driver *driver); +extern int cnss_get_fw_files(struct cnss_fw_files *pfw_files); +extern int cnss_get_fw_files_for_target(struct cnss_fw_files *pfw_files, + u32 target_type, u32 target_version); +extern void cnss_get_qca9377_fw_files(struct cnss_fw_files *pfw_files, + u32 size, u32 tufello_dual_fw); + +extern int cnss_request_bus_bandwidth(int bandwidth); + +#ifdef CONFIG_CNSS_SECURE_FW +extern int cnss_get_sha_hash(const u8 *data, u32 data_len, + u8 *hash_idx, u8 *out); +extern void *cnss_get_fw_ptr(void); +#endif + +extern int cnss_get_codeswap_struct(struct codeswap_codeseg_info *swap_seg); +extern int cnss_get_bmi_setup(void); + +#ifdef CONFIG_PCI_MSM +extern int cnss_wlan_pm_control(bool vote); +#endif +extern void cnss_lock_pm_sem(void); +extern void cnss_release_pm_sem(void); + +extern void cnss_request_pm_qos_type(int latency_type, u32 qos_val); +extern void cnss_request_pm_qos(u32 qos_val); +extern void cnss_remove_pm_qos(void); + +extern void cnss_pci_request_pm_qos_type(int latency_type, u32 qos_val); +extern void cnss_pci_request_pm_qos(u32 qos_val); +extern void cnss_pci_remove_pm_qos(void); + +extern void cnss_sdio_request_pm_qos_type(int latency_type, u32 qos_val); +extern void cnss_sdio_request_pm_qos(u32 qos_val); +extern void cnss_sdio_remove_pm_qos(void); + +extern int cnss_get_platform_cap(struct cnss_platform_cap *cap); +extern void cnss_set_driver_status(enum cnss_driver_status driver_status); + +#ifndef CONFIG_WCNSS_MEM_PRE_ALLOC +static inline int wcnss_pre_alloc_reset(void) { return 0; } +#endif + +extern int msm_pcie_enumerate(u32 rc_idx); +extern int cnss_auto_suspend(void); +extern int cnss_auto_resume(void); +extern int cnss_prevent_auto_suspend(const char *caller_func); +extern int cnss_allow_auto_suspend(const char *caller_func); +extern int cnss_is_auto_suspend_allowed(const char *caller_func); + +extern int cnss_pm_runtime_request(struct device *dev, enum + cnss_runtime_request request); +extern void cnss_set_cc_source(enum cnss_cc_src cc_source); +extern enum cnss_cc_src cnss_get_cc_source(void); +#endif + +extern void cnss_pm_wake_lock_init(struct wakeup_source *ws, const char *name); +extern void cnss_pm_wake_lock(struct wakeup_source *ws); + +extern void cnss_device_crashed(void); +extern void cnss_device_self_recovery(void); +extern void *cnss_get_virt_ramdump_mem(unsigned long *size); + +extern void cnss_schedule_recovery_work(void); +extern int cnss_pcie_set_wlan_mac_address(const u8 *in, uint32_t len); +extern u8 *cnss_get_wlan_mac_address(struct device *dev, uint32_t *num); +extern int cnss_sdio_set_wlan_mac_address(const u8 *in, uint32_t len); + +enum { + CNSS_RESET_SOC = 0, + CNSS_RESET_SUBSYS_COUPLED, + CNSS_RESET_LEVEL_MAX +}; +extern int cnss_get_restart_level(void); + +struct cnss_sdio_wlan_driver { + const char *name; + const struct sdio_device_id *id_table; + int (*probe)(struct sdio_func *, const struct sdio_device_id *); + void (*remove)(struct sdio_func *); + int (*reinit)(struct sdio_func *, const struct sdio_device_id *); + void (*shutdown)(struct sdio_func *); + void (*crash_shutdown)(struct sdio_func *); + int (*suspend)(struct device *); + int (*resume)(struct device *); +}; + +extern int cnss_sdio_wlan_register_driver( + struct cnss_sdio_wlan_driver *driver); +extern void cnss_sdio_wlan_unregister_driver( + struct cnss_sdio_wlan_driver *driver); + +typedef void (*oob_irq_handler_t)(void *dev_para); +extern int cnss_wlan_query_oob_status(void); +extern int cnss_wlan_register_oob_irq_handler(oob_irq_handler_t handler, + void *pm_oob); +extern int cnss_wlan_unregister_oob_irq_handler(void *pm_oob); + + +extern void cnss_dump_stack(struct task_struct *task); +extern u8 *cnss_common_get_wlan_mac_address(struct device *dev, uint32_t *num); +extern void cnss_init_work(struct work_struct *work, work_func_t func); +extern void cnss_flush_delayed_work(void *dwork); +extern void cnss_flush_work(void *work); +extern void cnss_pm_wake_lock_timeout(struct wakeup_source *ws, ulong msec); +extern void cnss_pm_wake_lock_release(struct wakeup_source *ws); +extern void cnss_pm_wake_lock_destroy(struct wakeup_source *ws); +extern void cnss_get_monotonic_boottime(struct timespec *ts); +extern void cnss_get_boottime(struct timespec *ts); +extern void cnss_init_delayed_work(struct delayed_work *work, work_func_t + func); +extern int cnss_vendor_cmd_reply(struct sk_buff *skb); +extern int cnss_set_cpus_allowed_ptr(struct task_struct *task, ulong cpu); +extern int cnss_set_wlan_unsafe_channel(u16 *unsafe_ch_list, u16 ch_count); +extern int cnss_get_wlan_unsafe_channel(u16 *unsafe_ch_list, u16 *ch_count, + u16 buf_len); +extern int cnss_wlan_set_dfs_nol(const void *info, u16 info_len); +extern int cnss_wlan_get_dfs_nol(void *info, u16 info_len); +extern int cnss_common_request_bus_bandwidth(struct device *dev, int + bandwidth); +extern void cnss_common_device_crashed(struct device *dev); +extern void cnss_common_device_self_recovery(struct device *dev); +extern void *cnss_common_get_virt_ramdump_mem(struct device *dev, unsigned long + *size); +extern void cnss_common_schedule_recovery_work(struct device *dev); +extern int cnss_common_set_wlan_mac_address(struct device *dev, const u8 *in, + uint32_t len); +extern u8 *cnss_common_get_wlan_mac_address(struct device *dev, uint32_t *num); +extern int cnss_power_up(struct device *dev); +extern int cnss_power_down(struct device *dev); +extern int cnss_sdio_configure_spdt(bool state); + +extern int cnss_common_register_tsf_captured_handler(struct device *dev, + irq_handler_t handler, + void *ctx); +extern int cnss_common_unregister_tsf_captured_handler(struct device *dev, + void *ctx); +#endif /* _NET_CNSS_H_ */ -- GitLab From 4f2db47723c96c5d6aa7698a2cf18252d6548db9 Mon Sep 17 00:00:00 2001 From: Jayadev K Date: Fri, 19 Jul 2019 11:11:28 +0530 Subject: [PATCH 0950/1121] ARM: dts: qcom: Modify the device tree for HS-I2S driver Adding new 'compatible' entry in the HS-I2S node to derive the SOC information in the driver. Change-Id: I1d3a06bec6737e55139bc291f82950fddfe06365 Signed-off-by: Jayadev K --- Documentation/devicetree/bindings/sound/qcom,hsi2s.txt | 8 ++++++-- arch/arm64/boot/dts/qcom/sa6155-adp-air.dtsi | 2 +- arch/arm64/boot/dts/qcom/sa6155-adp-star.dtsi | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/qcom,hsi2s.txt b/Documentation/devicetree/bindings/sound/qcom,hsi2s.txt index debeef5780d6..237f2857f646 100644 --- a/Documentation/devicetree/bindings/sound/qcom,hsi2s.txt +++ b/Documentation/devicetree/bindings/sound/qcom,hsi2s.txt @@ -4,7 +4,10 @@ Qualcomm Technologies, Inc. High Speed I2S Interface Required properties: - - compatible : Should be "qcom,hsi2s" + - compatible : Should include "qcom,hsi2s" + Should include target specific compatible field + "qcom,sa6155-hsi2s" for SA6155 + "qcom,sa8155-hsi2s" for SA8155 - number-of-interfaces : Denotes the number of HS-I2S interfaces - reg : Specifies the base physical address and the size of the HS-I2S register space @@ -21,6 +24,7 @@ Required properties: - minor-number : Minor number of the character device interface Should be 0 for HS0 interface Should be 1 for HS1 interface + Should be 2 for HS2 interface - clocks : Interface clock used by this interface - clock-names : Clock name for the interface clock - pinctrl-names : Pinctrl state names for each pin group configuration @@ -35,7 +39,7 @@ Optional properties: Example: hsi2s: qcom,hsi2s { - compatible = "qcom,hsi2s"; + compatible = "qcom,sa6155-hsi2s", "qcom,hsi2s"; number-of-interfaces = <2>; reg = <0x1B40000 0x28000>; reg-names = "lpa_if"; diff --git a/arch/arm64/boot/dts/qcom/sa6155-adp-air.dtsi b/arch/arm64/boot/dts/qcom/sa6155-adp-air.dtsi index 61a1491c3e6e..3912d090e2f3 100644 --- a/arch/arm64/boot/dts/qcom/sa6155-adp-air.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155-adp-air.dtsi @@ -51,7 +51,7 @@ }; hsi2s: qcom,hsi2s { - compatible = "qcom,hsi2s"; + compatible = "qcom,sa6155-hsi2s", "qcom,hsi2s"; number-of-interfaces = <2>; reg = <0x1B40000 0x28000>; reg-names = "lpa_if"; diff --git a/arch/arm64/boot/dts/qcom/sa6155-adp-star.dtsi b/arch/arm64/boot/dts/qcom/sa6155-adp-star.dtsi index 78c3bce754e6..08b15e83d218 100644 --- a/arch/arm64/boot/dts/qcom/sa6155-adp-star.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155-adp-star.dtsi @@ -44,7 +44,7 @@ }; hsi2s: qcom,hsi2s { - compatible = "qcom,hsi2s"; + compatible = "qcom,sa6155-hsi2s", "qcom,hsi2s"; number-of-interfaces = <2>; reg = <0x1B40000 0x28000>; reg-names = "lpa_if"; -- GitLab From 545b21dc702d97bb4094c794bf0911c470681054 Mon Sep 17 00:00:00 2001 From: Praveen Kurapati Date: Wed, 17 Jul 2019 15:41:32 +0530 Subject: [PATCH 0951/1121] msm: ipa3: vote to turbo incase of APQ platform Change the modem vote to turbo during usb-tethering only when APQ platform was configured. Change-Id: I467939c3dd4fe43faad05dc4616b13e4613ee923 Signed-off-by: Praveen Kurapati --- drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c | 26 ++++++++++++------- drivers/platform/msm/ipa/ipa_v3/teth_bridge.c | 7 ++--- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c index 9e66e5b6f045..ff90da302d86 100644 --- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c @@ -2214,19 +2214,25 @@ int ipa3_wwan_set_modem_state(struct wan_ioctl_notify_wan_state *state) return 0; if (state->up) { - bw_mbps = 5200; - ret = ipa3_vote_for_bus_bw(&bw_mbps); - if (ret) { - IPAERR("Failed to vote for bus BW (%u)\n", bw_mbps); - return ret; + if (rmnet_ipa3_ctx->ipa_config_is_apq) { + bw_mbps = 5200; + ret = ipa3_vote_for_bus_bw(&bw_mbps); + if (ret) { + IPAERR("Failed to vote for bus BW (%u)\n", + bw_mbps); + return ret; + } } ret = ipa_pm_activate_sync(rmnet_ipa3_ctx->q6_teth_pm_hdl); } else { - bw_mbps = 0; - ret = ipa3_vote_for_bus_bw(&bw_mbps); - if (ret) { - IPAERR("Failed to vote for bus BW (%u)\n", bw_mbps); - return ret; + if (rmnet_ipa3_ctx->ipa_config_is_apq) { + bw_mbps = 0; + ret = ipa3_vote_for_bus_bw(&bw_mbps); + if (ret) { + IPAERR("Failed to vote for bus BW (%u)\n", + bw_mbps); + return ret; + } } ret = ipa_pm_deactivate_sync(rmnet_ipa3_ctx->q6_teth_pm_hdl); } diff --git a/drivers/platform/msm/ipa/ipa_v3/teth_bridge.c b/drivers/platform/msm/ipa/ipa_v3/teth_bridge.c index bac75e2dba71..87c268d79daa 100644 --- a/drivers/platform/msm/ipa/ipa_v3/teth_bridge.c +++ b/drivers/platform/msm/ipa/ipa_v3/teth_bridge.c @@ -191,9 +191,10 @@ int ipa3_teth_bridge_connect(struct teth_bridge_connect_params *connect_params) TETH_ERR("fail to register with PM %d\n", res); return res; } - /* vote for turbo */ - res = ipa_pm_set_throughput(ipa3_teth_ctx->modem_pm_hdl, - 5200); + /* vote for turbo in case of MHIP channels*/ + if (ipa3_is_apq()) + res = ipa_pm_set_throughput(ipa3_teth_ctx->modem_pm_hdl, + 5200); res = ipa_pm_activate_sync(ipa3_teth_ctx->modem_pm_hdl); goto bail; } -- GitLab From 7badbcc3dcbb6a8cee42a8ddbc338be5b9305c88 Mon Sep 17 00:00:00 2001 From: Maria Yu Date: Fri, 19 Jul 2019 19:25:09 +0800 Subject: [PATCH 0952/1121] sched/fair: Only strict skip for current task Fix the issue that when a task called yield, it is not going to schedule again if there is always have task running in that cpu. Change-Id: I7ec037ac5ea9be159ccb9e9db676d1b8d677746d Signed-off-by: Maria Yu --- kernel/sched/fair.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 31e67d999d3e..1f17a523832c 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -4226,6 +4226,7 @@ pick_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *curr) { struct sched_entity *left = __pick_first_entity(cfs_rq); struct sched_entity *se; + bool strict_skip = false; /* * If curr is set we have to see if its left of the leftmost entity @@ -4245,13 +4246,15 @@ pick_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *curr) if (se == curr) { second = __pick_first_entity(cfs_rq); + if (sched_feat(STRICT_SKIP_BUDDY)) + strict_skip = true; } else { second = __pick_next_entity(se); if (!second || (curr && entity_before(curr, second))) second = curr; } - if (second && (sched_feat(STRICT_SKIP_BUDDY) || + if (second && (strict_skip || wakeup_preempt_entity(second, left) < 1)) se = second; } -- GitLab From fc4ad6f2271febadf26c97f8b9fce3e1b4aebe9b Mon Sep 17 00:00:00 2001 From: Sriharsha Allenki Date: Tue, 18 Jun 2019 16:49:24 +0530 Subject: [PATCH 0953/1121] usb: dwc3: Prevent continuous retries on error event Upon USB core generating an erratic error event, the dwc3-msm driver resets and restarts the core. Even after this if core could not recover, the driver keep on trying the same in a infinite loop. This could lead to the hogging of system resources leading to system failure. Prevent this by trying a maximum of three times to recover upon erratic error event. An example of continuous generation of error events is a DCP charger detected as SDP by the PMIC and core entering device mode. In this case, the core could not recover even after several tries. Change-Id: Ic2f2f10e6bcc7480be5116746072b0fb1651ce10 Signed-off-by: Sriharsha Allenki --- drivers/usb/dwc3/core.h | 2 ++ drivers/usb/dwc3/dwc3-msm.c | 9 +++++++-- drivers/usb/dwc3/gadget.c | 7 ++++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index da67caf2d47f..8d1a8d9d3132 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -45,6 +45,7 @@ #define DWC3_EP0_SETUP_SIZE 512 #define DWC3_ENDPOINTS_NUM 32 #define DWC3_XHCI_RESOURCES_NUM 2 +#define MAX_ERROR_RECOVERY_TRIES 3 #define DWC3_SCRATCHBUF_SIZE 4096 /* each buffer is assumed to be 4KiB */ #define DWC3_EVENT_BUFFERS_SIZE 4096 @@ -1204,6 +1205,7 @@ struct dwc3 { * connected devices on PM resume. */ bool host_poweroff_in_pm_suspend; + int retries_on_error; }; #define work_to_dwc(w) (container_of((w), struct dwc3, drd_work)) diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index dca0673a5f2a..3b17d33689cd 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -1885,8 +1885,13 @@ static void dwc3_msm_notify_event(struct dwc3 *dwc, unsigned int event, reg |= DWC3_GCTL_CORESOFTRESET; dwc3_msm_write_reg(mdwc->base, DWC3_GCTL, reg); - /* restart USB which performs full reset and reconnect */ - schedule_work(&mdwc->restart_usb_work); + /* + * If core could not recover after MAX_ERROR_RECOVERY_TRIES + * skip the restart USB work and keep the core in softreset + * state + */ + if (dwc->retries_on_error < MAX_ERROR_RECOVERY_TRIES) + schedule_work(&mdwc->restart_usb_work); break; case DWC3_CONTROLLER_RESET_EVENT: dev_dbg(mdwc->dev, "DWC3_CONTROLLER_RESET_EVENT received\n"); diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index aff6059aa854..d12e35371f26 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2091,6 +2091,7 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend) reg1 |= DWC3_GEVNTSIZ_INTMASK; dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), reg1); + dwc->err_evt_seen = false; dwc->pullups_connected = false; __dwc3_gadget_ep_disable(dwc->eps[0]); @@ -3265,6 +3266,9 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc) dwc3_writel(dwc->regs, DWC3_DEVTEN, reg); } + /* Reset the retry on erratic error event count */ + dwc->retries_on_error = 0; + /* * RAMClkSel is reset to 0 after USB reset, so it must be reprogrammed * each time on Connect Done. @@ -3628,7 +3632,7 @@ static void dwc3_gadget_interrupt(struct dwc3 *dwc, dwc->dbg_gadget_events.sof++; break; case DWC3_DEVICE_EVENT_ERRATIC_ERROR: - dbg_event(0xFF, "ERROR", 0); + dbg_event(0xFF, "ERROR", dwc->retries_on_error); dwc->dbg_gadget_events.erratic_error++; dwc->err_evt_seen = true; break; @@ -3686,6 +3690,7 @@ static irqreturn_t dwc3_process_event_buf(struct dwc3_event_buffer *evt) if (dwc3_notify_event(dwc, DWC3_CONTROLLER_ERROR_EVENT, 0)) dwc->err_evt_seen = 0; + dwc->retries_on_error++; break; } -- GitLab From e8247f0bb39f439662a006a4e9cfd7cf313c7677 Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Wed, 17 Jul 2019 13:16:51 -0700 Subject: [PATCH 0954/1121] ARM: dts: msm: Use PM8195 regulators for SA8195P ADP STAR The SA8195P ADP STAR platform uses sa8195-pmic regulators and GPIO definitions. Provide updated regulators for the devices and subsystems which run on the SA8195P ADP STAR platform. Change-Id: I7dc59e2f6922028b2490925239859c39246e7c72 Signed-off-by: Anant Goel --- arch/arm64/boot/dts/qcom/sa8195-pmic.dtsi | 40 ++------ arch/arm64/boot/dts/qcom/sa8195p.dtsi | 119 ++++++++++++++++++++++ 2 files changed, 127 insertions(+), 32 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sa8195-pmic.dtsi b/arch/arm64/boot/dts/qcom/sa8195-pmic.dtsi index 2cdf7df42ed9..c19adc024a9d 100644 --- a/arch/arm64/boot/dts/qcom/sa8195-pmic.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8195-pmic.dtsi @@ -75,40 +75,16 @@ /delete-property/ vdda33-supply; }; -&mdss_dsi0 { - vdda-1p2-supply = <&pm8195_1_l9>; +&lmh_dcvs1 { + isens_vref_0p8-supply = <&pm8195_3_l5>; + isens-vref-0p8-settings = <880000 880000 20000>; + isens_vref_1p8-supply = <&pm8195_1_l12>; + isens-vref-1p8-settings = <1800000 1800000 20000>; }; -&mdss_dsi1 { - vdda-1p2-supply = <&pm8195_1_l9>; -}; - -&mdss_dsi_phy0 { - vdda-0p9-supply = <&pm8195_3_l5>; -}; - -&mdss_dsi_phy1 { - vdda-0p9-supply = <&pm8195_3_l5>; -}; - -&clock_cpucc { - lmh_dcvs1: qcom,limits-dcvs@18350800 { - isens_vref_0p8-supply = <&pm8195_3_l5>; - isens-vref-0p8-settings = <880000 880000 20000>; - isens_vref_1p8-supply = <&pm8195_1_l12>; - isens-vref-1p8-settings = <1800000 1800000 20000>; - }; -}; - - -&soc { - qcom,lpass@17300000 { - vdd_cx-supply = <&VDD_CX_LEVEL>; - }; - clock_camcc: qcom,camcc@ad00000 { - vdd_mx-supply = <&VDD_MX_LEVEL>; - vdd_mm-supply = <&VDD_MMCX_LEVEL>; - }; +&clock_camcc { + vdd_mx-supply = <&VDD_MX_LEVEL>; + vdd_mm-supply = <&VDD_MMCX_LEVEL>; }; &gpu_gx_gdsc { diff --git a/arch/arm64/boot/dts/qcom/sa8195p.dtsi b/arch/arm64/boot/dts/qcom/sa8195p.dtsi index 237ab398e218..0498ae164529 100644 --- a/arch/arm64/boot/dts/qcom/sa8195p.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8195p.dtsi @@ -12,6 +12,10 @@ #include "sdmshrike-v2.dtsi" #include "sa8155-audio.dtsi" +#include "sa8195-pmic.dtsi" +#include "sm8150-camera.dtsi" +#include "sm8150-v2-camera.dtsi" +#include "sa8155-camera-sensor.dtsi" / { model = "Qualcomm Technologies, Inc. SA8195P"; @@ -106,3 +110,118 @@ }; }; }; + +&ufsphy_mem { + compatible = "qcom,ufs-phy-qmp-v4"; + vdda-phy-supply = <&pm8195_3_l5>; + vdda-pll-supply = <&pm8195_1_l9>; + vdda-phy-max-microamp = <138000>; + vdda-pll-max-microamp = <65100>; + + status = "ok"; +}; + +&ufshc_mem { + vdd-hba-supply = <&ufs_phy_gdsc>; + vdd-hba-fixed-regulator; + vcc-supply = <&pm8195_3_l10>; + vcc-voltage-level = <2894000 2904000>; + vcc-low-voltage-sup; + vccq-supply = <&pm8195_1_l11>; + vccq2-supply = <&pm8195_3_l7>; + vcc-max-microamp = <750000>; + vccq-max-microamp = <750000>; + vccq2-max-microamp = <750000>; + + status= "ok"; +}; + +&usb2_phy0 { + vdd-supply = <&pm8195_3_l5>; + vdda18-supply = <&pm8195_1_l12>; + vdda33-supply = <&pm8195_3_l16>; +}; + +&usb2_phy1 { + vdd-supply = <&pm8195_3_l5>; + vdda18-supply = <&pm8195_1_l12>; + vdda33-supply = <&pm8195_3_l16>; + status = "ok"; +}; + +&mdss_dsi_phy0 { + vdda-0p9-supply = <&pm8195_3_l5>; +}; + +&mdss_dsi_phy1 { + vdda-0p9-supply = <&pm8195_3_l5>; +}; + +&mdss_dsi0 { + vdda-1p2-supply = <&pm8195_1_l9>; +}; + +&mdss_dsi1 { + vdda-1p2-supply = <&pm8195_1_l9>; +}; + +&sde_dp { + vdda-1p2-supply = <&pm8195_1_l9>; + vdda-0p9-supply = <&pm8195_3_l5>; +}; + +&pil_lpass { + vdd_cx-supply = <&VDD_CX_LEVEL>; + status = "ok"; +}; + +&clock_scc { + vdd_scc_cx-supply = <&pm8195_3_l8_level>; + status = "ok"; +}; + +&cam_csiphy0 { + mipi-csi-vdd-supply = <&pm8195_1_l9>; +}; + +&cam_csiphy1 { + mipi-csi-vdd-supply = <&pm8195_1_l9>; +}; + +&cam_csiphy2 { + mipi-csi-vdd-supply = <&pm8195_1_l9>; +}; + +&cam_csiphy3 { + mipi-csi-vdd-supply = <&pm8195_1_l9>; +}; + +&cam_cci0 { + qcom,cam-sensor@0 { + cam_vio-supply = <&pm8195_s4>; + cam_bob-supply = <&pm8195_s4>; + cam_vana-supply = <&pm8195_s4>; + cam_vdig-supply = <&pm8195_s4>; + }; + + qcom,cam-sensor@1 { + cam_vio-supply = <&pm8195_s4>; + cam_bob-supply = <&pm8195_s4>; + cam_vana-supply = <&pm8195_s4>; + cam_vdig-supply = <&pm8195_s4>; + }; + + qcom,cam-sensor@2 { + cam_vio-supply = <&pm8195_s4>; + cam_bob-supply = <&pm8195_s4>; + cam_vana-supply = <&pm8195_s4>; + cam_vdig-supply = <&pm8195_s4>; + }; + + qcom,cam-sensor@3 { + cam_vio-supply = <&pm8195_s4>; + cam_bob-supply = <&pm8195_s4>; + cam_vana-supply = <&pm8195_s4>; + cam_vdig-supply = <&pm8195_s4>; + }; +}; -- GitLab From cd4ff658f3f683ca9a19c20b658aa1997101fc88 Mon Sep 17 00:00:00 2001 From: Michael Adisumarta Date: Thu, 11 Jul 2019 11:49:43 -0700 Subject: [PATCH 0955/1121] msm: ipa3: add qmi support for cleaning MHIP rules and frags Add QMI IDL changes for supporting cleaning DL MHIP filtering rules and also adds an option to use legacy path instead of MHIP path for DL frag packets which are not supported. Change-Id: Ic5641012f1d8a8365f51eef27426ad4d008d9892 Signed-off-by: Michael Adisumarta --- .../msm/ipa/ipa_v3/ipa_qmi_service_v01.c | 40 +++++++++++++++++++ include/uapi/linux/ipa_qmi_service_v01.h | 17 +++++++- 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service_v01.c b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service_v01.c index e760d16b0e38..eb402beffe85 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service_v01.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service_v01.c @@ -4948,6 +4948,26 @@ struct qmi_elem_info ipa_add_offload_connection_req_msg_v01_ei[] = { struct ipa_add_offload_connection_req_msg_v01, embedded_call_mux_id), }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x15, + .offset = offsetof( + struct ipa_add_offload_connection_req_msg_v01, + default_mhi_path_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x15, + .offset = offsetof( + struct ipa_add_offload_connection_req_msg_v01, + default_mhi_path), + }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, @@ -5041,6 +5061,26 @@ struct qmi_elem_info ipa_remove_offload_connection_req_msg_v01_ei[] = { .ei_array = ipa3_filter_rule_identifier_to_handle_map_data_v01_ei, }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x11, + .offset = offsetof( + struct ipa_remove_offload_connection_req_msg_v01, + clean_all_rules_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x11, + .offset = offsetof( + struct ipa_remove_offload_connection_req_msg_v01, + clean_all_rules), + }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, diff --git a/include/uapi/linux/ipa_qmi_service_v01.h b/include/uapi/linux/ipa_qmi_service_v01.h index 461ccc862ee6..eee60ddbee74 100644 --- a/include/uapi/linux/ipa_qmi_service_v01.h +++ b/include/uapi/linux/ipa_qmi_service_v01.h @@ -64,6 +64,7 @@ * Indicates presence of newly added member to support HW stats. */ #define IPA_QMI_SUPPORTS_STATS +#define IPA_QMI_SUPPORT_MHI_DEFAULT #define IPA_INT_MAX ((int)(~0U>>1)) #define IPA_INT_MIN (-IPA_INT_MAX - 1) @@ -2606,8 +2607,14 @@ struct ipa_add_offload_connection_req_msg_v01 { /* Must be set to true if embedded_call_mux_id is being passed */ uint32_t embedded_call_mux_id; /* Mux ID for the new embedded call */ + /* Optional */ + /* Default MHI path */ + uint8_t default_mhi_path_valid; + /* Must be set to true if default_mhi_path is being passed */ + uint8_t default_mhi_path; + /* Default MHI path */ }; /* Message */ -#define IPA_ADD_OFFLOAD_CONNECTION_REQ_MSG_V01_MAX_MSG_LEN 11357 +#define IPA_ADD_OFFLOAD_CONNECTION_REQ_MSG_V01_MAX_MSG_LEN 11361 struct ipa_add_offload_connection_resp_msg_v01 { /* Result Code */ @@ -2630,8 +2637,14 @@ struct ipa_remove_offload_connection_req_msg_v01 { uint32_t filter_handle_list_len; struct ipa_filter_rule_identifier_to_handle_map_v01 filter_handle_list[QMI_IPA_MAX_FILTERS_V01]; + /* Optional */ + /* Clean All rules */ + uint8_t clean_all_rules_valid; + /* Must be set to true if clean_all_rules is being passed */ + uint8_t clean_all_rules; + /* Clean All rules */ }; /* Message */ -#define IPA_REMOVE_OFFLOAD_CONNECTION_REQ_MSG_V01_MAX_MSG_LEN 516 +#define IPA_REMOVE_OFFLOAD_CONNECTION_REQ_MSG_V01_MAX_MSG_LEN 520 struct ipa_remove_offload_connection_resp_msg_v01 { /* optional */ -- GitLab From edd49fca0fbde48058f1180673d4bf68585378fd Mon Sep 17 00:00:00 2001 From: Michael Adisumarta Date: Mon, 8 Jul 2019 14:49:29 -0700 Subject: [PATCH 0956/1121] msm: ipa3: Cleanup MHIP Dl rules on IPACM restart Add a function called when IPACM is killed that will call qmi_rmv_offload which will send a qmi to modem to remove all valid MHIP connection from the qmi cache. Change-Id: I87032c11c17257659b16c8f28fd38323b878cb87 Signed-off-by: Michael Adisumarta --- drivers/platform/msm/ipa/ipa_v3/ipa.c | 23 ++++++++++++++++++- .../platform/msm/ipa/ipa_v3/ipa_qmi_service.c | 9 ++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index 840bb914eaef..c58d9582c064 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -259,6 +259,24 @@ static int ipa3_clean_modem_rule(void) return val; } +static int ipa3_clean_mhip_dl_rule(void) +{ + struct ipa_remove_offload_connection_req_msg_v01 req; + + memset(&req, 0, sizeof(struct + ipa_remove_offload_connection_req_msg_v01)); + + req.clean_all_rules_valid = true; + req.clean_all_rules = true; + + if (ipa3_qmi_rmv_offload_request_send(&req)) { + IPAWANDBG("clean dl rule cache failed\n"); + return -EFAULT; + } + + return 0; +} + static int ipa3_active_clients_panic_notifier(struct notifier_block *this, unsigned long event, void *ptr) { @@ -1862,7 +1880,10 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) memset(&nat_del, 0, sizeof(nat_del)); nat_del.table_index = 0; retval = ipa3_nat_del_cmd(&nat_del); - retval = ipa3_clean_modem_rule(); + if (ipa3_ctx->platform_type == IPA_PLAT_TYPE_APQ) + retval = ipa3_clean_mhip_dl_rule(); + else + retval = ipa3_clean_modem_rule(); ipa3_counter_id_remove_all(); break; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c index 60da89daf619..de12e84f2c7e 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c @@ -1088,6 +1088,15 @@ int ipa3_qmi_rmv_offload_request_send( req_desc.msg_id = QMI_IPA_REMOVE_OFFLOAD_CONNECTION_REQ_V01; req_desc.ei_array = ipa_remove_offload_connection_req_msg_v01_ei; + /* clean the Dl rules in the cache if flag is set */ + if (req->clean_all_rules) { + for (i = 0; i < QMI_IPA_MAX_FILTERS_V01; i++) + if (ipa3_qmi_ctx->ipa_offload_cache[i].valid) + ipa3_qmi_ctx->ipa_offload_cache[i].valid = + false; + } + + memset(&resp, 0, sizeof(struct ipa_remove_offload_connection_resp_msg_v01)); resp_desc.max_msg_len = -- GitLab From 07737f8aeb75fc89bb024bc2eccc320229a51c3b Mon Sep 17 00:00:00 2001 From: Gustavo Solaira Date: Fri, 19 Jul 2019 13:17:39 -0700 Subject: [PATCH 0957/1121] defconfig: msm: Enable TLV Audio codec for sdxprairie-auto Enable the TI audio codec for sdxprairie-auto platforms. Change-Id: Ia57b6a7c7defcdf30d3852c554662a512a7bc21e Signed-off-by: Gustavo Solaira --- arch/arm/configs/vendor/sdxprairie-auto-perf_defconfig | 1 + arch/arm/configs/vendor/sdxprairie-auto_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm/configs/vendor/sdxprairie-auto-perf_defconfig b/arch/arm/configs/vendor/sdxprairie-auto-perf_defconfig index dbfa32e26312..eceeaa266932 100644 --- a/arch/arm/configs/vendor/sdxprairie-auto-perf_defconfig +++ b/arch/arm/configs/vendor/sdxprairie-auto-perf_defconfig @@ -278,6 +278,7 @@ CONFIG_SOUND=y CONFIG_SND=y CONFIG_SND_DYNAMIC_MINORS=y CONFIG_SND_SOC=y +CONFIG_SND_SOC_TLV320AIC3X=y CONFIG_UHID=y CONFIG_HID_APPLE=y CONFIG_HID_ELECOM=y diff --git a/arch/arm/configs/vendor/sdxprairie-auto_defconfig b/arch/arm/configs/vendor/sdxprairie-auto_defconfig index f24bfa4d6dec..100a978a30d9 100644 --- a/arch/arm/configs/vendor/sdxprairie-auto_defconfig +++ b/arch/arm/configs/vendor/sdxprairie-auto_defconfig @@ -279,6 +279,7 @@ CONFIG_SOUND=y CONFIG_SND=y CONFIG_SND_DYNAMIC_MINORS=y CONFIG_SND_SOC=y +CONFIG_SND_SOC_TLV320AIC3X=y CONFIG_UHID=y CONFIG_HID_APPLE=y CONFIG_HID_ELECOM=y -- GitLab From e72948be4c29613c4d4b17e9521cece37c68317c Mon Sep 17 00:00:00 2001 From: Rajesha Kini Date: Wed, 19 Jun 2019 23:02:26 +0530 Subject: [PATCH 0958/1121] ASoC: tlv320aic3x: Add reset inverted DT property Add reset inverted property to allow reset signal as active high instead of the default active low polarity. Change-Id: I27ae32ba296f71b1d989837ada8b4ad8766ba8ba Signed-off-by: Rajesha Kini Signed-off-by: Gustavo Solaira --- .../devicetree/bindings/sound/tlv320aic3x.txt | 3 ++- sound/soc/codecs/tlv320aic3x.c | 15 +++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/tlv320aic3x.txt b/Documentation/devicetree/bindings/sound/tlv320aic3x.txt index ba5b45c483f5..41fec22d6480 100644 --- a/Documentation/devicetree/bindings/sound/tlv320aic3x.txt +++ b/Documentation/devicetree/bindings/sound/tlv320aic3x.txt @@ -17,7 +17,8 @@ Required properties: Optional properties: -- gpio-reset - gpio pin number used for codec reset +- gpio-reset - gpio pin number used for codec reset, default active low +- reset-inverted - set the reset gpio mode as active high - ai3x-gpio-func - - AIC3X_GPIO1 & AIC3X_GPIO2 Functionality - Not supported on tlv320aic3104 - ai3x-micbias-vg - MicBias Voltage required. diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 06f92571eba4..16dd1f61a721 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -84,6 +84,7 @@ struct aic3x_priv { struct list_head list; int master; int gpio_reset; + bool reset_inverted; int power; #define AIC3X_MODEL_3X 0 #define AIC3X_MODEL_33 1 @@ -1355,7 +1356,8 @@ static int aic3x_regulator_event(struct notifier_block *nb, * of the supplies was disabled */ if (gpio_is_valid(aic3x->gpio_reset)) - gpio_set_value(aic3x->gpio_reset, 0); + gpio_set_value(aic3x->gpio_reset, + aic3x->reset_inverted); regcache_mark_dirty(aic3x->regmap); } @@ -1377,7 +1379,8 @@ static int aic3x_set_power(struct snd_soc_codec *codec, int power) if (gpio_is_valid(aic3x->gpio_reset)) { udelay(1); - gpio_set_value(aic3x->gpio_reset, 1); + gpio_set_value(aic3x->gpio_reset, + !aic3x->reset_inverted); } /* Sync reg_cache with the hardware */ @@ -1810,6 +1813,9 @@ static int aic3x_i2c_probe(struct i2c_client *i2c, else aic3x->gpio_reset = -1; + aic3x->reset_inverted = + of_property_read_bool(np, "reset-inverted"); + if (of_property_read_u32_array(np, "ai3x-gpio-func", ai3x_setup->gpio_func, 2) >= 0) { aic3x->setup = ai3x_setup; @@ -1846,7 +1852,8 @@ static int aic3x_i2c_probe(struct i2c_client *i2c, ret = gpio_request(aic3x->gpio_reset, "tlv320aic3x reset"); if (ret != 0) goto err; - gpio_direction_output(aic3x->gpio_reset, 0); + gpio_direction_output(aic3x->gpio_reset, + aic3x->reset_inverted); } for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++) @@ -1894,7 +1901,7 @@ static int aic3x_i2c_remove(struct i2c_client *client) snd_soc_unregister_codec(&client->dev); if (gpio_is_valid(aic3x->gpio_reset) && !aic3x_is_shared_reset(aic3x)) { - gpio_set_value(aic3x->gpio_reset, 0); + gpio_set_value(aic3x->gpio_reset, aic3x->reset_inverted); gpio_free(aic3x->gpio_reset); } return 0; -- GitLab From c0a7f43e69a38bba19b5593d6ea5963810cb996b Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Fri, 19 Jul 2019 14:05:17 -0700 Subject: [PATCH 0959/1121] ARM: dts: msm: Update RPMh clock for SA8195P Use the SM8150 RPMh clock driver for the SA8195P target. Change-Id: I51ae91a32b4ef3ac99c76ca1053698061e1d1cd3 Signed-off-by: Anant Goel --- arch/arm64/boot/dts/qcom/sa8195p.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sa8195p.dtsi b/arch/arm64/boot/dts/qcom/sa8195p.dtsi index c704cdcbead0..b8e3ef36d3c2 100644 --- a/arch/arm64/boot/dts/qcom/sa8195p.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8195p.dtsi @@ -125,3 +125,7 @@ &ssc_sensors { status = "disabled"; }; + +&clock_rpmh { + compatible = "qcom,rpmh-clk-sm8150"; +}; -- GitLab From 9468e73c41d09a2f278858169ea72012358ceef8 Mon Sep 17 00:00:00 2001 From: Ashok Vuyyuru Date: Wed, 3 Jul 2019 20:48:28 +0530 Subject: [PATCH 0960/1121] msm: ipa4: Don't decrease channel ref conunt for GCI channel Because of decreasing channel reference count two times one channel ref count value going to negetive value and failed to deallocate this event ring. Add changes to avoid decreasing the reference count for GCI channel. Change-Id: Id85d476cb9ccf138dc3e5979395ce853d53dd317 Signed-off-by: Ashok Vuyyuru --- drivers/platform/msm/gsi/gsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/msm/gsi/gsi.c b/drivers/platform/msm/gsi/gsi.c index ac422bdd03af..1ede4d3ae6f3 100644 --- a/drivers/platform/msm/gsi/gsi.c +++ b/drivers/platform/msm/gsi/gsi.c @@ -3110,7 +3110,7 @@ int gsi_dealloc_channel(unsigned long chan_hdl) } devm_kfree(gsi_ctx->dev, ctx->user_data); ctx->allocated = false; - if (ctx->evtr) + if (ctx->evtr && (ctx->props.prot != GSI_CHAN_PROT_GCI)) atomic_dec(&ctx->evtr->chan_ref_cnt); atomic_dec(&gsi_ctx->num_chan); -- GitLab From 88942b1ef017a9966768ca4332afb6793487be28 Mon Sep 17 00:00:00 2001 From: Ashok Vuyyuru Date: Thu, 20 Jun 2019 22:52:27 +0530 Subject: [PATCH 0961/1121] msm: ipa4: Compare unsigned value with less than zero always false Because of wrong condition when it failed get cookie programming GCI TRE with wrong coockie values. Add changes to correct if condition logic with proper checks. Change-Id: I19eb4a628c4d6ee7ad5ab6a98ba78ff8a58bf198 Signed-off-by: Ashok Vuyyuru --- drivers/platform/msm/gsi/gsi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/platform/msm/gsi/gsi.c b/drivers/platform/msm/gsi/gsi.c index ac422bdd03af..5be3ec4cf8b4 100644 --- a/drivers/platform/msm/gsi/gsi.c +++ b/drivers/platform/msm/gsi/gsi.c @@ -3339,8 +3339,8 @@ int __gsi_get_gci_cookie(struct gsi_chan_ctx *ctx, uint16_t idx) * idx is not completed yet and it is getting reused by a new TRE. */ ctx->stats.userdata_in_use++; + end = ctx->ring.max_num_elem + 1; for (i = 0; i < GSI_VEID_MAX; i++) { - end = ctx->ring.max_num_elem + 1; if (!ctx->user_data[end + i].valid) { ctx->user_data[end + i].valid = true; return end + i; @@ -3349,7 +3349,7 @@ int __gsi_get_gci_cookie(struct gsi_chan_ctx *ctx, uint16_t idx) /* TODO: Increase escape buffer size if we hit this */ GSIERR("user_data is full\n"); - return -EPERM; + return 0xFFFF; } int __gsi_populate_gci_tre(struct gsi_chan_ctx *ctx, @@ -3380,7 +3380,7 @@ int __gsi_populate_gci_tre(struct gsi_chan_ctx *ctx, gci_tre.buf_len = xfer->len; gci_tre.re_type = GSI_RE_COAL; gci_tre.cookie = __gsi_get_gci_cookie(ctx, idx); - if (gci_tre.cookie < 0) + if (gci_tre.cookie > (ctx->ring.max_num_elem + GSI_VEID_MAX)) return -EPERM; /* write the TRE to ring */ -- GitLab From 3a28168a38a16ac8dc9b665efebeab9080aac693 Mon Sep 17 00:00:00 2001 From: Ashok Vuyyuru Date: Thu, 20 Jun 2019 23:16:12 +0530 Subject: [PATCH 0962/1121] msm: ipa4: initialize the replenish pointer for WAN consumer pipe When coalescing pipe and WAN consumer pipe are configuring case using the same replenish pointer as coalescing replenish pointer causing overriding head_idx/tail_idx values for both pipes. Add changes initialize the new replenish pointer for WAN consumer pipe. Change-Id: I4d637ae9fd6a6d95a12bc239fbff9dea5668ff03 Signed-off-by: Ashok Vuyyuru --- drivers/platform/msm/ipa/ipa_v3/ipa_dp.c | 88 ++++++++++++++++++++---- 1 file changed, 74 insertions(+), 14 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c index dd0b96d51dac..f7315eb50bc1 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c @@ -1098,10 +1098,6 @@ int ipa3_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl) atomic_set(&ep->sys->repl->pending, 0); ep->sys->repl->capacity = ep->sys->rx_pool_sz + 1; - /*double for wan_coal since it will be shared between 2 pipes */ - if (sys_in->client == IPA_CLIENT_APPS_WAN_COAL_CONS) - ep->sys->repl->capacity *= 2; - ep->sys->repl->cache = kcalloc(ep->sys->repl->capacity, sizeof(void *), GFP_KERNEL); if (!ep->sys->repl->cache) { @@ -1217,6 +1213,7 @@ static int ipa_setup_coal_def_pipe(struct ipa_sys_connect_params *sys_in, struct ipa3_ep_context *ep; int result = -EINVAL; int ipa_ep_idx, i; + char buff[IPA_RESOURCE_NAME_MAX]; ipa_ep_idx = ipa3_get_ep_mapping(sys_in->client); @@ -1239,13 +1236,34 @@ static int ipa_setup_coal_def_pipe(struct ipa_sys_connect_params *sys_in, IPAERR("failed to sys ctx for client %d\n", IPA_CLIENT_APPS_WAN_CONS); result = -ENOMEM; - goto fail_wq; + goto fail_gen; } ep->sys->ep = ep; - ep->sys->wq = ep_coalescing->sys->wq; - ep->sys->repl_wq = ep_coalescing->sys->repl_wq; + snprintf(buff, IPA_RESOURCE_NAME_MAX, "ipawq%d", + sys_in->client); + ep->sys->wq = alloc_workqueue(buff, + WQ_MEM_RECLAIM | WQ_UNBOUND | WQ_SYSFS, 1); + + if (!ep->sys->wq) { + IPAERR("failed to create wq for client %d\n", + sys_in->client); + result = -EFAULT; + goto fail_wq; + } + + snprintf(buff, IPA_RESOURCE_NAME_MAX, "iparepwq%d", + sys_in->client); + ep->sys->repl_wq = alloc_workqueue(buff, + WQ_MEM_RECLAIM | WQ_UNBOUND | WQ_SYSFS, 1); + if (!ep->sys->repl_wq) { + IPAERR("failed to create rep wq for client %d\n", + sys_in->client); + result = -EFAULT; + goto fail_wq2; + } + INIT_LIST_HEAD(&ep->sys->rcycl_list); spin_lock_init(&ep->sys->spinlock); hrtimer_init(&ep->sys->db_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); @@ -1260,7 +1278,7 @@ static int ipa_setup_coal_def_pipe(struct ipa_sys_connect_params *sys_in, IPAERR("failed to sys ctx for client %d\n", IPA_CLIENT_APPS_WAN_CONS); result = -ENOMEM; - goto fail_wq; + goto fail_gen2; } ep->valid = 1; @@ -1274,17 +1292,17 @@ static int ipa_setup_coal_def_pipe(struct ipa_sys_connect_params *sys_in, if (!ep->skip_ep_cfg) { if (ipa3_cfg_ep(ipa_ep_idx, &sys_in->ipa_ep_cfg)) { IPAERR("fail to configure EP.\n"); - goto fail_wq; + goto fail_gen2; } if (ep->status.status_en) { IPAERR("status should be disabled for this EP.\n"); - goto fail_wq; + goto fail_gen2; } if (ipa3_cfg_ep_status(ipa_ep_idx, &ep->status)) { IPAERR("fail to configure status of EP.\n"); - goto fail_wq; + goto fail_gen2; } IPADBG("ep %d configuration successful\n", ipa_ep_idx); } else { @@ -1294,10 +1312,33 @@ static int ipa_setup_coal_def_pipe(struct ipa_sys_connect_params *sys_in, result = ipa_gsi_setup_coal_def_channel(sys_in, ep, ep_coalescing); if (result) { IPAERR("Failed to setup default coal GSI channel\n"); - goto fail_wq; + goto fail_gen2; + } + + if (ep->sys->repl_hdlr == ipa3_fast_replenish_rx_cache) { + ep->sys->repl = kzalloc(sizeof(*ep->sys->repl), GFP_KERNEL); + if (!ep->sys->repl) { + IPAERR("failed to alloc repl for client %d\n", + sys_in->client); + result = -ENOMEM; + goto fail_gen2; + } + atomic_set(&ep->sys->repl->pending, 0); + ep->sys->repl->capacity = ep->sys->rx_pool_sz + 1; + + ep->sys->repl->cache = kcalloc(ep->sys->repl->capacity, + sizeof(void *), GFP_KERNEL); + if (!ep->sys->repl->cache) { + IPAERR("ep=%d fail to alloc repl cache\n", ipa_ep_idx); + ep->sys->repl_hdlr = ipa3_replenish_rx_cache; + ep->sys->repl->capacity = 0; + } else { + atomic_set(&ep->sys->repl->head_idx, 0); + atomic_set(&ep->sys->repl->tail_idx, 0); + ipa3_wq_repl_rx(&ep->sys->repl_work); + } } - ep->sys->repl = ep_coalescing->sys->repl; ipa3_replenish_rx_cache(ep->sys); for (i = 0; i < GSI_VEID_MAX; i++) @@ -1309,7 +1350,7 @@ static int ipa_setup_coal_def_pipe(struct ipa_sys_connect_params *sys_in, if (result) { IPAERR("enable data path failed res=%d ep=%d.\n", result, ipa_ep_idx); - goto fail_wq; + goto fail_repl; } result = gsi_start_channel(ep->gsi_chan_hdl); @@ -1324,6 +1365,14 @@ static int ipa_setup_coal_def_pipe(struct ipa_sys_connect_params *sys_in, /* the rest of the fails are handled by ipa3_setup_sys_pipe */ fail_start_channel: ipa3_disable_data_path(ipa_ep_idx); +fail_repl: + ep->sys->repl_hdlr = ipa3_replenish_rx_cache; + ep->sys->repl->capacity = 0; + kfree(ep->sys->repl); +fail_gen2: + destroy_workqueue(ep->sys->repl_wq); +fail_wq2: + destroy_workqueue(ep->sys->wq); fail_wq: kfree(ep->sys); memset(&ipa3_ctx->ep[ipa_ep_idx], 0, sizeof(struct ipa3_ep_context)); @@ -1526,6 +1575,17 @@ static int ipa3_teardown_coal_def_pipe(u32 clnt_hdl) ipa_assert(); return result; } + + if (IPA_CLIENT_IS_CONS(ep->client)) + cancel_delayed_work_sync(&ep->sys->replenish_rx_work); + + flush_workqueue(ep->sys->wq); + + if (ep->sys->repl_wq) + flush_workqueue(ep->sys->repl_wq); + if (IPA_CLIENT_IS_CONS(ep->client)) + ipa3_cleanup_rx(ep->sys); + ep->valid = 0; IPADBG("client (ep: %d) disconnected\n", clnt_hdl); -- GitLab From 6005908e5d1911b32dc4b65d0fa156174bf113f6 Mon Sep 17 00:00:00 2001 From: Ashok Vuyyuru Date: Mon, 24 Jun 2019 19:05:19 +0530 Subject: [PATCH 0963/1121] msm: ipa4: Send new QMI indication message to modem for RSC pipe Add changes to send QMI indication message to modem for RSC pipe. Change-Id: Iffbe33027bd782c4867de9441f041a12ae4b26f1 Signed-off-by: Ashok Vuyyuru --- .../platform/msm/ipa/ipa_v3/ipa_qmi_service.c | 16 +++++++++++++ .../platform/msm/ipa/ipa_v3/ipa_qmi_service.h | 9 ++++++++ drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c | 23 +++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c index 60da89daf619..043d5db457cb 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c @@ -2236,6 +2236,22 @@ int ipa3_qmi_send_mhi_cleanup_request(struct ipa_mhi_cleanup_req_msg_v01 *req) resp.resp.error, "ipa_mhi_cleanup_req_msg"); } +int ipa3_qmi_send_rsc_pipe_indication( + struct ipa_endp_desc_indication_msg_v01 *req) +{ + IPAWANDBG("Sending QMI_IPA_ENDP_DESC_INDICATION_V01\n"); + + if (unlikely(!ipa3_svc_handle)) + return -ETIMEDOUT; + + return qmi_send_indication(ipa3_svc_handle, + &ipa3_qmi_ctx->client_sq, + QMI_IPA_ENDP_DESC_INDICATION_V01, + IPA_ENDP_DESC_INDICATION_MSG_V01_MAX_MSG_LEN, + ipa_endp_desc_indication_msg_v01_ei, + req); +} + void ipa3_qmi_init(void) { mutex_init(&ipa3_qmi_lock); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.h b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.h index a0f3ea37306c..6cb54267899d 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.h @@ -346,6 +346,9 @@ int ipa3_qmi_get_per_client_packet_stats( int ipa3_qmi_send_mhi_ready_indication( struct ipa_mhi_ready_indication_msg_v01 *req); +int ipa3_qmi_send_rsc_pipe_indication( + struct ipa_endp_desc_indication_msg_v01 *req); + int ipa3_qmi_send_mhi_cleanup_request(struct ipa_mhi_cleanup_req_msg_v01 *req); void ipa3_qmi_init(void); @@ -488,6 +491,12 @@ static inline int ipa3_qmi_send_mhi_ready_indication( return -EPERM; } +static int ipa3_qmi_send_rsc_pipe_indication( + struct ipa_endp_desc_indication_msg_v01 *req) +{ + return -EPERM; +} + static inline int ipa3_qmi_send_mhi_cleanup_request( struct ipa_mhi_cleanup_req_msg_v01 *req) { diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c index 9e66e5b6f045..13414e47c125 100644 --- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c @@ -1473,6 +1473,26 @@ static void apps_ipa_packet_receive_notify(void *priv, } } +/* Send RSC endpoint info to modem using QMI indication message */ + +static int ipa_send_rsc_pipe_ind_to_modem(void) +{ + struct ipa_endp_desc_indication_msg_v01 req; + struct ipa_ep_id_type_v01 *ep_info; + + memset(&req, 0, sizeof(struct ipa_endp_desc_indication_msg_v01)); + req.ep_info_len = 1; + req.ep_info_valid = true; + req.num_eps_valid = true; + req.num_eps = 1; + ep_info = &req.ep_info[req.ep_info_len - 1]; + ep_info->ep_id = rmnet_ipa3_ctx->ipa3_to_apps_hdl; + ep_info->ic_type = DATA_IC_TYPE_AP_V01; + ep_info->ep_type = DATA_EP_DESC_TYPE_RSC_PROD_V01; + ep_info->ep_status = DATA_EP_STATUS_CONNECTED_V01; + return ipa3_qmi_send_rsc_pipe_indication(&req); +} + static int handle3_ingress_format(struct net_device *dev, struct rmnet_ioctl_extended_s *in) { @@ -1574,6 +1594,9 @@ static int handle3_ingress_format(struct net_device *dev, if (ret) ipa3_del_a7_qmap_hdr(); + /* Sending QMI indication message share RSC pipe details*/ + if (dev->features & NETIF_F_GRO_HW) + ipa_send_rsc_pipe_ind_to_modem(); end: if (ret) IPAWANERR("failed to configure ingress\n"); -- GitLab From 8a5fdbc5d7cb6a3d58399774aad95a8ab6ab9164 Mon Sep 17 00:00:00 2001 From: Gustavo Solaira Date: Fri, 19 Jul 2019 13:18:08 -0700 Subject: [PATCH 0964/1121] ARM: dts: msm: Add audio support for SA515M CCARD boards Add new ASoC device node for SA515M CCARD boards using the TI TLV302AIC3x codec. Change-Id: I048889fbf122283309181f5c2df9bf8daf9d0262 Signed-off-by: Gustavo Solaira --- .../bindings/sound/qcom-audio-dev.txt | 71 +++++++++++++++++++ arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi | 46 ++++++++++++ .../boot/dts/qcom/sdxprairie-pinctrl.dtsi | 15 ++++ 3 files changed, 132 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt index e5f44ae56a8b..02fd42028944 100644 --- a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt +++ b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt @@ -1859,6 +1859,77 @@ Example: "msm-dai-q6-auxpcm.2"; }; +* SDX ASoC Auto Machine driver + +Required properties: +- compatible : "qcom,sdx-asoc-snd-auto" +- qcom,model : The user-visible name of this sound card. +- qcom,prim_mi2s_aux_master : Handle to prim_master pinctrl configurations +- qcom,prim_mi2s_aux_slave : Handle to prim_slave pinctrl configurations +- qcom,sec_mi2s_aux_master : Handle to sec_master pinctrl configurations +- qcom,sec_mi2s_aux_slave : Handle to sec_slave pinctrl configurations +- asoc-platform: This is phandle list containing the references to platform device + nodes that are used as part of the sound card dai-links. +- asoc-platform-names: This property contains list of platform names. The order of + the platform names should match to that of the phandle order + given in "asoc-platform". +- asoc-cpu: This is phandle list containing the references to cpu dai device nodes + that are used as part of the sound card dai-links. +- asoc-cpu-names: This property contains list of cpu dai names. The order of the + cpu dai names should match to that of the phandle order give + in "asoc-cpu". The cpu names are in the form of "%s.%d" form, + where the id (%d) field represents the back-end AFE port id that + this CPU dai is associated with. +- asoc-codec: This is phandle list containing the references to codec dai device + nodes that are used as part of the sound card dai-links. +- asoc-codec-names: This property contains list of codec dai names. The order of the + codec dai names should match to that of the phandle order given + in "asoc-codec". + +Example: + + sound-auto { + compatible = "qcom,sdx-asoc-snd-auto"; + qcom,model = "sdx-auto-i2s-snd-card"; + qcom,prim_mi2s_aux_master = <&prim_master>; + qcom,prim_mi2s_aux_slave = <&prim_slave>; + qcom,sec_mi2s_aux_master = <&sec_master>; + qcom,sec_mi2s_aux_slave = <&sec_slave>; + + asoc-platform = <&pcm0>, <&pcm1>, <&voip>, <&voice>, + <&loopback>, <&hostless>, <&afe>, <&routing>, + <&pcm_dtmf>, <&host_pcm>, <&compress>; + asoc-platform-names = "msm-pcm-dsp.0", "msm-pcm-dsp.1", + "msm-voip-dsp", "msm-pcm-voice", + "msm-pcm-loopback", "msm-pcm-hostless", + "msm-pcm-afe", "msm-pcm-routing", + "msm-pcm-dtmf", "msm-voice-host-pcm", + "msm-compress-dsp"; + asoc-cpu = <&dai_pri_auxpcm>, <&mi2s_prim>, <&mi2s_sec>, + <&dtmf_tx>, + <&rx_capture_tx>, <&rx_playback_rx>, + <&tx_capture_tx>, <&tx_playback_rx>, + <&afe_pcm_rx>, <&afe_pcm_tx>, <&afe_proxy_rx>, + <&afe_proxy_tx>, <&incall_record_rx>, + <&incall_record_tx>, <&incall_music_rx>, + <&dai_pri_tdm_rx_0>, <&dai_pri_tdm_tx_0>, + <&dai_sec_tdm_rx_0>, <&dai_sec_tdm_tx_0>, + <&dai_sec_auxpcm>; + asoc-cpu-names = "msm-dai-q6-auxpcm.1", + "msm-dai-q6-mi2s.0", "msm-dai-q6-mi2s.1", + "msm-dai-stub-dev.4", "msm-dai-stub-dev.5", + "msm-dai-stub-dev.6", "msm-dai-stub-dev.7", + "msm-dai-stub-dev.8", "msm-dai-q6-dev.224", + "msm-dai-q6-dev.225", "msm-dai-q6-dev.241", + "msm-dai-q6-dev.240", "msm-dai-q6-dev.32771", + "msm-dai-q6-dev.32772", "msm-dai-q6-dev.32773", + "msm-dai-q6-tdm.36864", "msm-dai-q6-tdm.36865", + "msm-dai-q6-tdm.36880", "msm-dai-q6-tdm.36881", + "msm-dai-q6-auxpcm.2"; + asoc-codec = <&tlv320aic3x_codec>, <&stub_codec>; + asoc-codec-names = "tlv320aic3x-codec", "msm-stub-codec.1"; + }; + * voice-mhi-audio Required properties: diff --git a/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi b/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi index 09b5c7e03766..8fc92484f6b0 100644 --- a/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi +++ b/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi @@ -23,6 +23,51 @@ gpio = <&tlmm 23 GPIO_ACTIVE_HIGH>; enable-active-high; }; + + snd_tlv3x: sound-auto { + compatible = "qcom,sdx-asoc-snd-auto"; + qcom,model = "sdx-auto-i2s-snd-card"; + qcom,prim_mi2s_aux_master = <&prim_master>; + qcom,prim_mi2s_aux_slave = <&prim_slave>; + qcom,sec_mi2s_aux_master = <&sec_master>; + qcom,sec_mi2s_aux_slave = <&sec_slave>; + + pinctrl-names = "default"; + pinctrl-0 = <&a2b_cdc_sel_default>, <&i2s_mclk_active>; + + asoc-platform = <&pcm0>, <&pcm1>, <&voip>, <&voice>, + <&loopback>, <&hostless>, <&afe>, <&routing>, + <&pcm_dtmf>, <&host_pcm>, <&compress>; + asoc-platform-names = "msm-pcm-dsp.0", "msm-pcm-dsp.1", + "msm-voip-dsp", "msm-pcm-voice", + "msm-pcm-loopback", "msm-pcm-hostless", + "msm-pcm-afe", "msm-pcm-routing", + "msm-pcm-dtmf", "msm-voice-host-pcm", + "msm-compress-dsp"; + asoc-cpu = <&dai_pri_auxpcm>, <&mi2s_prim>, <&mi2s_sec>, + <&dtmf_tx>, + <&rx_capture_tx>, <&rx_playback_rx>, + <&tx_capture_tx>, <&tx_playback_rx>, + <&afe_pcm_rx>, <&afe_pcm_tx>, <&afe_proxy_rx>, + <&afe_proxy_tx>, <&incall_record_rx>, + <&incall_record_tx>, <&incall_music_rx>, + <&dai_pri_tdm_rx_0>, <&dai_pri_tdm_tx_0>, + <&dai_sec_tdm_rx_0>, <&dai_sec_tdm_tx_0>, + <&dai_sec_auxpcm>; + asoc-cpu-names = "msm-dai-q6-auxpcm.1", + "msm-dai-q6-mi2s.0", "msm-dai-q6-mi2s.1", + "msm-dai-stub-dev.4", "msm-dai-stub-dev.5", + "msm-dai-stub-dev.6", "msm-dai-stub-dev.7", + "msm-dai-stub-dev.8", "msm-dai-q6-dev.224", + "msm-dai-q6-dev.225", "msm-dai-q6-dev.241", + "msm-dai-q6-dev.240", "msm-dai-q6-dev.32771", + "msm-dai-q6-dev.32772", "msm-dai-q6-dev.32773", + "msm-dai-q6-tdm.36864", "msm-dai-q6-tdm.36865", + "msm-dai-q6-tdm.36880", "msm-dai-q6-tdm.36881", + "msm-dai-q6-auxpcm.2"; + asoc-codec = <&tlv320aic3x_codec>, <&stub_codec>; + asoc-codec-names = "tlv320aic3x-codec", "msm-stub-codec.1"; + }; }; /* delete pm8150b nodes */ @@ -113,6 +158,7 @@ reset-inverted; AVDD-supply = <&codec_vreg>; IOVDD-supply = <&codec_vreg>; + ai3x-ocmv = <1>; }; eeprom@52 { diff --git a/arch/arm64/boot/dts/qcom/sdxprairie-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sdxprairie-pinctrl.dtsi index 841e1675dc7a..c29c95dc5635 100644 --- a/arch/arm64/boot/dts/qcom/sdxprairie-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/sdxprairie-pinctrl.dtsi @@ -1473,5 +1473,20 @@ }; }; + a2b_cdc_sel { + a2b_cdc_sel_default: a2b_cdc_sel_default { + mux { + pins = "gpio97"; + function = "gpio"; + }; + + config { + pins = "gpio97"; + drive-strength = <8>; + bias-disable; + output-high; + }; + }; + }; }; }; -- GitLab From 5fd9214fcbc36adfa60aaae56dbea850f0a7d1e7 Mon Sep 17 00:00:00 2001 From: Subash Abhinov Kasiviswanathan Date: Sun, 21 Jul 2019 18:28:06 -0600 Subject: [PATCH 0965/1121] net: qualcomm: rmnet: Fix incorrect UL checksum offload logic The udp_ip4_ind bit is set only for IPv4 UDP non-fragmented packets so that the hardware can flip the checksum to 0xFFFF if the computed checksum is 0 per RFC768. However, this bit had to be set for IPv6 UDP non fragmented packets as well per hardware requirements. Otherwise, IPv6 UDP packets with computed checksum as 0 were transmitted by hardware and were dropped in the network. In addition to setting this bit for IPv6 UDP, the field is also appropriately renamed to udp_ind as part of this change. Change-Id: I3f4ee599e2a9d42e71ee1f4dc717668960168602 Signed-off-by: Subash Abhinov Kasiviswanathan --- drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h | 2 +- .../net/ethernet/qualcomm/rmnet/rmnet_map_data.c | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h index 6f7b4b2d83bd..354b2097b85b 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h @@ -122,7 +122,7 @@ struct rmnet_map_dl_csum_trailer { struct rmnet_map_ul_csum_header { __be16 csum_start_offset; u16 csum_insert_offset:14; - u16 udp_ip4_ind:1; + u16 udp_ind:1; u16 csum_enabled:1; } __aligned(1); diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c index 96ad754ae68f..cfef7e9c4c8d 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c @@ -230,9 +230,9 @@ rmnet_map_ipv4_ul_csum_header(void *iphdr, ul_header->csum_insert_offset = skb->csum_offset; ul_header->csum_enabled = 1; if (ip4h->protocol == IPPROTO_UDP) - ul_header->udp_ip4_ind = 1; + ul_header->udp_ind = 1; else - ul_header->udp_ip4_ind = 0; + ul_header->udp_ind = 0; /* Changing remaining fields to network order */ hdr++; @@ -263,6 +263,7 @@ rmnet_map_ipv6_ul_csum_header(void *ip6hdr, struct rmnet_map_ul_csum_header *ul_header, struct sk_buff *skb) { + struct ipv6hdr *ip6h = (struct ipv6hdr *)ip6hdr; __be16 *hdr = (__be16 *)ul_header, offset; offset = htons((__force u16)(skb_transport_header(skb) - @@ -270,7 +271,11 @@ rmnet_map_ipv6_ul_csum_header(void *ip6hdr, ul_header->csum_start_offset = offset; ul_header->csum_insert_offset = skb->csum_offset; ul_header->csum_enabled = 1; - ul_header->udp_ip4_ind = 0; + + if (ip6h->nexthdr == IPPROTO_UDP) + ul_header->udp_ind = 1; + else + ul_header->udp_ind = 0; /* Changing remaining fields to network order */ hdr++; @@ -479,7 +484,7 @@ void rmnet_map_v4_checksum_uplink_packet(struct sk_buff *skb, ul_header->csum_start_offset = 0; ul_header->csum_insert_offset = 0; ul_header->csum_enabled = 0; - ul_header->udp_ip4_ind = 0; + ul_header->udp_ind = 0; priv->stats.csum_sw++; } -- GitLab From 7043d28edee804df0301cb9d6b5637f418dc4c3c Mon Sep 17 00:00:00 2001 From: Praveen Kurapati Date: Fri, 28 Jun 2019 19:47:18 +0530 Subject: [PATCH 0966/1121] msm: ipa4: Cleanup duplicate code used for setup coalescing pipe Cleaning up duplicate code used for setup coalescing pipe and using the existing function ipa_setup_sys_pipe function for configuring coalescing pipe. Change-Id: I22be19f202ce9da96e9c0776b2b4dfa276a0e27b Signed-off-by: Praveen Kurapati Signed-off-by: Ashok Vuyyuru --- drivers/platform/msm/ipa/ipa_v3/ipa_dp.c | 209 ++--------------------- 1 file changed, 16 insertions(+), 193 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c index f7315eb50bc1..7c8b45767c60 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c @@ -118,8 +118,6 @@ static int ipa_gsi_setup_event_ring(struct ipa3_ep_context *ep, u32 ring_size, gfp_t mem_flag); static int ipa_gsi_setup_transfer_ring(struct ipa3_ep_context *ep, u32 ring_size, struct ipa3_sys_context *user_data, gfp_t mem_flag); -static int ipa_setup_coal_def_pipe(struct ipa_sys_connect_params *sys_in, - struct ipa3_ep_context *ep_coalescing); static int ipa3_teardown_coal_def_pipe(u32 clnt_hdl); static int ipa_populate_tag_field(struct ipa3_desc *desc, struct ipa3_tx_pkt_wrapper *tx_pkt, @@ -924,7 +922,7 @@ static void ipa_pm_sys_pipe_cb(void *p, enum ipa_pm_cb_event event) int ipa3_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl) { struct ipa3_ep_context *ep; - int i, ipa_ep_idx; + int i, ipa_ep_idx, wan_handle; int result = -EINVAL; struct ipahal_reg_coal_qmap_cfg qmap_cfg; struct ipahal_reg_coal_evict_lru evict_lru; @@ -1162,7 +1160,7 @@ int ipa3_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl) sys_in->client = IPA_CLIENT_APPS_WAN_CONS; sys_in->ipa_ep_cfg = ep_cfg_copy; - result = ipa_setup_coal_def_pipe(sys_in, ep); + result = ipa3_setup_sys_pipe(sys_in, &wan_handle); if (result) { IPAERR("failed to setup default coalescing pipe\n"); goto fail_repl; @@ -1193,193 +1191,6 @@ int ipa3_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl) return result; } -/** - * ipa3_setup_coal_def_pipe() - Setup a crippled default pipe in addition to the - * coalescing pipe. - * - * @sys_in: [in] input needed to setup the pipe and configure EP - * @ep_coalescing [in] the ep context of the coal pipe - * - * - configure the end-point registers with the supplied - * parameters from the user. - * - Creates a GPI connection with IPA. - * - allocate descriptor FIFO - * - * Returns: 0 on success, negative on failure - */ -static int ipa_setup_coal_def_pipe(struct ipa_sys_connect_params *sys_in, - struct ipa3_ep_context *ep_coalescing) -{ - struct ipa3_ep_context *ep; - int result = -EINVAL; - int ipa_ep_idx, i; - char buff[IPA_RESOURCE_NAME_MAX]; - - ipa_ep_idx = ipa3_get_ep_mapping(sys_in->client); - - if (ipa_ep_idx == IPA_EP_NOT_ALLOCATED) { - IPAERR("failed to get idx"); - goto fail_gen; - } - - ep = &ipa3_ctx->ep[ipa_ep_idx]; - if (ep->valid == 1) { - IPAERR("EP %d already allocated.\n", ipa_ep_idx); - goto fail_gen; - } - - memset(ep, 0, offsetof(struct ipa3_ep_context, sys)); - - if (!ep->sys) { - ep->sys = kzalloc(sizeof(struct ipa3_sys_context), GFP_KERNEL); - if (!ep->sys) { - IPAERR("failed to sys ctx for client %d\n", - IPA_CLIENT_APPS_WAN_CONS); - result = -ENOMEM; - goto fail_gen; - } - - ep->sys->ep = ep; - snprintf(buff, IPA_RESOURCE_NAME_MAX, "ipawq%d", - sys_in->client); - ep->sys->wq = alloc_workqueue(buff, - WQ_MEM_RECLAIM | WQ_UNBOUND | WQ_SYSFS, 1); - - if (!ep->sys->wq) { - IPAERR("failed to create wq for client %d\n", - sys_in->client); - result = -EFAULT; - goto fail_wq; - } - - snprintf(buff, IPA_RESOURCE_NAME_MAX, "iparepwq%d", - sys_in->client); - ep->sys->repl_wq = alloc_workqueue(buff, - WQ_MEM_RECLAIM | WQ_UNBOUND | WQ_SYSFS, 1); - if (!ep->sys->repl_wq) { - IPAERR("failed to create rep wq for client %d\n", - sys_in->client); - result = -EFAULT; - goto fail_wq2; - } - - INIT_LIST_HEAD(&ep->sys->rcycl_list); - spin_lock_init(&ep->sys->spinlock); - hrtimer_init(&ep->sys->db_timer, CLOCK_MONOTONIC, - HRTIMER_MODE_REL); - ep->sys->db_timer.function = ipa3_ring_doorbell_timer_fn; - } else { - memset(ep->sys, 0, offsetof(struct ipa3_sys_context, ep)); - } - - ep->skip_ep_cfg = ep_coalescing->skip_ep_cfg; - - if (ipa3_assign_policy(sys_in, ep->sys)) { - IPAERR("failed to sys ctx for client %d\n", - IPA_CLIENT_APPS_WAN_CONS); - result = -ENOMEM; - goto fail_gen2; - } - - ep->valid = 1; - ep->client = sys_in->client; - ep->client_notify = ep_coalescing->client_notify; - ep->priv = ep_coalescing->priv; - ep->keep_ipa_awake = ep_coalescing->keep_ipa_awake; - atomic_set(&ep->avail_fifo_desc, - ((sys_in->desc_fifo_sz / IPA_FIFO_ELEMENT_SIZE) - 1)); - - if (!ep->skip_ep_cfg) { - if (ipa3_cfg_ep(ipa_ep_idx, &sys_in->ipa_ep_cfg)) { - IPAERR("fail to configure EP.\n"); - goto fail_gen2; - } - - if (ep->status.status_en) { - IPAERR("status should be disabled for this EP.\n"); - goto fail_gen2; - } - - if (ipa3_cfg_ep_status(ipa_ep_idx, &ep->status)) { - IPAERR("fail to configure status of EP.\n"); - goto fail_gen2; - } - IPADBG("ep %d configuration successful\n", ipa_ep_idx); - } else { - IPADBG("skipping ep %d configuration\n", ipa_ep_idx); - } - - result = ipa_gsi_setup_coal_def_channel(sys_in, ep, ep_coalescing); - if (result) { - IPAERR("Failed to setup default coal GSI channel\n"); - goto fail_gen2; - } - - if (ep->sys->repl_hdlr == ipa3_fast_replenish_rx_cache) { - ep->sys->repl = kzalloc(sizeof(*ep->sys->repl), GFP_KERNEL); - if (!ep->sys->repl) { - IPAERR("failed to alloc repl for client %d\n", - sys_in->client); - result = -ENOMEM; - goto fail_gen2; - } - atomic_set(&ep->sys->repl->pending, 0); - ep->sys->repl->capacity = ep->sys->rx_pool_sz + 1; - - ep->sys->repl->cache = kcalloc(ep->sys->repl->capacity, - sizeof(void *), GFP_KERNEL); - if (!ep->sys->repl->cache) { - IPAERR("ep=%d fail to alloc repl cache\n", ipa_ep_idx); - ep->sys->repl_hdlr = ipa3_replenish_rx_cache; - ep->sys->repl->capacity = 0; - } else { - atomic_set(&ep->sys->repl->head_idx, 0); - atomic_set(&ep->sys->repl->tail_idx, 0); - ipa3_wq_repl_rx(&ep->sys->repl_work); - } - } - - ipa3_replenish_rx_cache(ep->sys); - - for (i = 0; i < GSI_VEID_MAX; i++) - INIT_LIST_HEAD(&ep->sys->pending_pkts[i]); - - ipa3_ctx->skip_ep_cfg_shadow[ipa_ep_idx] = ep->skip_ep_cfg; - - result = ipa3_enable_data_path(ipa_ep_idx); - if (result) { - IPAERR("enable data path failed res=%d ep=%d.\n", result, - ipa_ep_idx); - goto fail_repl; - } - - result = gsi_start_channel(ep->gsi_chan_hdl); - if (result != GSI_STATUS_SUCCESS) - goto fail_start_channel; - - IPADBG("client %d (ep: %d) connected sys=%pK\n", ep->client, - ipa_ep_idx, ep->sys); - - return 0; - -/* the rest of the fails are handled by ipa3_setup_sys_pipe */ -fail_start_channel: - ipa3_disable_data_path(ipa_ep_idx); -fail_repl: - ep->sys->repl_hdlr = ipa3_replenish_rx_cache; - ep->sys->repl->capacity = 0; - kfree(ep->sys->repl); -fail_gen2: - destroy_workqueue(ep->sys->repl_wq); -fail_wq2: - destroy_workqueue(ep->sys->wq); -fail_wq: - kfree(ep->sys); - memset(&ipa3_ctx->ep[ipa_ep_idx], 0, sizeof(struct ipa3_ep_context)); -fail_gen: - return result; -} - /** * ipa3_teardown_sys_pipe() - Teardown the GPI pipe and cleanup IPA EP * @clnt_hdl: [in] the handle obtained from ipa3_setup_sys_pipe @@ -4126,7 +3937,7 @@ static int ipa_gsi_setup_channel(struct ipa_sys_connect_params *in, u32 ring_size; int result; gfp_t mem_flag = GFP_KERNEL; - + u32 coale_ep_idx; if (in->client == IPA_CLIENT_APPS_WAN_CONS || in->client == IPA_CLIENT_APPS_WAN_COAL_CONS || @@ -4137,6 +3948,7 @@ static int ipa_gsi_setup_channel(struct ipa_sys_connect_params *in, IPAERR("EP context is empty\n"); return -EINVAL; } + coale_ep_idx = ipa3_get_ep_mapping(IPA_CLIENT_APPS_WAN_COAL_CONS); /* * GSI ring length is calculated based on the desc_fifo_sz * which was meant to define the BAM desc fifo. GSI descriptors @@ -4155,8 +3967,19 @@ static int ipa_gsi_setup_channel(struct ipa_sys_connect_params *in, } ipa3_ctx->gsi_evt_comm_ring_rem -= (ring_size); ep->gsi_evt_ring_hdl = ipa3_ctx->gsi_evt_comm_hdl; + } else if (in->client == IPA_CLIENT_APPS_WAN_CONS && + coale_ep_idx != IPA_EP_NOT_ALLOCATED && + ipa3_ctx->ep[coale_ep_idx].valid == 1) { + IPADBG("Wan consumer pipe configured\n"); + result = ipa_gsi_setup_coal_def_channel(in, ep, + &ipa3_ctx->ep[coale_ep_idx]); + if (result) { + IPAERR("Failed to setup default coal GSI channel\n"); + goto fail_setup_event_ring; + } + return result; } else if (ep->sys->policy != IPA_POLICY_NOINTR_MODE || - IPA_CLIENT_IS_CONS(ep->client)) { + IPA_CLIENT_IS_CONS(ep->client)) { result = ipa_gsi_setup_event_ring(ep, ring_size, mem_flag); if (result) goto fail_setup_event_ring; -- GitLab From 4b9fd21a5ece929bae6f2107a241a5ae2c747790 Mon Sep 17 00:00:00 2001 From: Sumalatha Malothu Date: Mon, 22 Jul 2019 13:47:49 +0530 Subject: [PATCH 0967/1121] msm:camera:isp: Fix array index bound checks Added check for max array index Change-Id: I4f8a4b559c83c04577cd58376526668d29b6b723 Signed-off-by: Sumalatha Malothu --- .../media/platform/msm/camera_v2/isp/msm_isp_axi_util_32.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util_32.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util_32.c index 2eed3c077ff2..6dec6f8cb15c 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util_32.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util_32.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1214,7 +1214,7 @@ static void msm_isp_update_rdi_output_count( for (i = 0; i < stream_cfg_cmd->num_streams; i++) { if (HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i]) - > MAX_NUM_STREAM) + >= MAX_NUM_STREAM) return; stream_info = &axi_data->stream_info[ -- GitLab From 7e6ef6d1e3106d19f23f177d232f1fd50c752c31 Mon Sep 17 00:00:00 2001 From: Sahil Chandna Date: Mon, 22 Jul 2019 15:12:02 +0530 Subject: [PATCH 0968/1121] power: power_supply: Add property to display skin temperature status Add power supply property POWER_SUPPLY_PROP_SKIN_HEALTH to indicate skin temperature status. Change-Id: Ib04d93cd0a74f39b23591c29c696c5a35c70291a Signed-off-by: Sahil Chandna --- drivers/power/supply/power_supply_sysfs.c | 1 + include/linux/power_supply.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/power/supply/power_supply_sysfs.c b/drivers/power/supply/power_supply_sysfs.c index 760923cef852..5f2ceb3e9d98 100644 --- a/drivers/power/supply/power_supply_sysfs.c +++ b/drivers/power/supply/power_supply_sysfs.c @@ -403,6 +403,7 @@ static struct device_attribute power_supply_attrs[] = { POWER_SUPPLY_ATTR(force_main_fcc), POWER_SUPPLY_ATTR(comp_clamp_level), POWER_SUPPLY_ATTR(adapter_cc_mode), + POWER_SUPPLY_ATTR(skin_health), /* Charge pump properties */ POWER_SUPPLY_ATTR(cp_status1), POWER_SUPPLY_ATTR(cp_status2), diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h index 34de20f36285..27493b041092 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h @@ -341,6 +341,7 @@ enum power_supply_property { POWER_SUPPLY_PROP_FORCE_MAIN_FCC, POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL, POWER_SUPPLY_PROP_ADAPTER_CC_MODE, + POWER_SUPPLY_PROP_SKIN_HEALTH, /* Charge pump properties */ POWER_SUPPLY_PROP_CP_STATUS1, POWER_SUPPLY_PROP_CP_STATUS2, -- GitLab From b20ab5df5a8e2273c9cb886c091785ebcdf4ea6c Mon Sep 17 00:00:00 2001 From: Akhil P Oommen Date: Tue, 18 Jun 2019 17:29:47 +0530 Subject: [PATCH 0969/1121] msm: kgsl: Avoid redundant AOP message during GPU wake up Sending ACD configuration message to AOP can have latency in milliseconds. It is a redundant job sending this message on every GPU wake up. Avoid this to improve the GPU wake up time. Change-Id: I9df7dc1920bd9ef1a13469402df523eb7805e85b Signed-off-by: Akhil P Oommen --- drivers/gpu/msm/kgsl_gmu.c | 20 +++++++++++++++----- drivers/gpu/msm/kgsl_gmu.h | 1 + 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/msm/kgsl_gmu.c b/drivers/gpu/msm/kgsl_gmu.c index 164148f55280..11ec6fa448df 100644 --- a/drivers/gpu/msm/kgsl_gmu.c +++ b/drivers/gpu/msm/kgsl_gmu.c @@ -1241,22 +1241,30 @@ static void gmu_aop_send_acd_state(struct kgsl_device *device) { struct adreno_device *adreno_dev = ADRENO_DEVICE(device); struct gmu_device *gmu = KGSL_GMU_DEVICE(device); + struct kgsl_mailbox *mailbox = &gmu->mailbox; struct mbox_message msg; char msg_buf[33]; bool state = test_bit(ADRENO_ACD_CTRL, &adreno_dev->pwrctrl_flag); int ret; - if (!gmu->mailbox.client) + if (!mailbox->client) + return; + + if (state == mailbox->enabled) return; msg.len = scnprintf(msg_buf, sizeof(msg_buf), "{class: gpu, res: acd, value: %d}", state); msg.msg = msg_buf; - ret = mbox_send_message(gmu->mailbox.channel, &msg); - if (ret < 0) + ret = mbox_send_message(mailbox->channel, &msg); + if (ret < 0) { dev_err(&gmu->pdev->dev, "AOP mbox send message failed: %d\n", ret); + return; + } + + mailbox->enabled = state; } static void gmu_aop_mailbox_destroy(struct kgsl_device *device) @@ -1268,13 +1276,15 @@ static void gmu_aop_mailbox_destroy(struct kgsl_device *device) if (!mailbox->client) return; + /* Turn off ACD in AOP */ + clear_bit(ADRENO_ACD_CTRL, &adreno_dev->pwrctrl_flag); + gmu_aop_send_acd_state(device); + mbox_free_channel(mailbox->channel); mailbox->channel = NULL; kfree(mailbox->client); mailbox->client = NULL; - - clear_bit(ADRENO_ACD_CTRL, &adreno_dev->pwrctrl_flag); } static int gmu_aop_mailbox_init(struct kgsl_device *device, diff --git a/drivers/gpu/msm/kgsl_gmu.h b/drivers/gpu/msm/kgsl_gmu.h index 56eee96ab65e..3ed6582eabfa 100644 --- a/drivers/gpu/msm/kgsl_gmu.h +++ b/drivers/gpu/msm/kgsl_gmu.h @@ -120,6 +120,7 @@ enum gmu_load_mode { }; struct kgsl_mailbox { + bool enabled; struct mbox_client *client; struct mbox_chan *channel; }; -- GitLab From df81f1c596c96ebc64b193af65ea9ff75077ee70 Mon Sep 17 00:00:00 2001 From: Avaneesh Kumar Dwivedi Date: Mon, 22 Jul 2019 16:35:32 +0530 Subject: [PATCH 0970/1121] defconfig: qcs405: Enable ARCH_QCS403 in qcs405 defconfig We are trying to separate out qcs403 defconfig from qcs405. but before we can remove support for qcs405 for 32 bit build, we need to enable qcs403 support in qcs405 defconfig. Change-Id: I0729d169e669a585fdcca1cd404af8a53f53022f Signed-off-by: Avaneesh Kumar Dwivedi --- arch/arm/configs/vendor/qcs405-perf_defconfig | 1 + arch/arm/configs/vendor/qcs405_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm/configs/vendor/qcs405-perf_defconfig b/arch/arm/configs/vendor/qcs405-perf_defconfig index 1ab1d99cd67d..8042c3000e0d 100644 --- a/arch/arm/configs/vendor/qcs405-perf_defconfig +++ b/arch/arm/configs/vendor/qcs405-perf_defconfig @@ -37,6 +37,7 @@ CONFIG_MODULE_SIG_SHA512=y CONFIG_PARTITION_ADVANCED=y CONFIG_ARCH_QCOM=y CONFIG_ARCH_QCS405=y +CONFIG_ARCH_QCS403=y # CONFIG_VDSO is not set CONFIG_SMP=y CONFIG_ARM_PSCI=y diff --git a/arch/arm/configs/vendor/qcs405_defconfig b/arch/arm/configs/vendor/qcs405_defconfig index f8fcf714bd37..4a06454d8699 100644 --- a/arch/arm/configs/vendor/qcs405_defconfig +++ b/arch/arm/configs/vendor/qcs405_defconfig @@ -39,6 +39,7 @@ CONFIG_MODULE_SIG_SHA512=y CONFIG_PARTITION_ADVANCED=y CONFIG_ARCH_QCOM=y CONFIG_ARCH_QCS405=y +CONFIG_ARCH_QCS403=y # CONFIG_VDSO is not set CONFIG_SMP=y CONFIG_ARM_PSCI=y -- GitLab From 748f46926c2e69fa4e568a617dbca340165fb948 Mon Sep 17 00:00:00 2001 From: Deepak Kumar Date: Mon, 15 Jul 2019 12:16:18 +0530 Subject: [PATCH 0971/1121] Revert "ARM: dts: msm: Defer regulator disable for trinket GPU SMMU" This reverts commit 844b3000934d("ARM: dts: msm: Defer regulator disable for trinket GPU SMMU"). This is needed to ensure GPU CX headswitch off is not delayed by SMMU driver. Change-Id: I1a0ac3853b9a1655fbcd9263d25588c145e0ee0d Signed-off-by: Deepak Kumar --- arch/arm64/boot/dts/qcom/msm-arm-smmu-trinket.dtsi | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/msm-arm-smmu-trinket.dtsi b/arch/arm64/boot/dts/qcom/msm-arm-smmu-trinket.dtsi index 6fab5f53ea61..bd1f37554f7e 100644 --- a/arch/arm64/boot/dts/qcom/msm-arm-smmu-trinket.dtsi +++ b/arch/arm64/boot/dts/qcom/msm-arm-smmu-trinket.dtsi @@ -28,7 +28,6 @@ #global-interrupts = <1>; qcom,regulator-names = "vdd"; vdd-supply = <&gpu_cx_gdsc>; - qcom,deferred-regulator-disable-delay = <80>; clocks = <&clock_gcc GCC_GPU_MEMNOC_GFX_CLK>, <&clock_gcc GCC_GPU_SNOC_DVM_GFX_CLK>, <&clock_gpucc GPU_CC_AHB_CLK>, -- GitLab From 8f7bad46c65a9734c3824aa1c8388b2dfa2e1a95 Mon Sep 17 00:00:00 2001 From: Subash Abhinov Kasiviswanathan Date: Wed, 12 Jun 2019 19:25:23 -0600 Subject: [PATCH 0972/1121] defconfig: sdxprairie: Enable burst flow control Enable data flow control so that grant indications can limit and control the number of packets to be sent to modem. Change-Id: Iaa768e037d3a1d27a71732b4e15ea63366cacc4b Acked-by: Ning Cai Signed-off-by: Subash Abhinov Kasiviswanathan --- arch/arm/configs/vendor/sdxprairie-perf_defconfig | 3 +++ arch/arm/configs/vendor/sdxprairie_defconfig | 3 +++ 2 files changed, 6 insertions(+) diff --git a/arch/arm/configs/vendor/sdxprairie-perf_defconfig b/arch/arm/configs/vendor/sdxprairie-perf_defconfig index d629857a60fe..79d65b746d91 100644 --- a/arch/arm/configs/vendor/sdxprairie-perf_defconfig +++ b/arch/arm/configs/vendor/sdxprairie-perf_defconfig @@ -379,6 +379,9 @@ CONFIG_RPMSG_QCOM_GLINK_SMEM=y CONFIG_QCOM_LLCC=y CONFIG_QCOM_SDXPRAIRIE_LLCC=y CONFIG_QCOM_QMI_HELPERS=y +CONFIG_QCOM_QMI_RMNET=y +CONFIG_QCOM_QMI_DFC=y +CONFIG_QCOM_QMI_POWER_COLLAPSE=y CONFIG_QCOM_SMEM=y CONFIG_QCOM_SCM=y CONFIG_QCOM_MEMORY_DUMP_V2=y diff --git a/arch/arm/configs/vendor/sdxprairie_defconfig b/arch/arm/configs/vendor/sdxprairie_defconfig index 04b5b0310ce4..8519954bea96 100644 --- a/arch/arm/configs/vendor/sdxprairie_defconfig +++ b/arch/arm/configs/vendor/sdxprairie_defconfig @@ -384,6 +384,9 @@ CONFIG_RPMSG_QCOM_GLINK_SMEM=y CONFIG_QCOM_LLCC=y CONFIG_QCOM_SDXPRAIRIE_LLCC=y CONFIG_QCOM_QMI_HELPERS=y +CONFIG_QCOM_QMI_RMNET=y +CONFIG_QCOM_QMI_DFC=y +CONFIG_QCOM_QMI_POWER_COLLAPSE=y CONFIG_QCOM_SMEM=y CONFIG_QCOM_SCM=y CONFIG_QCOM_MEMORY_DUMP_V2=y -- GitLab From dea80350151e614a282d5e461efdba81379ede08 Mon Sep 17 00:00:00 2001 From: Gustavo Solaira Date: Mon, 22 Jul 2019 11:21:03 -0700 Subject: [PATCH 0973/1121] ARM: dts: msm: Enable dual-CAN for SA515M CCARD Enable 2 CAN interfaces for SA515M CCARD boards using the qti-can driver. Change-Id: I4c0dbe4bae25d7a24be350a2218cc1723d4d10bd Signed-off-by: Gustavo Solaira --- arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi b/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi index 09b5c7e03766..9f300404a961 100644 --- a/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi +++ b/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi @@ -99,7 +99,7 @@ interrupts = <88 0>; spi-max-frequency = <5000000>; qcom,clk-freq-mhz = <40000000>; - qcom,max-can-channels = <1>; + qcom,max-can-channels = <2>; qcom,bits-per-word = <8>; qcom,support-can-fd; }; -- GitLab From 16609f93e556667f90baaa74f1c79ee6dc73ed61 Mon Sep 17 00:00:00 2001 From: Tony Truong Date: Mon, 22 Jul 2019 14:27:36 -0700 Subject: [PATCH 0974/1121] mhi: core: make timesync register access strict Ensure timesync register access is only attempted if both pm states allow it to prevent unclocked access leading to NOC errors when any of the pm states is a false-positive. CRs-Fixed: 2465813 Change-Id: I46eb2179ce406bef833cbeb7f1728871b54c4eaf Acked-by: Bhaumik Vasav Bhatt Signed-off-by: Tony Truong --- drivers/bus/mhi/core/mhi_pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/bus/mhi/core/mhi_pm.c b/drivers/bus/mhi/core/mhi_pm.c index 7ebd6b209d04..517645b0211b 100644 --- a/drivers/bus/mhi/core/mhi_pm.c +++ b/drivers/bus/mhi/core/mhi_pm.c @@ -145,7 +145,7 @@ enum MHI_PM_STATE __must_check mhi_tryset_pm_state( MHI_VERB("Transition to pm state from:%s to:%s\n", to_mhi_pm_state_str(cur_state), to_mhi_pm_state_str(state)); - if (MHI_REG_ACCESS_VALID(cur_state) || MHI_REG_ACCESS_VALID(state)) + if (MHI_REG_ACCESS_VALID(cur_state) && MHI_REG_ACCESS_VALID(state)) mhi_timesync_log(mhi_cntrl); mhi_cntrl->pm_state = state; -- GitLab From 8779eed86e464fbf58aa56ebe24104cf1a457b8f Mon Sep 17 00:00:00 2001 From: Rama Aparna Mallavarapu Date: Wed, 3 Apr 2019 12:12:30 -0700 Subject: [PATCH 0975/1121] devfreq: bimc_bwmon: Add support to enable BWMON clks Some BWMON devices requires clocks to be enabled, hence add necessary support in the bwmon driver to enable the required clocks if any. Change-Id: Ie06731f764ff24d602ae2a86dea4f39ce75df800 Signed-off-by: Rama Aparna Mallavarapu --- drivers/devfreq/bimc-bwmon.c | 84 +++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) diff --git a/drivers/devfreq/bimc-bwmon.c b/drivers/devfreq/bimc-bwmon.c index 1c9f77fac738..af19be8c6628 100644 --- a/drivers/devfreq/bimc-bwmon.c +++ b/drivers/devfreq/bimc-bwmon.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -28,6 +28,7 @@ #include #include #include +#include #include "governor_bw_hwmon.h" #define GLB_INT_STATUS(m) ((m)->global_base + 0x100) @@ -99,6 +100,8 @@ struct bwmon { void __iomem *global_base; unsigned int mport; int irq; + int nr_clks; + struct clk **clks; const struct bwmon_spec *spec; struct device *dev; struct bw_hwmon hw; @@ -783,6 +786,27 @@ void mon_set_byte_count_filter(struct bwmon *m, enum mon_reg_type type) } } +static __always_inline int mon_clk_enable(struct bwmon *m) +{ + int ret; + int i; + + for (i = 0; i < m->nr_clks; i++) { + ret = clk_prepare_enable(m->clks[i]); + if (ret) { + dev_err(m->dev, "BWMON clk not enabled %d\n", ret); + goto err; + } + } + + return 0; +err: + for (i--; i >= 0; i--) + clk_disable_unprepare(m->clks[i]); + + return ret; +} + static __always_inline int __start_bw_hwmon(struct bw_hwmon *hw, unsigned long mbps, enum mon_reg_type type) { @@ -791,6 +815,12 @@ static __always_inline int __start_bw_hwmon(struct bw_hwmon *hw, int ret; irq_handler_t handler; + ret = mon_clk_enable(m); + if (ret) { + dev_err(m->dev, "Unable to turn on bwmon clks! (%d)\n", ret); + return ret; + } + switch (type) { case MON1: handler = bwmon_intr_handler; @@ -857,6 +887,14 @@ static int start_bw_hwmon3(struct bw_hwmon *hw, unsigned long mbps) return __start_bw_hwmon(hw, mbps, MON3); } +static __always_inline void mon_clk_disable(struct bwmon *m) +{ + int i; + + for (i = m->nr_clks - 1; i >= 0; i--) + clk_disable_unprepare(m->clks[i]); +} + static __always_inline void __stop_bw_hwmon(struct bw_hwmon *hw, enum mon_reg_type type) { @@ -867,6 +905,7 @@ void __stop_bw_hwmon(struct bw_hwmon *hw, enum mon_reg_type type) mon_disable(m, type); mon_clear(m, true, type); mon_irq_clear(m, type); + mon_clk_disable(m); } static void stop_bw_hwmon(struct bw_hwmon *hw) @@ -919,6 +958,12 @@ int __resume_bw_hwmon(struct bw_hwmon *hw, enum mon_reg_type type) int ret; irq_handler_t handler; + ret = mon_clk_enable(m); + if (ret) { + dev_err(m->dev, "Unable to turn on bwmon clks! (%d)\n", ret); + return ret; + } + switch (type) { case MON1: handler = bwmon_intr_handler; @@ -1022,6 +1067,7 @@ static int bimc_bwmon_driver_probe(struct platform_device *pdev) struct bwmon *m; int ret; u32 data, count_unit; + unsigned int len, i; m = devm_kzalloc(dev, sizeof(*m), GFP_KERNEL); if (!m) @@ -1067,6 +1113,42 @@ static int bimc_bwmon_driver_probe(struct platform_device *pdev) m->mport = data; } + if (of_find_property(dev->of_node, "qcom,bwmon_clks", &len)) { + m->nr_clks = of_property_count_strings(dev->of_node, + "qcom,bwmon_clks"); + if (!m->nr_clks) { + dev_err(dev, "Failed to get clock names\n"); + return -EINVAL; + } + + m->clks = devm_kzalloc(dev, sizeof(struct clk *) * m->nr_clks, + GFP_KERNEL); + if (!m->clks) + return -ENOMEM; + + for (i = 0; i < m->nr_clks; i++) { + const char *clock_name; + + ret = of_property_read_string_index(dev->of_node, + "qcom,bwmon_clks", i, + &clock_name); + if (ret) { + pr_err("failed to read clk index %d ret %d\n", + i, ret); + return ret; + } + m->clks[i] = devm_clk_get(dev, clock_name); + if (IS_ERR(m->clks[i])) { + ret = PTR_ERR(m->clks[i]); + if (ret != -EPROBE_DEFER) + dev_err(dev, "Error to get %s clk %d\n", + clock_name, ret); + return ret; + } + } + } else + m->nr_clks = 0; + m->irq = platform_get_irq(pdev, 0); if (m->irq < 0) { dev_err(dev, "Unable to get IRQ number\n"); -- GitLab From 0e1c32ea10ad94c22733ec5d0eac7d69c2db5ca8 Mon Sep 17 00:00:00 2001 From: Rama Aparna Mallavarapu Date: Mon, 25 Mar 2019 11:46:23 -0700 Subject: [PATCH 0976/1121] devfreq: bw_mon: check for the return value of start_monitor The BWMON governor start is returning success on GOV_START event without checking for the return value of start_monitor. The return value of start_monitor is not being returned to ret variable. This would cause the governor to start successfully even when the monitor failed to start causing a NULL pointer derefence when accessing the device attributes. Fix it by checking the return value of start_monitor. Change-Id: I8c1f6933d44ae4533c6b81ccda8a5c4c0da3779c Signed-off-by: Rama Aparna Mallavarapu --- drivers/devfreq/governor_bw_hwmon.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/devfreq/governor_bw_hwmon.c b/drivers/devfreq/governor_bw_hwmon.c index 164d622c3a50..330c45a8c1fe 100644 --- a/drivers/devfreq/governor_bw_hwmon.c +++ b/drivers/devfreq/governor_bw_hwmon.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -617,7 +617,8 @@ static int gov_start(struct devfreq *df) node->orig_data = df->data; df->data = node; - if (start_monitor(df, true)) + ret = start_monitor(df, true); + if (ret) goto err_start; ret = sysfs_create_group(&df->dev.kobj, node->attr_grp); -- GitLab From c3e062d8cfc4eccd5f44cb416bd74e158373dd51 Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Thu, 11 Jul 2019 21:51:40 -0700 Subject: [PATCH 0977/1121] ARM: dts: msm: Include PCIe for SA8195P The SA8195P target requires PCIe support to interact with clients connected over PCIe RCO and RC1. Include the PCIe file to add support for PCIe on SA8195P. Change-Id: I58214402b2d79feb25209f5a1451d3f41edf1819 Signed-off-by: Anant Goel --- arch/arm64/boot/dts/qcom/sa8195p.dtsi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sa8195p.dtsi b/arch/arm64/boot/dts/qcom/sa8195p.dtsi index 39da524bb6c4..318d8a5e00a7 100644 --- a/arch/arm64/boot/dts/qcom/sa8195p.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8195p.dtsi @@ -10,12 +10,14 @@ * GNU General Public License for more details. */ +#include #include "sdmshrike-v2.dtsi" #include "sa8155-audio.dtsi" #include "sa8195-pmic.dtsi" #include "sm8150-camera.dtsi" #include "sm8150-v2-camera.dtsi" #include "sa8155-camera-sensor.dtsi" +#include "sa8195p-pcie.dtsi" / { model = "Qualcomm Technologies, Inc. SA8195P"; @@ -23,7 +25,6 @@ qcom,msm-id = <405 0x20000>; }; -#include &soc { emac_hw: qcom,emac@00020000 { compatible = "qcom,emac-dwc-eqos"; -- GitLab From e78c217d009ed50213cf8230bbc0001999a3c2dd Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Mon, 22 Jul 2019 10:46:16 -0700 Subject: [PATCH 0978/1121] ARM: dts: msm: Update the SDHC driver for SA8195P ADP STAR Update the regulators, voltage levels, and GPIOs for the SDHC driver on the SA8195P ADP STAR target. Change-Id: Ic7c7bce80aac7961ccb1c742cf2a8c324f2745a9 Signed-off-by: Anant Goel --- .../arm64/boot/dts/qcom/sa8195p-adp-star.dtsi | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sa8195p-adp-star.dtsi b/arch/arm64/boot/dts/qcom/sa8195p-adp-star.dtsi index 02e46d986949..31187172cde3 100644 --- a/arch/arm64/boot/dts/qcom/sa8195p-adp-star.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8195p-adp-star.dtsi @@ -34,3 +34,23 @@ &qupv3_se12_2uart { status = "ok"; }; + +&sdhc_2 { + vdd-supply = <&pm8195_1_l10>; + qcom,vdd-voltage-level = <2950000 2960000>; + qcom,vdd-current-level = <200 800000>; + + vdd-io-supply = <&pm8195_1_l2>; + qcom,vdd-io-voltage-level = <1808000 2960000>; + qcom,vdd-io-current-level = <200 22000>; + + pinctrl-names = "active", "sleep"; + pinctrl-0 = <&sdc2_clk_on + &sdc2_cmd_on &sdc2_data_on &storage_cd_default>; + pinctrl-1 = <&sdc2_clk_off + &sdc2_cmd_off &sdc2_data_off &storage_cd_default>; + + cd-gpios = <&pm8195_1_gpios 4 GPIO_ACTIVE_LOW>; + + status = "ok"; +}; -- GitLab From d2a049b51bb90fafcaef3e77e25a380e027e9391 Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Mon, 22 Jul 2019 17:47:23 -0700 Subject: [PATCH 0979/1121] ARM: dts: msm: Add QMP debugfs client on sdmshrike The QMP debugfs client uses the QMP mailbox driver to communicate with the Always On Processor. Change-Id: I7e26ff6def96139a8db0295c21ce83fc66a328a7 Signed-off-by: Anant Goel --- arch/arm64/boot/dts/qcom/sdmshrike.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdmshrike.dtsi b/arch/arm64/boot/dts/qcom/sdmshrike.dtsi index 50372a88962a..6444e2578bed 100644 --- a/arch/arm64/boot/dts/qcom/sdmshrike.dtsi +++ b/arch/arm64/boot/dts/qcom/sdmshrike.dtsi @@ -2298,6 +2298,11 @@ }; }; + aop-msg-client { + compatible = "qcom,debugfs-qmp-client"; + mboxes = <&qmp_aop 0>; + mbox-names = "aop"; + }; }; &emac_gdsc { -- GitLab From 8892d4f22dd684fe57a9248a061fb39cdb7c5877 Mon Sep 17 00:00:00 2001 From: Michael Adisumarta Date: Thu, 11 Jul 2019 12:09:49 -0700 Subject: [PATCH 0980/1121] msm: ipa3: Update BW values for debugfs to change clk rate Update debugfs to use new values from sm8150-sdxprairie.dtsi clk rates. Change-Id: Ied1800fb0346cb5df4d1516663f2589f57c48f3c Signed-off-by: Michael Adisumarta --- drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c index 81f1ff4a72b6..d56d3d262183 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c @@ -356,15 +356,15 @@ static ssize_t ipa3_write_keep_awake(struct file *file, const char __user *buf, break; case 2: IPA_ACTIVE_CLIENTS_INC_SIMPLE(); - bw_mbps = 350; + bw_mbps = 700; break; case 3: IPA_ACTIVE_CLIENTS_INC_SIMPLE(); - bw_mbps = 690; + bw_mbps = 3000; break; case 4: IPA_ACTIVE_CLIENTS_INC_SIMPLE(); - bw_mbps = 1200; + bw_mbps = 7000; break; default: pr_err("Not support this vote (%d)\n", option); -- GitLab From 464e1004aed2ed8ef6f7559bf152c627eb7ee720 Mon Sep 17 00:00:00 2001 From: Manoj Prabhu B Date: Mon, 22 Jul 2019 15:57:12 +0530 Subject: [PATCH 0981/1121] diag: Update hdlc mode for all peripherals after mdlog exit Presently hdlc mode is not getting updated for a peripheral after multimode mdlog exit. Update the peripheral's hdlc mode while closing the mdlog session. Change-Id: I255db98b592648df00e779027232a55c4585de6a Signed-off-by: Manoj Prabhu B --- drivers/char/diag/diagchar_core.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c index 52c5027ebeda..8c88b006e0a9 100644 --- a/drivers/char/diag/diagchar_core.c +++ b/drivers/char/diag/diagchar_core.c @@ -523,9 +523,11 @@ static void diag_close_logging_process(const int pid) } } } + mutex_lock(&driver->hdlc_disable_mutex); mutex_lock(&driver->md_session_lock); diag_md_session_close(pid); mutex_unlock(&driver->md_session_lock); + mutex_unlock(&driver->hdlc_disable_mutex); diag_switch_logging(¶ms); mutex_unlock(&driver->diagchar_mutex); } @@ -1443,6 +1445,8 @@ static void diag_md_session_close(int pid) driver->md_session_map[proc][i] = NULL; driver->md_session_mask[proc] &= ~session_info->peripheral_mask[proc]; + driver->p_hdlc_disabled[i] = + driver->hdlc_disabled; } } diag_log_mask_free(session_info->log_mask); -- GitLab From cb92d44233553880014918d75286700b70a10ba6 Mon Sep 17 00:00:00 2001 From: E V Ravi Date: Fri, 19 Jul 2019 12:13:04 +0530 Subject: [PATCH 0982/1121] msm: ais: eeprom: Fix OOB condition for memory map count Fix OOB check for memory map count to access correct memory map. Change-Id: I55fb4ecbca36d47ebde80a912e621fb030f187a0 Signed-off-by: E V Ravi --- .../msm/ais/cam_sensor_module/cam_eeprom/cam_eeprom_core.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/msm/ais/cam_sensor_module/cam_eeprom/cam_eeprom_core.c b/drivers/media/platform/msm/ais/cam_sensor_module/cam_eeprom/cam_eeprom_core.c index 209daa2064d9..3683fc73501b 100644 --- a/drivers/media/platform/msm/ais/cam_sensor_module/cam_eeprom/cam_eeprom_core.c +++ b/drivers/media/platform/msm/ais/cam_sensor_module/cam_eeprom/cam_eeprom_core.c @@ -439,7 +439,8 @@ static int32_t cam_eeprom_parse_memory_map( validate_size = sizeof(struct cam_cmd_unconditional_wait); if (remain_buf_len < validate_size || - *num_map >= MSM_EEPROM_MAX_MEM_MAP_CNT) { + *num_map >= (MSM_EEPROM_MAX_MEM_MAP_CNT * + MSM_EEPROM_MEMORY_MAP_MAX_SIZE)) { CAM_ERR(CAM_EEPROM, "not enough buffer"); return -EINVAL; } @@ -449,7 +450,9 @@ static int32_t cam_eeprom_parse_memory_map( if (i2c_random_wr->header.count == 0 || i2c_random_wr->header.count >= MSM_EEPROM_MAX_MEM_MAP_CNT || - (size_t)*num_map > U16_MAX - i2c_random_wr->header.count) { + (size_t)*num_map >= ((MSM_EEPROM_MAX_MEM_MAP_CNT * + MSM_EEPROM_MEMORY_MAP_MAX_SIZE) - + i2c_random_wr->header.count)) { CAM_ERR(CAM_EEPROM, "OOB Error"); return -EINVAL; } -- GitLab From 463b3b0e53914cf64c52d7ada135edbc8467f113 Mon Sep 17 00:00:00 2001 From: Mounika Reddy Tangirala Date: Wed, 29 May 2019 17:37:06 +0530 Subject: [PATCH 0983/1121] msm: camera: Add new sof event to include nanosecond timestamp Thirdparty EIS need sof timestamp to be in nanoseconds and this change will send new event sof_nanosec to get nanosec timestamp. Change-Id: Ia9884a2612cc3aa1153b4677521fce7ddfb8d1ba Signed-off-by: Mounika Reddy Tangirala --- .../platform/msm/camera_v2/isp/msm_isp.c | 60 +++++++++++++------ .../platform/msm/camera_v2/isp/msm_isp.h | 5 ++ .../msm/camera_v2/isp/msm_isp_axi_util.c | 13 ++++ .../platform/msm/camera_v2/isp/msm_isp_util.c | 36 ++++++++++- .../platform/msm/camera_v2/isp/msm_isp_util.h | 2 + include/uapi/media/msmb_isp.h | 20 +++++++ 6 files changed, 116 insertions(+), 20 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp.c index 097046d30ff0..c159b144c42d 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.c @@ -357,26 +357,48 @@ static long msm_isp_dqevent(struct file *file, struct v4l2_fh *vfh, void *arg) file->f_flags & O_NONBLOCK); if (rc) return rc; - event_data = (struct msm_isp_event_data *) - isp_event.u.data; - isp_event_user = (struct v4l2_event *)arg; - memcpy(isp_event_user, &isp_event, + if (isp_event.type == ISP_EVENT_SOF_UPDATE_NANOSEC) { + struct msm_isp_event_data_nanosec *event_data_nanosec; + struct msm_isp_event_data_nanosec + *event_data_nanosec_user; + + event_data_nanosec = + (struct msm_isp_event_data_nanosec *) + isp_event.u.data; + isp_event_user = (struct v4l2_event *)arg; + memcpy(isp_event_user, &isp_event, sizeof(*isp_event_user)); - event_data32 = (struct msm_isp_event_data32 *) - isp_event_user->u.data; - memset(event_data32, 0, - sizeof(struct msm_isp_event_data32)); - event_data32->timestamp.tv_sec = - event_data->timestamp.tv_sec; - event_data32->timestamp.tv_usec = - event_data->timestamp.tv_usec; - event_data32->mono_timestamp.tv_sec = - event_data->mono_timestamp.tv_sec; - event_data32->mono_timestamp.tv_usec = - event_data->mono_timestamp.tv_usec; - event_data32->frame_id = event_data->frame_id; - memcpy(&(event_data32->u), &(event_data->u), - sizeof(event_data32->u)); + event_data_nanosec_user = + (struct msm_isp_event_data_nanosec *) + isp_event_user->u.data; + memset(event_data_nanosec_user, 0, + sizeof(struct msm_isp_event_data_nanosec)); + event_data_nanosec_user->nano_timestamp = + event_data_nanosec->nano_timestamp; + event_data_nanosec_user->frame_id = + event_data_nanosec->frame_id; + } else { + event_data = (struct msm_isp_event_data *) + isp_event.u.data; + isp_event_user = (struct v4l2_event *)arg; + memcpy(isp_event_user, &isp_event, + sizeof(*isp_event_user)); + event_data32 = (struct msm_isp_event_data32 *) + isp_event_user->u.data; + memset(event_data32, 0, + sizeof(struct msm_isp_event_data32)); + event_data32->timestamp.tv_sec = + event_data->timestamp.tv_sec; + event_data32->timestamp.tv_usec = + event_data->timestamp.tv_usec; + event_data32->mono_timestamp.tv_sec = + event_data->mono_timestamp.tv_sec; + event_data32->mono_timestamp.tv_usec = + event_data->mono_timestamp.tv_usec; + event_data32->frame_id = event_data->frame_id; + memcpy(&(event_data32->u), &(event_data->u), + sizeof(event_data32->u)); + } } else { rc = v4l2_event_dequeue(vfh, arg, file->f_flags & O_NONBLOCK); diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h index 233e61f45880..bd54899f6454 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h @@ -131,6 +131,8 @@ struct msm_isp_timestamp { struct timeval vt_time; /*Wall clock for userspace event*/ struct timeval event_time; + /* event time in nanosec*/ + uint64_t buf_time_ns; }; struct msm_vfe_irq_ops { @@ -874,6 +876,9 @@ struct vfe_device { /* irq info */ uint32_t dual_irq_mask; uint32_t irq_sof_id; + + /* nano sec timestamp */ + uint32_t nanosec_ts_enable; }; struct vfe_parent_device { diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c index 73ca32b1f7f8..871d7b90fd46 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c @@ -1153,6 +1153,19 @@ void msm_isp_notify(struct vfe_device *vfe_dev, uint32_t event_type, break; } + if ((vfe_dev->nanosec_ts_enable) && + (event_type == ISP_EVENT_SOF) && + (frame_src == VFE_PIX_0)) { + struct msm_isp_event_data_nanosec event_data_nanosec; + + event_data_nanosec.frame_id = + vfe_dev->axi_data.src_info[frame_src].frame_id; + event_data_nanosec.nano_timestamp = ts->buf_time_ns; + msm_isp_send_event_update_nanosec(vfe_dev, + ISP_EVENT_SOF_UPDATE_NANOSEC, + &event_data_nanosec); + } + event_data.frame_id = vfe_dev->axi_data.src_info[frame_src].frame_id; event_data.timestamp = ts->event_time; event_data.mono_timestamp = ts->buf_time; diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c index e38cf5eb1081..c1bc1c2f0177 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c @@ -218,6 +218,8 @@ void msm_isp_get_timestamp(struct msm_isp_timestamp *time_stamp, get_monotonic_boottime(&ts); time_stamp->buf_time.tv_sec = ts.tv_sec; time_stamp->buf_time.tv_usec = ts.tv_nsec/1000; + time_stamp->buf_time_ns = + ((uint64_t)ts.tv_sec * 1000000000) + ts.tv_nsec; } } @@ -265,6 +267,9 @@ static inline u32 msm_isp_evt_mask_to_isp_event(u32 evt_mask) case ISP_EVENT_MASK_INDEX_BUF_FATAL_ERROR: evt_id = ISP_EVENT_BUF_FATAL_ERROR; break; + case ISP_EVENT_MASK_INDEX_SOF_UPDATE_NANOSEC: + evt_id = ISP_EVENT_SOF_UPDATE_NANOSEC; + break; default: evt_id = ISP_EVENT_SUBS_MASK_NONE; break; @@ -294,6 +299,7 @@ static inline int msm_isp_subscribe_event_mask(struct v4l2_fh *fh, } } } else if (evt_mask_index == ISP_EVENT_MASK_INDEX_SOF || + evt_mask_index == ISP_EVENT_MASK_INDEX_SOF_UPDATE_NANOSEC || evt_mask_index == ISP_EVENT_MASK_INDEX_REG_UPDATE || evt_mask_index == ISP_EVENT_MASK_INDEX_STREAM_UPDATE_DONE) { for (interface = 0; interface < VFE_SRC_MAX; interface++) { @@ -339,7 +345,7 @@ static inline int msm_isp_process_event_subscription(struct v4l2_fh *fh, } for (evt_mask_index = ISP_EVENT_MASK_INDEX_STATS_NOTIFY; - evt_mask_index <= ISP_EVENT_MASK_INDEX_BUF_FATAL_ERROR; + evt_mask_index <= ISP_EVENT_MASK_INDEX_SOF_UPDATE_NANOSEC; evt_mask_index++) { if (evt_mask & (1<dual_vfe_sync_enable = mode->enable; return 0; } +static int msm_isp_nano_sec_timestamp( + struct vfe_device *vfe_dev, void *arg) +{ + struct msm_vfe_nano_sec_timestamp *mode = arg; + + vfe_dev->nanosec_ts_enable = mode->enable; + return 0; +} int msm_isp_cfg_input(struct vfe_device *vfe_dev, void *arg) { int rc = 0; @@ -1072,6 +1086,11 @@ static long msm_isp_ioctl_unlocked(struct v4l2_subdev *sd, rc = msm_isp_set_dual_vfe_sync_mode(vfe_dev, arg); mutex_unlock(&vfe_dev->core_mutex); break; + case VIDIOC_MSM_ISP_NANOSEC_TIMESTAMP: + mutex_lock(&vfe_dev->core_mutex); + rc = msm_isp_nano_sec_timestamp(vfe_dev, arg); + mutex_unlock(&vfe_dev->core_mutex); + break; default: pr_err_ratelimited("%s: Invalid ISP command %x\n", __func__, cmd); @@ -1572,6 +1591,21 @@ int msm_isp_send_event(struct vfe_device *vfe_dev, return 0; } +int msm_isp_send_event_update_nanosec(struct vfe_device *vfe_dev, + uint32_t event_type, + struct msm_isp_event_data_nanosec *event_data) +{ + struct v4l2_event isp_event; + + memset(&isp_event, 0, sizeof(struct v4l2_event)); + isp_event.id = 0; + isp_event.type = event_type; + memcpy(&isp_event.u.data[0], event_data, + sizeof(struct msm_isp_event_data_nanosec)); + v4l2_event_queue(vfe_dev->subdev.sd.devnode, &isp_event); + return 0; +} + #define CAL_WORD(width, M, N) ((width * M + N - 1) / N) int msm_isp_cal_word_per_line(uint32_t output_format, diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.h index 638697b6d635..032ede501bc7 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.h +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.h @@ -54,6 +54,8 @@ int msm_isp_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, int msm_isp_proc_cmd(struct vfe_device *vfe_dev, void *arg); int msm_isp_send_event(struct vfe_device *vfe_dev, uint32_t type, struct msm_isp_event_data *event_data); +int msm_isp_send_event_update_nanosec(struct vfe_device *vfe_dev, + uint32_t type, struct msm_isp_event_data_nanosec *event_data); int msm_isp_cal_word_per_line(uint32_t output_format, uint32_t pixel_per_line); int msm_isp_get_bit_per_pixel(uint32_t output_format); diff --git a/include/uapi/media/msmb_isp.h b/include/uapi/media/msmb_isp.h index c77824ae6d66..5ef82a4c8de9 100644 --- a/include/uapi/media/msmb_isp.h +++ b/include/uapi/media/msmb_isp.h @@ -657,6 +657,7 @@ enum msm_isp_event_mask_index { ISP_EVENT_MASK_INDEX_REG_UPDATE_MISSING = 10, ISP_EVENT_MASK_INDEX_PING_PONG_MISMATCH = 11, ISP_EVENT_MASK_INDEX_BUF_FATAL_ERROR = 12, + ISP_EVENT_MASK_INDEX_SOF_UPDATE_NANOSEC = 13, }; @@ -701,6 +702,9 @@ enum msm_isp_event_mask_index { #define ISP_EVENT_SUBS_MASK_BUF_FATAL_ERROR \ (1 << ISP_EVENT_MASK_INDEX_BUF_FATAL_ERROR) +#define ISP_EVENT_SUBS_MASK_SOF_UPDATE_NANOSEC \ + (1 << ISP_EVENT_MASK_INDEX_SOF_UPDATE_NANOSEC) + enum msm_isp_event_idx { ISP_REG_UPDATE = 0, ISP_EPOCH_0 = 1, @@ -738,6 +742,7 @@ enum msm_isp_event_idx { #define ISP_EVENT_ERROR (ISP_EVENT_BASE + ISP_ERROR) #define ISP_EVENT_SOF (ISP_CAMIF_EVENT_BASE) #define ISP_EVENT_EOF (ISP_CAMIF_EVENT_BASE + 1) +#define ISP_EVENT_SOF_UPDATE_NANOSEC (ISP_CAMIF_EVENT_BASE + 512) #define ISP_EVENT_BUF_DONE (ISP_EVENT_BASE + ISP_BUF_DONE) #define ISP_EVENT_BUF_DIVERT (ISP_BUF_EVENT_BASE) #define ISP_EVENT_STATS_NOTIFY (ISP_STATS_EVENT_BASE) @@ -872,6 +877,12 @@ struct msm_isp_event_data { } u; /* union can have max 52 bytes */ }; +struct msm_isp_event_data_nanosec { + /* nano second timestamp */ + uint64_t nano_timestamp; + uint32_t frame_id; +}; + struct msm_isp32_event_data { /*Wall clock except for buffer divert events *which use monotonic clock @@ -923,6 +934,10 @@ struct msm_vfe_dual_vfe_sync_mode { uint32_t enable; }; +struct msm_vfe_nano_sec_timestamp { + uint32_t enable; +}; + #define V4L2_PIX_FMT_QBGGR8 v4l2_fourcc('Q', 'B', 'G', '8') #define V4L2_PIX_FMT_QGBRG8 v4l2_fourcc('Q', 'G', 'B', '8') #define V4L2_PIX_FMT_QGRBG8 v4l2_fourcc('Q', 'G', 'R', '8') @@ -991,6 +1006,7 @@ enum msm_isp_ioctl_cmd_code { MSM_ISP32_REQUEST_STREAM, MSM_ISP_DUAL_SYNC_CFG, MSM_ISP_DUAL_SYNC_CFG_VER2, + MSM_ISP_NANOSEC_TIMESTAMP, }; #define VIDIOC_MSM_VFE_REG_CFG \ @@ -1129,4 +1145,8 @@ enum msm_isp_ioctl_cmd_code { _IOWR('V', MSM_ISP_DUAL_SYNC_CFG_VER2, \ struct msm_vfe_dual_vfe_sync_mode) +#define VIDIOC_MSM_ISP_NANOSEC_TIMESTAMP \ + _IOW('V', MSM_ISP_NANOSEC_TIMESTAMP, \ + struct msm_vfe_nano_sec_timestamp) + #endif /* __MSMB_ISP__ */ -- GitLab From 873ea921b3b986a3fa2e6d6ed783072046d444dc Mon Sep 17 00:00:00 2001 From: Odelu Kukatla Date: Fri, 12 Apr 2019 14:22:23 +0530 Subject: [PATCH 0984/1121] clk: qcom: clk-rpmh: Add support for clk-rpmh driver for ATOLL Add the support for clock RPMh driver to vote for ARC and VRM managed clock resources. Change-Id: I5359344cb4bd87d73a732fe4057b4986132778e8 Signed-off-by: Odelu Kukatla --- Documentation/devicetree/bindings/clock/qcom,rpmh.txt | 3 ++- drivers/clk/qcom/clk-rpmh.c | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/clock/qcom,rpmh.txt b/Documentation/devicetree/bindings/clock/qcom,rpmh.txt index ece6b9e5b769..a244c6376f11 100644 --- a/Documentation/devicetree/bindings/clock/qcom,rpmh.txt +++ b/Documentation/devicetree/bindings/clock/qcom,rpmh.txt @@ -6,7 +6,8 @@ Required properties: "qcom,rpmh-clk-sm8150", "qcom,rpmh-clk-sdmshrike", "qcom,rpmh-clk-sdmmagpie" - "qcom,rpmh-clk-sdxprairie". + "qcom,rpmh-clk-sdxprairie", + "qcom,rpmh-clk-atoll". - #clock-cells: Must contain 1. - mboxes: List of RPMh mailbox phandle and channel identifier tuples. - mbox-names: List of names to identify the RPMh mailboxes used. diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c index 97d761daf08e..b7e69b449d80 100644 --- a/drivers/clk/qcom/clk-rpmh.c +++ b/drivers/clk/qcom/clk-rpmh.c @@ -522,6 +522,7 @@ static const struct of_device_id clk_rpmh_match_table[] = { { .compatible = "qcom,rpmh-clk-sdmmagpie", .data = &clk_rpmh_sm6150}, { .compatible = "qcom,rpmh-clk-sdxprairie", .data = &clk_rpmh_sdxprairie}, + { .compatible = "qcom,rpmh-clk-atoll", .data = &clk_rpmh_sm6150}, { } }; MODULE_DEVICE_TABLE(of, clk_rpmh_match_table); -- GitLab From f947fec2d1ec22ded05397a5ccb1a1a9364f9032 Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Tue, 18 Jun 2019 14:50:18 +0530 Subject: [PATCH 0985/1121] defconfig: trinket: Disable BUILD_ARM64_APPENDED_DTB_IMAGE flag Add support to compile the kernel without the dtbs appended to it. All the dtbs are concatenated to form dtb.img. Boot image with header version 2 will now have this dtb.img added towards the end at an offset. Change-Id: I11e3f9e74d7bea45a718c0cc25cf142950dcddbc Signed-off-by: Mukesh Ojha --- arch/arm64/configs/vendor/trinket-perf_defconfig | 1 - arch/arm64/configs/vendor/trinket_defconfig | 1 - 2 files changed, 2 deletions(-) diff --git a/arch/arm64/configs/vendor/trinket-perf_defconfig b/arch/arm64/configs/vendor/trinket-perf_defconfig index ada21ac70ca0..c9be69b22d25 100644 --- a/arch/arm64/configs/vendor/trinket-perf_defconfig +++ b/arch/arm64/configs/vendor/trinket-perf_defconfig @@ -79,7 +79,6 @@ CONFIG_ARM64_SW_TTBR0_PAN=y # CONFIG_ARM64_PAN is not set # CONFIG_ARM64_VHE is not set CONFIG_RANDOMIZE_BASE=y -CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_COMPAT=y CONFIG_PM_WAKELOCKS=y diff --git a/arch/arm64/configs/vendor/trinket_defconfig b/arch/arm64/configs/vendor/trinket_defconfig index ed1eac7f348d..d1b85103eef6 100644 --- a/arch/arm64/configs/vendor/trinket_defconfig +++ b/arch/arm64/configs/vendor/trinket_defconfig @@ -85,7 +85,6 @@ CONFIG_ARM64_SW_TTBR0_PAN=y # CONFIG_ARM64_PAN is not set # CONFIG_ARM64_VHE is not set CONFIG_RANDOMIZE_BASE=y -CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_COMPAT=y CONFIG_PM_WAKELOCKS=y -- GitLab From 0528e7f72bbde2562c16c6bb9935236b44024afa Mon Sep 17 00:00:00 2001 From: blong Date: Thu, 9 May 2019 11:04:56 +0800 Subject: [PATCH 0986/1121] sched: Add task boost feature This change is for general scheduler improvement. Change-Id: I3fc3976316350f9b2c392b8484d5390240a04782 Signed-off-by: Abhijeet Dharmapurikar Signed-off-by: blong --- fs/proc/base.c | 113 ++++++++++++++++++++++++++++++++++++++++++ include/linux/sched.h | 7 ++- kernel/sched/core.c | 23 +++++++++ kernel/sched/fair.c | 28 +++++++++-- 4 files changed, 165 insertions(+), 6 deletions(-) diff --git a/fs/proc/base.c b/fs/proc/base.c index db3cf5c83bb4..e8f621589f62 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -91,6 +91,7 @@ #include #include #include +#include #include #include #include @@ -2979,6 +2980,116 @@ static const struct file_operations proc_hung_task_detection_enabled_operations }; #endif +static ssize_t proc_sched_task_boost_read(struct file *file, + char __user *buf, size_t count, loff_t *ppos) +{ + struct task_struct *task = get_proc_task(file_inode(file)); + char buffer[PROC_NUMBUF]; + int sched_boost; + size_t len; + + if (!task) + return -ESRCH; + sched_boost = task->boost; + put_task_struct(task); + len = snprintf(buffer, sizeof(buffer), "%d\n", sched_boost); + return simple_read_from_buffer(buf, count, ppos, buffer, len); +} + +static ssize_t proc_sched_task_boost_write(struct file *file, + const char __user *buf, size_t count, loff_t *ppos) +{ + struct task_struct *task = get_proc_task(file_inode(file)); + char buffer[PROC_NUMBUF]; + int sched_boost; + int err; + + if (!task) + return -ESRCH; + memset(buffer, 0, sizeof(buffer)); + if (count > sizeof(buffer) - 1) + count = sizeof(buffer) - 1; + if (copy_from_user(buffer, buf, count)) { + err = -EFAULT; + goto out; + } + + err = kstrtoint(strstrip(buffer), 0, &sched_boost); + if (err) + goto out; + if (sched_boost < 0 || sched_boost > 2) { + err = -EINVAL; + goto out; + } + + task->boost = sched_boost; + if (sched_boost == 0) + task->boost_period = 0; +out: + put_task_struct(task); + return err < 0 ? err : count; +} + +static ssize_t proc_sched_task_boost_period_read(struct file *file, + char __user *buf, size_t count, loff_t *ppos) +{ + struct task_struct *task = get_proc_task(file_inode(file)); + char buffer[PROC_NUMBUF]; + u64 sched_boost_period_ms = 0; + size_t len; + + if (!task) + return -ESRCH; + sched_boost_period_ms = div64_ul(task->boost_period, 1000000UL); + put_task_struct(task); + len = snprintf(buffer, sizeof(buffer), "%llu\n", sched_boost_period_ms); + return simple_read_from_buffer(buf, count, ppos, buffer, len); +} + +static ssize_t proc_sched_task_boost_period_write(struct file *file, + const char __user *buf, size_t count, loff_t *ppos) +{ + struct task_struct *task = get_proc_task(file_inode(file)); + char buffer[PROC_NUMBUF]; + unsigned int sched_boost_period; + int err; + + memset(buffer, 0, sizeof(buffer)); + if (count > sizeof(buffer) - 1) + count = sizeof(buffer) - 1; + if (copy_from_user(buffer, buf, count)) { + err = -EFAULT; + goto out; + } + + err = kstrtouint(strstrip(buffer), 0, &sched_boost_period); + if (err) + goto out; + if (task->boost == 0 && sched_boost_period) { + /* setting boost period without boost is invalid */ + err = -EINVAL; + goto out; + } + + task->boost_period = (u64)sched_boost_period * 1000 * 1000; + task->boost_expires = sched_clock() + task->boost_period; +out: + put_task_struct(task); + return err < 0 ? err : count; +} + +static const struct file_operations proc_task_boost_enabled_operations = { + .read = proc_sched_task_boost_read, + .write = proc_sched_task_boost_write, + .llseek = generic_file_llseek, +}; + +static const struct file_operations proc_task_boost_period_operations = { + .read = proc_sched_task_boost_period_read, + .write = proc_sched_task_boost_period_write, + .llseek = generic_file_llseek, +}; + #ifdef CONFIG_USER_NS static int proc_id_map_open(struct inode *inode, struct file *file, const struct seq_operations *seq_ops) @@ -3157,6 +3268,8 @@ static const struct pid_entry tgid_base_stuff[] = { #ifdef CONFIG_SCHED_WALT REG("sched_init_task_load", 00644, proc_pid_sched_init_task_load_operations), REG("sched_group_id", 00666, proc_pid_sched_group_id_operations), + REG("sched_boost", 0666, proc_task_boost_enabled_operations), + REG("sched_boost_period_ms", 0666, proc_task_boost_period_operations), #endif #ifdef CONFIG_SCHED_DEBUG REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), diff --git a/include/linux/sched.h b/include/linux/sched.h index 3511ef6af4d3..8dc7f180aee3 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -274,6 +274,7 @@ extern int __must_check io_schedule_prepare(void); extern void io_schedule_finish(int token); extern long io_schedule_timeout(long timeout); extern void io_schedule(void); +extern int set_task_boost(int boost, u64 period); /** * struct prev_cputime - snapshot of system and user cputime @@ -777,7 +778,11 @@ struct task_struct { const struct sched_class *sched_class; struct sched_entity se; struct sched_rt_entity rt; - u64 last_sleep_ts; + u64 last_sleep_ts; + + int boost; + u64 boost_period; + u64 boost_expires; #ifdef CONFIG_SCHED_WALT struct ravg ravg; /* diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 91b80307795c..17c8b715af7e 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -2293,6 +2293,9 @@ static void __sched_fork(unsigned long clone_flags, struct task_struct *p) p->se.nr_migrations = 0; p->se.vruntime = 0; p->last_sleep_ts = 0; + p->boost = 0; + p->boost_expires = 0; + p->boost_period = 0; INIT_LIST_HEAD(&p->se.group_node); @@ -7490,6 +7493,26 @@ const u32 sched_prio_to_wmult[40] = { /* 15 */ 119304647, 148102320, 186737708, 238609294, 286331153, }; +/* + *@boost:should be 0,1,2. + *@period:boost time based on ms units. + */ +int set_task_boost(int boost, u64 period) +{ + if (boost < 0 || boost > 2) + return -EINVAL; + if (boost) { + current->boost = boost; + current->boost_period = (u64)period * 1000 * 1000; + current->boost_expires = sched_clock() + current->boost_period; + } else { + current->boost = 0; + current->boost_expires = 0; + current->boost_period = 0; + } + return 0; +} + #ifdef CONFIG_SCHED_WALT /* * sched_exit() - Set EXITING_TASK_MARKER in task's ravg.demand field diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index acf345c28b76..0f3ae67ee192 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -2890,6 +2890,18 @@ static inline void cfs_rq_util_change(struct cfs_rq *cfs_rq) } } +static inline int per_task_boost(struct task_struct *p) +{ + if (p->boost_period) { + if (sched_clock() > p->boost_expires) { + p->boost_period = 0; + p->boost_expires = 0; + p->boost = 0; + } + } + return p->boost; +} + #ifdef CONFIG_SMP /* * Approximate: @@ -7339,14 +7351,20 @@ static inline bool task_fits_max(struct task_struct *p, int cpu) { unsigned long capacity = capacity_orig_of(cpu); unsigned long max_capacity = cpu_rq(cpu)->rd->max_cpu_capacity.val; + unsigned long task_boost = per_task_boost(p); if (capacity == max_capacity) return true; - if ((task_boost_policy(p) == SCHED_BOOST_ON_BIG || - schedtune_task_boost(p) > 0) && - is_min_capacity_cpu(cpu)) - return false; + if (is_min_capacity_cpu(cpu)) { + if (task_boost_policy(p) == SCHED_BOOST_ON_BIG || + task_boost > 0 || + schedtune_task_boost(p) > 0) + return false; + } else { /* mid cap cpu */ + if (task_boost > 1) + return false; + } return task_fits_capacity(p, capacity, cpu); } @@ -8115,7 +8133,7 @@ static int find_energy_efficient_cpu(struct sched_domain *sd, int placement_boost = task_boost_policy(p); u64 start_t = 0; int next_cpu = -1, backup_cpu = -1; - int boosted = (schedtune_task_boost(p) > 0); + int boosted = (schedtune_task_boost(p) > 0 || per_task_boost(p) > 0); fbt_env.fastpath = 0; -- GitLab From 30c686a11f35b117291e202f604ee167bd1b245a Mon Sep 17 00:00:00 2001 From: Jayadev K Date: Fri, 19 Jul 2019 18:40:36 +0530 Subject: [PATCH 0987/1121] ARM: dts: qcom: Add HS-I2S device tree support on SA8155 Adding device nodes and pinctrl definitions for HS-I2S driver. Change-Id: I49a18d052ed9f269ee887e0fc9c36a66cd2ec9a8 Signed-off-by: Jayadev K --- arch/arm64/boot/dts/qcom/sa8155.dtsi | 54 +++ arch/arm64/boot/dts/qcom/sm8150-pinctrl.dtsi | 450 +++++++++++++++++++ 2 files changed, 504 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sa8155.dtsi b/arch/arm64/boot/dts/qcom/sa8155.dtsi index 0efa2b9e1346..b2403f41e8b5 100644 --- a/arch/arm64/boot/dts/qcom/sa8155.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8155.dtsi @@ -499,6 +499,60 @@ #include &soc { + hsi2s: qcom,hsi2s { + compatible = "qcom,sa8155-hsi2s", "qcom,hsi2s"; + number-of-interfaces = <3>; + reg = <0x172C0000 0x28000>, + <0x17080000 0xE000>; + reg-names = "lpa_if", "lpass_tcsr"; + interrupts = ; + + sdr0: qcom,hs0_i2s { + compatible = "qcom,hsi2s-interface"; + minor-number = <0>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&hs1_i2s_mclk_active &hs1_i2s_sck_active + &hs1_i2s_ws_active &hs1_i2s_data0_active + &hs1_i2s_data1_active>; + pinctrl-1 = <&hs1_i2s_mclk_sleep &hs1_i2s_sck_sleep + &hs1_i2s_ws_sleep &hs1_i2s_data0_sleep + &hs1_i2s_data1_sleep>; + iommus = <&apps_smmu 0x1B5C 0x0>; + qcom,smmu-s1-bypass; + qcom,iova-mapping = <0x0 0xFFFFFFFF>; + }; + + sdr1: qcom,hs1_i2s { + compatible = "qcom,hsi2s-interface"; + minor-number = <1>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&hs2_i2s_mclk_active &hs2_i2s_sck_active + &hs2_i2s_ws_active &hs2_i2s_data0_active + &hs2_i2s_data1_active>; + pinctrl-1 = <&hs2_i2s_mclk_sleep &hs2_i2s_sck_sleep + &hs2_i2s_ws_sleep &hs2_i2s_data0_sleep + &hs2_i2s_data1_sleep>; + iommus = <&apps_smmu 0x1B5D 0x0>; + qcom,smmu-s1-bypass; + qcom,iova-mapping = <0x0 0xFFFFFFFF>; + }; + + sdr2: qcom,hs2_i2s { + compatible = "qcom,hsi2s-interface"; + minor-number = <2>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&hs3_i2s_mclk_active &hs3_i2s_sck_active + &hs3_i2s_ws_active &hs3_i2s_data0_active + &hs3_i2s_data1_active>; + pinctrl-1 = <&hs3_i2s_mclk_sleep &hs3_i2s_sck_sleep + &hs3_i2s_ws_sleep &hs3_i2s_data0_sleep + &hs3_i2s_data1_sleep>; + iommus = <&apps_smmu 0x1B5E 0x0>; + qcom,smmu-s1-bypass; + qcom,iova-mapping = <0x0 0xFFFFFFFF>; + }; + }; + emac_hw: qcom,emac@00020000 { compatible = "qcom,emac-dwc-eqos"; qcom,arm-smmu; diff --git a/arch/arm64/boot/dts/qcom/sm8150-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sm8150-pinctrl.dtsi index 4835a9c6e98e..29df85b5fe82 100644 --- a/arch/arm64/boot/dts/qcom/sm8150-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150-pinctrl.dtsi @@ -4285,6 +4285,456 @@ }; }; + hs1_i2s_mclk { + hs1_i2s_mclk_sleep: hs1_i2s_mclk_sleep { + mux { + pins = "gpio155"; + function = "gpio"; + }; + + config { + pins = "gpio155"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + hs1_i2s_mclk_active: hs1_i2s_mclk_active { + mux { + pins = "gpio155"; + function = "hs1_mi2s"; + }; + + config { + pins = "gpio155"; + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + output-high; + }; + }; + }; + + hs1_i2s_sck { + hs1_i2s_sck_sleep: hs1_i2s_sck_sleep { + mux { + pins = "gpio156"; + function = "gpio"; + }; + + config { + pins = "gpio156"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + hs1_i2s_sck_active: hs1_i2s_sck_active { + mux { + pins = "gpio156"; + function = "hs1_mi2s"; + }; + + config { + pins = "gpio156"; + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + output-high; + }; + }; + }; + + hs1_i2s_ws { + hs1_i2s_ws_sleep: hs1_i2s_ws_sleep { + mux { + pins = "gpio157"; + function = "gpio"; + }; + + config { + pins = "gpio157"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + hs1_i2s_ws_active: hs1_i2s_ws_active { + mux { + pins = "gpio157"; + function = "hs1_mi2s"; + }; + + config { + pins = "gpio157"; + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + output-high; + }; + }; + }; + + hs1_i2s_data0 { + hs1_i2s_data0_sleep: hs1_i2s_data0_sleep { + mux { + pins = "gpio158"; + function = "sleep"; + }; + + config { + pins = "gpio158"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + hs1_i2s_data0_active: hs1_i2s_data0_active { + mux { + pins = "gpio158"; + function = "hs1_mi2s"; + }; + + config { + pins = "gpio158"; + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + output-high; + }; + }; + }; + + hs1_i2s_data1 { + hs1_i2s_data1_sleep: hs1_i2s_data1_sleep { + mux { + pins = "gpio159"; + function = "gpio"; + }; + + config { + pins = "gpio159"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + hs1_i2s_data1_active: hs1_i2s_data1_active { + mux { + pins = "gpio159"; + function = "hs1_mi2s"; + }; + + config { + pins = "gpio159"; + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + input-enable; + }; + }; + }; + + hs2_i2s_mclk { + hs2_i2s_mclk_sleep: hs2_i2s_mclk_sleep { + mux { + pins = "gpio160"; + function = "gpio"; + }; + + config { + pins = "gpio160"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + hs2_i2s_mclk_active: hs2_i2s_mclk_active { + mux { + pins = "gpio160"; + function = "hs2_mi2s"; + }; + + config { + pins = "gpio160"; + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + output-high; + }; + }; + }; + + hs2_i2s_sck { + hs2_i2s_sck_sleep: hs2_i2s_sck_sleep { + mux { + pins = "gpio161"; + function = "gpio"; + }; + + config { + pins = "gpio161"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + hs2_i2s_sck_active: hs2_i2s_sck_active { + mux { + pins = "gpio161"; + function = "hs2_mi2s"; + }; + + config { + pins = "gpio161"; + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + output-high; + }; + }; + }; + + hs2_i2s_ws { + hs2_i2s_ws_sleep: hs2_i2s_ws_sleep { + mux { + pins = "gpio162"; + function = "gpio"; + }; + + config { + pins = "gpio162"; + drive-strength = <2>; /* 8 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + hs2_i2s_ws_active: hs2_i2s_ws_active { + mux { + pins = "gpio162"; + function = "hs2_mi2s"; + }; + + config { + pins = "gpio162"; + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + output-high; + }; + }; + }; + + hs2_i2s_data0 { + hs2_i2s_data0_sleep: hs2_i2s_data0_sleep { + mux { + pins = "gpio163"; + function = "gpio"; + }; + + config { + pins = "gpio163"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + hs2_i2s_data0_active: hs2_i2s_data0_active { + mux { + pins = "gpio163"; + function = "hs2_mi2s"; + }; + + config { + pins = "gpio163"; + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + output-high; + }; + }; + }; + + hs2_i2s_data1 { + hs2_i2s_data1_sleep: hs2_i2s_data1_sleep { + mux { + pins = "gpio164"; + function = "gpio"; + }; + + config { + pins = "gpio164"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + hs2_i2s_data1_active: hs2_i2s_data1_active { + mux { + pins = "gpio164"; + function = "hs2_mi2s"; + }; + + config { + pins = "gpio164"; + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + input-enable; + }; + }; + }; + + hs3_i2s_mclk { + hs3_i2s_mclk_sleep: hs3_i2s_mclk_sleep { + mux { + pins = "gpio125"; + function = "gpio"; + }; + + config { + pins = "gpio125"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + hs3_i2s_mclk_active: hs3_i2s_mclk_active { + mux { + pins = "gpio125"; + function = "hs3_mi2s"; + }; + + config { + pins = "gpio125"; + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + output-high; + }; + }; + }; + + hs3_i2s_sck { + hs3_i2s_sck_sleep: hs3_i2s_sck_sleep { + mux { + pins = "gpio165"; + function = "gpio"; + }; + + config { + pins = "gpio165"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + hs3_i2s_sck_active: hs3_i2s_sck_active { + mux { + pins = "gpio165"; + function = "hs3_mi2s"; + }; + + config { + pins = "gpio165"; + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + output-high; + }; + }; + }; + + hs3_i2s_ws { + hs3_i2s_ws_sleep: hs3_i2s_ws_sleep { + mux { + pins = "gpio166"; + function = "gpio"; + }; + + config { + pins = "gpio166"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + hs3_i2s_ws_active: hs3_i2s_ws_active { + mux { + pins = "gpio166"; + function = "hs3_mi2s"; + }; + + config { + pins = "gpio166"; + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + output-high; + }; + }; + }; + + hs3_i2s_data0 { + hs3_i2s_data0_sleep: hs3_i2s_data0_sleep { + mux { + pins = "gpio167"; + function = "gpio"; + }; + + config { + pins = "gpio167"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + hs3_i2s_data0_active: hs3_i2s_data0_active { + mux { + pins = "gpio167"; + function = "hs3_mi2s"; + }; + + config { + pins = "gpio167"; + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + output-high; + }; + }; + }; + + hs3_i2s_data1 { + hs3_i2s_data1_sleep: hs3_i2s_data1_sleep { + mux { + pins = "gpio168"; + function = "gpio"; + }; + + config { + pins = "gpio168"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + hs3_i2s_data1_active: hs3_i2s_data1_active { + mux { + pins = "gpio168"; + function = "hs3_mi2s"; + }; + + config { + pins = "gpio168"; + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + input-enable; + }; + }; + }; + emac { emac_mdc: emac_mdc { mux { -- GitLab From e027eb51540102452bbac6c7f02593667cfab200 Mon Sep 17 00:00:00 2001 From: Deepak Kumar Singh Date: Wed, 3 Jul 2019 15:42:10 +0530 Subject: [PATCH 0988/1121] rpmsg: glink: Resource cleanup on glink smem probe fail When glink smem probe fails before completion, allocated resources are not freed properly before return. Freeing up allocated resources before return, in case of glink smem probe failure before completion. CRs-Fixed: 2482441 Change-Id: Ia3834fe7a9555b4e4a9e225fe3002400523f0f1e Signed-off-by: Deepak Kumar Singh --- drivers/rpmsg/qcom_glink_smem.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/rpmsg/qcom_glink_smem.c b/drivers/rpmsg/qcom_glink_smem.c index 8b279dc2a713..600c3619051c 100644 --- a/drivers/rpmsg/qcom_glink_smem.c +++ b/drivers/rpmsg/qcom_glink_smem.c @@ -231,6 +231,7 @@ struct qcom_glink *qcom_glink_smem_register(struct device *parent, ret = device_register(dev); if (ret) { pr_err("failed to register glink edge\n"); + kfree(dev); return ERR_PTR(ret); } @@ -238,21 +239,21 @@ struct qcom_glink *qcom_glink_smem_register(struct device *parent, &remote_pid); if (ret) { dev_err(dev, "failed to parse qcom,remote-pid\n"); - goto err_put_dev; + goto unregister; } rx_pipe = devm_kzalloc(dev, sizeof(*rx_pipe), GFP_KERNEL); tx_pipe = devm_kzalloc(dev, sizeof(*tx_pipe), GFP_KERNEL); if (!rx_pipe || !tx_pipe) { ret = -ENOMEM; - goto err_put_dev; + goto unregister; } ret = qcom_smem_alloc(remote_pid, SMEM_GLINK_NATIVE_XPRT_DESCRIPTOR, 32); if (ret && ret != -EEXIST) { dev_err(dev, "failed to allocate glink descriptors\n"); - goto err_put_dev; + goto unregister; } descs = qcom_smem_get(remote_pid, @@ -260,13 +261,13 @@ struct qcom_glink *qcom_glink_smem_register(struct device *parent, if (IS_ERR(descs)) { dev_err(dev, "failed to acquire xprt descriptor\n"); ret = PTR_ERR(descs); - goto err_put_dev; + goto unregister; } if (size != 32) { dev_err(dev, "glink descriptor of invalid size\n"); ret = -EINVAL; - goto err_put_dev; + goto unregister; } tx_pipe->tail = &descs[0]; @@ -278,7 +279,7 @@ struct qcom_glink *qcom_glink_smem_register(struct device *parent, SZ_16K); if (ret && ret != -EEXIST) { dev_err(dev, "failed to allocate TX fifo\n"); - goto err_put_dev; + goto unregister; } tx_pipe->fifo = qcom_smem_get(remote_pid, SMEM_GLINK_NATIVE_XPRT_FIFO_0, @@ -286,7 +287,7 @@ struct qcom_glink *qcom_glink_smem_register(struct device *parent, if (IS_ERR(tx_pipe->fifo)) { dev_err(dev, "failed to acquire TX fifo\n"); ret = PTR_ERR(tx_pipe->fifo); - goto err_put_dev; + goto unregister; } rx_pipe->native.avail = glink_smem_rx_avail; @@ -307,13 +308,13 @@ struct qcom_glink *qcom_glink_smem_register(struct device *parent, false); if (IS_ERR(glink)) { ret = PTR_ERR(glink); - goto err_put_dev; + goto unregister; } return glink; -err_put_dev: - put_device(dev); +unregister: + device_unregister(dev); return ERR_PTR(ret); } -- GitLab From 128d9c81dda51fc036b89f1f5e932ab05dad5d27 Mon Sep 17 00:00:00 2001 From: Mao Jinlong Date: Tue, 23 Jul 2019 17:42:46 +0530 Subject: [PATCH 0989/1121] ARM: dts: msm: Correct the qmi id of npu etm for atoll Correct the qmi id of npu etm to make npu etm work. Change-Id: Ia5460df57218c15fa3e4e4691b021c90b3148f7f Signed-off-by: Mao Jinlong --- arch/arm64/boot/dts/qcom/atoll-coresight.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/atoll-coresight.dtsi b/arch/arm64/boot/dts/qcom/atoll-coresight.dtsi index 1cd3070a7918..30469db9e54b 100644 --- a/arch/arm64/boot/dts/qcom/atoll-coresight.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll-coresight.dtsi @@ -240,7 +240,7 @@ compatible = "qcom,coresight-remote-etm"; coresight-name = "coresight-npu-etm0"; - qcom,inst-id = <2>; + qcom,inst-id = <14>; port { npu_etm0_out_funnel_npu: endpoint { -- GitLab From b0a706dc8d1640cfd205cb10ecf32fe0918ff7a1 Mon Sep 17 00:00:00 2001 From: Rahul Agarwal Date: Tue, 16 Jul 2019 15:08:01 +0530 Subject: [PATCH 0990/1121] defconfig: sa515m: Rename defconfigs Rename debug and perf defconfigs to make it same as machine name for sa515m automotive telematics target. Change-Id: Ib23752c53dfad2c8afb3dfbc81144834458d4754 Signed-off-by: Rahul Agarwal --- arch/arm/configs/sa515m-perf_defconfig | 1 + arch/arm/configs/sa515m_defconfig | 1 + arch/arm/configs/sdxprairie-auto-perf_defconfig | 1 - arch/arm/configs/sdxprairie-auto_defconfig | 1 - .../{sdxprairie-auto-perf_defconfig => sa515m-perf_defconfig} | 0 .../vendor/{sdxprairie-auto_defconfig => sa515m_defconfig} | 0 6 files changed, 2 insertions(+), 2 deletions(-) create mode 120000 arch/arm/configs/sa515m-perf_defconfig create mode 120000 arch/arm/configs/sa515m_defconfig delete mode 120000 arch/arm/configs/sdxprairie-auto-perf_defconfig delete mode 120000 arch/arm/configs/sdxprairie-auto_defconfig rename arch/arm/configs/vendor/{sdxprairie-auto-perf_defconfig => sa515m-perf_defconfig} (100%) rename arch/arm/configs/vendor/{sdxprairie-auto_defconfig => sa515m_defconfig} (100%) diff --git a/arch/arm/configs/sa515m-perf_defconfig b/arch/arm/configs/sa515m-perf_defconfig new file mode 120000 index 000000000000..f15877fab05a --- /dev/null +++ b/arch/arm/configs/sa515m-perf_defconfig @@ -0,0 +1 @@ +vendor/sa515m-perf_defconfig \ No newline at end of file diff --git a/arch/arm/configs/sa515m_defconfig b/arch/arm/configs/sa515m_defconfig new file mode 120000 index 000000000000..16aa13f59770 --- /dev/null +++ b/arch/arm/configs/sa515m_defconfig @@ -0,0 +1 @@ +vendor/sa515m_defconfig \ No newline at end of file diff --git a/arch/arm/configs/sdxprairie-auto-perf_defconfig b/arch/arm/configs/sdxprairie-auto-perf_defconfig deleted file mode 120000 index bea718d54c27..000000000000 --- a/arch/arm/configs/sdxprairie-auto-perf_defconfig +++ /dev/null @@ -1 +0,0 @@ -vendor/sdxprairie-auto-perf_defconfig \ No newline at end of file diff --git a/arch/arm/configs/sdxprairie-auto_defconfig b/arch/arm/configs/sdxprairie-auto_defconfig deleted file mode 120000 index 3c219277895b..000000000000 --- a/arch/arm/configs/sdxprairie-auto_defconfig +++ /dev/null @@ -1 +0,0 @@ -vendor/sdxprairie-auto_defconfig \ No newline at end of file diff --git a/arch/arm/configs/vendor/sdxprairie-auto-perf_defconfig b/arch/arm/configs/vendor/sa515m-perf_defconfig similarity index 100% rename from arch/arm/configs/vendor/sdxprairie-auto-perf_defconfig rename to arch/arm/configs/vendor/sa515m-perf_defconfig diff --git a/arch/arm/configs/vendor/sdxprairie-auto_defconfig b/arch/arm/configs/vendor/sa515m_defconfig similarity index 100% rename from arch/arm/configs/vendor/sdxprairie-auto_defconfig rename to arch/arm/configs/vendor/sa515m_defconfig -- GitLab From b6c544aa54ca809edb0e6e79332e8a8339e6b1e3 Mon Sep 17 00:00:00 2001 From: Mitul Golani Date: Wed, 26 Jun 2019 16:38:06 +0530 Subject: [PATCH 0991/1121] serial: msm_geni_serial: Decide UART sampling rate based on config Clock divider needs to get doubled for QUP HW version greater than 2.5.0 as sampling rate is half. As earlycon can't have HW version awareness,decision is taken based on the configuration. Change-Id: I639b8b5bff1d3b897d6d202501708a195e0dac31 Signed-off-by: Mitul Golani --- drivers/tty/serial/Kconfig | 9 +++++++++ drivers/tty/serial/msm_geni_serial.c | 12 ++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 9323f7b5115e..bd0cf13acd59 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1135,6 +1135,15 @@ config SERIAL_MSM_HS Choose M here to compile it as a module. The module will be called msm_serial_hs. +config SERIAL_MSM_WITH_HALF_SAMPLING + bool "Changes clock divider which impacts sampling rate for QUP HW ver greater than 2.5.0" + depends on SERIAL_MSM_GENI + help + Clock divider value should get double for QUP Hardware version + greater than 2.5.0. + As earlycon can't have HW version awareness,decision is taken + based on the configuration. + config SERIAL_VT8500 bool "VIA VT8500 on-chip serial port support" depends on ARCH_VT8500 diff --git a/drivers/tty/serial/msm_geni_serial.c b/drivers/tty/serial/msm_geni_serial.c index 594e7515308e..64161da417bc 100644 --- a/drivers/tty/serial/msm_geni_serial.c +++ b/drivers/tty/serial/msm_geni_serial.c @@ -131,7 +131,6 @@ #define DMA_RX_BUF_SIZE (2048) #define UART_CONSOLE_RX_WM (2) -#define QUP_VER (0x20050000) struct msm_geni_serial_port { struct uart_port uport; @@ -200,11 +199,6 @@ static int uart_line_id; static struct msm_geni_serial_port msm_geni_console_port; static struct msm_geni_serial_port msm_geni_serial_ports[GENI_UART_NR_PORTS]; -static int hw_version_info(void __iomem *base_addr) -{ - return geni_read_reg(base_addr, QUPV3_HW_VER); -} - static void msm_geni_serial_config_port(struct uart_port *uport, int cfg_flags) { if (cfg_flags & UART_CONFIG_TYPE) @@ -1875,8 +1869,9 @@ static void msm_geni_serial_set_termios(struct uart_port *uport, if (clk_div <= 0) goto exit_set_termios; - if (hw_version_info(uport->membase) >= QUP_VER) + if (IS_ENABLED(CONFIG_SERIAL_MSM_WITH_HALF_SAMPLING)) clk_div *= 2; + uport->uartclk = clk_rate; clk_set_rate(port->serial_rsc.se_clk, clk_rate); ser_clk_cfg |= SER_CLK_EN; @@ -2155,8 +2150,9 @@ msm_geni_serial_earlycon_setup(struct earlycon_device *dev, goto exit_geni_serial_earlyconsetup; } - if (hw_version_info(uport->membase) >= QUP_VER) + if (IS_ENABLED(CONFIG_SERIAL_MSM_WITH_HALF_SAMPLING)) clk_div *= 2; + s_clk_cfg |= SER_CLK_EN; s_clk_cfg |= (clk_div << CLK_DIV_SHFT); -- GitLab From 299370814873acb9b5aadfc80d21635375d51686 Mon Sep 17 00:00:00 2001 From: Zhenhua Huang Date: Mon, 10 Jun 2019 14:20:05 +0800 Subject: [PATCH 0992/1121] ARM: dts: msm: Enable deep pre-fetch on apps smmu for atoll Enable +3 deep pre-fetch for all context banks of multimedia tbu's and +3 deep pre-fetch for NPU clients of apps smmu for atoll. Change-Id: Idde96c26a453e14070f367ec243ea2028daeafcd Signed-off-by: Zhenhua Huang --- arch/arm64/boot/dts/qcom/msm-arm-smmu-atoll.dtsi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm-arm-smmu-atoll.dtsi b/arch/arm64/boot/dts/qcom/msm-arm-smmu-atoll.dtsi index d96746cce5cd..9bb5e06182c8 100644 --- a/arch/arm64/boot/dts/qcom/msm-arm-smmu-atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/msm-arm-smmu-atoll.dtsi @@ -202,3 +202,13 @@ dma-coherent; }; }; + +&apps_smmu { + qcom,actlr = + /* HF_0 and SF_0 TBUs: +3 deep PF */ + <0x800 0x7ff 0x103>, + + /* NPU SIDs: +3 deep PF */ + <0x1460 0x1f 0x303>, + <0x1480 0x1f 0x303>; +}; -- GitLab From c503c7596d6856b208fbd1795094fba810ffe66e Mon Sep 17 00:00:00 2001 From: lijuang Date: Wed, 24 Jul 2019 10:58:43 +0800 Subject: [PATCH 0993/1121] defconfig: sm8150: Disable BUILD_ARM64_APPENDED_DTB_IMAGE flag Add support to compile the kernel without the dtbs appended to it. All the dtbs are concatenated to form dtb.img. Boot image with header version 2 will now have this dtb.img added towards the end at an offset. Change-Id: I650dd10a8e2b6546249b0a7bffc2f99101409a22 Signed-off-by: lijuang --- arch/arm64/configs/vendor/sm8150-perf_defconfig | 1 - arch/arm64/configs/vendor/sm8150_defconfig | 1 - 2 files changed, 2 deletions(-) diff --git a/arch/arm64/configs/vendor/sm8150-perf_defconfig b/arch/arm64/configs/vendor/sm8150-perf_defconfig index a5eb2713d8df..8fcd9b28f6df 100644 --- a/arch/arm64/configs/vendor/sm8150-perf_defconfig +++ b/arch/arm64/configs/vendor/sm8150-perf_defconfig @@ -80,7 +80,6 @@ CONFIG_SETEND_EMULATION=y # CONFIG_ARM64_VHE is not set CONFIG_RANDOMIZE_BASE=y # CONFIG_EFI is not set -CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y CONFIG_BUILD_ARM64_UNCOMPRESSED_KERNEL=y CONFIG_KRYO_PMU_WORKAROUND=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set diff --git a/arch/arm64/configs/vendor/sm8150_defconfig b/arch/arm64/configs/vendor/sm8150_defconfig index c2dcde871c63..879933700ef9 100644 --- a/arch/arm64/configs/vendor/sm8150_defconfig +++ b/arch/arm64/configs/vendor/sm8150_defconfig @@ -86,7 +86,6 @@ CONFIG_CP15_BARRIER_EMULATION=y CONFIG_SETEND_EMULATION=y # CONFIG_ARM64_VHE is not set CONFIG_RANDOMIZE_BASE=y -CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y CONFIG_BUILD_ARM64_UNCOMPRESSED_KERNEL=y CONFIG_KRYO_PMU_WORKAROUND=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -- GitLab From f87a5edc9c65fb75be5b6f0d08c6ed03587de040 Mon Sep 17 00:00:00 2001 From: Hareesh Gundu Date: Tue, 28 May 2019 15:23:49 +0530 Subject: [PATCH 0994/1121] msm: kgsl: Free up preemption buffers on ringbuffer close Ensure that all HW preemption related buffers gets freed up during ringbuffer close. Also move preemption buffers allocation from HW init to ringbuffer probe. Change-Id: Ia144a6a891e20deab9488d6cc49d7ffd32f0d1e4 Signed-off-by: Hareesh Gundu --- drivers/gpu/msm/adreno.c | 13 ------------- drivers/gpu/msm/adreno.h | 1 + drivers/gpu/msm/adreno_a5xx.c | 1 + drivers/gpu/msm/adreno_a5xx.h | 3 ++- drivers/gpu/msm/adreno_a5xx_preempt.c | 17 +++++++++++++---- drivers/gpu/msm/adreno_a6xx.c | 1 + drivers/gpu/msm/adreno_a6xx.h | 1 + drivers/gpu/msm/adreno_a6xx_preempt.c | 15 ++++++++++++--- drivers/gpu/msm/adreno_ringbuffer.c | 22 +++++++++++++++++++--- 9 files changed, 50 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index e30933ce93e6..bdc499bf937e 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -1761,19 +1761,6 @@ static int adreno_init(struct kgsl_device *device) } - if (nopreempt == false && - ADRENO_FEATURE(adreno_dev, ADRENO_PREEMPTION)) { - int r = 0; - - if (gpudev->preemption_init) - r = gpudev->preemption_init(adreno_dev); - - if (r == 0) - set_bit(ADRENO_DEVICE_PREEMPTION, &adreno_dev->priv); - else - WARN(1, "adreno: GPU preemption is disabled\n"); - } - return 0; } diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h index 5b1981e70fb5..69f7235decbf 100644 --- a/drivers/gpu/msm/adreno.h +++ b/drivers/gpu/msm/adreno.h @@ -1013,6 +1013,7 @@ struct adreno_gpudev { struct adreno_device *adreno_dev, unsigned int *cmds); int (*preemption_init)(struct adreno_device *); + void (*preemption_close)(struct adreno_device *); void (*preemption_schedule)(struct adreno_device *); int (*preemption_context_init)(struct kgsl_context *); void (*preemption_context_destroy)(struct kgsl_context *); diff --git a/drivers/gpu/msm/adreno_a5xx.c b/drivers/gpu/msm/adreno_a5xx.c index 100f34edf269..6570d84bfb8a 100644 --- a/drivers/gpu/msm/adreno_a5xx.c +++ b/drivers/gpu/msm/adreno_a5xx.c @@ -3642,6 +3642,7 @@ struct adreno_gpudev adreno_a5xx_gpudev = { .preemption_post_ibsubmit = a5xx_preemption_post_ibsubmit, .preemption_init = a5xx_preemption_init, + .preemption_close = a5xx_preemption_close, .preemption_schedule = a5xx_preemption_schedule, .enable_64bit = a5xx_enable_64bit, .clk_set_options = a5xx_clk_set_options, diff --git a/drivers/gpu/msm/adreno_a5xx.h b/drivers/gpu/msm/adreno_a5xx.h index 510eff2f94f2..08f56d6701f2 100644 --- a/drivers/gpu/msm/adreno_a5xx.h +++ b/drivers/gpu/msm/adreno_a5xx.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2017,2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -226,6 +226,7 @@ void a5xx_preemption_trigger(struct adreno_device *adreno_dev); void a5xx_preemption_schedule(struct adreno_device *adreno_dev); void a5xx_preemption_start(struct adreno_device *adreno_dev); int a5xx_preemption_init(struct adreno_device *adreno_dev); +void a5xx_preemption_close(struct adreno_device *adreno_dev); int a5xx_preemption_yield_enable(unsigned int *cmds); unsigned int a5xx_preemption_post_ibsubmit(struct adreno_device *adreno_dev, diff --git a/drivers/gpu/msm/adreno_a5xx_preempt.c b/drivers/gpu/msm/adreno_a5xx_preempt.c index d5da56261d39..cb7a65f92135 100644 --- a/drivers/gpu/msm/adreno_a5xx_preempt.c +++ b/drivers/gpu/msm/adreno_a5xx_preempt.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2017,2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -567,9 +567,9 @@ static void a5xx_preemption_iommu_close(struct adreno_device *adreno_dev) } #endif -static void a5xx_preemption_close(struct kgsl_device *device) +static void _preemption_close(struct adreno_device *adreno_dev) { - struct adreno_device *adreno_dev = ADRENO_DEVICE(device); + struct kgsl_device *device = KGSL_DEVICE(adreno_dev); struct adreno_preemption *preempt = &adreno_dev->preempt; struct adreno_ringbuffer *rb; unsigned int i; @@ -583,6 +583,15 @@ static void a5xx_preemption_close(struct kgsl_device *device) } } +void a5xx_preemption_close(struct adreno_device *adreno_dev) +{ + if (!test_bit(ADRENO_DEVICE_PREEMPTION, &adreno_dev->priv)) + return; + + _preemption_close(adreno_dev); +} + + int a5xx_preemption_init(struct adreno_device *adreno_dev) { struct kgsl_device *device = KGSL_DEVICE(adreno_dev); @@ -624,7 +633,7 @@ int a5xx_preemption_init(struct adreno_device *adreno_dev) err: if (ret) - a5xx_preemption_close(device); + _preemption_close(adreno_dev); return ret; } diff --git a/drivers/gpu/msm/adreno_a6xx.c b/drivers/gpu/msm/adreno_a6xx.c index dc304037a240..0724bda629e0 100644 --- a/drivers/gpu/msm/adreno_a6xx.c +++ b/drivers/gpu/msm/adreno_a6xx.c @@ -3341,6 +3341,7 @@ struct adreno_gpudev adreno_a6xx_gpudev = { .preemption_pre_ibsubmit = a6xx_preemption_pre_ibsubmit, .preemption_post_ibsubmit = a6xx_preemption_post_ibsubmit, .preemption_init = a6xx_preemption_init, + .preemption_close = a6xx_preemption_close, .preemption_schedule = a6xx_preemption_schedule, .set_marker = a6xx_set_marker, .preemption_context_init = a6xx_preemption_context_init, diff --git a/drivers/gpu/msm/adreno_a6xx.h b/drivers/gpu/msm/adreno_a6xx.h index f2869b6bc4fe..bd1b916b638a 100644 --- a/drivers/gpu/msm/adreno_a6xx.h +++ b/drivers/gpu/msm/adreno_a6xx.h @@ -173,6 +173,7 @@ void a6xx_preemption_trigger(struct adreno_device *adreno_dev); void a6xx_preemption_schedule(struct adreno_device *adreno_dev); void a6xx_preemption_start(struct adreno_device *adreno_dev); int a6xx_preemption_init(struct adreno_device *adreno_dev); +void a6xx_preemption_close(struct adreno_device *adreno_dev); unsigned int a6xx_preemption_post_ibsubmit(struct adreno_device *adreno_dev, unsigned int *cmds); diff --git a/drivers/gpu/msm/adreno_a6xx_preempt.c b/drivers/gpu/msm/adreno_a6xx_preempt.c index 53e2a1afaecd..651306eb0ea5 100644 --- a/drivers/gpu/msm/adreno_a6xx_preempt.c +++ b/drivers/gpu/msm/adreno_a6xx_preempt.c @@ -694,9 +694,9 @@ static void a6xx_preemption_iommu_close(struct adreno_device *adreno_dev) } #endif -static void a6xx_preemption_close(struct kgsl_device *device) +static void _preemption_close(struct adreno_device *adreno_dev) { - struct adreno_device *adreno_dev = ADRENO_DEVICE(device); + struct kgsl_device *device = KGSL_DEVICE(adreno_dev); struct adreno_preemption *preempt = &adreno_dev->preempt; struct adreno_ringbuffer *rb; unsigned int i; @@ -714,6 +714,15 @@ static void a6xx_preemption_close(struct kgsl_device *device) } } +void a6xx_preemption_close(struct adreno_device *adreno_dev) +{ + if (!test_bit(ADRENO_DEVICE_PREEMPTION, &adreno_dev->priv)) + return; + + _preemption_close(adreno_dev); +} + + int a6xx_preemption_init(struct adreno_device *adreno_dev) { struct kgsl_device *device = KGSL_DEVICE(adreno_dev); @@ -755,7 +764,7 @@ int a6xx_preemption_init(struct adreno_device *adreno_dev) err: if (ret) - a6xx_preemption_close(device); + _preemption_close(adreno_dev); return ret; } diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c index d791ee485736..41d993362a8b 100644 --- a/drivers/gpu/msm/adreno_ringbuffer.c +++ b/drivers/gpu/msm/adreno_ringbuffer.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2002,2007-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2002,2007-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -317,7 +317,7 @@ int adreno_ringbuffer_probe(struct adreno_device *adreno_dev, bool nopreempt) { struct kgsl_device *device = KGSL_DEVICE(adreno_dev); struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev); - int i; + int i, r = 0; int status = -ENOMEM; if (!adreno_is_a3xx(adreno_dev)) { @@ -338,6 +338,19 @@ int adreno_ringbuffer_probe(struct adreno_device *adreno_dev, bool nopreempt) break; } + if (!status && (nopreempt == false) && + ADRENO_FEATURE(adreno_dev, ADRENO_PREEMPTION)) { + + if (gpudev->preemption_init) + r = gpudev->preemption_init(adreno_dev); + + if (r == 0) + set_bit(ADRENO_DEVICE_PREEMPTION, &adreno_dev->priv); + else + WARN(1, "adreno: GPU preemption is disabled\n"); + + } + if (status) adreno_ringbuffer_close(adreno_dev); else @@ -352,7 +365,6 @@ static void _adreno_ringbuffer_close(struct adreno_device *adreno_dev, struct kgsl_device *device = KGSL_DEVICE(adreno_dev); kgsl_free_global(device, &rb->pagetable_desc); - kgsl_free_global(device, &rb->preemption_desc); kgsl_free_global(device, &rb->buffer_desc); kgsl_del_event_group(&rb->events); @@ -362,6 +374,7 @@ static void _adreno_ringbuffer_close(struct adreno_device *adreno_dev, void adreno_ringbuffer_close(struct adreno_device *adreno_dev) { struct kgsl_device *device = KGSL_DEVICE(adreno_dev); + struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev); struct adreno_ringbuffer *rb; int i; @@ -370,6 +383,9 @@ void adreno_ringbuffer_close(struct adreno_device *adreno_dev) FOR_EACH_RINGBUFFER(adreno_dev, rb, i) _adreno_ringbuffer_close(adreno_dev, rb); + + if (gpudev->preemption_close) + gpudev->preemption_close(adreno_dev); } /* -- GitLab From 5f3fe471f4f3183b5da7dbbd4fbcd088bdaabdd3 Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Tue, 23 Jul 2019 22:20:05 -0700 Subject: [PATCH 0995/1121] ARM: dts: msm: Update IRQs for APPS SMMU on SA8195 virtual machine Provide additional IRQs that are used by the APPS SMMU on the SA8195 virtual machine target. Change-Id: I5e4a91dfe5015038c56ff1921fd17efd1347a885 Signed-off-by: Anant Goel --- arch/arm64/boot/dts/qcom/sa8195-vm.dtsi | 50 ++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sa8195-vm.dtsi b/arch/arm64/boot/dts/qcom/sa8195-vm.dtsi index 12c910533271..1999ff8668b2 100644 --- a/arch/arm64/boot/dts/qcom/sa8195-vm.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8195-vm.dtsi @@ -136,7 +136,55 @@ , , , - ; + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; status = "disabled"; }; -- GitLab From 78c14fcb6e86032b1f15ca9a908ebcf95e83ab8f Mon Sep 17 00:00:00 2001 From: Anmolpreet Kaur Date: Wed, 24 Jul 2019 13:14:37 +0530 Subject: [PATCH 0996/1121] ARM: dts: msm: Add qseecom node and heap for atoll Add qseecom driver node to enable the qseecom driver to communicate with trustzone.The qseecom heap and the qseecom_ta heap will be used by qseecom userspace library for allocating memory for loading trusted applications. Change-Id: I5c676a57ccb22017ab98d02d5f2caf32f4c7fe9c Signed-off-by: Anmolpreet Kaur --- arch/arm64/boot/dts/qcom/atoll-ion.dtsi | 6 ++++++ arch/arm64/boot/dts/qcom/atoll.dtsi | 24 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/atoll-ion.dtsi b/arch/arm64/boot/dts/qcom/atoll-ion.dtsi index fa7262d64552..a8835f67e78b 100644 --- a/arch/arm64/boot/dts/qcom/atoll-ion.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll-ion.dtsi @@ -27,6 +27,12 @@ qcom,ion-heap-type = "DMA"; }; + qcom,ion-heap@19 { /* QSEECOM TA HEAP */ + reg = <19>; + memory-region = <&qseecom_ta_mem>; + qcom,ion-heap-type = "DMA"; + }; + qcom,ion-heap@9 { reg = <9>; qcom,ion-heap-type = "SYSTEM_SECURE"; diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index ef8f9ebafa09..7f1f8665e2da 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -573,6 +573,13 @@ reg = <0 0x9e000000 0 0x1400000>; }; + qseecom_ta_mem: qseecom_ta_region@0 { + compatible = "shared-dma-pool"; + reusable; + alignment = <0x400000>; + size = <0x1000000>; + }; + cdsp_sec_mem: cdsp_sec_regions@0x9f400000 { compatible = "removed-dma-pool"; no-map; @@ -867,6 +874,23 @@ reg-names = "pshold-base", "tcsr-boot-misc-detect"; }; + qcom_seecom: qseecom@82200000 { + compatible = "qcom,qseecom"; + reg = <0x82200000 0x2200000>; + reg-names = "secapp-region"; + memory-region = <&qseecom_mem>; + qcom,hlos-num-ce-hw-instances = <1>; + qcom,hlos-ce-hw-instance = <0>; + qcom,qsee-ce-hw-instance = <0>; + qcom,disk-encrypt-pipe-pair = <2>; + qcom,support-fde; + qcom,no-clock-support; + qcom,fde-key-size; + qcom,appsbl-qseecom-support; + qcom,commonlib64-loaded-by-uefi; + qcom,qsee-reentrancy-support = <2>; + }; + aop-msg-client { compatible = "qcom,debugfs-qmp-client"; mboxes = <&qmp_aop 0>; -- GitLab From 7c5cb7ebff4d5739d928b0a0eb6be132bb946c12 Mon Sep 17 00:00:00 2001 From: Vijayavardhan Vennapusa Date: Mon, 22 Jul 2019 13:14:56 +0530 Subject: [PATCH 0997/1121] ARM: dts: msm: Enable lpm and modify boot option for QCS405 This will disable PCIe endpoint enumeration upon bootup. Change-Id: If124015d963f6b0ad5c7263bee4ed29fa8213f2a Signed-off-by: Vijayavardhan Vennapusa --- arch/arm64/boot/dts/qcom/qcs405-pcie.dtsi | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/qcs405-pcie.dtsi b/arch/arm64/boot/dts/qcom/qcs405-pcie.dtsi index 7ead59ebba67..b8fbb572f023 100644 --- a/arch/arm64/boot/dts/qcom/qcs405-pcie.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs405-pcie.dtsi @@ -81,13 +81,9 @@ qcom,phy-status-offset = <0x3c>; qcom,phy-status-bit = <0>; qcom,phy-power-down-offset = <0x98>; - qcom,boot-option = <0x0>; + qcom,boot-option = <0x1>; qcom,keep-powerdown-phy; - qcom,no-l0s-supported; - qcom,no-l1-supported; - qcom,no-l1ss-supported; - qcom,no-aux-clk-sync; linux,pci-domain = <0>; -- GitLab From 98bc8498263aba59462a10347576e8d54b2750cf Mon Sep 17 00:00:00 2001 From: Sahil Chandna Date: Wed, 24 Jul 2019 15:30:32 +0530 Subject: [PATCH 0998/1121] dt-bindings: qpnp-smb5: Add property to enable thermal mitigation Add DT properties to enable thermal mitigation for triple charging in CC mode. In thermal mitigation, thermal status of main charger, SMB, skin and connector are polled periodically and power supply change event is generated to notify userspace. Change-Id: I431605ea961796184c237ead127b628fe18f3e32 Signed-off-by: Sahil Chandna --- .../bindings/power/supply/qcom/qpnp-smb5.txt | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb5.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb5.txt index 23803b2992e0..f8f71c901761 100644 --- a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb5.txt +++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb5.txt @@ -306,6 +306,12 @@ Charger specific properties: Definition: Boolean flag which when present enables h/w based skin temperature mitigation. +- qcom,en-skin-therm-mitigation + Usage: optional + Value type: bool + Definition: Boolean flag which when present enables skin + thermal mitigation. + - qcom,connector-internal-pull-kohm Usage: optional Value type: @@ -313,6 +319,13 @@ Charger specific properties: connector THERM, only valid values are (0/30/100/400). If not specified 100K is used as default pull-up. +- qcom,smb-internal-pull-kohm + Usage: optional + Value type: + Definition: Specifies internal pull-up configuration to be applied to + smb THERM, only valid values are (0/30/100/400). + If not specified 100K is used as default pull-up. + - qcom,wd-snarl-time-config Usage: optional Value type: -- GitLab From 0329ffa07ebdf7836f67bf7e12cdf86a184598d0 Mon Sep 17 00:00:00 2001 From: Anmolpreet Kaur Date: Wed, 24 Jul 2019 17:22:28 +0530 Subject: [PATCH 0999/1121] ARM: dts: msm: Add the smcinvoke node for atoll Add the smcinvoke device tree node to communicate with TZ from HLOS for atoll. Change-Id: I47ab3ac82405080602c3ed7def50be0703034ddf Signed-off-by: Anmolpreet Kaur --- arch/arm64/boot/dts/qcom/atoll.dtsi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index 7f1f8665e2da..1c91386ef95b 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -891,6 +891,12 @@ qcom,qsee-reentrancy-support = <2>; }; + qcom_smcinvoke: smcinvoke@82200000 { + compatible = "qcom,smcinvoke"; + reg = <0x82200000 0x2200000>; + reg-names = "secapp-region"; + }; + aop-msg-client { compatible = "qcom,debugfs-qmp-client"; mboxes = <&qmp_aop 0>; -- GitLab From c2624262fd588d1ab335c1c429d2d9502fc26244 Mon Sep 17 00:00:00 2001 From: Manaf Meethalavalappu Pallikunhi Date: Fri, 19 Jul 2019 15:12:39 +0530 Subject: [PATCH 1000/1121] dt-bindings: thermal: bcl: Update the interrupt name for bclv5 BCL driver supports a different set of interrupt names depicting the mitigation levels instead of voltage and current violations. Change-Id: I30c20576c81bc1215314244f3842aff672e9ca5f Signed-off-by: Manaf Meethalavalappu Pallikunhi --- .../devicetree/bindings/thermal/qcom-bcl-pmic5.txt | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/Documentation/devicetree/bindings/thermal/qcom-bcl-pmic5.txt b/Documentation/devicetree/bindings/thermal/qcom-bcl-pmic5.txt index 82da01868532..8e5ba1b7e914 100644 --- a/Documentation/devicetree/bindings/thermal/qcom-bcl-pmic5.txt +++ b/Documentation/devicetree/bindings/thermal/qcom-bcl-pmic5.txt @@ -26,11 +26,9 @@ Required Parameters: interrupt names will be used by the drivers to identify the interrupts, instead of specifying the ID's. bcl driver will accept these standard interrupts. - "bcl-ibat-lvl0", - "bcl-ibat-lvl1", - "bcl-vbat-lvl0", - "bcl-vbat-lvl1", - "bcl-vbat-lvl2", + "bcl-lvl0", + "bcl-lvl1", + "bcl-lvl2", Optional Parameters: - qcom,ibat-use-qg-adc-5a: This optional property is used to divide Ibat @@ -44,7 +42,7 @@ Example: reg = <0x4200 0x100>; interrupts = <0x2 0x42 0x0 IRQ_TYPE_NONE>, <0x2 0x42 0x1 IRQ_TYPE_NONE>; - interrupt-names = "bcl-ibat-lvl0", - "bcl-vbat-lvl0"; + interrupt-names = "bcl-lvl0", + "bcl-lvl1"; qcom,ibat-use-qg-adc-5a; }; -- GitLab From 1b7b584acde8d23b2e4edc5081f611965c37a1a7 Mon Sep 17 00:00:00 2001 From: Subash Abhinov Kasiviswanathan Date: Thu, 28 Feb 2019 14:55:02 -0700 Subject: [PATCH 1001/1121] soc: qcom: dfc: Traffic control optimization Optimized data structures to avoid frequent list lookup and redundant flow control for dual IP calls. Supports using skb mark for tx queue assignment. Change-Id: I94d8ee6bf30778ad8e4eb0cfeacf7c18267d20da Acked-by: Weiyi Chen Signed-off-by: Subash Abhinov Kasiviswanathan --- drivers/soc/qcom/dfc_qmi.c | 59 +++++------ drivers/soc/qcom/qmi_rmnet.c | 174 +++++++++++++++++++++------------ drivers/soc/qcom/qmi_rmnet_i.h | 33 ++++--- include/trace/events/dfc.h | 25 ++--- 4 files changed, 173 insertions(+), 118 deletions(-) diff --git a/drivers/soc/qcom/dfc_qmi.c b/drivers/soc/qcom/dfc_qmi.c index 75c71590ce0f..e269f7eaed7a 100644 --- a/drivers/soc/qcom/dfc_qmi.c +++ b/drivers/soc/qcom/dfc_qmi.c @@ -26,8 +26,6 @@ #define DFC_IS_TCP_BIDIR(r) (bool)((r) & DFC_MASK_TCP_BIDIR) #define DFC_IS_RAT_SWITCH(r) (bool)((r) & DFC_MASK_RAT_SWITCH) -#define DFC_IS_ANCILLARY(type) ((type) != AF_INET && (type) != AF_INET6) - #define DFC_MAX_QOS_ID_V01 2 #define DFC_ACK_TYPE_DISABLE 1 @@ -996,26 +994,23 @@ int dfc_bearer_flow_ctl(struct net_device *dev, struct rmnet_bearer_map *bearer, struct qos_info *qos) { - struct rmnet_flow_map *itm; int rc = 0, qlen; int enable; + int i; enable = bearer->grant_size ? 1 : 0; - list_for_each_entry(itm, &qos->flow_head, list) { - if (itm->bearer_id == bearer->bearer_id) { - /* - * Do not flow disable ancillary q if ancillary is true - */ - if (bearer->tcp_bidir && enable == 0 && - DFC_IS_ANCILLARY(itm->ip_type)) + for (i = 0; i < MAX_MQ_NUM; i++) { + if (qos->mq[i].bearer == bearer) { + /* Do not flow disable ancillary q in tcp bidir */ + if (qos->mq[i].ancillary && + bearer->tcp_bidir && !enable) continue; - qlen = qmi_rmnet_flow_control(dev, itm->tcm_handle, - enable); - trace_dfc_qmi_tc(dev->name, itm->bearer_id, - itm->flow_id, bearer->grant_size, - qlen, itm->tcm_handle, enable); + qlen = qmi_rmnet_flow_control(dev, i, enable); + trace_dfc_qmi_tc(dev->name, bearer->bearer_id, + bearer->grant_size, + qlen, i, enable); rc++; } } @@ -1033,9 +1028,9 @@ static int dfc_all_bearer_flow_ctl(struct net_device *dev, struct dfc_flow_status_info_type_v01 *fc_info) { struct rmnet_bearer_map *bearer_itm; - struct rmnet_flow_map *flow_itm; int rc = 0, qlen; bool enable; + int i; enable = fc_info->num_bytes > 0 ? 1 : 0; @@ -1050,12 +1045,14 @@ static int dfc_all_bearer_flow_ctl(struct net_device *dev, bearer_itm->last_seq = fc_info->seq_num; } - list_for_each_entry(flow_itm, &qos->flow_head, list) { - qlen = qmi_rmnet_flow_control(dev, flow_itm->tcm_handle, - enable); - trace_dfc_qmi_tc(dev->name, flow_itm->bearer_id, - flow_itm->flow_id, fc_info->num_bytes, - qlen, flow_itm->tcm_handle, enable); + for (i = 0; i < MAX_MQ_NUM; i++) { + bearer_itm = qos->mq[i].bearer; + if (!bearer_itm) + continue; + qlen = qmi_rmnet_flow_control(dev, i, enable); + trace_dfc_qmi_tc(dev->name, bearer_itm->bearer_id, + fc_info->num_bytes, + qlen, i, enable); rc++; } @@ -1519,22 +1516,28 @@ void dfc_qmi_client_exit(void *dfc_data) void dfc_qmi_burst_check(struct net_device *dev, struct qos_info *qos, int ip_type, u32 mark, unsigned int len) { - struct rmnet_bearer_map *bearer; + struct rmnet_bearer_map *bearer = NULL; struct rmnet_flow_map *itm; u32 start_grant; spin_lock_bh(&qos->qos_lock); - itm = qmi_rmnet_get_flow_map(qos, mark, ip_type); - if (unlikely(!itm)) - goto out; + if (dfc_mode == DFC_MODE_MQ_NUM) { + /* Mark is mq num */ + if (likely(mark < MAX_MQ_NUM)) + bearer = qos->mq[mark].bearer; + } else { + /* Mark is flow_id */ + itm = qmi_rmnet_get_flow_map(qos, mark, ip_type); + if (likely(itm)) + bearer = itm->bearer; + } - bearer = qmi_rmnet_get_bearer_map(qos, itm->bearer_id); if (unlikely(!bearer)) goto out; trace_dfc_flow_check(dev->name, bearer->bearer_id, - len, bearer->grant_size); + len, mark, bearer->grant_size); if (!bearer->grant_size) goto out; diff --git a/drivers/soc/qcom/qmi_rmnet.c b/drivers/soc/qcom/qmi_rmnet.c index 4b35f8dfe3d5..6d867048d25b 100644 --- a/drivers/soc/qcom/qmi_rmnet.c +++ b/drivers/soc/qcom/qmi_rmnet.c @@ -31,7 +31,12 @@ #define FLAG_DFC_MASK 0x000F #define FLAG_POWERSAVE_MASK 0x0010 -#define DFC_MODE_MULTIQ 2 +#define FLAG_TO_MODE(f) ((f) & FLAG_DFC_MASK) +#define DFC_SUPPORTED_MODE(m) \ + ((m) == DFC_MODE_FLOW_ID || (m) == DFC_MODE_MQ_NUM) + +int dfc_mode; +#define IS_ANCILLARY(type) ((type) != AF_INET && (type) != AF_INET6) unsigned int rmnet_wq_frequency __read_mostly = 1000; module_param(rmnet_wq_frequency, uint, 0644); @@ -46,6 +51,10 @@ MODULE_PARM_DESC(rmnet_wq_frequency, "Frequency of PS check in ms"); static unsigned int qmi_rmnet_scale_factor = 5; #endif +static int +qmi_rmnet_del_flow(struct net_device *dev, struct tcmsg *tcm, + struct qmi_info *qmi); + struct qmi_elem_info data_ep_id_type_v01_ei[] = { { .data_type = QMI_SIGNED_4_BYTE_ENUM, @@ -83,7 +92,7 @@ void *qmi_rmnet_has_dfc_client(struct qmi_info *qmi) { int i; - if (!qmi || ((qmi->flag & FLAG_DFC_MASK) != DFC_MODE_MULTIQ)) + if (!qmi || !DFC_SUPPORTED_MODE(FLAG_TO_MODE(qmi->flag))) return NULL; for (i = 0; i < MAX_CLIENT_NUM; i++) { @@ -138,6 +147,8 @@ qmi_rmnet_clean_flow_list(struct qmi_info *qmi, struct net_device *dev, list_del(&bearer->list); kfree(bearer); } + + memset(qos->mq, 0, sizeof(qos->mq)); } struct rmnet_flow_map * @@ -176,17 +187,17 @@ static void qmi_rmnet_update_flow_map(struct rmnet_flow_map *itm, itm->bearer_id = new_map->bearer_id; itm->flow_id = new_map->flow_id; itm->ip_type = new_map->ip_type; - itm->tcm_handle = new_map->tcm_handle; + itm->mq_idx = new_map->mq_idx; } -int qmi_rmnet_flow_control(struct net_device *dev, u32 tcm_handle, int enable) +int qmi_rmnet_flow_control(struct net_device *dev, u32 mq_idx, int enable) { struct netdev_queue *q; - if (unlikely(tcm_handle >= dev->num_tx_queues)) + if (unlikely(mq_idx >= dev->num_tx_queues)) return 0; - q = netdev_get_tx_queue(dev, tcm_handle); + q = netdev_get_tx_queue(dev, mq_idx); if (unlikely(!q)) return 0; @@ -219,69 +230,92 @@ static int qmi_rmnet_add_flow(struct net_device *dev, struct tcmsg *tcm, struct qos_info *qos_info = (struct qos_info *)rmnet_get_qos_pt(dev); struct rmnet_flow_map new_map, *itm; struct rmnet_bearer_map *bearer; + struct tcmsg tmp_tcm; + struct mq_map *mq; + u32 mq_idx; - if (!qos_info) + if (!qos_info || !tcm || tcm->tcm_handle >= MAX_MQ_NUM) return -EINVAL; ASSERT_RTNL(); /* flow activate * tcm->tcm__pad1 - bearer_id, tcm->tcm_parent - flow_id, - * tcm->tcm_ifindex - ip_type, tcm->tcm_handle - tcm_handle + * tcm->tcm_ifindex - ip_type, tcm->tcm_handle - mq_idx */ new_map.bearer_id = tcm->tcm__pad1; new_map.flow_id = tcm->tcm_parent; new_map.ip_type = tcm->tcm_ifindex; - new_map.tcm_handle = tcm->tcm_handle; + new_map.mq_idx = tcm->tcm_handle; trace_dfc_flow_info(dev->name, new_map.bearer_id, new_map.flow_id, - new_map.ip_type, new_map.tcm_handle, 1); + new_map.ip_type, new_map.mq_idx, 1); +again: spin_lock_bh(&qos_info->qos_lock); itm = qmi_rmnet_get_flow_map(qos_info, new_map.flow_id, new_map.ip_type); if (itm) { - qmi_rmnet_update_flow_map(itm, &new_map); + pr_debug("%s: stale flow found\n", __func__); + tmp_tcm.tcm__pad1 = itm->bearer_id; + tmp_tcm.tcm_parent = itm->flow_id; + tmp_tcm.tcm_ifindex = itm->ip_type; + tmp_tcm.tcm_handle = itm->mq_idx; + spin_unlock_bh(&qos_info->qos_lock); + qmi_rmnet_del_flow(dev, &tmp_tcm, qmi); + goto again; + } + + /* Create flow map */ + itm = kzalloc(sizeof(*itm), GFP_ATOMIC); + if (!itm) { + spin_unlock_bh(&qos_info->qos_lock); + return -ENOMEM; + } + + qmi_rmnet_update_flow_map(itm, &new_map); + list_add(&itm->list, &qos_info->flow_head); + + /* Create or update bearer map */ + bearer = qmi_rmnet_get_bearer_map(qos_info, new_map.bearer_id); + if (bearer) { + bearer->flow_ref++; } else { - itm = kzalloc(sizeof(*itm), GFP_ATOMIC); - if (!itm) { + bearer = kzalloc(sizeof(*bearer), GFP_ATOMIC); + if (!bearer) { spin_unlock_bh(&qos_info->qos_lock); return -ENOMEM; } - qmi_rmnet_update_flow_map(itm, &new_map); - list_add(&itm->list, &qos_info->flow_head); - - bearer = qmi_rmnet_get_bearer_map(qos_info, new_map.bearer_id); - if (bearer) { - bearer->flow_ref++; - } else { - bearer = kzalloc(sizeof(*bearer), GFP_ATOMIC); - if (!bearer) { - spin_unlock_bh(&qos_info->qos_lock); - return -ENOMEM; - } - - bearer->bearer_id = new_map.bearer_id; - bearer->flow_ref = 1; - bearer->grant_size = qos_info->default_grant; - bearer->grant_thresh = - qmi_rmnet_grant_per(bearer->grant_size); - qos_info->default_grant = DEFAULT_GRANT; - list_add(&bearer->list, &qos_info->bearer_head); - } - - qmi_rmnet_flow_control(dev, itm->tcm_handle, - bearer->grant_size > 0 ? 1 : 0); - - trace_dfc_qmi_tc(dev->name, itm->bearer_id, itm->flow_id, - bearer->grant_size, 0, itm->tcm_handle, + bearer->bearer_id = new_map.bearer_id; + bearer->flow_ref = 1; + bearer->grant_size = qos_info->default_grant; + bearer->grant_thresh = qmi_rmnet_grant_per(bearer->grant_size); + qos_info->default_grant = DEFAULT_GRANT; + list_add(&bearer->list, &qos_info->bearer_head); + } + itm->bearer = bearer; + + /* Update mq map */ + mq_idx = tcm->tcm_handle; + mq = &qos_info->mq[mq_idx]; + if (!mq->bearer) { + mq->bearer = bearer; + mq->ancillary = IS_ANCILLARY(new_map.ip_type); + + qmi_rmnet_flow_control(dev, mq_idx, + bearer->grant_size > 0 ? 1 : 0); + trace_dfc_qmi_tc(dev->name, itm->bearer_id, + bearer->grant_size, 0, mq_idx, bearer->grant_size > 0 ? 1 : 0); + + } else if (mq->bearer->bearer_id != new_map.bearer_id) { + pr_debug("%s: un-managered bearer %u\n", + __func__, new_map.bearer_id); } spin_unlock_bh(&qos_info->qos_lock); - return 0; } @@ -292,6 +326,8 @@ qmi_rmnet_del_flow(struct net_device *dev, struct tcmsg *tcm, struct qos_info *qos_info = (struct qos_info *)rmnet_get_qos_pt(dev); struct rmnet_flow_map new_map, *itm; struct rmnet_bearer_map *bearer; + struct mq_map *mq; + u32 mq_idx; if (!qos_info) return -EINVAL; @@ -313,35 +349,38 @@ qmi_rmnet_del_flow(struct net_device *dev, struct tcmsg *tcm, if (itm) { trace_dfc_flow_info(dev->name, new_map.bearer_id, new_map.flow_id, new_map.ip_type, - itm->tcm_handle, 0); - list_del(&itm->list); + itm->mq_idx, 0); - /*clear bearer map*/ - bearer = qmi_rmnet_get_bearer_map(qos_info, new_map.bearer_id); + bearer = itm->bearer; if (bearer && --bearer->flow_ref == 0) { + /* Remove the bearer from mq map */ + for (mq_idx = 0; mq_idx < MAX_MQ_NUM; mq_idx++) { + mq = &qos_info->mq[mq_idx]; + if (mq->bearer != bearer) + continue; + + mq->bearer = NULL; + mq->ancillary = false; + qmi_rmnet_reset_txq(dev, mq_idx); + qmi_rmnet_flow_control(dev, mq_idx, 1); + trace_dfc_qmi_tc(dev->name, + new_map.bearer_id, 0, 0, mq_idx, 1); + } + + /* Remove from bearer map */ list_del(&bearer->list); kfree(bearer); - - /* Purge pending packets for dedicated flow */ - if (itm->flow_id) - qmi_rmnet_reset_txq(dev, itm->tcm_handle); } - /* Enable flow to allow new flow setup */ - qmi_rmnet_flow_control(dev, itm->tcm_handle, 1); - trace_dfc_qmi_tc(dev->name, itm->bearer_id, itm->flow_id, - 0, 0, itm->tcm_handle, 1); - + /* Remove from flow map */ + list_del(&itm->list); kfree(itm); } - if (list_empty(&qos_info->flow_head)) { + if (list_empty(&qos_info->flow_head)) netif_tx_wake_all_queues(dev); - trace_dfc_qmi_tc(dev->name, 0xFF, 0, DEFAULT_GRANT, 0, 0, 1); - } spin_unlock_bh(&qos_info->qos_lock); - return 0; } @@ -438,7 +477,7 @@ qmi_rmnet_setup_client(void *port, struct qmi_info *qmi, struct tcmsg *tcm) svc.ep_type = tcm->tcm_info; svc.iface_id = tcm->tcm_parent; - if (((tcm->tcm_ifindex & FLAG_DFC_MASK) == DFC_MODE_MULTIQ) && + if (DFC_SUPPORTED_MODE(FLAG_TO_MODE(tcm->tcm_ifindex)) && !qmi->dfc_clients[idx] && !qmi->dfc_pending[idx]) { rc = dfc_qmi_client_init(port, idx, &svc, qmi); if (rc < 0) @@ -515,20 +554,21 @@ void qmi_rmnet_change_link(struct net_device *dev, void *port, void *tcm_pt) switch (tcm->tcm_family) { case NLMSG_FLOW_ACTIVATE: - if (!qmi || ((qmi->flag & FLAG_DFC_MASK) != DFC_MODE_MULTIQ) || + if (!qmi || !DFC_SUPPORTED_MODE(FLAG_TO_MODE(qmi->flag)) || !qmi_rmnet_has_dfc_client(qmi)) return; qmi_rmnet_add_flow(dev, tcm, qmi); break; case NLMSG_FLOW_DEACTIVATE: - if (!qmi || ((qmi->flag & FLAG_DFC_MASK) != DFC_MODE_MULTIQ)) + if (!qmi || !DFC_SUPPORTED_MODE(FLAG_TO_MODE(qmi->flag))) return; qmi_rmnet_del_flow(dev, tcm, qmi); break; case NLMSG_CLIENT_SETUP: - if (((tcm->tcm_ifindex & FLAG_DFC_MASK) != DFC_MODE_MULTIQ) && + dfc_mode = FLAG_TO_MODE(tcm->tcm_ifindex); + if (!DFC_SUPPORTED_MODE(dfc_mode) && !(tcm->tcm_ifindex & FLAG_POWERSAVE_MASK)) return; @@ -673,6 +713,10 @@ int qmi_rmnet_get_queue(struct net_device *dev, struct sk_buff *skb) if (!qos) return 0; + /* If mark is mq num return it */ + if (dfc_mode == DFC_MODE_MQ_NUM) + return mark; + switch (skb->protocol) { /* TCPv4 ACKs */ case htons(ETH_P_IP): @@ -707,7 +751,7 @@ int qmi_rmnet_get_queue(struct net_device *dev, struct sk_buff *skb) if (unlikely(!itm)) goto done; - txq = itm->tcm_handle; + txq = itm->mq_idx; done: spin_unlock_bh(&qos->qos_lock); @@ -725,7 +769,7 @@ void *qmi_rmnet_qos_init(struct net_device *real_dev, u8 mux_id) { struct qos_info *qos; - qos = kmalloc(sizeof(*qos), GFP_KERNEL); + qos = kzalloc(sizeof(*qos), GFP_KERNEL); if (!qos) return NULL; @@ -952,7 +996,7 @@ void qmi_rmnet_work_init(void *port) rmnet_ps_wq = alloc_workqueue("rmnet_powersave_work", WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE, 1); - rmnet_work = kmalloc(sizeof(*rmnet_work), GFP_ATOMIC); + rmnet_work = kzalloc(sizeof(*rmnet_work), GFP_ATOMIC); if (!rmnet_work) { destroy_workqueue(rmnet_ps_wq); rmnet_ps_wq = NULL; diff --git a/drivers/soc/qcom/qmi_rmnet_i.h b/drivers/soc/qcom/qmi_rmnet_i.h index b24a6aa37c5c..b95c8a0ebd8f 100644 --- a/drivers/soc/qcom/qmi_rmnet_i.h +++ b/drivers/soc/qcom/qmi_rmnet_i.h @@ -20,18 +20,15 @@ #define IP_VER_4 4 #define IP_VER_6 6 +#define MAX_MQ_NUM 10 #define MAX_CLIENT_NUM 2 #define MAX_FLOW_NUM 32 #define DEFAULT_GRANT 1 #define DFC_MAX_BEARERS_V01 16 -struct rmnet_flow_map { - struct list_head list; - u8 bearer_id; - u32 flow_id; - int ip_type; - u32 tcm_handle; -}; +#define DFC_MODE_FLOW_ID 2 +#define DFC_MODE_MQ_NUM 3 +extern int dfc_mode; struct rmnet_bearer_map { struct list_head list; @@ -48,27 +45,37 @@ struct rmnet_bearer_map { bool tx_off; }; +struct rmnet_flow_map { + struct list_head list; + u8 bearer_id; + u32 flow_id; + int ip_type; + u32 mq_idx; + struct rmnet_bearer_map *bearer; +}; + struct svc_info { u32 instance; u32 ep_type; u32 iface_id; }; +struct mq_map { + struct rmnet_bearer_map *bearer; + bool ancillary; +}; + struct qos_info { u8 mux_id; struct net_device *real_dev; struct list_head flow_head; struct list_head bearer_head; + struct mq_map mq[MAX_MQ_NUM]; u32 default_grant; u32 tran_num; spinlock_t qos_lock; }; -struct flow_info { - struct net_device *dev; - struct rmnet_flow_map *itm; -}; - struct qmi_info { int flag; void *wda_client; @@ -119,7 +126,7 @@ void dfc_qmi_client_exit(void *dfc_data); void dfc_qmi_burst_check(struct net_device *dev, struct qos_info *qos, int ip_type, u32 mark, unsigned int len); -int qmi_rmnet_flow_control(struct net_device *dev, u32 tcm_handle, int enable); +int qmi_rmnet_flow_control(struct net_device *dev, u32 mq_idx, int enable); void dfc_qmi_query_flow(void *dfc_data); diff --git a/include/trace/events/dfc.h b/include/trace/events/dfc.h index 70eec100c2e3..28810f781fc2 100644 --- a/include/trace/events/dfc.h +++ b/include/trace/events/dfc.h @@ -20,15 +20,14 @@ TRACE_EVENT(dfc_qmi_tc, - TP_PROTO(const char *name, u8 bearer_id, u32 flow_id, u32 grant, + TP_PROTO(const char *name, u8 bearer_id, u32 grant, int qlen, u32 tcm_handle, int enable), - TP_ARGS(name, bearer_id, flow_id, grant, qlen, tcm_handle, enable), + TP_ARGS(name, bearer_id, grant, qlen, tcm_handle, enable), TP_STRUCT__entry( __string(dev_name, name) __field(u8, bid) - __field(u32, fid) __field(u32, grant) __field(int, qlen) __field(u32, tcm_handle) @@ -38,16 +37,15 @@ TRACE_EVENT(dfc_qmi_tc, TP_fast_assign( __assign_str(dev_name, name); __entry->bid = bearer_id; - __entry->fid = flow_id; __entry->grant = grant; __entry->qlen = qlen; __entry->tcm_handle = tcm_handle; __entry->enable = enable; ), - TP_printk("dev=%s bearer_id=%u grant=%u len=%d flow_id=%u q=%d %s", + TP_printk("dev=%s bearer_id=%u grant=%u len=%d mq=%u %s", __get_str(dev_name), - __entry->bid, __entry->grant, __entry->qlen, __entry->fid, + __entry->bid, __entry->grant, __entry->qlen, __entry->tcm_handle, __entry->enable ? "enable" : "disable") ); @@ -90,14 +88,16 @@ TRACE_EVENT(dfc_flow_ind, TRACE_EVENT(dfc_flow_check, - TP_PROTO(const char *name, u8 bearer_id, unsigned int len, u32 grant), + TP_PROTO(const char *name, u8 bearer_id, unsigned int len, + u32 mark, u32 grant), - TP_ARGS(name, bearer_id, len, grant), + TP_ARGS(name, bearer_id, len, mark, grant), TP_STRUCT__entry( __string(dev_name, name) __field(u8, bearer_id) __field(unsigned int, len) + __field(u32, mark) __field(u32, grant) ), @@ -105,12 +105,13 @@ TRACE_EVENT(dfc_flow_check, __assign_str(dev_name, name) __entry->bearer_id = bearer_id; __entry->len = len; + __entry->mark = mark; __entry->grant = grant; ), - TP_printk("dev=%s bearer_id=%u skb_len=%u current_grant=%u", - __get_str(dev_name), - __entry->bearer_id, __entry->len, __entry->grant) + TP_printk("dev=%s bearer_id=%u skb_len=%u mark=%u current_grant=%u", + __get_str(dev_name), __entry->bearer_id, + __entry->len, __entry->mark, __entry->grant) ); TRACE_EVENT(dfc_flow_info, @@ -138,7 +139,7 @@ TRACE_EVENT(dfc_flow_info, __entry->action = add; ), - TP_printk("%s: dev=%s bearer_id=%u flow_id=%u ip_type=%d q=%d", + TP_printk("%s: dev=%s bearer_id=%u flow_id=%u ip_type=%d mq=%d", __entry->action ? "add flow" : "delete flow", __get_str(dev_name), __entry->bid, __entry->fid, __entry->ip, __entry->handle) -- GitLab From 437d40b8466a77737cc13e5c1ff318cfc86de832 Mon Sep 17 00:00:00 2001 From: Sujeev Dias Date: Thu, 11 Jul 2019 15:45:57 -0700 Subject: [PATCH 1002/1121] ARM: dts: re-enable mhi boot logger channel for sm8150-sdxprairie Boot logger channel was disabled temporarily for sm8150-sdxprairie. Re-enabling the channel with memory reduction on both host and device. CRs-Fixed: 2488498 Change-Id: I9a4950a07cd1f03d46c965682f48d436090d9013 Acked-by: Bhaumik Vasav Bhatt Signed-off-by: Sujeev Dias --- arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi b/arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi index 0089c7edd887..403d2a86556d 100644 --- a/arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi @@ -42,7 +42,8 @@ }; mhi_chan@25 { - status = "disabled"; + mhi,num-elements = <32>; + mhi,event-ring = <1>; }; mhi_chan@80 { -- GitLab From a506692d2e674156cb6dff8b9d8dd45d85f7273b Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Tue, 23 Jul 2019 16:01:40 -0700 Subject: [PATCH 1003/1121] ARM: dts: msm: Update status fields for PIL nodes on SA8195P ADP STAR Update the PIL nodes to enable or disable PIL subsystems, and the drivers which load them, for the SA8195P ADP STAR target. Change-Id: I9caa5b8b6db17e1c59ca3072a0b441d456bac82d Signed-off-by: Anant Goel --- .../arm64/boot/dts/qcom/sa8195p-adp-star.dtsi | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sa8195p-adp-star.dtsi b/arch/arm64/boot/dts/qcom/sa8195p-adp-star.dtsi index 31187172cde3..f54520033f94 100644 --- a/arch/arm64/boot/dts/qcom/sa8195p-adp-star.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8195p-adp-star.dtsi @@ -54,3 +54,35 @@ status = "ok"; }; + +&pil_lpass { + status = "ok"; +}; + +&pil_ssc { + status = "disabled"; +}; + +&pil_spss { + status = "ok"; +}; + +&pil_turing { + status = "ok"; +}; + +&pil_venus { + status = "ok"; +}; + +&pil_npu { + status = "ok"; +}; + +&glink_modem { + status = "disabled"; +}; + +&ssc_sensors { + status = "disabled"; +}; -- GitLab From db8206e636d7642c400419ddf2d4e2cb15855a77 Mon Sep 17 00:00:00 2001 From: Tony Truong Date: Thu, 13 Jun 2019 17:57:47 -0700 Subject: [PATCH 1004/1121] msm: msi: update SNPS MSI mask and unmask based on PCIe LPM Synopsys MSI registers are part of PCIe core controller. To prevent unclock accesses during PCIe low power mode, provide PCIe core driver the ability to control when MSI driver can access the registers. Whenever clients disable/mask SNPS MSI, update only the S/W mask and do the actual masking next time the IRQ is received. Change-Id: Iea4da81002239aac07bcc6f06444ece44e9019af Signed-off-by: Tony Truong --- drivers/pci/host/pci-msm-msi.c | 76 +++++++++++++++++++++++++--------- include/linux/msm_pcie.h | 5 +++ 2 files changed, 62 insertions(+), 19 deletions(-) diff --git a/drivers/pci/host/pci-msm-msi.c b/drivers/pci/host/pci-msm-msi.c index 2e7e95d666fc..a09e4fd0bd96 100644 --- a/drivers/pci/host/pci-msm-msi.c +++ b/drivers/pci/host/pci-msm-msi.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -56,7 +57,6 @@ struct msm_msi_grp { void __iomem *int_mask_reg; void __iomem *int_status_reg; u32 mask; /* tracks masked/unmasked MSI */ - spinlock_t cfg_lock; /* lock for configuring Synopsys MSI registers */ struct msm_msi_irq irqs[MSI_IRQ_PER_GRP]; }; @@ -75,6 +75,8 @@ struct msm_msi { struct irq_domain *msi_domain; /* child domain; pci related */ phys_addr_t msi_addr; enum msi_type type; + spinlock_t cfg_lock; /* lock for configuring Synopsys MSI registers */ + bool cfg_access; /* control access to Synopsys MSI registers */ void __iomem *pcie_cfg; void (*mask_irq)(struct irq_data *data); @@ -94,9 +96,6 @@ static void msm_msi_snps_handler(struct irq_desc *desc) { struct irq_chip *chip = irq_desc_get_chip(desc); struct msm_msi *msi; - struct msm_msi_grp *msi_grp; - unsigned long val = 0; - u32 index; int i; chained_irq_enter(chip, desc); @@ -104,12 +103,25 @@ static void msm_msi_snps_handler(struct irq_desc *desc) msi = irq_desc_get_handler_data(desc); for (i = 0; i < msi->nr_grps; i++) { - msi_grp = &msi->grps[i]; - val = readl_relaxed(msi_grp->int_status_reg); - writel_relaxed(val, msi_grp->int_status_reg); + struct msm_msi_grp *msi_grp = &msi->grps[i]; + u32 mask = msi_grp->mask; + u32 status; + u32 index; + + status = readl_relaxed(msi_grp->int_status_reg); + if (!status) + continue; + + /* always update the mask set in msm_msi_snps_mask_irq */ + mask = msi_grp->mask; + writel_relaxed(mask, msi_grp->int_mask_reg); + + /* process only interrupts which are not masked */ + status ^= (status & mask); + writel_relaxed(status, msi_grp->int_status_reg); - for (index = 0; val; index++, val >>= 1) - if (val & 0x1) + for (index = 0; status; index++, status >>= 1) + if (status & 0x1) generic_handle_irq(msi_grp->irqs[index].virq); } @@ -136,12 +148,12 @@ static void msm_msi_snps_mask_irq(struct irq_data *data) { struct msm_msi_irq *msi_irq = irq_data_get_irq_chip_data(data); struct msm_msi_grp *msi_grp = msi_irq->grp; + struct msm_msi *msi = msi_irq->client->msi; unsigned long flags; - spin_lock_irqsave(&msi_grp->cfg_lock, flags); + spin_lock_irqsave(&msi->cfg_lock, flags); msi_grp->mask |= BIT(msi_irq->grp_index); - writel_relaxed(msi_grp->mask, msi_grp->int_mask_reg); - spin_unlock_irqrestore(&msi_grp->cfg_lock, flags); + spin_unlock_irqrestore(&msi->cfg_lock, flags); } static void msm_msi_qgic_mask_irq(struct irq_data *data) @@ -176,12 +188,16 @@ static void msm_msi_snps_unmask_irq(struct irq_data *data) { struct msm_msi_irq *msi_irq = irq_data_get_irq_chip_data(data); struct msm_msi_grp *msi_grp = msi_irq->grp; + struct msm_msi *msi = msi_irq->client->msi; unsigned long flags; - spin_lock_irqsave(&msi_grp->cfg_lock, flags); + spin_lock_irqsave(&msi->cfg_lock, flags); + msi_grp->mask &= ~BIT(msi_irq->grp_index); - writel_relaxed(msi_grp->mask, msi_grp->int_mask_reg); - spin_unlock_irqrestore(&msi_grp->cfg_lock, flags); + if (msi->cfg_access) + writel_relaxed(msi_grp->mask, msi_grp->int_mask_reg); + + spin_unlock_irqrestore(&msi->cfg_lock, flags); } static void msm_msi_qgic_unmask_irq(struct irq_data *data) @@ -457,6 +473,21 @@ static int msm_msi_alloc_domains(struct msm_msi *msi) return 0; } +/* control access to Synopsys PCIe MSI registers */ +void msm_msi_config_access(struct irq_domain *domain, bool allow) +{ + struct msm_msi *msi = domain->parent->host_data; + unsigned long flags; + + if (msi->type == MSM_MSI_TYPE_QCOM) + return; + + spin_lock_irqsave(&msi->cfg_lock, flags); + msi->cfg_access = allow; + spin_unlock_irqrestore(&msi->cfg_lock, flags); +} +EXPORT_SYMBOL(msm_msi_config_access); + /* configure Synopsys PCIe MSI registers */ void msm_msi_config(struct irq_domain *domain) { @@ -467,13 +498,20 @@ void msm_msi_config(struct irq_domain *domain) if (msi->type == MSM_MSI_TYPE_QCOM) return; + /* PCIe core driver sets to false during LPM */ + msm_msi_config_access(domain, true); + /* program MSI termination address */ writel_relaxed(msi->msi_addr, msi->pcie_cfg + PCIE_MSI_CTRL_ADDR_OFFS); writel_relaxed(0, msi->pcie_cfg + PCIE_MSI_CTRL_UPPER_ADDR_OFFS); - /* enable all interrupts for each group */ - for (i = 0; i < msi->nr_grps; i++) - writel_relaxed(~0, msi->grps[i].int_en_reg); + /* restore mask and enable all interrupts for each group */ + for (i = 0; i < msi->nr_grps; i++) { + struct msm_msi_grp *msi_grp = &msi->grps[i]; + + writel_relaxed(msi_grp->mask, msi_grp->int_mask_reg); + writel_relaxed(~0, msi_grp->int_en_reg); + } } EXPORT_SYMBOL(msm_msi_config); @@ -514,6 +552,7 @@ int msm_msi_init(struct device *dev) msi->dev = dev; msi->of_node = of_node; mutex_init(&msi->mutex); + spin_lock_init(&msi->cfg_lock); INIT_LIST_HEAD(&msi->clients); prop_val = of_get_address(msi->of_node, 0, NULL, NULL); @@ -613,7 +652,6 @@ int msm_msi_init(struct device *dev) for (i = 0; i < msi->nr_grps; i++) { msi_grp = &msi->grps[i]; - spin_lock_init(&msi_grp->cfg_lock); msi_grp->int_en_reg = msi->pcie_cfg + PCIE_MSI_CTRL_INT_N_EN_OFFS(i); msi_grp->int_mask_reg = msi->pcie_cfg + diff --git a/include/linux/msm_pcie.h b/include/linux/msm_pcie.h index aa89ae1e179c..58d4fb22733d 100644 --- a/include/linux/msm_pcie.h +++ b/include/linux/msm_pcie.h @@ -61,9 +61,14 @@ struct msm_pcie_register_event { }; #ifdef CONFIG_PCI_MSM_MSI +void msm_msi_config_access(struct irq_domain *domain, bool allow); void msm_msi_config(struct irq_domain *domain); int msm_msi_init(struct device *dev); #else +static inline void msm_msi_config_access(struct irq_domain *domain, bool allow) +{ +} + static inline void msm_msi_config(struct irq_domain *domain) { } -- GitLab From eac9c06e484c558b46b075afb25ba85431c73921 Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Wed, 10 Jul 2019 18:47:45 -0700 Subject: [PATCH 1005/1121] ARM: dts: msm: Add eSOC support for sdmshrike Add nodes to support external soc communication for the sdmshrike target. Change-Id: I59e209dbec4f20f068ad2fe8e67b183a2d263190 Signed-off-by: Anant Goel --- .../boot/dts/qcom/sdmshrike-pinctrl.dtsi | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdmshrike-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sdmshrike-pinctrl.dtsi index 36a98fc4fbc0..cbc0a8078a31 100644 --- a/arch/arm64/boot/dts/qcom/sdmshrike-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/sdmshrike-pinctrl.dtsi @@ -1819,6 +1819,77 @@ }; }; + ap2mdm { + ap2mdm_active: ap2mdm_active { + mux { + /* ap2mdm-status + * ap2mdm-errfatal + * ap2mdm-vddmin + */ + pins = "gpio135", "gpio139"; + function = "gpio"; + }; + + config { + pins = "gpio135", "gpio139"; + drive-strength = <16>; + bias-disable; + }; + }; + ap2mdm_sleep: ap2mdm_sleep { + mux { + /* ap2mdm-status + * ap2mdm-errfatal + * ap2mdm-vddmin + */ + pins = "gpio135", "gpio139"; + function = "gpio"; + }; + + config { + pins = "gpio135", "gpio139"; + drive-strength = <8>; + bias-disable; + }; + + }; + }; + + mdm2ap { + mdm2ap_active: mdm2ap_active { + mux { + /* mdm2ap-status + * mdm2ap-errfatal + * mdm2ap-vddmin + */ + pins = "gpio81", "gpio53"; + function = "gpio"; + }; + + config { + pins = "gpio81", "gpio53"; + drive-strength = <8>; + bias-disable; + }; + }; + mdm2ap_sleep: mdm2ap_sleep { + mux { + /* mdm2ap-status + * mdm2ap-errfatal + * mdm2ap-vddmin + */ + pins = "gpio81", "gpio53"; + function = "gpio"; + }; + + config { + pins = "gpio81", "gpio53"; + drive-strength = <8>; + bias-disable; + }; + }; + }; + cam_sensor_mclk0_active: cam_sensor_mclk0_active { /* MCLK0 */ mux { -- GitLab From 764689b3e8255251077ed55bbb201acb98fdda6a Mon Sep 17 00:00:00 2001 From: jiad Date: Fri, 5 Jul 2019 16:51:55 +0800 Subject: [PATCH 1006/1121] mhi: core: export symbols for references Export symbols for below three APIs. mhi_unprepare_after_power_down mhi_unregister_mhi_controller mhi_pm_resume. Change-Id: If5a447e77f04e40782b74fd75b31ea42ee706d6d Signed-off-by: jiad --- drivers/bus/mhi/core/mhi_init.c | 2 ++ drivers/bus/mhi/core/mhi_pm.c | 1 + 2 files changed, 3 insertions(+) diff --git a/drivers/bus/mhi/core/mhi_init.c b/drivers/bus/mhi/core/mhi_init.c index d070c5c773d8..da10001d560c 100644 --- a/drivers/bus/mhi/core/mhi_init.c +++ b/drivers/bus/mhi/core/mhi_init.c @@ -1366,6 +1366,7 @@ void mhi_unregister_mhi_controller(struct mhi_controller *mhi_cntrl) list_del(&mhi_cntrl->node); mutex_unlock(&mhi_bus.lock); } +EXPORT_SYMBOL(mhi_unregister_mhi_controller); /* set ptr to control private data */ static inline void mhi_controller_set_devdata(struct mhi_controller *mhi_cntrl, @@ -1466,6 +1467,7 @@ void mhi_unprepare_after_power_down(struct mhi_controller *mhi_cntrl) mhi_deinit_dev_ctxt(mhi_cntrl); mhi_cntrl->pre_init = false; } +EXPORT_SYMBOL(mhi_unprepare_after_power_down); /* match dev to drv */ static int mhi_match(struct device *dev, struct device_driver *drv) diff --git a/drivers/bus/mhi/core/mhi_pm.c b/drivers/bus/mhi/core/mhi_pm.c index 517645b0211b..93f642895ac0 100644 --- a/drivers/bus/mhi/core/mhi_pm.c +++ b/drivers/bus/mhi/core/mhi_pm.c @@ -1326,6 +1326,7 @@ int mhi_pm_fast_resume(struct mhi_controller *mhi_cntrl, bool notify_client) return 0; } +EXPORT_SYMBOL(mhi_pm_resume); int __mhi_device_get_sync(struct mhi_controller *mhi_cntrl) { -- GitLab From b88aaa3a17d7a8936f2d8cfcf1cc80af8715fbdb Mon Sep 17 00:00:00 2001 From: "Jinesh K. Jayakumar" Date: Wed, 24 Jul 2019 23:51:18 -0400 Subject: [PATCH 1007/1121] msm: ipa: Use correct VLAN header size in partial headers Fix IPA offload sub-system to use correct VLAN ethernet header size while registering partial headers with IPA driver. CRs-Fixed: 2496455 Change-Id: Iaf85a3d049c8b99062f9b242c705cb348bdea826 Signed-off-by: Jinesh K. Jayakumar --- drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_ep.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_ep.c b/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_ep.c index d497214e2193..72199565ffdc 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_ep.c +++ b/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_ep.c @@ -95,7 +95,7 @@ static void ipa_eth_init_vlan_header_v4(struct ipa_eth_device *eth_dev, eth_hdr.h_vlan_proto = htons(ETH_P_8021Q); eth_hdr.h_vlan_encapsulated_proto = htons(ETH_P_IP); - hdr_add->hdr_len = ETH_HLEN; + hdr_add->hdr_len = VLAN_ETH_HLEN; memcpy(hdr_add->hdr, ð_hdr, hdr_add->hdr_len); ipa_eth_init_header_common(eth_dev, hdr_add); @@ -113,7 +113,7 @@ static void ipa_eth_init_vlan_header_v6(struct ipa_eth_device *eth_dev, eth_hdr.h_vlan_proto = htons(ETH_P_8021Q); eth_hdr.h_vlan_encapsulated_proto = htons(ETH_P_IPV6); - hdr_add->hdr_len = ETH_HLEN; + hdr_add->hdr_len = VLAN_ETH_HLEN; memcpy(hdr_add->hdr, ð_hdr, hdr_add->hdr_len); ipa_eth_init_header_common(eth_dev, hdr_add); -- GitLab From 6687a60d3e691b0fb093bb575516646137b62b7a Mon Sep 17 00:00:00 2001 From: Sahil Chandna Date: Wed, 10 Jul 2019 11:00:28 +0530 Subject: [PATCH 1008/1121] power: smb5: Add support for thermal mitigation for CC Mode Add support for thermal mitigation for Triple charging in CC mode. Poll thermal status of charger, SMB, skin and connector periodically and generate a power supply event to notify user space to handle thermal mitigation. Change-Id: I4908cf2a148c017ba67ff6759640aac67c324406 Signed-off-by: Sahil Chandna --- drivers/power/supply/qcom/qpnp-smb5.c | 27 ++++++++++++++ drivers/power/supply/qcom/smb5-lib.c | 53 ++++++++++++++++++++++++++- drivers/power/supply/qcom/smb5-lib.h | 4 ++ drivers/power/supply/qcom/smb5-reg.h | 6 +++ 4 files changed, 89 insertions(+), 1 deletion(-) diff --git a/drivers/power/supply/qcom/qpnp-smb5.c b/drivers/power/supply/qcom/qpnp-smb5.c index ae931091fe2a..a5205a669a02 100644 --- a/drivers/power/supply/qcom/qpnp-smb5.c +++ b/drivers/power/supply/qcom/qpnp-smb5.c @@ -561,10 +561,17 @@ static int smb5_parse_dt(struct smb5 *chip) chg->hw_skin_temp_mitigation = of_property_read_bool(node, "qcom,hw-skin-temp-mitigation"); + chg->en_skin_therm_mitigation = of_property_read_bool(node, + "qcom,en-skin-therm-mitigation"); + chg->connector_pull_up = -EINVAL; of_property_read_u32(node, "qcom,connector-internal-pull-kohm", &chg->connector_pull_up); + chg->smb_pull_up = -EINVAL; + of_property_read_u32(node, "qcom,smb-internal-pull-kohm", + &chg->smb_pull_up); + chip->dt.adc_based_aicl = of_property_read_bool(node, "qcom,adc-based-aicl"); @@ -682,6 +689,7 @@ static enum power_supply_property smb5_usb_props[] = { POWER_SUPPLY_PROP_QC_OPTI_DISABLE, POWER_SUPPLY_PROP_VOLTAGE_VPH, POWER_SUPPLY_PROP_THERM_ICL_LIMIT, + POWER_SUPPLY_PROP_SKIN_HEALTH, }; static int smb5_usb_get_prop(struct power_supply *psy, @@ -856,6 +864,9 @@ static int smb5_usb_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_ADAPTER_CC_MODE: val->intval = chg->adapter_cc_mode; break; + case POWER_SUPPLY_PROP_SKIN_HEALTH: + val->intval = smblib_get_skin_temp_status(chg); + break; default: pr_err("get prop %d is not supported in usb\n", psp); rc = -EINVAL; @@ -1117,6 +1128,7 @@ static enum power_supply_property smb5_usb_main_props[] = { POWER_SUPPLY_PROP_FORCE_MAIN_FCC, POWER_SUPPLY_PROP_FORCE_MAIN_ICL, POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL, + POWER_SUPPLY_PROP_HEALTH, }; static int smb5_usb_main_get_prop(struct power_supply *psy, @@ -1176,6 +1188,10 @@ static int smb5_usb_main_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL: val->intval = chg->comp_clamp_level; break; + /* Use this property to report SMB health */ + case POWER_SUPPLY_PROP_HEALTH: + val->intval = smblib_get_prop_smb_health(chg); + break; default: pr_debug("get prop %d is not supported in usb-main\n", psp); rc = -EINVAL; @@ -2830,6 +2846,17 @@ static int smb5_init_hw(struct smb5 *chip) } } + if (chg->smb_pull_up != -EINVAL) { + rc = smb5_configure_internal_pull(chg, SMB_THERM, + get_valid_pullup(chg->smb_pull_up)); + if (rc < 0) { + dev_err(chg->dev, + "Couldn't configure SMB pull-up rc=%d\n", + rc); + return rc; + } + } + return rc; } diff --git a/drivers/power/supply/qcom/smb5-lib.c b/drivers/power/supply/qcom/smb5-lib.c index 0fb3ef0944f7..aac6b220f21d 100644 --- a/drivers/power/supply/qcom/smb5-lib.c +++ b/drivers/power/supply/qcom/smb5-lib.c @@ -3675,6 +3675,54 @@ int smblib_get_pe_start(struct smb_charger *chg, return 0; } +int smblib_get_prop_smb_health(struct smb_charger *chg) +{ + int rc; + u8 stat; + int input_present; + + rc = smblib_is_input_present(chg, &input_present); + if (rc < 0) + return rc; + + if (input_present == INPUT_NOT_PRESENT) + return POWER_SUPPLY_HEALTH_UNKNOWN; + + if (chg->wa_flags & SW_THERM_REGULATION_WA) { + if (chg->smb_temp == -ENODATA) + return POWER_SUPPLY_HEALTH_UNKNOWN; + + if (chg->smb_temp > SMB_TEMP_RST_THRESH) + return POWER_SUPPLY_HEALTH_OVERHEAT; + + if (chg->smb_temp > SMB_TEMP_REG_H_THRESH) + return POWER_SUPPLY_HEALTH_HOT; + + if (chg->smb_temp > SMB_TEMP_REG_L_THRESH) + return POWER_SUPPLY_HEALTH_WARM; + + return POWER_SUPPLY_HEALTH_COOL; + } + + rc = smblib_read(chg, SMB_TEMP_STATUS_REG, &stat); + if (rc < 0) { + smblib_err(chg, "Couldn't read SMB_TEMP_STATUS_REG, rc=%d\n", + rc); + return POWER_SUPPLY_HEALTH_UNKNOWN; + } + + if (stat & SMB_TEMP_RST_BIT) + return POWER_SUPPLY_HEALTH_OVERHEAT; + + if (stat & SMB_TEMP_UB_BIT) + return POWER_SUPPLY_HEALTH_HOT; + + if (stat & SMB_TEMP_LB_BIT) + return POWER_SUPPLY_HEALTH_WARM; + + return POWER_SUPPLY_HEALTH_COOL; +} + int smblib_get_prop_die_health(struct smb_charger *chg) { int rc; @@ -3763,11 +3811,14 @@ static int smblib_get_typec_connector_temp_status(struct smb_charger *chg) return POWER_SUPPLY_HEALTH_COOL; } -static int smblib_get_skin_temp_status(struct smb_charger *chg) +int smblib_get_skin_temp_status(struct smb_charger *chg) { int rc; u8 stat; + if (!chg->en_skin_therm_mitigation) + return POWER_SUPPLY_HEALTH_UNKNOWN; + rc = smblib_read(chg, SKIN_TEMP_STATUS_REG, &stat); if (rc < 0) { smblib_err(chg, "Couldn't read SKIN_TEMP_STATUS_REG, rc=%d\n", diff --git a/drivers/power/supply/qcom/smb5-lib.h b/drivers/power/supply/qcom/smb5-lib.h index 956c4425dd05..42ac64965924 100644 --- a/drivers/power/supply/qcom/smb5-lib.h +++ b/drivers/power/supply/qcom/smb5-lib.h @@ -531,7 +531,9 @@ struct smb_charger { bool hw_die_temp_mitigation; bool hw_connector_mitigation; bool hw_skin_temp_mitigation; + bool en_skin_therm_mitigation; int connector_pull_up; + int smb_pull_up; int aicl_5v_threshold_mv; int default_aicl_5v_threshold_mv; int aicl_cont_threshold_mv; @@ -718,7 +720,9 @@ int smblib_get_pe_start(struct smb_charger *chg, int smblib_get_prop_charger_temp(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_prop_die_health(struct smb_charger *chg); +int smblib_get_prop_smb_health(struct smb_charger *chg); int smblib_get_prop_connector_health(struct smb_charger *chg); +int smblib_get_skin_temp_status(struct smb_charger *chg); int smblib_get_prop_vph_voltage_now(struct smb_charger *chg, union power_supply_propval *val); int smblib_set_prop_pd_current_max(struct smb_charger *chg, diff --git a/drivers/power/supply/qcom/smb5-reg.h b/drivers/power/supply/qcom/smb5-reg.h index 0166a8824b77..18e197ef4698 100644 --- a/drivers/power/supply/qcom/smb5-reg.h +++ b/drivers/power/supply/qcom/smb5-reg.h @@ -493,6 +493,12 @@ enum { #define CONNECTOR_TEMP_UB_BIT BIT(1) #define CONNECTOR_TEMP_LB_BIT BIT(0) +#define SMB_TEMP_STATUS_REG (MISC_BASE + 0x0A) +#define SMB_TEMP_SHDN_BIT BIT(3) +#define SMB_TEMP_RST_BIT BIT(2) +#define SMB_TEMP_UB_BIT BIT(1) +#define SMB_TEMP_LB_BIT BIT(0) + #define BARK_BITE_WDOG_PET_REG (MISC_BASE + 0x43) #define BARK_BITE_WDOG_PET_BIT BIT(0) -- GitLab From 9876434e87c16e08b406588f4312035711312c38 Mon Sep 17 00:00:00 2001 From: Sahil Chandna Date: Tue, 16 Jul 2019 16:52:20 +0530 Subject: [PATCH 1009/1121] power: smb1390-psy: Configure temperature output buffer to High-Z state Configure temperature buffer output of slave CP to high impedance since in HW we are only reading temperature for Master CP and temperature of slave CP is assumed same as that of Master due to physical proximity between them. Change-Id: I4f9b8bf0baaf7435c3770bb573bb1a27dd5062b6 Signed-off-by: Sahil Chandna --- drivers/power/supply/qcom/smb1390-charger-psy.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/power/supply/qcom/smb1390-charger-psy.c b/drivers/power/supply/qcom/smb1390-charger-psy.c index d583ce66694c..9dbdad28ccb4 100644 --- a/drivers/power/supply/qcom/smb1390-charger-psy.c +++ b/drivers/power/supply/qcom/smb1390-charger-psy.c @@ -74,6 +74,7 @@ #define CORE_FTRIM_CTRL_REG 0x1031 #define TEMP_ALERT_LVL_MASK GENMASK(6, 5) #define TEMP_ALERT_LVL_SHIFT 5 +#define TEMP_BUFFER_OUTPUT_BIT BIT(7) #define CORE_FTRIM_LVL_REG 0x1033 #define CFG_WIN_HI_MASK GENMASK(3, 2) @@ -1829,6 +1830,15 @@ static int smb1390_slave_probe(struct smb1390 *chip) if (rc < 0) return rc; + /* Configure Slave CP Temp buffer O/P to High Impedance */ + rc = smb1390_masked_write(chip, CORE_FTRIM_CTRL_REG, + TEMP_BUFFER_OUTPUT_BIT, + TEMP_BUFFER_OUTPUT_BIT); + if (rc < 0) { + pr_err("Couldn't configure Slave temp Buffer rc=%d\n", rc); + return rc; + } + rc = smb1390_init_cps_psy(chip); if (rc < 0) pr_err("Couldn't initialize cps psy rc=%d\n", rc); -- GitLab From 91e7ffd65e0838b3f090fe9ea55adb1a3f8dea7e Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Tue, 28 May 2019 13:22:15 -0700 Subject: [PATCH 1010/1121] clk: qcom: Update SCC regulator configurations for SA 8195 Update the number of voltage levels needed by the SCC regulator for the SA8195 hardware. Change-Id: I296495c8079a293aa857b5ae9f6ddeed18e7f908 Signed-off-by: Anant Goel --- .../devicetree/bindings/clock/qcom,scc.txt | 2 +- drivers/clk/qcom/scc-sm8150.c | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/qcom,scc.txt b/Documentation/devicetree/bindings/clock/qcom,scc.txt index d095b3eb57f3..d60889ad94f2 100644 --- a/Documentation/devicetree/bindings/clock/qcom,scc.txt +++ b/Documentation/devicetree/bindings/clock/qcom,scc.txt @@ -2,7 +2,7 @@ Qualcomm Technologies, Inc. Sensor Clock Controller Bindings Required properties: - compatible: shall contain "qcom,scc-sm8150" or "qcom,scc-sm8150-v2" or - "qcom,scc-sm6150" or qcom,scc-sa6155". + "qcom,scc-sm6150" or "qcom,scc-sa6155" or "qcom,scc-sa8195". - reg: shall contain base register location and length. - vdd_scc_cx-supply: the logic rail supply. - #clock-cells: shall contain 1. diff --git a/drivers/clk/qcom/scc-sm8150.c b/drivers/clk/qcom/scc-sm8150.c index 9cf33169f268..554d5590eaba 100644 --- a/drivers/clk/qcom/scc-sm8150.c +++ b/drivers/clk/qcom/scc-sm8150.c @@ -576,10 +576,19 @@ static const struct qcom_cc_desc scc_sm8150_desc = { static const struct of_device_id scc_sm8150_match_table[] = { { .compatible = "qcom,scc-sm8150" }, { .compatible = "qcom,scc-sm8150-v2" }, + { .compatible = "qcom,scc-sa8195" }, { } }; MODULE_DEVICE_TABLE(of, scc_sm8150_match_table); +static void scc_sa8195_fixup(struct platform_device *pdev) +{ + if (of_device_is_compatible(pdev->dev.of_node, "qcom,scc-sa8195")) { + vdd_scc_cx.num_levels = VDD_MM_NUM; + vdd_scc_cx.cur_level = VDD_MM_NUM; + } +} + static void scc_sm8150_fixup_sm8150v2(struct regmap *regmap) { scc_pll.config = &scc_pll_config_sm8150_v2; @@ -635,7 +644,8 @@ static int scc_sm8150_fixup(struct platform_device *pdev, struct regmap *regmap) if (!compat || (compatlen <= 0)) return -EINVAL; - if (!strcmp(compat, "qcom,scc-sm8150-v2")) + if (!strcmp(compat, "qcom,scc-sm8150-v2") || + !strcmp(compat, "qcom,scc-sa8195")) scc_sm8150_fixup_sm8150v2(regmap); return 0; @@ -652,6 +662,8 @@ static int scc_sm8150_probe(struct platform_device *pdev) return PTR_ERR(regmap); } + scc_sa8195_fixup(pdev); + vdd_scc_cx.regulator[0] = devm_regulator_get(&pdev->dev, "vdd_scc_cx"); if (IS_ERR(vdd_scc_cx.regulator[0])) { ret = PTR_ERR(vdd_scc_cx.regulator[0]); -- GitLab From 8020cf10297d62e3d11b135e62266ca90b57d904 Mon Sep 17 00:00:00 2001 From: Odelu Kukatla Date: Mon, 17 Jun 2019 16:20:08 +0530 Subject: [PATCH 1011/1121] ARM: dts: msm: Introduce bus topology for ATOLL Bus topology is the representation of bus connections in SOC and is required for bus scaling driver to serve the bandwidth requests from clients. Change-Id: Ib7204524da5ab8a752a64426fc7ac8e3b139034a Signed-off-by: Odelu Kukatla --- arch/arm64/boot/dts/qcom/atoll-bus.dtsi | 1994 +++++++++++++++++++++++ arch/arm64/boot/dts/qcom/atoll.dtsi | 1 + include/dt-bindings/msm/msm-bus-ids.h | 39 +- 3 files changed, 2023 insertions(+), 11 deletions(-) create mode 100644 arch/arm64/boot/dts/qcom/atoll-bus.dtsi diff --git a/arch/arm64/boot/dts/qcom/atoll-bus.dtsi b/arch/arm64/boot/dts/qcom/atoll-bus.dtsi new file mode 100644 index 000000000000..2b38acb511bb --- /dev/null +++ b/arch/arm64/boot/dts/qcom/atoll-bus.dtsi @@ -0,0 +1,1994 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include + +&soc { + ad_hoc_bus: ad-hoc-bus { + compatible = "qcom,msm-bus-device"; + reg = <0x16E0000 0x15080>, + <0x1700000 0x1F880>, + <0x1500000 0x28000>, + <0x9160000 0x03200>, + <0x9680000 0x3E200>, + <0x1620000 0x4000>, + <0x1740000 0x1C100>, + <0x1620000 0x17080>, + <0x1620000 0x4000>, + <0x1700000 0x1F880>, + <0x9990000 0x1600>, + <0x1620000 0x4000>; + + reg-names = "aggre1_noc-base", "aggre2_noc-base", + "config_noc-base", "dc_noc-base", + "gem_noc-base", "mc_virt-base", + "mmss_noc-base", "system_noc-base", + "ipa_virt-base", "compute_noc-base", + "npu_noc-base", "qup_virt-base"; + + mbox-names = "apps_rsc", "disp_rsc"; + mboxes = <&apps_rsc 0 &disp_rsc 0>; + + /*RSCs*/ + rsc_apps: rsc-apps { + cell-id = ; + label = "apps_rsc"; + qcom,rsc-dev; + qcom,req_state = <2>; + }; + + rsc_disp: rsc-disp { + cell-id = ; + label = "disp_rsc"; + qcom,rsc-dev; + qcom,req_state = <2>; + }; + + /*BCMs*/ + bcm_acv: bcm-acv { + cell-id = ; + label = "ACV"; + qcom,bcm-name = "ACV"; + qcom,rscs = <&rsc_apps>; + qcom,bcm-dev; + }; + + bcm_alc: bcm-alc { + cell-id = ; + label = "ALC"; + qcom,bcm-name = "ALC"; + qcom,rscs = <&rsc_apps>; + qcom,bcm-dev; + }; + + bcm_mc0: bcm-mc0 { + cell-id = ; + label = "MC0"; + qcom,bcm-name = "MC0"; + qcom,rscs = <&rsc_apps>; + qcom,bcm-dev; + }; + + bcm_sh0: bcm-sh0 { + cell-id = ; + label = "SH0"; + qcom,bcm-name = "SH0"; + qcom,rscs = <&rsc_apps>; + qcom,bcm-dev; + }; + + bcm_mm0: bcm-mm0 { + cell-id = ; + label = "MM0"; + qcom,bcm-name = "MM0"; + qcom,rscs = <&rsc_apps>; + qcom,bcm-dev; + }; + + bcm_co0: bcm-co0 { + cell-id = ; + label = "CO0"; + qcom,bcm-name = "CO0"; + qcom,rscs = <&rsc_apps>; + qcom,bcm-dev; + }; + + bcm_ce0: bcm-ce0 { + cell-id = ; + label = "CE0"; + qcom,bcm-name = "CE0"; + qcom,rscs = <&rsc_apps>; + qcom,bcm-dev; + }; + + bcm_ip0: bcm-ip0 { + cell-id = ; + label = "IP0"; + qcom,bcm-name = "IP0"; + qcom,rscs = <&rsc_apps>; + qcom,bcm-dev; + }; + + bcm_cn0: bcm-cn0 { + cell-id = ; + label = "CN0"; + qcom,bcm-name = "CN0"; + qcom,rscs = <&rsc_apps>; + qcom,bcm-dev; + }; + + bcm_mm1: bcm-mm1 { + cell-id = ; + label = "MM1"; + qcom,bcm-name = "MM1"; + qcom,rscs = <&rsc_apps>; + qcom,bcm-dev; + }; + + bcm_cn1: bcm-cn1 { + cell-id = ; + label = "CN1"; + qcom,bcm-name = "CN1"; + qcom,rscs = <&rsc_apps>; + qcom,bcm-dev; + }; + + bcm_sh2: bcm-sh2 { + cell-id = ; + label = "SH2"; + qcom,bcm-name = "SH2"; + qcom,rscs = <&rsc_apps>; + qcom,bcm-dev; + }; + + bcm_mm2: bcm-mm2 { + cell-id = ; + label = "MM2"; + qcom,bcm-name = "MM2"; + qcom,rscs = <&rsc_apps>; + qcom,bcm-dev; + }; + + bcm_co2: bcm-co2 { + cell-id = ; + label = "CO2"; + qcom,bcm-name = "CO2"; + qcom,rscs = <&rsc_apps>; + qcom,bcm-dev; + }; + + bcm_qup0: bcm-qup0 { + cell-id = ; + label = "QUP0"; + qcom,bcm-name = "QUP0"; + qcom,rscs = <&rsc_apps>; + qcom,bcm-dev; + }; + + bcm_sh3: bcm-sh3 { + cell-id = ; + label = "SH3"; + qcom,bcm-name = "SH3"; + qcom,rscs = <&rsc_apps>; + qcom,bcm-dev; + }; + + bcm_co3: bcm-co3 { + cell-id = ; + label = "CO3"; + qcom,bcm-name = "CO3"; + qcom,rscs = <&rsc_apps>; + qcom,bcm-dev; + }; + + bcm_sh4: bcm-sh4 { + cell-id = ; + label = "SH4"; + qcom,bcm-name = "SH4"; + qcom,rscs = <&rsc_apps>; + qcom,bcm-dev; + }; + + bcm_sn0: bcm-sn0 { + cell-id = ; + label = "SN0"; + qcom,bcm-name = "SN0"; + qcom,rscs = <&rsc_apps>; + qcom,bcm-dev; + }; + + bcm_sn1: bcm-sn1 { + cell-id = ; + label = "SN1"; + qcom,bcm-name = "SN1"; + qcom,rscs = <&rsc_apps>; + qcom,bcm-dev; + }; + + bcm_sn2: bcm-sn2 { + cell-id = ; + label = "SN2"; + qcom,bcm-name = "SN2"; + qcom,rscs = <&rsc_apps>; + qcom,bcm-dev; + }; + + bcm_sn3: bcm-sn3 { + cell-id = ; + label = "SN3"; + qcom,bcm-name = "SN3"; + qcom,rscs = <&rsc_apps>; + qcom,bcm-dev; + }; + + bcm_sn4: bcm-sn4 { + cell-id = ; + label = "SN4"; + qcom,bcm-name = "SN4"; + qcom,rscs = <&rsc_apps>; + qcom,bcm-dev; + }; + + bcm_sn7: bcm-sn7 { + cell-id = ; + label = "SN7"; + qcom,bcm-name = "SN7"; + qcom,rscs = <&rsc_apps>; + qcom,bcm-dev; + }; + + bcm_sn9: bcm-sn9 { + cell-id = ; + label = "SN9"; + qcom,bcm-name = "SN9"; + qcom,rscs = <&rsc_apps>; + qcom,bcm-dev; + }; + + bcm_sn10: bcm-sn10 { + cell-id = ; + label = "SN10"; + qcom,bcm-name = "SN10"; + qcom,rscs = <&rsc_apps>; + qcom,bcm-dev; + }; + + bcm_sn12: bcm-sn12 { + cell-id = ; + label = "SN12"; + qcom,bcm-name = "SN12"; + qcom,rscs = <&rsc_apps>; + qcom,bcm-dev; + }; + + bcm_acv_display: bcm-acv_display { + cell-id = ; + label = "ACV_DISPLAY"; + qcom,bcm-name = "ACV"; + qcom,rscs = <&rsc_disp>; + qcom,bcm-dev; + }; + + bcm_alc_display: bcm-alc_display { + cell-id = ; + label = "ALC_DISPLAY"; + qcom,bcm-name = "ALC"; + qcom,rscs = <&rsc_disp>; + qcom,bcm-dev; + }; + + bcm_mc0_display: bcm-mc0_display { + cell-id = ; + label = "MC0_DISPLAY"; + qcom,bcm-name = "MC0"; + qcom,rscs = <&rsc_disp>; + qcom,bcm-dev; + }; + + bcm_sh0_display: bcm-sh0_display { + cell-id = ; + label = "SH0_DISPLAY"; + qcom,bcm-name = "SH0"; + qcom,rscs = <&rsc_disp>; + qcom,bcm-dev; + }; + + bcm_mm0_display: bcm-mm0_display { + cell-id = ; + label = "MM0_DISPLAY"; + qcom,bcm-name = "MM0"; + qcom,rscs = <&rsc_disp>; + qcom,bcm-dev; + }; + + bcm_mm1_display: bcm-mm1_display { + cell-id = ; + label = "MM1_DISPLAY"; + qcom,bcm-name = "MM1"; + qcom,rscs = <&rsc_disp>; + qcom,bcm-dev; + }; + + bcm_mm2_display: bcm-mm2_display { + cell-id = ; + label = "MM2_DISPLAY"; + qcom,bcm-name = "MM2"; + qcom,rscs = <&rsc_disp>; + qcom,bcm-dev; + }; + + /*Buses*/ + fab_aggre1_noc: fab-aggre1_noc { + cell-id = ; + label = "fab-aggre1_noc"; + qcom,fab-dev; + qcom,base-name = "aggre1_noc-base"; + qcom,qos-off = <4096>; + qcom,base-offset = <16384>; + qcom,sbm-offset = <0>; + qcom,bypass-qos-prg; + qcom,bus-type = <1>; + clocks = <>; + }; + + fab_aggre2_noc: fab-aggre2_noc { + cell-id = ; + label = "fab-aggre2_noc"; + qcom,fab-dev; + qcom,base-name = "aggre2_noc-base"; + qcom,qos-off = <4096>; + qcom,base-offset = <20480>; + qcom,sbm-offset = <0>; + qcom,bypass-qos-prg; + qcom,bus-type = <1>; + clocks = <>; + }; + + fab_compute_noc: fab-compute_noc { + cell-id = ; + label = "fab-compute_noc"; + qcom,fab-dev; + qcom,base-name = "compute_noc-base"; + qcom,qos-off = <4096>; + qcom,base-offset = <57344>; + qcom,sbm-offset = <0>; + qcom,bypass-qos-prg; + qcom,bus-type = <1>; + clocks = <>; + }; + + fab_config_noc: fab-config_noc { + cell-id = ; + label = "fab-config_noc"; + qcom,fab-dev; + qcom,base-name = "config_noc-base"; + qcom,qos-off = <0>; + qcom,base-offset = <0>; + qcom,sbm-offset = <0>; + qcom,bypass-qos-prg; + qcom,bus-type = <1>; + clocks = <>; + }; + + fab_dc_noc: fab-dc_noc { + cell-id = ; + label = "fab-dc_noc"; + qcom,fab-dev; + qcom,base-name = "dc_noc-base"; + qcom,qos-off = <0>; + qcom,base-offset = <0>; + qcom,sbm-offset = <0>; + qcom,bypass-qos-prg; + qcom,bus-type = <1>; + clocks = <>; + }; + + fab_gem_noc: fab-gem_noc { + cell-id = ; + label = "fab-gem_noc"; + qcom,fab-dev; + qcom,base-name = "gem_noc-base"; + qcom,qos-off = <128>; + qcom,base-offset = <176128>; + qcom,sbm-offset = <0>; + qcom,bypass-qos-prg; + qcom,bus-type = <1>; + clocks = <>; + }; + + fab_ipa_virt: fab-ipa_virt { + cell-id = ; + label = "fab-ipa_virt"; + qcom,fab-dev; + qcom,base-name = "ipa_virt-base"; + qcom,qos-off = <0>; + qcom,base-offset = <0>; + qcom,sbm-offset = <0>; + qcom,bypass-qos-prg; + clocks = <>; + }; + + fab_mc_virt: fab-mc_virt { + cell-id = ; + label = "fab-mc_virt"; + qcom,fab-dev; + qcom,base-name = "mc_virt-base"; + qcom,qos-off = <0>; + qcom,base-offset = <0>; + qcom,sbm-offset = <0>; + qcom,bypass-qos-prg; + clocks = <>; + }; + + fab_mmss_noc: fab-mmss_noc { + cell-id = ; + label = "fab-mmss_noc"; + qcom,fab-dev; + qcom,base-name = "mmss_noc-base"; + qcom,qos-off = <4096>; + qcom,base-offset = <36864>; + qcom,sbm-offset = <0>; + qcom,bypass-qos-prg; + qcom,bus-type = <1>; + clocks = <>; + }; + + fab_npu_noc: fab-npu_noc { + cell-id = ; + label = "fab-npu_noc"; + qcom,fab-dev; + qcom,base-name = "npu_noc-base"; + qcom,qos-off = <0>; + qcom,base-offset = <0>; + qcom,sbm-offset = <0>; + qcom,bypass-qos-prg; + qcom,bus-type = <1>; + clocks = <>; + }; + + fab_qup_virt: fab-qup_virt { + cell-id = ; + label = "fab-qup_virt"; + qcom,fab-dev; + qcom,base-name = "qup_virt-base"; + qcom,qos-off = <0>; + qcom,base-offset = <0>; + qcom,sbm-offset = <0>; + qcom,bypass-qos-prg; + clocks = <>; + }; + + fab_system_noc: fab-system_noc { + cell-id = ; + label = "fab-system_noc"; + qcom,fab-dev; + qcom,base-name = "system_noc-base"; + qcom,qos-off = <4096>; + qcom,base-offset = <45056>; + qcom,sbm-offset = <0>; + qcom,bypass-qos-prg; + qcom,bus-type = <1>; + clocks = <>; + }; + + fab_gem_noc_display: fab-gem_noc_display { + cell-id = ; + label = "fab-gem_noc_display"; + qcom,fab-dev; + qcom,base-name = "gem_noc-base"; + qcom,qos-off = <128>; + qcom,base-offset = <176128>; + qcom,sbm-offset = <0>; + qcom,bypass-qos-prg; + qcom,bus-type = <1>; + clocks = <>; + }; + + fab_mc_virt_display: fab-mc_virt_display { + cell-id = ; + label = "fab-mc_virt_display"; + qcom,fab-dev; + qcom,base-name = "mc_virt-base"; + qcom,qos-off = <0>; + qcom,base-offset = <0>; + qcom,sbm-offset = <0>; + qcom,bypass-qos-prg; + clocks = <>; + }; + + fab_mmss_noc_display: fab-mmss_noc_display { + cell-id = ; + label = "fab-mmss_noc_display"; + qcom,fab-dev; + qcom,base-name = "mmss_noc-base"; + qcom,qos-off = <4096>; + qcom,base-offset = <36864>; + qcom,sbm-offset = <0>; + qcom,bypass-qos-prg; + qcom,bus-type = <1>; + clocks = <>; + }; + + /*Masters*/ + mas_qhm_a1noc_cfg: mas-qhm-a1noc-cfg { + cell-id = ; + label = "mas-qhm-a1noc-cfg"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,connections = <&slv_srvc_aggre1_noc>; + qcom,bus-dev = <&fab_aggre1_noc>; + }; + + mas_qhm_qspi: mas-qhm-qspi { + cell-id = ; + label = "mas-qhm-qspi"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,qport = <5>; + qcom,connections = <&slv_qns_a1noc_snoc>; + qcom,bus-dev = <&fab_aggre1_noc>; + qcom,bcms = <&bcm_cn1>; + qcom,ap-owned; + qcom,prio = <2>; + }; + + mas_qhm_qup_0: mas-qhm-qup-0 { + cell-id = ; + label = "mas-qhm-qup-0"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,qport = <6>; + qcom,connections = <&slv_qns_a1noc_snoc>; + qcom,bus-dev = <&fab_aggre1_noc>; + qcom,ap-owned; + qcom,prio = <2>; + }; + + mas_xm_emmc: mas-xm-emmc { + cell-id = ; + label = "mas-xm-emmc"; + qcom,buswidth = <8>; + qcom,agg-ports = <1>; + qcom,qport = <3>; + qcom,connections = <&slv_qns_a1noc_snoc>; + qcom,bus-dev = <&fab_aggre1_noc>; + qcom,bcms = <&bcm_cn1>; + qcom,ap-owned; + qcom,prio = <2>; + }; + + mas_xm_sdc2: mas-xm-sdc2 { + cell-id = ; + label = "mas-xm-sdc2"; + qcom,buswidth = <8>; + qcom,agg-ports = <1>; + qcom,qport = <1>; + qcom,connections = <&slv_qns_a1noc_snoc>; + qcom,bus-dev = <&fab_aggre1_noc>; + qcom,bcms = <&bcm_cn1>; + qcom,ap-owned; + qcom,prio = <2>; + }; + + mas_xm_ufs_mem: mas-xm-ufs-mem { + cell-id = ; + label = "mas-xm-ufs-mem"; + qcom,buswidth = <8>; + qcom,agg-ports = <1>; + qcom,qport = <4>; + qcom,connections = <&slv_qns_a1noc_snoc>; + qcom,bus-dev = <&fab_aggre1_noc>; + qcom,ap-owned; + qcom,prio = <2>; + }; + + mas_qhm_a2noc_cfg: mas-qhm-a2noc-cfg { + cell-id = ; + label = "mas-qhm-a2noc-cfg"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,connections = <&slv_srvc_aggre2_noc>; + qcom,bus-dev = <&fab_aggre2_noc>; + }; + + mas_qhm_qdss_bam: mas-qhm-qdss-bam { + cell-id = ; + label = "mas-qhm-qdss-bam"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,qport = <6>; + qcom,connections = <&slv_qns_a2noc_snoc>; + qcom,bus-dev = <&fab_aggre2_noc>; + qcom,ap-owned; + qcom,prio = <2>; + }; + + mas_qhm_qup_1: mas-qhm-qup-1 { + cell-id = ; + label = "mas-qhm-qup-1"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,qport = <4>; + qcom,connections = <&slv_qns_a2noc_snoc>; + qcom,bus-dev = <&fab_aggre2_noc>; + qcom,ap-owned; + qcom,prio = <2>; + }; + + mas_qxm_crypto: mas-qxm-crypto { + cell-id = ; + label = "mas-qxm-crypto"; + qcom,buswidth = <8>; + qcom,agg-ports = <1>; + qcom,qport = <1>; + qcom,connections = <&slv_qns_a2noc_snoc>; + qcom,bus-dev = <&fab_aggre2_noc>; + qcom,bcms = <&bcm_ce0>; + qcom,ap-owned; + qcom,prio = <2>; + qcom,forwarding; + }; + + mas_qxm_ipa: mas-qxm-ipa { + cell-id = ; + label = "mas-qxm-ipa"; + qcom,buswidth = <8>; + qcom,agg-ports = <1>; + qcom,qport = <2>; + qcom,connections = <&slv_qns_a2noc_snoc>; + qcom,bus-dev = <&fab_aggre2_noc>; + qcom,ap-owned; + qcom,prio = <2>; + qcom,forwarding; + qcom,defer-init-qos; + qcom,node-qos-bcms = <7035 0 1>; + }; + + mas_xm_qdss_etr: mas-xm-qdss-etr { + cell-id = ; + label = "mas-xm-qdss-etr"; + qcom,buswidth = <8>; + qcom,agg-ports = <1>; + qcom,qport = <7>; + qcom,connections = <&slv_qns_a2noc_snoc>; + qcom,bus-dev = <&fab_aggre2_noc>; + qcom,ap-owned; + qcom,prio = <2>; + }; + + mas_xm_usb3_0: mas-xm-usb3-0 { + cell-id = ; + label = "mas-xm-usb3-0"; + qcom,buswidth = <8>; + qcom,agg-ports = <1>; + qcom,qport = <8>; + qcom,connections = <&slv_qns_a2noc_snoc>; + qcom,bus-dev = <&fab_aggre2_noc>; + qcom,ap-owned; + qcom,prio = <2>; + }; + + mas_qnm_npu: mas-qnm-npu { + cell-id = ; + label = "mas-qnm-npu"; + qcom,buswidth = <32>; + qcom,agg-ports = <2>; + qcom,qport = <1 3>; + qcom,connections = <&slv_qns_cdsp_gemnoc>; + qcom,bus-dev = <&fab_compute_noc>; + qcom,bcms = <&bcm_co2>; + qcom,ap-owned; + qcom,prio = <0>; + qcom,forwarding; + }; + + mas_qxm_npu_dsp: mas-qxm-npu-dsp { + cell-id = ; + label = "mas-qxm-npu-dsp"; + qcom,buswidth = <8>; + qcom,agg-ports = <1>; + qcom,qport = <5>; + qcom,connections = <&slv_qns_cdsp_gemnoc>; + qcom,bus-dev = <&fab_compute_noc>; + qcom,bcms = <&bcm_co3>; + qcom,ap-owned; + qcom,prio = <0>; + qcom,forwarding; + }; + + mas_qnm_snoc: mas-qnm-snoc { + cell-id = ; + label = "mas-qnm-snoc"; + qcom,buswidth = <8>; + qcom,agg-ports = <1>; + qcom,connections = <&slv_qhs_tlmm_3 &slv_qhs_tlmm_2 + &slv_qhs_camera_cfg &slv_qhs_sdc2 + &slv_qhs_mnoc_cfg &slv_qhs_ufs_mem_cfg + &slv_qhs_qm_cfg &slv_qhs_snoc_cfg + &slv_qhs_qm_mpu_cfg &slv_qhs_glm &slv_qhs_pdm + &slv_qhs_camera_nrt_throttle_cfg + &slv_qhs_a2_noc_cfg &slv_qhs_qdss_cfg + &slv_qhs_vsense_ctrl_cfg + &slv_qhs_camera_rt_throttle_cfg + &slv_qhs_npu_dsp_throttle_cfg + &slv_qhs_display_cfg &slv_qhs_qspi + &slv_qhs_display_throttle_cfg &slv_qhs_tlmm_1 + &slv_qhs_tcsr &slv_qhs_dcc_cfg + &slv_qhs_ddrss_cfg + &slv_qhs_display_rt_throttle_cfg + &slv_qhs_ahb2phy2 &slv_qhs_npu_cfg + &slv_qhs_ahb2phy0 &slv_qhs_gpuss_cfg + &slv_qhs_boot_rom &slv_qhs_venus_cfg + &slv_qhs_ipa &slv_qhs_security + &slv_qhs_aop &slv_qhs_imem_cfg + &slv_qhs_mss_cfg &slv_srvc_cnoc + &slv_qhs_usb3_0 &slv_qhs_venus_throttle_cfg + &slv_qhs_cpr_cx &slv_qhs_a1_noc_cfg + &slv_qhs_aoss &slv_qhs_prng + &slv_qhs_npu_dma_throttle_cfg &slv_qhs_emmc_cfg + &slv_qhs_crypto0_cfg &slv_qhs_pimem_cfg + &slv_qhs_cpr_mx &slv_qhs_qup0 + &slv_qhs_qup1 &slv_qhs_clk_ctl>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + mas_xm_qdss_dap: mas-xm-qdss-dap { + cell-id = ; + label = "mas-xm-qdss-dap"; + qcom,buswidth = <8>; + qcom,agg-ports = <1>; + qcom,connections = <&slv_qhs_tlmm_3 &slv_qhs_tlmm_2 + &slv_qhs_camera_cfg &slv_qhs_sdc2 + &slv_qhs_mnoc_cfg &slv_qhs_ufs_mem_cfg + &slv_qhs_qm_cfg &slv_qhs_snoc_cfg + &slv_qhs_qm_mpu_cfg &slv_qhs_glm &slv_qhs_pdm + &slv_qhs_camera_nrt_throttle_cfg + &slv_qhs_a2_noc_cfg &slv_qhs_qdss_cfg + &slv_qhs_vsense_ctrl_cfg + &slv_qhs_camera_rt_throttle_cfg + &slv_qhs_npu_dsp_throttle_cfg + &slv_qhs_display_cfg &slv_qhs_qspi + &slv_qhs_display_throttle_cfg &slv_qhs_tlmm_1 + &slv_qhs_tcsr &slv_qhs_dcc_cfg + &slv_qhs_ddrss_cfg + &slv_qhs_display_rt_throttle_cfg + &slv_qhs_ahb2phy2 &slv_qhs_npu_cfg + &slv_qhs_ahb2phy0 &slv_qhs_gpuss_cfg + &slv_qhs_boot_rom &slv_qhs_venus_cfg + &slv_qhs_ipa &slv_qhs_security + &slv_qhs_aop &slv_qhs_imem_cfg + &slv_qhs_mss_cfg &slv_srvc_cnoc + &slv_qhs_usb3_0 &slv_qhs_venus_throttle_cfg + &slv_qhs_cpr_cx &slv_qhs_a1_noc_cfg + &slv_qhs_aoss &slv_qhs_prng + &slv_qhs_npu_dma_throttle_cfg &slv_qhs_emmc_cfg + &slv_qhs_crypto0_cfg &slv_qhs_pimem_cfg + &slv_qhs_cpr_mx &slv_qhs_qup0 + &slv_qhs_qup1 &slv_qhs_clk_ctl>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + mas_qhm_cnoc_dc_noc: mas-qhm-cnoc-dc-noc { + cell-id = ; + label = "mas-qhm-cnoc-dc-noc"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,connections = <&slv_qhs_llcc &slv_qhs_gemnoc>; + qcom,bus-dev = <&fab_dc_noc>; + }; + + mas_acm_apps: mas-acm-apps { + cell-id = ; + label = "mas-acm-apps"; + qcom,buswidth = <16>; + qcom,agg-ports = <1>; + qcom,qport = <96 98>; + qcom,connections = <&slv_qns_llcc + &slv_qns_gem_noc_snoc>; + qcom,bus-dev = <&fab_gem_noc>; + qcom,bcms = <&bcm_sh4>; + qcom,ap-owned; + qcom,prio = <0>; + }; + + mas_acm_sys_tcu: mas-acm-sys-tcu { + cell-id = ; + label = "mas-acm-sys-tcu"; + qcom,buswidth = <8>; + qcom,agg-ports = <1>; + qcom,qport = <384>; + qcom,connections = <&slv_qns_llcc + &slv_qns_gem_noc_snoc>; + qcom,bus-dev = <&fab_gem_noc>; + qcom,bcms = <&bcm_sh2>; + qcom,ap-owned; + qcom,prio = <6>; + }; + + mas_qhm_gemnoc_cfg: mas-qhm-gemnoc-cfg { + cell-id = ; + label = "mas-qhm-gemnoc-cfg"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,connections = <&slv_srvc_gemnoc + &slv_qhs_mdsp_ms_mpu_cfg>; + qcom,bus-dev = <&fab_gem_noc>; + }; + + mas_qnm_cmpnoc: mas-qnm-cmpnoc { + cell-id = ; + label = "mas-qnm-cmpnoc"; + qcom,buswidth = <32>; + qcom,agg-ports = <1>; + qcom,qport = <64>; + qcom,connections = <&slv_qns_llcc + &slv_qns_gem_noc_snoc>; + qcom,bus-dev = <&fab_gem_noc>; + qcom,bcms = <&bcm_sh3>; + qcom,ap-owned; + qcom,prio = <0>; + }; + + mas_qnm_mnoc_hf: mas-qnm-mnoc-hf { + cell-id = ; + label = "mas-qnm-mnoc-hf"; + qcom,buswidth = <32>; + qcom,agg-ports = <1>; + qcom,qport = <128>; + qcom,connections = <&slv_qns_llcc>; + qcom,bus-dev = <&fab_gem_noc>; + qcom,ap-owned; + qcom,prio = <0>; + qcom,forwarding; + qcom,node-qos-bcms = <7012 0 1>; + }; + + mas_qnm_mnoc_sf: mas-qnm-mnoc-sf { + cell-id = ; + label = "mas-qnm-mnoc-sf"; + qcom,buswidth = <32>; + qcom,agg-ports = <1>; + qcom,qport = <320>; + qcom,connections = <&slv_qns_llcc + &slv_qns_gem_noc_snoc>; + qcom,bus-dev = <&fab_gem_noc>; + qcom,ap-owned; + qcom,prio = <0>; + qcom,forwarding; + qcom,node-qos-bcms = <7012 0 1>; + }; + + mas_qnm_snoc_gc: mas-qnm-snoc-gc { + cell-id = ; + label = "mas-qnm-snoc-gc"; + qcom,buswidth = <8>; + qcom,agg-ports = <1>; + qcom,qport = <192>; + qcom,connections = <&slv_qns_llcc>; + qcom,bus-dev = <&fab_gem_noc>; + qcom,ap-owned; + qcom,prio = <0>; + qcom,forwarding; + }; + + mas_qnm_snoc_sf: mas-qnm-snoc-sf { + cell-id = ; + label = "mas-qnm-snoc-sf"; + qcom,buswidth = <16>; + qcom,agg-ports = <1>; + qcom,qport = <160>; + qcom,connections = <&slv_qns_llcc>; + qcom,bus-dev = <&fab_gem_noc>; + qcom,ap-owned; + qcom,prio = <0>; + qcom,forwarding; + }; + + mas_qxm_gpu: mas-qxm-gpu { + cell-id = ; + label = "mas-qxm-gpu"; + qcom,buswidth = <32>; + qcom,agg-ports = <2>; + qcom,qport = <288 289>; + qcom,connections = <&slv_qns_llcc + &slv_qns_gem_noc_snoc>; + qcom,bus-dev = <&fab_gem_noc>; + qcom,ap-owned; + qcom,prio = <0>; + qcom,forwarding; + }; + + mas_ipa_core_master: mas-ipa-core-master { + cell-id = ; + label = "mas-ipa-core-master"; + qcom,buswidth = <8>; + qcom,agg-ports = <1>; + qcom,connections = <&slv_ipa_core_slave>; + qcom,bus-dev = <&fab_ipa_virt>; + }; + + mas_llcc_mc: mas-llcc-mc { + cell-id = ; + label = "mas-llcc-mc"; + qcom,buswidth = <4>; + qcom,agg-ports = <2>; + qcom,connections = <&slv_ebi>; + qcom,bus-dev = <&fab_mc_virt>; + }; + + mas_qhm_mnoc_cfg: mas-qhm-mnoc-cfg { + cell-id = ; + label = "mas-qhm-mnoc-cfg"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,connections = <&slv_srvc_mnoc>; + qcom,bus-dev = <&fab_mmss_noc>; + qcom,bcms = <&bcm_mm1>; + }; + + mas_qxm_camnoc_hf: mas-qxm-camnoc-hf { + cell-id = ; + label = "mas-qxm-camnoc-hf"; + qcom,buswidth = <32>; + qcom,agg-ports = <2>; + qcom,qport = <1 2>; + qcom,connections = <&slv_qns_mem_noc_hf>; + qcom,bus-dev = <&fab_mmss_noc>; + qcom,ap-owned; + qcom,prio = <0>; + qcom,forwarding; + qcom,node-qos-bcms = <7012 0 1>; + }; + + mas_qxm_camnoc_sf: mas-qxm-camnoc-sf { + cell-id = ; + label = "mas-qxm-camnoc-sf"; + qcom,buswidth = <32>; + qcom,agg-ports = <1>; + qcom,qport = <0>; + qcom,connections = <&slv_qns_mem_noc_sf>; + qcom,bus-dev = <&fab_mmss_noc>; + qcom,ap-owned; + qcom,prio = <0>; + qcom,forwarding; + qcom,node-qos-bcms = <7012 0 1>; + }; + + mas_qxm_mdp0: mas-qxm-mdp0 { + cell-id = ; + label = "mas-qxm-mdp0"; + qcom,buswidth = <32>; + qcom,agg-ports = <1>; + qcom,qport = <3>; + qcom,connections = <&slv_qns_mem_noc_hf>; + qcom,bus-dev = <&fab_mmss_noc>; + qcom,bcms = <&bcm_mm1>; + qcom,ap-owned; + qcom,prio = <0>; + qcom,forwarding; + qcom,node-qos-bcms = <7012 0 1>; + }; + + mas_qxm_rot: mas-qxm-rot { + cell-id = ; + label = "mas-qxm-rot"; + qcom,buswidth = <16>; + qcom,agg-ports = <1>; + qcom,qport = <5>; + qcom,connections = <&slv_qns_mem_noc_sf>; + qcom,bus-dev = <&fab_mmss_noc>; + qcom,bcms = <&bcm_mm1>; + qcom,ap-owned; + qcom,prio = <0>; + qcom,forwarding; + qcom,node-qos-bcms = <7012 0 1>; + }; + + mas_qxm_venus0: mas-qxm-venus0 { + cell-id = ; + label = "mas-qxm-venus0"; + qcom,buswidth = <32>; + qcom,agg-ports = <1>; + qcom,qport = <6>; + qcom,connections = <&slv_qns_mem_noc_sf>; + qcom,bus-dev = <&fab_mmss_noc>; + qcom,bcms = <&bcm_mm1>; + qcom,ap-owned; + qcom,prio = <0>; + qcom,forwarding; + qcom,node-qos-bcms = <7012 0 1>; + }; + + mas_qxm_venus_arm9: mas-qxm-venus-arm9 { + cell-id = ; + label = "mas-qxm-venus-arm9"; + qcom,buswidth = <8>; + qcom,agg-ports = <1>; + qcom,qport = <8>; + qcom,connections = <&slv_qns_mem_noc_sf>; + qcom,bus-dev = <&fab_mmss_noc>; + qcom,bcms = <&bcm_mm1>; + qcom,ap-owned; + qcom,prio = <5>; + qcom,forwarding; + qcom,node-qos-bcms = <7012 0 1>; + }; + + mas_amm_npu_sys: mas-amm-npu-sys { + cell-id = ; + label = "mas-amm-npu-sys"; + qcom,buswidth = <32>; + qcom,agg-ports = <2>; + qcom,connections = <&slv_qns_npu_sys>; + qcom,bus-dev = <&fab_npu_noc>; + }; + + mas_qhm_npu_cfg: mas-qhm-npu-cfg { + cell-id = ; + label = "mas-qhm-npu-cfg"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,connections = <&slv_srvc_noc &slv_qhs_isense + &slv_qhs_llm &slv_qhs_dma_bwmon &slv_qhs_cp + &slv_qhs_tcm &slv_qhs_cal_dp0 + &slv_qhs_dpm>; + qcom,bus-dev = <&fab_npu_noc>; + }; + + mas_qup_core_master_0: mas-qup-core-master-0 { + cell-id = ; + label = "mas-qup-core-master-0"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,connections = <&slv_qup_core_slave_0>; + qcom,bus-dev = <&fab_qup_virt>; + qcom,bcms = <&bcm_qup0>; + }; + + mas_qup_core_master_1: mas-qup-core-master-1 { + cell-id = ; + label = "mas-qup-core-master-1"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,connections = <&slv_qup_core_slave_1>; + qcom,bus-dev = <&fab_qup_virt>; + qcom,bcms = <&bcm_qup0>; + }; + + mas_qhm_snoc_cfg: mas-qhm-snoc-cfg { + cell-id = ; + label = "mas-qhm-snoc-cfg"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,connections = <&slv_srvc_snoc>; + qcom,bus-dev = <&fab_system_noc>; + }; + + mas_qnm_aggre1_noc: mas-qnm-aggre1-noc { + cell-id = ; + label = "mas-qnm-aggre1-noc"; + qcom,buswidth = <16>; + qcom,agg-ports = <1>; + qcom,connections = <&slv_qns_gemnoc_sf &slv_qxs_pimem + &slv_qxs_imem &slv_qhs_apss &slv_qns_cnoc + &slv_xs_qdss_stm>; + qcom,bus-dev = <&fab_system_noc>; + qcom,bcms = <&bcm_sn7>; + }; + + mas_qnm_aggre2_noc: mas-qnm-aggre2-noc { + cell-id = ; + label = "mas-qnm-aggre2-noc"; + qcom,buswidth = <16>; + qcom,agg-ports = <1>; + qcom,connections = <&slv_qns_gemnoc_sf &slv_qxs_pimem + &slv_qxs_imem &slv_qhs_apss &slv_qns_cnoc + &slv_xs_sys_tcu_cfg &slv_xs_qdss_stm>; + qcom,bus-dev = <&fab_system_noc>; + qcom,bcms = <&bcm_sn9>; + }; + + mas_qnm_gemnoc: mas-qnm-gemnoc { + cell-id = ; + label = "mas-qnm-gemnoc"; + qcom,buswidth = <8>; + qcom,agg-ports = <1>; + qcom,connections = <&slv_qxs_pimem &slv_qxs_imem + &slv_qhs_apss &slv_qns_cnoc + &slv_xs_sys_tcu_cfg &slv_xs_qdss_stm>; + qcom,bus-dev = <&fab_system_noc>; + qcom,bcms = <&bcm_sn12>; + }; + + mas_qxm_pimem: mas-qxm-pimem { + cell-id = ; + label = "mas-qxm-pimem"; + qcom,buswidth = <8>; + qcom,agg-ports = <1>; + qcom,qport = <2>; + qcom,connections = <&slv_qns_gemnoc_gc &slv_qxs_imem>; + qcom,bus-dev = <&fab_system_noc>; + qcom,bcms = <&bcm_sn2>; + qcom,ap-owned; + qcom,prio = <2>; + }; + + mas_qnm_mnoc_hf_display: mas-qnm-mnoc-hf_display { + cell-id = ; + label = "mas-qnm-mnoc-hf_display"; + qcom,buswidth = <32>; + qcom,agg-ports = <1>; + qcom,qport = <128>; + qcom,connections = <&slv_qns_llcc_display>; + qcom,bus-dev = <&fab_gem_noc_display>; + }; + + mas_qnm_mnoc_sf_display: mas-qnm-mnoc-sf_display { + cell-id = ; + label = "mas-qnm-mnoc-sf_display"; + qcom,buswidth = <32>; + qcom,agg-ports = <1>; + qcom,qport = <320>; + qcom,connections = <&slv_qns_llcc_display>; + qcom,bus-dev = <&fab_gem_noc_display>; + }; + + mas_llcc_mc_display: mas-llcc-mc_display { + cell-id = ; + label = "mas-llcc-mc_display"; + qcom,buswidth = <4>; + qcom,agg-ports = <2>; + qcom,connections = <&slv_ebi_display>; + qcom,bus-dev = <&fab_mc_virt_display>; + }; + + mas_qxm_mdp0_display: mas-qxm-mdp0_display { + cell-id = ; + label = "mas-qxm-mdp0_display"; + qcom,buswidth = <32>; + qcom,agg-ports = <1>; + qcom,qport = <3>; + qcom,connections = <&slv_qns_mem_noc_hf_display>; + qcom,bus-dev = <&fab_mmss_noc_display>; + qcom,bcms = <&bcm_mm1_display>; + }; + + mas_qxm_rot_display: mas-qxm-rot_display { + cell-id = ; + label = "mas-qxm-rot_display"; + qcom,buswidth = <16>; + qcom,agg-ports = <1>; + qcom,qport = <5>; + qcom,connections = <&slv_qns_mem_noc_sf_display>; + qcom,bus-dev = <&fab_mmss_noc_display>; + qcom,bcms = <&bcm_mm1_display>; + }; + + /*Slaves*/ + slv_qns_a1noc_snoc:slv-qns-a1noc-snoc { + cell-id = ; + label = "slv-qns-a1noc-snoc"; + qcom,buswidth = <16>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_aggre1_noc>; + qcom,connections = <&mas_qnm_aggre1_noc>; + }; + + slv_srvc_aggre1_noc:slv-srvc-aggre1-noc { + cell-id = ; + label = "slv-srvc-aggre1-noc"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_aggre1_noc>; + }; + + slv_qns_a2noc_snoc:slv-qns-a2noc-snoc { + cell-id = ; + label = "slv-qns-a2noc-snoc"; + qcom,buswidth = <16>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_aggre2_noc>; + qcom,connections = <&mas_qnm_aggre2_noc>; + }; + + slv_srvc_aggre2_noc:slv-srvc-aggre2-noc { + cell-id = ; + label = "slv-srvc-aggre2-noc"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_aggre2_noc>; + }; + + slv_qns_cdsp_gemnoc:slv-qns-cdsp-gemnoc { + cell-id = ; + label = "slv-qns-cdsp-gemnoc"; + qcom,buswidth = <32>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_compute_noc>; + qcom,connections = <&mas_qnm_cmpnoc>; + qcom,bcms = <&bcm_co0>; + }; + + slv_qhs_a1_noc_cfg:slv-qhs-a1-noc-cfg { + cell-id = ; + label = "slv-qhs-a1-noc-cfg"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,connections = <&mas_qhm_a1noc_cfg>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_a2_noc_cfg:slv-qhs-a2-noc-cfg { + cell-id = ; + label = "slv-qhs-a2-noc-cfg"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,connections = <&mas_qhm_a2noc_cfg>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_ahb2phy0:slv-qhs-ahb2phy0 { + cell-id = ; + label = "slv-qhs-ahb2phy0"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_ahb2phy2:slv-qhs-ahb2phy2 { + cell-id = ; + label = "slv-qhs-ahb2phy2"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn1>; + }; + + slv_qhs_aop:slv-qhs-aop { + cell-id = ; + label = "slv-qhs-aop"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_aoss:slv-qhs-aoss { + cell-id = ; + label = "slv-qhs-aoss"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_boot_rom:slv-qhs-boot-rom { + cell-id = ; + label = "slv-qhs-boot-rom"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_camera_cfg:slv-qhs-camera-cfg { + cell-id = ; + label = "slv-qhs-camera-cfg"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_camera_nrt_throttle_cfg:slv-qhs-camera-nrt-thrott-cfg { + cell-id = ; + label = "slv-qhs-camera-nrt-throttle-cfg"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_camera_rt_throttle_cfg:slv-qhs-camera-rt-throttle-cfg { + cell-id = ; + label = "slv-qhs-camera-rt-throttle-cfg"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_clk_ctl:slv-qhs-clk-ctl { + cell-id = ; + label = "slv-qhs-clk-ctl"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_cpr_cx:slv-qhs-cpr-cx { + cell-id = ; + label = "slv-qhs-cpr-cx"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_cpr_mx:slv-qhs-cpr-mx { + cell-id = ; + label = "slv-qhs-cpr-mx"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_crypto0_cfg:slv-qhs-crypto0-cfg { + cell-id = ; + label = "slv-qhs-crypto0-cfg"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_dcc_cfg:slv-qhs-dcc-cfg { + cell-id = ; + label = "slv-qhs-dcc-cfg"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_ddrss_cfg:slv-qhs-ddrss-cfg { + cell-id = ; + label = "slv-qhs-ddrss-cfg"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,connections = <&mas_qhm_cnoc_dc_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_display_cfg:slv-qhs-display-cfg { + cell-id = ; + label = "slv-qhs-display-cfg"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_display_rt_throttle_cfg:slv-qhs-display-rt-throt-cfg { + cell-id = ; + label = "slv-qhs-display-rt-throttle-cfg"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_display_throttle_cfg:slv-qhs-display-throttle-cfg { + cell-id = ; + label = "slv-qhs-display-throttle-cfg"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_emmc_cfg:slv-qhs-emmc-cfg { + cell-id = ; + label = "slv-qhs-emmc-cfg"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn1>; + }; + + slv_qhs_glm:slv-qhs-glm { + cell-id = ; + label = "slv-qhs-glm"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_gpuss_cfg:slv-qhs-gpuss-cfg { + cell-id = ; + label = "slv-qhs-gpuss-cfg"; + qcom,buswidth = <8>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_imem_cfg:slv-qhs-imem-cfg { + cell-id = ; + label = "slv-qhs-imem-cfg"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_ipa:slv-qhs-ipa { + cell-id = ; + label = "slv-qhs-ipa"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_mnoc_cfg:slv-qhs-mnoc-cfg { + cell-id = ; + label = "slv-qhs-mnoc-cfg"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,connections = <&mas_qhm_mnoc_cfg>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_mss_cfg:slv-qhs-mss-cfg { + cell-id = ; + label = "slv-qhs-mss-cfg"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_npu_cfg:slv-qhs-npu-cfg { + cell-id = ; + label = "slv-qhs-npu-cfg"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,connections = <&mas_qhm_npu_cfg>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_npu_dma_throttle_cfg:slv-qhs-npu-dma-throttle-cfg { + cell-id = ; + label = "slv-qhs-npu-dma-throttle-cfg"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_npu_dsp_throttle_cfg:slv-qhs-npu-dsp-throttle-cfg { + cell-id = ; + label = "slv-qhs-npu-dsp-throttle-cfg"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_pdm:slv-qhs-pdm { + cell-id = ; + label = "slv-qhs-pdm"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn1>; + }; + + slv_qhs_pimem_cfg:slv-qhs-pimem-cfg { + cell-id = ; + label = "slv-qhs-pimem-cfg"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_prng:slv-qhs-prng { + cell-id = ; + label = "slv-qhs-prng"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_qdss_cfg:slv-qhs-qdss-cfg { + cell-id = ; + label = "slv-qhs-qdss-cfg"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_qm_cfg:slv-qhs-qm-cfg { + cell-id = ; + label = "slv-qhs-qm-cfg"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_qm_mpu_cfg:slv-qhs-qm-mpu-cfg { + cell-id = ; + label = "slv-qhs-qm-mpu-cfg"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_qspi:slv-qhs-qspi { + cell-id = ; + label = "slv-qhs-qspi"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn1>; + }; + + slv_qhs_qup0:slv-qhs-qup0 { + cell-id = ; + label = "slv-qhs-qup0"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_qup1:slv-qhs-qup1 { + cell-id = ; + label = "slv-qhs-qup1"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_sdc2:slv-qhs-sdc2 { + cell-id = ; + label = "slv-qhs-sdc2"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn1>; + }; + + slv_qhs_security:slv-qhs-security { + cell-id = ; + label = "slv-qhs-security"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_snoc_cfg:slv-qhs-snoc-cfg { + cell-id = ; + label = "slv-qhs-snoc-cfg"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,connections = <&mas_qhm_snoc_cfg>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_tcsr:slv-qhs-tcsr { + cell-id = ; + label = "slv-qhs-tcsr"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_tlmm_1:slv-qhs-tlmm-1 { + cell-id = ; + label = "slv-qhs-tlmm-1"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_tlmm_2:slv-qhs-tlmm-2 { + cell-id = ; + label = "slv-qhs-tlmm-2"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_tlmm_3:slv-qhs-tlmm-3 { + cell-id = ; + label = "slv-qhs-tlmm-3"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_ufs_mem_cfg:slv-qhs-ufs-mem-cfg { + cell-id = ; + label = "slv-qhs-ufs-mem-cfg"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_usb3_0:slv-qhs-usb3-0 { + cell-id = ; + label = "slv-qhs-usb3-0"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_venus_cfg:slv-qhs-venus-cfg { + cell-id = ; + label = "slv-qhs-venus-cfg"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_venus_throttle_cfg:slv-qhs-venus-throttle-cfg { + cell-id = ; + label = "slv-qhs-venus-throttle-cfg"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_vsense_ctrl_cfg:slv-qhs-vsense-ctrl-cfg { + cell-id = ; + label = "slv-qhs-vsense-ctrl-cfg"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_srvc_cnoc:slv-srvc-cnoc { + cell-id = ; + label = "slv-srvc-cnoc"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_config_noc>; + qcom,bcms = <&bcm_cn0>; + }; + + slv_qhs_gemnoc:slv-qhs-gemnoc { + cell-id = ; + label = "slv-qhs-gemnoc"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_dc_noc>; + qcom,connections = <&mas_qhm_gemnoc_cfg>; + }; + + slv_qhs_llcc:slv-qhs-llcc { + cell-id = ; + label = "slv-qhs-llcc"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_dc_noc>; + }; + + slv_qhs_mdsp_ms_mpu_cfg:slv-qhs-mdsp-ms-mpu-cfg { + cell-id = ; + label = "slv-qhs-mdsp-ms-mpu-cfg"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_gem_noc>; + }; + + slv_qns_gem_noc_snoc:slv-qns-gem-noc-snoc { + cell-id = ; + label = "slv-qns-gem-noc-snoc"; + qcom,buswidth = <8>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_gem_noc>; + qcom,connections = <&mas_qnm_gemnoc>; + }; + + slv_qns_llcc:slv-qns-llcc { + cell-id = ; + label = "slv-qns-llcc"; + qcom,buswidth = <16>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_gem_noc>; + qcom,connections = <&mas_llcc_mc>; + qcom,bcms = <&bcm_sh0>; + }; + + slv_srvc_gemnoc:slv-srvc-gemnoc { + cell-id = ; + label = "slv-srvc-gemnoc"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_gem_noc>; + }; + + slv_ipa_core_slave:slv-ipa-core-slave { + cell-id = ; + label = "slv-ipa-core-slave"; + qcom,buswidth = <8>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_ipa_virt>; + qcom,bcms = <&bcm_ip0>; + }; + + slv_ebi:slv-ebi { + cell-id = ; + label = "slv-ebi"; + qcom,buswidth = <4>; + qcom,agg-ports = <2>; + qcom,bus-dev = <&fab_mc_virt>; + qcom,bcms = <&bcm_mc0>, <&bcm_acv>; + }; + + slv_qns_mem_noc_hf:slv-qns-mem-noc-hf { + cell-id = ; + label = "slv-qns-mem-noc-hf"; + qcom,buswidth = <32>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_mmss_noc>; + qcom,connections = <&mas_qnm_mnoc_hf>; + qcom,bcms = <&bcm_mm0>; + }; + + slv_qns_mem_noc_sf:slv-qns-mem-noc-sf { + cell-id = ; + label = "slv-qns-mem-noc-sf"; + qcom,buswidth = <32>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_mmss_noc>; + qcom,connections = <&mas_qnm_mnoc_sf>; + qcom,bcms = <&bcm_mm2>; + }; + + slv_srvc_mnoc:slv-srvc-mnoc { + cell-id = ; + label = "slv-srvc-mnoc"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_mmss_noc>; + }; + + slv_qhs_cal_dp0:slv-qhs-cal-dp0 { + cell-id = ; + label = "slv-qhs-cal-dp0"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_npu_noc>; + }; + + slv_qhs_cp:slv-qhs-cp { + cell-id = ; + label = "slv-qhs-cp"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_npu_noc>; + }; + + slv_qhs_dma_bwmon:slv-qhs-dma-bwmon { + cell-id = ; + label = "slv-qhs-dma-bwmon"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_npu_noc>; + }; + + slv_qhs_dpm:slv-qhs-dpm { + cell-id = ; + label = "slv-qhs-dpm"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_npu_noc>; + }; + + slv_qhs_isense:slv-qhs-isense { + cell-id = ; + label = "slv-qhs-isense"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_npu_noc>; + }; + + slv_qhs_llm:slv-qhs-llm { + cell-id = ; + label = "slv-qhs-llm"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_npu_noc>; + }; + + slv_qhs_tcm:slv-qhs-tcm { + cell-id = ; + label = "slv-qhs-tcm"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_npu_noc>; + }; + + slv_qns_npu_sys:slv-qns-npu-sys { + cell-id = ; + label = "slv-qns-npu-sys"; + qcom,buswidth = <32>; + qcom,agg-ports = <2>; + qcom,bus-dev = <&fab_npu_noc>; + }; + + slv_srvc_noc:slv-srvc-noc { + cell-id = ; + label = "slv-srvc-noc"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_npu_noc>; + }; + + slv_qup_core_slave_0:slv-qup-core-slave-0 { + cell-id = ; + label = "slv-qup-core-slave-0"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_qup_virt>; + }; + + slv_qup_core_slave_1:slv-qup-core-slave-1 { + cell-id = ; + label = "slv-qup-core-slave-1"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_qup_virt>; + }; + + slv_qhs_apss:slv-qhs-apss { + cell-id = ; + label = "slv-qhs-apss"; + qcom,buswidth = <8>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_system_noc>; + }; + + slv_qns_cnoc:slv-qns-cnoc { + cell-id = ; + label = "slv-qns-cnoc"; + qcom,buswidth = <8>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_system_noc>; + qcom,connections = <&mas_qnm_snoc>; + }; + + slv_qns_gemnoc_gc:slv-qns-gemnoc-gc { + cell-id = ; + label = "slv-qns-gemnoc-gc"; + qcom,buswidth = <8>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_system_noc>; + qcom,connections = <&mas_qnm_snoc_gc>; + qcom,bcms = <&bcm_sn2>; + }; + + slv_qns_gemnoc_sf:slv-qns-gemnoc-sf { + cell-id = ; + label = "slv-qns-gemnoc-sf"; + qcom,buswidth = <16>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_system_noc>; + qcom,connections = <&mas_qnm_snoc_sf>; + qcom,bcms = <&bcm_sn0>; + }; + + slv_qxs_imem:slv-qxs-imem { + cell-id = ; + label = "slv-qxs-imem"; + qcom,buswidth = <8>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_system_noc>; + qcom,bcms = <&bcm_sn1>; + }; + + slv_qxs_pimem:slv-qxs-pimem { + cell-id = ; + label = "slv-qxs-pimem"; + qcom,buswidth = <8>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_system_noc>; + qcom,bcms = <&bcm_sn3>; + }; + + slv_srvc_snoc:slv-srvc-snoc { + cell-id = ; + label = "slv-srvc-snoc"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_system_noc>; + }; + + slv_xs_qdss_stm:slv-xs-qdss-stm { + cell-id = ; + label = "slv-xs-qdss-stm"; + qcom,buswidth = <4>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_system_noc>; + qcom,bcms = <&bcm_sn4>; + }; + + slv_xs_sys_tcu_cfg:slv-xs-sys-tcu-cfg { + cell-id = ; + label = "slv-xs-sys-tcu-cfg"; + qcom,buswidth = <8>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_system_noc>; + }; + + slv_qns_llcc_display:slv-qns-llcc_display { + cell-id = ; + label = "slv-qns-llcc_display"; + qcom,buswidth = <16>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_gem_noc_display>; + qcom,connections = <&mas_llcc_mc_display>; + qcom,bcms = <&bcm_sh0_display>; + }; + + slv_ebi_display:slv-ebi_display { + cell-id = ; + label = "slv-ebi_display"; + qcom,buswidth = <4>; + qcom,agg-ports = <2>; + qcom,bus-dev = <&fab_mc_virt_display>; + qcom,bcms = <&bcm_mc0_display>, <&bcm_acv_display>; + }; + + slv_qns_mem_noc_hf_display:slv-qns-mem-noc-hf_display { + cell-id = ; + label = "slv-qns-mem-noc-hf_display"; + qcom,buswidth = <32>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_mmss_noc_display>; + qcom,connections = <&mas_qnm_mnoc_hf_display>; + qcom,bcms = <&bcm_mm0_display>; + }; + + slv_qns_mem_noc_sf_display:slv-qns-mem-noc-sf_display { + cell-id = ; + label = "slv-qns-mem-noc-sf_display"; + qcom,buswidth = <32>; + qcom,agg-ports = <1>; + qcom,bus-dev = <&fab_mmss_noc_display>; + qcom,connections = <&mas_qnm_mnoc_sf_display>; + qcom,bcms = <&bcm_mm2_display>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index ef8f9ebafa09..a18f7bfcc1ce 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -2249,6 +2249,7 @@ #include "msm-arm-smmu-atoll.dtsi" #include "atoll-qupv3.dtsi" #include "sdmmagpie-gpu.dtsi" +#include "atoll-bus.dtsi" &msm_gpu { /delete-property/qcom,gpu-speed-bin; diff --git a/include/dt-bindings/msm/msm-bus-ids.h b/include/dt-bindings/msm/msm-bus-ids.h index e0a2b41634cd..978b5e20eed6 100644 --- a/include/dt-bindings/msm/msm-bus-ids.h +++ b/include/dt-bindings/msm/msm-bus-ids.h @@ -50,6 +50,7 @@ #define MSM_BUS_FAB_GPU_VIRT 6158 #define MSM_BUS_FAB_MMNRT_VIRT 6159 #define MSM_BUS_FAB_MMRT_VIRT 6160 +#define MSM_BUS_FAB_NPU_NOC 6161 #define MSM_BUS_FAB_MC_VIRT_DISPLAY 26000 #define MSM_BUS_FAB_MEM_NOC_DISPLAY 26001 @@ -100,16 +101,17 @@ #define MSM_BUS_BCM_CO0 7041 #define MSM_BUS_BCM_CO1 7042 #define MSM_BUS_BCM_CO2 7043 -#define MSM_BUS_BCM_QP0 7044 -#define MSM_BUS_BCM_PN0 7045 -#define MSM_BUS_BCM_PN1 7046 -#define MSM_BUS_BCM_PN2 7047 -#define MSM_BUS_BCM_PN3 7048 -#define MSM_BUS_BCM_PN4 7049 -#define MSM_BUS_BCM_PN5 7050 -#define MSM_BUS_BCM_SH8 7051 -#define MSM_BUS_BCM_SH9 7052 -#define MSM_BUS_BCM_SH10 7053 +#define MSM_BUS_BCM_CO3 7044 +#define MSM_BUS_BCM_QP0 7045 +#define MSM_BUS_BCM_PN0 7046 +#define MSM_BUS_BCM_PN1 7047 +#define MSM_BUS_BCM_PN2 7048 +#define MSM_BUS_BCM_PN3 7049 +#define MSM_BUS_BCM_PN4 7050 +#define MSM_BUS_BCM_PN5 7051 +#define MSM_BUS_BCM_SH8 7052 +#define MSM_BUS_BCM_SH9 7053 +#define MSM_BUS_BCM_SH10 7054 #define MSM_BUS_RSC_APPS 8000 #define MSM_BUS_RSC_DISP 8001 @@ -308,6 +310,8 @@ #define MSM_BUS_MASTER_GPU_CDSP_PROC 182 #define MSM_BUS_MASTER_QUP_CORE_0 183 #define MSM_BUS_MASTER_QUP_CORE_1 184 +#define MSM_BUS_MASTER_NPU_PROC 185 +#define MSM_BUS_MASTER_NPU_SYS 186 #define MSM_BUS_MASTER_LLCC_DISPLAY 20000 #define MSM_BUS_MASTER_MNOC_HF_MEM_NOC_DISPLAY 20001 @@ -698,7 +702,20 @@ #define MSM_BUS_SLAVE_SNOC_BIMC_RT 819 #define MSM_BUS_SLAVE_GPU_CDSP_BIMC 820 #define MSM_BUS_SLAVE_QM_MPU_CFG 821 -#define MSM_BUS_SLAVE_CDSP_THROTTLE_CFG 822 +#define MSM_BUS_SLAVE_CDSP_THROTTLE_CFG 822 +#define MSM_BUS_MASTER_NPU_NOC_CFG 823 +#define MSM_BUS_SLAVE_NPU_CAL_DP0 824 +#define MSM_BUS_SLAVE_NPU_CP 825 +#define MSM_BUS_SLAVE_NPU_INT_DMA_BWMON_CFG 826 +#define MSM_BUS_SLAVE_NPU_DPM 827 +#define MSM_BUS_SLAVE_ISENSE_CFG 828 +#define MSM_BUS_SLAVE_NPU_LLM_CFG 829 +#define MSM_BUS_SLAVE_NPU_TCM 830 +#define MSM_BUS_SLAVE_NPU_COMPUTE_NOC 831 +#define MSM_BUS_SLAVE_SERVICE_NPU_NOC 832 +#define MSM_BUS_SLAVE_DISPLAY_RT_THROTTLE_CFG 833 +#define MSM_BUS_SLAVE_NPU_DMA_BWMON_CFG 834 +#define MSM_BUS_SLAVE_NPU_PROC_BWMON_CFG 835 #define MSM_BUS_SLAVE_EBI_CH0_DISPLAY 20512 #define MSM_BUS_SLAVE_LLCC_DISPLAY 20513 -- GitLab From 72c0fd6726695611224e4da443007b503b065771 Mon Sep 17 00:00:00 2001 From: Sahil Chandna Date: Thu, 25 Jul 2019 10:32:25 +0530 Subject: [PATCH 1012/1121] power: power_supply: Display skin health in proper format This patch helps to display skin health status in proper format instead of reporting integer value. Change-Id: I3267059b42759c1902fe70e70c44bfb86936f574 Signed-off-by: Sahil Chandna --- drivers/power/supply/power_supply_sysfs.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/power/supply/power_supply_sysfs.c b/drivers/power/supply/power_supply_sysfs.c index 5f2ceb3e9d98..3789e3bf5e47 100644 --- a/drivers/power/supply/power_supply_sysfs.c +++ b/drivers/power/supply/power_supply_sysfs.c @@ -155,6 +155,9 @@ static ssize_t power_supply_show_property(struct device *dev, else if (off == POWER_SUPPLY_PROP_CONNECTOR_HEALTH) return scnprintf(buf, PAGE_SIZE, "%s\n", power_supply_health_text[value.intval]); + else if (off == POWER_SUPPLY_PROP_SKIN_HEALTH) + return scnprintf(buf, PAGE_SIZE, "%s\n", + power_supply_health_text[value.intval]); else if (off >= POWER_SUPPLY_PROP_MODEL_NAME) return sprintf(buf, "%s\n", value.strval); -- GitLab From c0e7627fca461d9badad115178f97d2b8f21bf85 Mon Sep 17 00:00:00 2001 From: Jay Jayanna Date: Wed, 24 Jul 2019 22:39:59 -0700 Subject: [PATCH 1013/1121] net: qrtr: mhi: Use spin_lock_bh in qcom_mhi_qrtr_send Use spin_lock_bh in qcom_mhi_qrtr_send as this is sufficient to avoid recursive spin lock issue. Change-Id: I214c056f66831837b7589940fe1789d0e9edc00c Signed-off-by: Jay Jayanna --- net/qrtr/mhi.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/net/qrtr/mhi.c b/net/qrtr/mhi.c index 17a7677e8e40..90dc2e917f5b 100644 --- a/net/qrtr/mhi.c +++ b/net/qrtr/mhi.c @@ -103,7 +103,6 @@ static int qcom_mhi_qrtr_send(struct qrtr_endpoint *ep, struct sk_buff *skb) { struct qrtr_mhi_dev *qdev = container_of(ep, struct qrtr_mhi_dev, ep); struct qrtr_mhi_pkt *pkt; - unsigned long flags; int rc; rc = skb_linearize(skb); @@ -123,7 +122,7 @@ static int qcom_mhi_qrtr_send(struct qrtr_endpoint *ep, struct sk_buff *skb) kref_get(&pkt->refcount); pkt->skb = skb; - spin_lock_irqsave(&qdev->ul_lock, flags); + spin_lock_bh(&qdev->ul_lock); list_add_tail(&pkt->node, &qdev->ul_pkts); rc = mhi_queue_transfer(qdev->mhi_dev, DMA_TO_DEVICE, skb, skb->len, MHI_EOT); @@ -131,10 +130,10 @@ static int qcom_mhi_qrtr_send(struct qrtr_endpoint *ep, struct sk_buff *skb) list_del(&pkt->node); kfree_skb(skb); kfree(pkt); - spin_unlock_irqrestore(&qdev->ul_lock, flags); + spin_unlock_bh(&qdev->ul_lock); return rc; } - spin_unlock_irqrestore(&qdev->ul_lock, flags); + spin_unlock_bh(&qdev->ul_lock); if (skb->sk) sock_hold(skb->sk); -- GitLab From 8a42496377d71d127528de8a1a6c105d6b00f1df Mon Sep 17 00:00:00 2001 From: Zou Shunxiang Date: Thu, 25 Jul 2019 14:31:33 +0800 Subject: [PATCH 1014/1121] defconfig: quin gvm: add ptp config Add ptp config for supporting ptp clock feature Change-Id: If5fc35d66350fbea3f04b0c89cbd7f7624efffff Signed-off-by: Zou Shunxiang --- arch/arm64/configs/vendor/qti-quin-gvm-perf_defconfig | 1 + arch/arm64/configs/vendor/qti-quin-gvm_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm64/configs/vendor/qti-quin-gvm-perf_defconfig b/arch/arm64/configs/vendor/qti-quin-gvm-perf_defconfig index 1c21491ae274..11b0d60e4112 100644 --- a/arch/arm64/configs/vendor/qti-quin-gvm-perf_defconfig +++ b/arch/arm64/configs/vendor/qti-quin-gvm-perf_defconfig @@ -308,6 +308,7 @@ CONFIG_SPI=y CONFIG_SPI_QCOM_GENI=y CONFIG_SPI_SPIDEV=y CONFIG_SPMI=y +CONFIG_PTP_1588_CLOCK=y CONFIG_PINCTRL_SX150X=y CONFIG_PINCTRL_SM8150=y CONFIG_PINCTRL_SDMSHRIKE=y diff --git a/arch/arm64/configs/vendor/qti-quin-gvm_defconfig b/arch/arm64/configs/vendor/qti-quin-gvm_defconfig index 0ab5f39e47ad..c6fa0e9008c3 100644 --- a/arch/arm64/configs/vendor/qti-quin-gvm_defconfig +++ b/arch/arm64/configs/vendor/qti-quin-gvm_defconfig @@ -320,6 +320,7 @@ CONFIG_SPI=y CONFIG_SPI_QCOM_GENI=y CONFIG_SPI_SPIDEV=y CONFIG_SPMI=y +CONFIG_PTP_1588_CLOCK=y CONFIG_PINCTRL_SX150X=y CONFIG_PINCTRL_SM8150=y CONFIG_PINCTRL_SDMSHRIKE=y -- GitLab From 3656905245896c2af4bad445282328f53a282a87 Mon Sep 17 00:00:00 2001 From: Vipin Deep Kaur Date: Wed, 26 Jun 2019 10:14:57 +0530 Subject: [PATCH 1015/1121] ARM: dts: msm: Add GPI DMA and QUPv3 SE dt nodes for atoll Add GPI device tree nodes and QUPv3 SE dt nodes for SPI, I2C, HSUART and console UART on atoll. Change-Id: I4720cb0784e8ab67f4725fe9346010d06726d754 Signed-off-by: Vipin Deep Kaur --- arch/arm64/boot/dts/qcom/atoll-pinctrl.dtsi | 663 +++++++++++++++++++- arch/arm64/boot/dts/qcom/atoll-qupv3.dtsi | 525 +++++++++++++++- 2 files changed, 1174 insertions(+), 14 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/atoll-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/atoll-pinctrl.dtsi index 328f975d136b..93cb2fda4f8a 100644 --- a/arch/arm64/boot/dts/qcom/atoll-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll-pinctrl.dtsi @@ -218,6 +218,668 @@ }; }; + qupv3_se0_spi_pins: qupv3_se0_spi_pins { + qupv3_se0_spi_active: qupv3_se0_spi_active { + mux { + pins = "gpio34", "gpio35", + "gpio36", "gpio37"; + function = "qup00"; + }; + + config { + pins = "gpio34", "gpio35", + "gpio36", "gpio37"; + drive-strength = <6>; + bias-disable; + }; + }; + + qupv3_se0_spi_sleep: qupv3_se0_spi_sleep { + mux { + pins = "gpio34", "gpio35", + "gpio36", "gpio37"; + function = "gpio"; + }; + + config { + pins = "gpio34", "gpio35", + "gpio36", "gpio37"; + drive-strength = <6>; + bias-disable; + }; + }; + }; + + qupv3_se1_spi_pins: qupv3_se1_spi_pins { + qupv3_se1_spi_active: qupv3_se1_spi_active { + mux { + pins = "gpio0", "gpio1", + "gpio2", "gpio3"; + function = "qup01"; + }; + + config { + pins = "gpio0", "gpio1", + "gpio2", "gpio3"; + drive-strength = <6>; + bias-disable; + }; + }; + + qupv3_se1_spi_sleep: qupv3_se1_spi_sleep { + mux { + pins = "gpio0", "gpio1", + "gpio2", "gpio3"; + function = "gpio"; + }; + + config { + pins = "gpio0", "gpio1", + "gpio2", "gpio3"; + drive-strength = <6>; + bias-disable; + }; + }; + }; + + qupv3_se3_spi_pins: qupv3_se3_spi_pins { + qupv3_se3_spi_active: qupv3_se3_spi_active { + mux { + pins = "gpio38", "gpio39", + "gpio40 ", "gpio41"; + function = "qup03"; + }; + + config { + pins = "gpio38", "gpio39", + "gpio40 ", "gpio41"; + drive-strength = <6>; + bias-disable; + }; + }; + + qupv3_se3_spi_sleep: qupv3_se3_spi_sleep { + mux { + pins = "gpio38", "gpio39", + "gpio40 ", "gpio41"; + function = "gpio"; + }; + + config { + pins = "gpio38", "gpio39", + "gpio40 ", "gpio41"; + drive-strength = <6>; + bias-disable; + }; + }; + }; + + qupv3_se5_spi_pins: qupv3_se5_spi_pins { + qupv3_se5_spi_active: qupv3_se5_spi_active { + mux { + pins = "gpio25", "gpio26", + "gpio27", "gpio28"; + function = "qup05"; + }; + + config { + pins = "gpio25", "gpio26", + "gpio27", "gpio28"; + drive-strength = <6>; + bias-disable; + }; + }; + + qupv3_se5_spi_sleep: qupv3_se5_spi_sleep { + mux { + pins = "gpio25", "gpio26", + "gpio27", "gpio28"; + function = "gpio"; + }; + + config { + pins = "gpio25", "gpio26", + "gpio27", "gpio28"; + drive-strength = <6>; + bias-disable; + }; + }; + }; + + qupv3_se0_i2c_pins: qupv3_se0_i2c_pins { + qupv3_se0_i2c_active: qupv3_se0_i2c_active { + mux { + pins = "gpio34", "gpio35"; + function = "qup00"; + }; + + config { + pins = "gpio34", "gpio35"; + drive-strength = <2>; + bias-disable; + }; + }; + + qupv3_se0_i2c_sleep: qupv3_se0_i2c_sleep { + mux { + pins = "gpio34", "gpio35"; + function = "gpio"; + }; + + config { + pins = "gpio34", "gpio35"; + drive-strength = <2>; + bias-pull-up; + }; + }; + }; + + qupv3_se1_i2c_pins: qupv3_se1_i2c_pins { + qupv3_se1_i2c_active: qupv3_se1_i2c_active { + mux { + pins = "gpio0", "gpio1"; + function = "qup01"; + }; + + config { + pins = "gpio0", "gpio1"; + drive-strength = <2>; + bias-disable; + }; + }; + + qupv3_se1_i2c_sleep: qupv3_se1_i2c_sleep { + mux { + pins = "gpio0", "gpio1"; + function = "gpio"; + }; + + config { + pins = "gpio0", "gpio1"; + drive-strength = <2>; + bias-pull-up; + }; + }; + }; + + qupv3_se2_i2c_pins: qupv3_se2_i2c_pins { + qupv3_se2_i2c_active: qupv3_se2_i2c_active { + mux { + pins = "gpio15", "gpio16"; + function = "qup02"; + }; + + config { + pins = "gpio15", "gpio16"; + drive-strength = <2>; + bias-disable; + }; + }; + + qupv3_se2_i2c_sleep: qupv3_se2_i2c_sleep { + mux { + pins = "gpio15", "gpio16"; + function = "gpio"; + }; + + config { + pins = "gpio15", "gpio16"; + drive-strength = <2>; + bias-pull-up; + }; + }; + }; + + qupv3_se3_i2c_pins: qupv3_se3_i2c_pins { + qupv3_se3_i2c_active: qupv3_se3_i2c_active { + mux { + pins = "gpio38", "gpio39"; + function = "qup03"; + }; + + config { + pins = "gpio38", "gpio39"; + drive-strength = <2>; + bias-disable; + }; + }; + + qupv3_se3_i2c_sleep: qupv3_se3_i2c_sleep { + mux { + pins = "gpio38", "gpio39"; + function = "gpio"; + }; + + config { + pins = "gpio38", "gpio39"; + drive-strength = <2>; + bias-pull-up; + }; + }; + }; + + qupv3_se4_i2c_pins: qupv3_se4_i2c_pins { + qupv3_se4_i2c_active: qupv3_se4_i2c_active { + mux { + pins = "gpio115", "gpio116"; + function = "qup04"; + }; + + config { + pins = "gpio115", "gpio116"; + drive-strength = <2>; + bias-disable; + }; + }; + + qupv3_se4_i2c_sleep: qupv3_se4_i2c_sleep { + mux { + pins = "gpio115", "gpio116"; + function = "gpio"; + }; + + config { + pins = "gpio115", "gpio116"; + drive-strength = <2>; + bias-pull-up; + }; + }; + }; + + qupv3_se5_i2c_pins: qupv3_se5_i2c_pins { + qupv3_se5_i2c_active: qupv3_se5_i2c_active { + mux { + pins = "gpio25", "gpio26"; + function = "qup05"; + }; + + config { + pins = "gpio25", "gpio26"; + drive-strength = <2>; + bias-disable; + }; + }; + + qupv3_se5_i2c_sleep: qupv3_se5_i2c_sleep { + mux { + pins = "gpio25", "gpio26"; + function = "gpio"; + }; + + config { + pins = "gpio25", "gpio26"; + drive-strength = <2>; + bias-pull-up; + }; + }; + }; + + qupv3_se3_4uart_pins: qupv3_se3_4uart_pins { + qupv3_se3_default_ctsrtsrx: + qupv3_se3_default_ctsrtsrx { + mux { + pins = "gpio38", "gpio39", + "gpio41"; + function = "gpio"; + }; + + config { + pins = "gpio38", "gpio39", + "gpio41"; + drive-strength = <2>; + bias-pull-down; + }; + }; + + qupv3_se3_default_tx: qupv3_se3_default_tx { + mux { + pins = "gpio40"; + function = "gpio"; + }; + + config { + pins = "gpio40"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + qupv3_se3_ctsrx: qupv3_se3_ctsrx { + mux { + pins = "gpio38", "gpio41"; + function = "qup03"; + }; + + config { + pins = "gpio38", "gpio41"; + drive-strength = <2>; + bias-disable; + }; + }; + + qupv3_se3_rts: qupv3_se3_rts { + mux { + pins = "gpio39"; + function = "qup03"; + }; + + config { + pins = "gpio39"; + drive-strength = <2>; + bias-pull-down; + }; + }; + + qupv3_se3_tx: qupv3_se3_tx { + mux { + pins = "gpio40"; + function = "qup03"; + }; + + config { + pins = "gpio40"; + drive-strength = <2>; + bias-pull-up; + }; + }; + }; + + qupv3_se6_spi_pins: qupv3_se6_spi_pins { + qupv3_se6_spi_active: qupv3_se6_spi_active { + mux { + pins = "gpio59", "gpio60", + "gpio61", "gpio62"; + function = "qup10"; + }; + + config { + pins = "gpio59", "gpio60", + "gpio61", "gpio62"; + drive-strength = <6>; + bias-disable; + }; + }; + + qupv3_se6_spi_sleep: qupv3_se6_spi_sleep { + mux { + pins = "gpio59", "gpio60", + "gpio61", "gpio62"; + function = "gpio"; + }; + + config { + pins = "gpio59", "gpio60", + "gpio61", "gpio62"; + drive-strength = <6>; + bias-disable; + }; + }; + }; + + qupv3_se8_spi_pins: qupv3_se8_spi_pins { + qupv3_se8_spi_active: qupv3_se8_spi_active { + mux { + pins = "gpio42", "gpio43", + "gpio44", "gpio45"; + function = "qup12"; + }; + + config { + pins = "gpio42", "gpio43", + "gpio44", "gpio45"; + drive-strength = <6>; + bias-disable; + }; + }; + + qupv3_se8_spi_sleep: qupv3_se8_spi_sleep { + mux { + pins = "gpio42", "gpio43", + "gpio44", "gpio45"; + function = "gpio"; + }; + + config { + pins = "gpio42", "gpio43", + "gpio44", "gpio45"; + drive-strength = <6>; + bias-disable; + }; + }; + }; + + qupv3_se10_spi_pins: qupv3_se10_spi_pins { + qupv3_se10_spi_active: qupv3_se10_spi_active { + mux { + pins = "gpio86", "gpio87", + "gpio88 ", "gpio89"; + function = "qup14"; + }; + + config { + pins = "gpio86", "gpio87", + "gpio88 ", "gpio89"; + drive-strength = <6>; + bias-disable; + }; + }; + + qupv3_se10_spi_sleep: qupv3_se10_spi_sleep { + mux { + pins = "gpio86", "gpio87", + "gpio88 ", "gpio89"; + function = "gpio"; + }; + + config { + pins = "gpio86", "gpio87", + "gpio88 ", "gpio89"; + drive-strength = <6>; + bias-disable; + }; + }; + }; + + qupv3_se11_spi_pins: qupv3_se11_spi_pins { + qupv3_se11_spi_active: qupv3_se11_spi_active { + mux { + pins = "gpio53", "gpio54", + "gpio55", "gpio56"; + function = "qup15"; + }; + + config { + pins = "gpio53", "gpio54", + "gpio55", "gpio56"; + drive-strength = <6>; + bias-disable; + }; + }; + + qupv3_se11_spi_sleep: qupv3_se11_spi_sleep { + mux { + pins = "gpio53", "gpio54", + "gpio55", "gpio56"; + function = "gpio"; + }; + + config { + pins = "gpio53", "gpio54", + "gpio55", "gpio56"; + drive-strength = <6>; + bias-disable; + }; + }; + }; + + qupv3_se6_i2c_pins: qupv3_se6_i2c_pins { + qupv3_se6_i2c_active: qupv3_se6_i2c_active { + mux { + pins = "gpio59", "gpio60"; + function = "qup10"; + }; + + config { + pins = "gpio59", "gpio60"; + drive-strength = <2>; + bias-disable; + }; + }; + + qupv3_se6_i2c_sleep: qupv3_se6_i2c_sleep { + mux { + pins = "gpio59", "gpio60"; + function = "gpio"; + }; + + config { + pins = "gpio59", "gpio60"; + drive-strength = <2>; + bias-pull-up; + }; + }; + }; + + qupv3_se7_i2c_pins: qupv3_se7_i2c_pins { + qupv3_se7_i2c_active: qupv3_se7_i2c_active { + mux { + pins = "gpio6", "gpio7"; + function = "qup11"; + }; + + config { + pins = "gpio6", "gpio7"; + drive-strength = <2>; + bias-disable; + }; + }; + + qupv3_se7_i2c_sleep: qupv3_se7_i2c_sleep { + mux { + pins = "gpio6", "gpio7"; + function = "gpio"; + }; + + config { + pins = "gpio6", "gpio7"; + drive-strength = <2>; + bias-pull-up; + }; + }; + }; + + qupv3_se8_i2c_pins: qupv3_se8_i2c_pins { + qupv3_se8_i2c_active: qupv3_se8_i2c_active { + mux { + pins = "gpio42", "gpio43"; + function = "qup12"; + }; + + config { + pins = "gpio42", "gpio43"; + drive-strength = <2>; + bias-disable; + }; + }; + + qupv3_se8_i2c_sleep: qupv3_se8_i2c_sleep { + mux { + pins = "gpio42", "gpio43"; + function = "gpio"; + }; + + config { + pins = "gpio42", "gpio43"; + drive-strength = <2>; + bias-pull-up; + }; + }; + }; + + qupv3_se9_i2c_pins: qupv3_se9_i2c_pins { + qupv3_se9_i2c_active: qupv3_se9_i2c_active { + mux { + pins = "gpio46", "gpio47"; + function = "qup13"; + }; + + config { + pins = "gpio46", "gpio47"; + drive-strength = <2>; + bias-disable; + }; + }; + + qupv3_se9_i2c_sleep: qupv3_se9_i2c_sleep { + mux { + pins = "gpio46", "gpio47"; + function = "gpio"; + }; + + config { + pins = "gpio46", "gpio47"; + drive-strength = <2>; + bias-pull-up; + }; + }; + }; + + qupv3_se10_i2c_pins: qupv3_se10_i2c_pins { + qupv3_se10_i2c_active: qupv3_se10_i2c_active { + mux { + pins = "gpio86", "gpio87"; + function = "qup14"; + }; + + config { + pins = "gpio86", "gpio87"; + drive-strength = <2>; + bias-disable; + }; + }; + + qupv3_se10_i2c_sleep: qupv3_se10_i2c_sleep { + mux { + pins = "gpio86", "gpio87"; + function = "gpio"; + }; + + config { + pins = "gpio86", "gpio87"; + drive-strength = <2>; + bias-pull-up; + }; + }; + }; + + qupv3_se11_i2c_pins: qupv3_se11_i2c_pins { + qupv3_se11_i2c_active: qupv3_se11_i2c_active { + mux { + pins = "gpio53", "gpio54"; + function = "qup15"; + }; + + config { + pins = "gpio53", "gpio54"; + drive-strength = <2>; + bias-disable; + }; + }; + + qupv3_se11_i2c_sleep: qupv3_se11_i2c_sleep { + mux { + pins = "gpio53", "gpio54"; + function = "gpio"; + }; + + config { + pins = "gpio53", "gpio54"; + drive-strength = <2>; + bias-pull-up; + }; + }; + }; + qupv3_se8_2uart_pins: qupv3_se8_2uart_pins { qupv3_se8_2uart_active: qupv3_se8_2uart_active { mux { @@ -245,6 +907,5 @@ }; }; }; - }; }; diff --git a/arch/arm64/boot/dts/qcom/atoll-qupv3.dtsi b/arch/arm64/boot/dts/qcom/atoll-qupv3.dtsi index a79cdac7c492..a5075a5bc40b 100644 --- a/arch/arm64/boot/dts/qcom/atoll-qupv3.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll-qupv3.dtsi @@ -13,27 +13,298 @@ #include &soc { + /* QUPv3 North Instances + * North 0 : SE 0 + * North 1 : SE 1 + * North 2 : SE 2 + * North 3 : SE 3 + * North 4 : SE 4 + * North 5 : SE 5 + */ - /* QUPv3 North instances */ - qupv3_0: qcom,qupv3_0_geni_se@0x8c0000 { + qupv3_0: qcom,qupv3_0_geni_se@8c0000 { compatible = "qcom,qupv3-geni-se"; reg = <0x8c0000 0x2000>; - qcom,bus-mas-id = ; - qcom,bus-slv-id = ; + qcom,msm-bus,num-paths = <2>; + qcom,msm-bus,vectors-bus-ids = + , + ; qcom,iommu-s1-bypass; iommu_qupv3_0_geni_se_cb: qcom,iommu_qupv3_0_geni_se_cb { compatible = "qcom,qupv3-geni-se-cb"; - iommus = <&apps_smmu 0x043 0x0>; + iommus = <&apps_smmu 0x43 0x0>; }; }; - /* QUPv3 South Instances */ - qupv3_1: qcom,qupv3_1_geni_se@0xac0000 { + /* GPI */ + gpi_dma0: qcom,gpi-dma@800000 { + #dma-cells = <5>; + compatible = "qcom,gpi-dma"; + reg = <0x800000 0x60000>; + reg-names = "gpi-top"; + interrupts = <0 244 0>, <0 245 0>, <0 246 0>, <0 247 0>, + <0 248 0>, <0 249 0>, <0 250 0>, <0 251 0>, + <0 252 0>, <0 253 0>; + qcom,max-num-gpii = <10>; + qcom,gpii-mask = <0x1f>; + qcom,ev-factor = <2>; + iommus = <&apps_smmu 0x56 0x0>; + qcom,smmu-cfg = <0x1>; + qcom,gpi-ee-offset = <0x10000>; + qcom,iova-range = <0x0 0x100000 0x0 0x100000>; + status = "ok"; + }; + + /* SPI */ + qupv3_se0_spi: spi@880000 { + compatible = "qcom,spi-geni"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x880000 0x4000>; + reg-names = "se_phys"; + clock-names = "se-clk", "m-ahb", "s-ahb"; + clocks = <&clock_gcc GCC_QUPV3_WRAP0_S0_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_0_M_AHB_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_0_S_AHB_CLK>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&qupv3_se0_spi_active>; + pinctrl-1 = <&qupv3_se0_spi_sleep>; + interrupts = ; + spi-max-frequency = <50000000>; + qcom,wrapper-core = <&qupv3_0>; + dmas = <&gpi_dma0 0 0 1 64 0>, + <&gpi_dma0 1 0 1 64 0>; + dma-names = "tx", "rx"; + status = "disabled"; + }; + + qupv3_se1_spi: spi@884000 { + compatible = "qcom,spi-geni"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x884000 0x4000>; + reg-names = "se_phys"; + clock-names = "se-clk", "m-ahb", "s-ahb"; + clocks = <&clock_gcc GCC_QUPV3_WRAP0_S1_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_0_M_AHB_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_0_S_AHB_CLK>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&qupv3_se1_spi_active>; + pinctrl-1 = <&qupv3_se1_spi_sleep>; + interrupts = ; + spi-max-frequency = <50000000>; + qcom,wrapper-core = <&qupv3_0>; + dmas = <&gpi_dma0 0 1 1 64 0>, + <&gpi_dma0 1 1 1 64 0>; + dma-names = "tx", "rx"; + status = "disabled"; + }; + + qupv3_se3_spi: spi@88c000 { + compatible = "qcom,spi-geni"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x88c000 0x4000>; + reg-names = "se_phys"; + clock-names = "se-clk", "m-ahb", "s-ahb"; + clocks = <&clock_gcc GCC_QUPV3_WRAP0_S3_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_0_M_AHB_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_0_S_AHB_CLK>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&qupv3_se3_spi_active>; + pinctrl-1 = <&qupv3_se3_spi_sleep>; + interrupts = ; + spi-max-frequency = <50000000>; + qcom,wrapper-core = <&qupv3_0>; + dmas = <&gpi_dma0 0 3 1 64 0>, + <&gpi_dma0 1 3 1 64 0>; + dma-names = "tx", "rx"; + status = "disabled"; + }; + + qupv3_se5_spi: spi@894000 { + compatible = "qcom,spi-geni"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x894000 0x4000>; + reg-names = "se_phys"; + clock-names = "se-clk", "m-ahb", "s-ahb"; + clocks = <&clock_gcc GCC_QUPV3_WRAP0_S5_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_0_M_AHB_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_0_S_AHB_CLK>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&qupv3_se5_spi_active>; + pinctrl-1 = <&qupv3_se5_spi_sleep>; + interrupts = ; + spi-max-frequency = <50000000>; + qcom,wrapper-core = <&qupv3_0>; + dmas = <&gpi_dma0 0 5 1 64 0>, + <&gpi_dma0 1 5 1 64 0>; + dma-names = "tx", "rx"; + status = "disabled"; + }; + + /* I2C */ + qupv3_se0_i2c: i2c@880000 { + compatible = "qcom,i2c-geni"; + reg = <0x880000 0x4000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clock-names = "se-clk", "m-ahb", "s-ahb"; + clocks = <&clock_gcc GCC_QUPV3_WRAP0_S0_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_0_M_AHB_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_0_S_AHB_CLK>; + dmas = <&gpi_dma0 0 0 3 64 0>, + <&gpi_dma0 1 0 3 64 0>; + dma-names = "tx", "rx"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&qupv3_se0_i2c_active>; + pinctrl-1 = <&qupv3_se0_i2c_sleep>; + qcom,wrapper-core = <&qupv3_0>; + status = "disabled"; + }; + + qupv3_se1_i2c: i2c@884000 { + compatible = "qcom,i2c-geni"; + reg = <0x884000 0x4000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clock-names = "se-clk", "m-ahb", "s-ahb"; + clocks = <&clock_gcc GCC_QUPV3_WRAP0_S1_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_0_M_AHB_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_0_S_AHB_CLK>; + dmas = <&gpi_dma0 0 1 3 64 0>, + <&gpi_dma0 1 1 3 64 0>; + dma-names = "tx", "rx"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&qupv3_se1_i2c_active>; + pinctrl-1 = <&qupv3_se1_i2c_sleep>; + qcom,wrapper-core = <&qupv3_0>; + status = "disabled"; + }; + + qupv3_se2_i2c: i2c@888000 { + compatible = "qcom,i2c-geni"; + reg = <0x888000 0x4000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clock-names = "se-clk", "m-ahb", "s-ahb"; + clocks = <&clock_gcc GCC_QUPV3_WRAP0_S2_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_0_M_AHB_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_0_S_AHB_CLK>; + dmas = <&gpi_dma0 0 2 3 64 0>, + <&gpi_dma0 1 2 3 64 0>; + dma-names = "tx", "rx"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&qupv3_se2_i2c_active>; + pinctrl-1 = <&qupv3_se2_i2c_sleep>; + qcom,wrapper-core = <&qupv3_0>; + status = "disabled"; + }; + + qupv3_se3_i2c: i2c@88c000 { + compatible = "qcom,i2c-geni"; + reg = <0x88c000 0x4000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clock-names = "se-clk", "m-ahb", "s-ahb"; + clocks = <&clock_gcc GCC_QUPV3_WRAP0_S3_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_0_M_AHB_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_0_S_AHB_CLK>; + dmas = <&gpi_dma0 0 3 3 64 0>, + <&gpi_dma0 1 3 3 64 0>; + dma-names = "tx", "rx"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&qupv3_se3_i2c_active>; + pinctrl-1 = <&qupv3_se3_i2c_sleep>; + qcom,wrapper-core = <&qupv3_0>; + status = "disabled"; + }; + + qupv3_se4_i2c: i2c@890000 { + compatible = "qcom,i2c-geni"; + reg = <0x890000 0x4000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clock-names = "se-clk", "m-ahb", "s-ahb"; + clocks = <&clock_gcc GCC_QUPV3_WRAP0_S4_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_0_M_AHB_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_0_S_AHB_CLK>; + dmas = <&gpi_dma0 0 4 3 64 0>, + <&gpi_dma0 1 4 3 64 0>; + dma-names = "tx", "rx"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&qupv3_se4_i2c_active>; + pinctrl-1 = <&qupv3_se4_i2c_sleep>; + qcom,wrapper-core = <&qupv3_0>; + status = "disabled"; + }; + + qupv3_se5_i2c: i2c@894000 { + compatible = "qcom,i2c-geni"; + reg = <0x894000 0x4000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clock-names = "se-clk", "m-ahb", "s-ahb"; + clocks = <&clock_gcc GCC_QUPV3_WRAP0_S5_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_0_M_AHB_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_0_S_AHB_CLK>; + dmas = <&gpi_dma0 0 5 3 64 0>, + <&gpi_dma0 1 5 3 64 0>; + dma-names = "tx", "rx"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&qupv3_se5_i2c_active>; + pinctrl-1 = <&qupv3_se5_i2c_sleep>; + qcom,wrapper-core = <&qupv3_0>; + status = "disabled"; + }; + + /* HSUART: BT used instance */ + qupv3_se3_4uart: qcom,qup_uart@88c000 { + compatible = "qcom,msm-geni-serial-hs"; + reg = <0x88c000 0x4000>; + reg-names = "se_phys"; + clock-names = "se-clk", "m-ahb", "s-ahb"; + clocks = <&clock_gcc GCC_QUPV3_WRAP0_S3_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_0_M_AHB_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_0_S_AHB_CLK>; + pinctrl-names = "default", "active", "sleep"; + pinctrl-0 = <&qupv3_se3_default_ctsrtsrx>, + <&qupv3_se3_default_tx>; + pinctrl-1 = <&qupv3_se3_ctsrx>, <&qupv3_se3_rts>, + <&qupv3_se3_tx>; + pinctrl-2 = <&qupv3_se3_ctsrx>, <&qupv3_se3_rts>, + <&qupv3_se3_tx>; + interrupts-extended = <&intc GIC_SPI 604 IRQ_TYPE_LEVEL_HIGH>, + <&tlmm 41 IRQ_TYPE_LEVEL_HIGH>; + qcom,wrapper-core = <&qupv3_0>; + qcom,wakeup-byte = <0xFD>; + status = "disabled"; + }; + + /* QUPv3 South Instances + * South 0 : SE 6 + * South 1 : SE 7 + * South 2 : SE 8 + * South 3 : SE 9 + * South 4 : SE 10 + * South 5 : SE 11 + */ + + qupv3_1: qcom,qupv3_1_geni_se@ac0000 { compatible = "qcom,qupv3-geni-se"; reg = <0xac0000 0x2000>; - qcom,bus-mas-id = ; - qcom,bus-slv-id = ; + qcom,msm-bus,num-paths = <2>; + qcom,msm-bus,vectors-bus-ids = + , + ; qcom,iommu-s1-bypass; iommu_qupv3_1_geni_se_cb: qcom,iommu_qupv3_1_geni_se_cb { @@ -42,8 +313,236 @@ }; }; - /* Debug UART Instance for CDP/MTP/RUMI platform: QUPV3_1_SE2 */ - qupv3_se8_2uart: qcom,qup_uart@0xa88000 { + /* GPI */ + gpi_dma1: qcom,gpi-dma@a00000 { + #dma-cells = <5>; + compatible = "qcom,gpi-dma"; + reg = <0xa00000 0x60000>; + reg-names = "gpi-top"; + interrupts = <0 646 0>, <0 647 0>, <0 648 0>, <0 649 0>, + <0 650 0>, <0 651 0>, <0 652 0>, <0 653 0>, + <0 654 0>, <0 655 0>; + qcom,max-num-gpii = <10>; + qcom,gpii-mask = <0x3f>; + qcom,ev-factor = <2>; + iommus = <&apps_smmu 0x4d6 0x0>; + qcom,smmu-cfg = <0x1>; + qcom,gpi-ee-offset = <0x10000>; + qcom,iova-range = <0x0 0x100000 0x0 0x100000>; + status = "ok"; + }; + + /* SPI */ + qupv3_se6_spi: spi@a80000 { + compatible = "qcom,spi-geni"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xa80000 0x4000>; + reg-names = "se_phys"; + clock-names = "se-clk", "m-ahb", "s-ahb"; + clocks = <&clock_gcc GCC_QUPV3_WRAP1_S0_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_1_M_AHB_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_1_S_AHB_CLK>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&qupv3_se6_spi_active>; + pinctrl-1 = <&qupv3_se6_spi_sleep>; + interrupts = ; + spi-max-frequency = <50000000>; + qcom,wrapper-core = <&qupv3_1>; + dmas = <&gpi_dma1 0 0 1 64 0>, + <&gpi_dma1 1 0 1 64 0>; + dma-names = "tx", "rx"; + status = "disabled"; + }; + + qupv3_se8_spi: spi@a88000 { + compatible = "qcom,spi-geni"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xa88000 0x4000>; + reg-names = "se_phys"; + clock-names = "se-clk", "m-ahb", "s-ahb"; + clocks = <&clock_gcc GCC_QUPV3_WRAP1_S2_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_1_M_AHB_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_1_S_AHB_CLK>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&qupv3_se8_spi_active>; + pinctrl-1 = <&qupv3_se8_spi_sleep>; + interrupts = ; + spi-max-frequency = <50000000>; + qcom,wrapper-core = <&qupv3_1>; + dmas = <&gpi_dma1 0 2 1 64 0>, + <&gpi_dma1 1 2 1 64 0>; + dma-names = "tx", "rx"; + status = "disabled"; + }; + + qupv3_se10_spi: spi@a90000 { + compatible = "qcom,spi-geni"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xa90000 0x4000>; + reg-names = "se_phys"; + clock-names = "se-clk", "m-ahb", "s-ahb"; + clocks = <&clock_gcc GCC_QUPV3_WRAP1_S4_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_1_M_AHB_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_1_S_AHB_CLK>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&qupv3_se10_spi_active>; + pinctrl-1 = <&qupv3_se10_spi_sleep>; + interrupts = ; + spi-max-frequency = <50000000>; + qcom,wrapper-core = <&qupv3_1>; + dmas = <&gpi_dma1 0 4 1 64 0>, + <&gpi_dma1 1 4 1 64 0>; + dma-names = "tx", "rx"; + status = "disabled"; + }; + + qupv3_se11_spi: spi@a94000 { + compatible = "qcom,spi-geni"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xa94000 0x4000>; + reg-names = "se_phys"; + clock-names = "se-clk", "m-ahb", "s-ahb"; + clocks = <&clock_gcc GCC_QUPV3_WRAP1_S5_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_1_M_AHB_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_1_S_AHB_CLK>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&qupv3_se11_spi_active>; + pinctrl-1 = <&qupv3_se11_spi_sleep>; + interrupts = ; + spi-max-frequency = <50000000>; + qcom,wrapper-core = <&qupv3_1>; + dmas = <&gpi_dma1 0 5 1 64 0>, + <&gpi_dma1 1 5 1 64 0>; + dma-names = "tx", "rx"; + status = "disabled"; + }; + + /* I2C */ + qupv3_se6_i2c: i2c@a80000 { + compatible = "qcom,i2c-geni"; + reg = <0xa80000 0x4000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clock-names = "se-clk", "m-ahb", "s-ahb"; + clocks = <&clock_gcc GCC_QUPV3_WRAP1_S0_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_1_M_AHB_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_1_S_AHB_CLK>; + dmas = <&gpi_dma1 0 0 3 64 0>, + <&gpi_dma1 1 0 3 64 0>; + dma-names = "tx", "rx"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&qupv3_se6_i2c_active>; + pinctrl-1 = <&qupv3_se6_i2c_sleep>; + qcom,wrapper-core = <&qupv3_1>; + status = "disabled"; + }; + + qupv3_se7_i2c: i2c@a84000 { + compatible = "qcom,i2c-geni"; + reg = <0xa84000 0x4000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clock-names = "se-clk", "m-ahb", "s-ahb"; + clocks = <&clock_gcc GCC_QUPV3_WRAP1_S1_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_1_M_AHB_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_1_S_AHB_CLK>; + dmas = <&gpi_dma1 0 1 3 64 0>, + <&gpi_dma1 1 1 3 64 0>; + dma-names = "tx", "rx"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&qupv3_se7_i2c_active>; + pinctrl-1 = <&qupv3_se7_i2c_sleep>; + qcom,wrapper-core = <&qupv3_1>; + status = "disabled"; + }; + + qupv3_se8_i2c: i2c@a88000 { + compatible = "qcom,i2c-geni"; + reg = <0xa88000 0x4000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clock-names = "se-clk", "m-ahb", "s-ahb"; + clocks = <&clock_gcc GCC_QUPV3_WRAP1_S2_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_1_M_AHB_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_1_S_AHB_CLK>; + dmas = <&gpi_dma1 0 2 3 64 0>, + <&gpi_dma1 1 2 3 64 0>; + dma-names = "tx", "rx"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&qupv3_se8_i2c_active>; + pinctrl-1 = <&qupv3_se8_i2c_sleep>; + qcom,wrapper-core = <&qupv3_1>; + status = "disabled"; + }; + + qupv3_se9_i2c: i2c@a8c000 { + compatible = "qcom,i2c-geni"; + reg = <0xa8c000 0x4000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clock-names = "se-clk", "m-ahb", "s-ahb"; + clocks = <&clock_gcc GCC_QUPV3_WRAP1_S3_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_1_M_AHB_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_1_S_AHB_CLK>; + dmas = <&gpi_dma1 0 3 3 64 0>, + <&gpi_dma1 1 3 3 64 0>; + dma-names = "tx", "rx"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&qupv3_se9_i2c_active>; + pinctrl-1 = <&qupv3_se9_i2c_sleep>; + qcom,wrapper-core = <&qupv3_1>; + status = "disabled"; + }; + + qupv3_se10_i2c: i2c@a90000 { + compatible = "qcom,i2c-geni"; + reg = <0xa90000 0x4000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clock-names = "se-clk", "m-ahb", "s-ahb"; + clocks = <&clock_gcc GCC_QUPV3_WRAP1_S4_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_1_M_AHB_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_1_S_AHB_CLK>; + dmas = <&gpi_dma1 0 4 3 64 0>, + <&gpi_dma1 1 4 3 64 0>; + dma-names = "tx", "rx"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&qupv3_se10_i2c_active>; + pinctrl-1 = <&qupv3_se10_i2c_sleep>; + qcom,wrapper-core = <&qupv3_1>; + status = "disabled"; + }; + + qupv3_se11_i2c: i2c@a94000 { + compatible = "qcom,i2c-geni"; + reg = <0xa94000 0x4000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clock-names = "se-clk", "m-ahb", "s-ahb"; + clocks = <&clock_gcc GCC_QUPV3_WRAP1_S5_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_1_M_AHB_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_1_S_AHB_CLK>; + dmas = <&gpi_dma1 0 5 3 64 0>, + <&gpi_dma1 1 5 3 64 0>; + dma-names = "tx", "rx"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&qupv3_se11_i2c_active>; + pinctrl-1 = <&qupv3_se11_i2c_sleep>; + qcom,wrapper-core = <&qupv3_1>; + status = "disabled"; + }; + + qupv3_se8_2uart: qcom,qup_uart@a88000 { compatible = "qcom,msm-geni-console"; reg = <0xa88000 0x4000>; reg-names = "se_phys"; @@ -54,9 +553,9 @@ pinctrl-names = "default", "sleep"; pinctrl-0 = <&qupv3_se8_2uart_active>; pinctrl-1 = <&qupv3_se8_2uart_sleep>; - interrupts = ; + interrupts = ; qcom,wrapper-core = <&qupv3_1>; status = "disabled"; }; -}; +}; -- GitLab From 5e173ecd3fe203ba208d648dddf0f496b7199609 Mon Sep 17 00:00:00 2001 From: Tengfei Fan Date: Thu, 25 Jul 2019 16:45:49 +0800 Subject: [PATCH 1016/1121] defconfig: sm8150: change BLK_DEV_LOOP_MIN_COUNT's value Change BLK_DEV_LOOP_MIN_COUNT's value from 8 to 16. Change-Id: Icf134b71bf198f2c0440122d1b4e87bf831a466d Signed-off-by: Tengfei Fan --- arch/arm64/configs/vendor/sm8150-perf_defconfig | 1 + arch/arm64/configs/vendor/sm8150_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm64/configs/vendor/sm8150-perf_defconfig b/arch/arm64/configs/vendor/sm8150-perf_defconfig index a5eb2713d8df..903da83ac2d8 100644 --- a/arch/arm64/configs/vendor/sm8150-perf_defconfig +++ b/arch/arm64/configs/vendor/sm8150-perf_defconfig @@ -265,6 +265,7 @@ CONFIG_MHI_NETDEV=y CONFIG_MHI_UCI=y CONFIG_ZRAM=y CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=16 CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_HDCP_QSEECOM=y diff --git a/arch/arm64/configs/vendor/sm8150_defconfig b/arch/arm64/configs/vendor/sm8150_defconfig index c2dcde871c63..9253c88d2826 100644 --- a/arch/arm64/configs/vendor/sm8150_defconfig +++ b/arch/arm64/configs/vendor/sm8150_defconfig @@ -276,6 +276,7 @@ CONFIG_MHI_NETDEV=y CONFIG_MHI_UCI=y CONFIG_ZRAM=y CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=16 CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_HDCP_QSEECOM=y -- GitLab From 2baa4a42f2ca65632363ceec6063528faa4edf4c Mon Sep 17 00:00:00 2001 From: Ashay Jaiswal Date: Sat, 22 Jun 2019 15:25:16 +0530 Subject: [PATCH 1017/1121] power: smb1390-charger-psy: use voting mechanism to control slave Use voting mechanism to enable/disable slave, this ensures proper slave state across insertion/removal of charger. Change-Id: I32457dcb74801c35300b083c2cc0ca79cad7be33 Signed-off-by: Ashay Jaiswal --- .../power/supply/qcom/smb1390-charger-psy.c | 43 ++++++++++++++----- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/drivers/power/supply/qcom/smb1390-charger-psy.c b/drivers/power/supply/qcom/smb1390-charger-psy.c index 9dbdad28ccb4..7d8086e09349 100644 --- a/drivers/power/supply/qcom/smb1390-charger-psy.c +++ b/drivers/power/supply/qcom/smb1390-charger-psy.c @@ -105,6 +105,7 @@ #define SOC_LEVEL_VOTER "SOC_LEVEL_VOTER" #define HW_DISABLE_VOTER "HW_DISABLE_VOTER" #define CC_MODE_VOTER "CC_MODE_VOTER" +#define MAIN_DISABLE_VOTER "MAIN_DISABLE_VOTER" #define CP_MASTER 0 #define CP_SLAVE 1 @@ -181,6 +182,7 @@ struct smb1390 { struct votable *fcc_votable; struct votable *fv_votable; struct votable *cp_awake_votable; + struct votable *slave_disable_votable; /* power supplies */ struct power_supply *cps_psy; @@ -840,15 +842,16 @@ static int smb1390_disable_vote_cb(struct votable *votable, void *data, { struct smb1390 *chip = data; int rc = 0; - u8 mask, val; if (!is_psy_voter_available(chip) || chip->suspended) return -EAGAIN; - mask = CMD_EN_SWITCHER_BIT | CMD_EN_SL_BIT; - val = is_cps_available(chip) ? mask : CMD_EN_SWITCHER_BIT; - rc = smb1390_masked_write(chip, CORE_CONTROL1_REG, mask, - disable ? 0 : val); + if (is_cps_available(chip)) + vote(chip->slave_disable_votable, MAIN_DISABLE_VOTER, + disable ? true : false, 0); + + rc = smb1390_masked_write(chip, CORE_CONTROL1_REG, CMD_EN_SWITCHER_BIT, + disable ? 0 : CMD_EN_SWITCHER_BIT); if (rc < 0) { pr_err("Couldn't write CORE_CONTROL1_REG, rc=%d\n", rc); return rc; @@ -862,6 +865,21 @@ static int smb1390_disable_vote_cb(struct votable *votable, void *data, return rc; } +static int smb1390_slave_disable_vote_cb(struct votable *votable, void *data, + int disable, const char *client) +{ + struct smb1390 *chip = data; + int rc; + + rc = smb1390_masked_write(chip, CORE_CONTROL1_REG, CMD_EN_SL_BIT, + disable ? 0 : CMD_EN_SL_BIT); + if (rc < 0) + pr_err("Couldn't %s slave rc=%d\n", + disable ? "disable" : "enable", rc); + + return rc; +} + static int smb1390_ilim_vote_cb(struct votable *votable, void *data, int ilim_uA, const char *client) { @@ -1082,6 +1100,8 @@ static void smb1390_status_change_work(struct work_struct *work) vote(chip->fcc_votable, CP_VOTER, false, 0); vote(chip->disable_votable, SOC_LEVEL_VOTER, true, 0); vote_override(chip->ilim_votable, CC_MODE_VOTER, false, 0); + vote(chip->slave_disable_votable, TAPER_END_VOTER, false, 0); + vote(chip->slave_disable_votable, MAIN_DISABLE_VOTER, true, 0); } out: @@ -1092,18 +1112,14 @@ static void smb1390_status_change_work(struct work_struct *work) static int smb1390_validate_slave_chg_taper(struct smb1390 *chip, int fcc_uA) { int rc = 0; - u8 mask; /* * In Collapse mode, while in Taper, Disable the slave SMB1390 * when FCC drops below a specified threshold. */ if (fcc_uA < (chip->cp_slave_thr_taper_ua) && is_cps_available(chip)) { - mask = CMD_EN_SWITCHER_BIT | CMD_EN_SL_BIT; - rc = smb1390_masked_write(chip, CORE_CONTROL1_REG, - mask, CMD_EN_SWITCHER_BIT); - if (rc < 0) - return rc; + vote(chip->slave_disable_votable, TAPER_END_VOTER, + true, 0); /* * Set ILIM of master SMB1390 to Max value = 3.2A once slave is * disabled to prevent ILIM irq storm. @@ -1439,6 +1455,11 @@ static int smb1390_create_votables(struct smb1390 *chip) if (IS_ERR(chip->ilim_votable)) return PTR_ERR(chip->ilim_votable); + chip->slave_disable_votable = create_votable("CP_SLAVE_DISABLE", + VOTE_SET_ANY, smb1390_slave_disable_vote_cb, chip); + if (IS_ERR(chip->slave_disable_votable)) + return PTR_ERR(chip->slave_disable_votable); + /* * charge pump is initially disabled; this indirectly votes to allow * traditional parallel charging if present -- GitLab From f590dae75736a834c3de75534c8bb8fa32dea6b4 Mon Sep 17 00:00:00 2001 From: Sahil Chandna Date: Wed, 17 Jul 2019 15:34:54 +0530 Subject: [PATCH 1018/1121] power: smb1390-psy: Configure IREV and main's ICL to prevent IREV condition CP might enter IREV conditions in case of load attacks or when adapter is configured to low output current(during taper). To prevent IREV condition, configure CP IREV to 200mA and configure ICL of main charger to 500mA when slave CP is disabled during taper. Change-Id: I37be906a9d193e3f40cc5d1a1fec0777df14e6f8 Signed-off-by: Sahil Chandna --- .../power/supply/qcom/smb1390-charger-psy.c | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/drivers/power/supply/qcom/smb1390-charger-psy.c b/drivers/power/supply/qcom/smb1390-charger-psy.c index 7d8086e09349..3aede4f148d9 100644 --- a/drivers/power/supply/qcom/smb1390-charger-psy.c +++ b/drivers/power/supply/qcom/smb1390-charger-psy.c @@ -82,6 +82,7 @@ #define CORE_FTRIM_MISC_REG 0x1034 #define TR_WIN_1P5X_BIT BIT(0) +#define TR_IREV_BIT BIT(1) #define WINDOW_DETECTION_DELTA_X1P0 0 #define WINDOW_DETECTION_DELTA_X1P5 1 @@ -106,6 +107,7 @@ #define HW_DISABLE_VOTER "HW_DISABLE_VOTER" #define CC_MODE_VOTER "CC_MODE_VOTER" #define MAIN_DISABLE_VOTER "MAIN_DISABLE_VOTER" +#define TAPER_MAIN_ICL_LIMIT_VOTER "TAPER_MAIN_ICL_LIMIT_VOTER" #define CP_MASTER 0 #define CP_SLAVE 1 @@ -114,6 +116,7 @@ #define MAX_ILIM_DUAL_CP_UA 6400000 #define CC_MODE_TAPER_DELTA_UA 200000 #define DEFAULT_TAPER_DELTA_UA 100000 +#define CC_MODE_TAPER_MAIN_ICL_UA 500000 #define smb1390_dbg(chip, reason, fmt, ...) \ do { \ @@ -183,6 +186,7 @@ struct smb1390 { struct votable *fv_votable; struct votable *cp_awake_votable; struct votable *slave_disable_votable; + struct votable *usb_icl_votable; /* power supplies */ struct power_supply *cps_psy; @@ -211,6 +215,7 @@ struct smb1390 { enum isns_mode current_capability; bool batt_soc_validated; int cp_slave_thr_taper_ua; + int cc_mode_taper_main_icl_ua; }; struct smb_cfg { @@ -330,6 +335,14 @@ static bool is_psy_voter_available(struct smb1390 *chip) } } + if (!chip->usb_icl_votable) { + chip->usb_icl_votable = find_votable("USB_ICL"); + if (!chip->usb_icl_votable) { + smb1390_dbg(chip, PR_EXT_DEPENDENCY, "Couldn't find ICL votable\n"); + return false; + } + } + if (!chip->disable_votable) { smb1390_dbg(chip, PR_MISC, "Couldn't find CP DISABLE votable\n"); return false; @@ -1102,6 +1115,8 @@ static void smb1390_status_change_work(struct work_struct *work) vote_override(chip->ilim_votable, CC_MODE_VOTER, false, 0); vote(chip->slave_disable_votable, TAPER_END_VOTER, false, 0); vote(chip->slave_disable_votable, MAIN_DISABLE_VOTER, true, 0); + vote_override(chip->usb_icl_votable, TAPER_MAIN_ICL_LIMIT_VOTER, + false, 0); } out: @@ -1128,6 +1143,10 @@ static int smb1390_validate_slave_chg_taper(struct smb1390 *chip, int fcc_uA) fcc_uA); vote_override(chip->ilim_votable, CC_MODE_VOTER, true, MAX_ILIM_DUAL_CP_UA); + if (chip->usb_icl_votable) + vote_override(chip->usb_icl_votable, + TAPER_MAIN_ICL_LIMIT_VOTER, + true, chip->cc_mode_taper_main_icl_ua); } return rc; @@ -1180,6 +1199,15 @@ static void smb1390_taper_work(struct work_struct *work) if (fcc_uA < (chip->min_ilim_ua * 2)) { vote(chip->disable_votable, TAPER_END_VOTER, true, 0); + /* + * When master CP is disabled, reset all votes + * on ICL to enable Main charger to pump + * charging current. + */ + if (chip->usb_icl_votable) + vote_override(chip->usb_icl_votable, + TAPER_MAIN_ICL_LIMIT_VOTER, + false, 0); goto out; } } else { @@ -1432,6 +1460,12 @@ static int smb1390_parse_dt(struct smb1390 *chip) chip->cp_slave_thr_taper_ua = chip->min_ilim_ua * 3; of_property_read_u32(chip->dev->of_node, "qcom,cp-slave-thr-taper-ua", &chip->cp_slave_thr_taper_ua); + + chip->cc_mode_taper_main_icl_ua = CC_MODE_TAPER_MAIN_ICL_UA; + of_property_read_u32(chip->dev->of_node, + "qcom,cc-mode-taper-main-icl-ua", + &chip->cc_mode_taper_main_icl_ua); + return 0; } @@ -1529,6 +1563,12 @@ static int smb1390_init_hw(struct smb1390 *chip) return rc; } + /* Configure IREV threshold to 200mA */ + rc = smb1390_masked_write(chip, CORE_FTRIM_MISC_REG, TR_IREV_BIT, 0); + if (rc < 0) { + pr_err("Couldn't configure IREV threshold rc=%d\n", rc); + return rc; + } /* * If the slave charger has registered, configure Master SMB1390 for * triple-chg config, else configure for dual. Later, if the slave -- GitLab From 1090ccf8f04b4f49b924cd023e1cb1871feb0df2 Mon Sep 17 00:00:00 2001 From: Vipin Deep Kaur Date: Wed, 19 Jun 2019 14:24:20 +0530 Subject: [PATCH 1019/1121] gpi: Evaluate EE GSI registers offset for QUP The GSI EE registers offset may vary for some targets based on the GSI HW version. If so, read the variable offset for these registers from dt node property. Change-Id: I585d56552eddc5e6343ebacdc8c004a2f7303d4e Signed-off-by: Vipin Deep Kaur --- .../devicetree/bindings/dma/qcom_gpi.txt | 6 ++++ drivers/dma/qcom/gpi.c | 33 ++++++++++++------- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/Documentation/devicetree/bindings/dma/qcom_gpi.txt b/Documentation/devicetree/bindings/dma/qcom_gpi.txt index f1b4a429ed39..bb4a7ca3ae31 100644 --- a/Documentation/devicetree/bindings/dma/qcom_gpi.txt +++ b/Documentation/devicetree/bindings/dma/qcom_gpi.txt @@ -79,6 +79,12 @@ Main node properties: Value type: Array of Definition: Pair of values describing iova base and size to allocate. +Optional property: +- qcom,gpi-ee-offset + Usage: optional + Value type: u64 + Definition: Specifies the gsi ee register offset for the QUP. + ======== Example: ======== diff --git a/drivers/dma/qcom/gpi.c b/drivers/dma/qcom/gpi.c index eab48c682d85..ca1028e7ab45 100644 --- a/drivers/dma/qcom/gpi.c +++ b/drivers/dma/qcom/gpi.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -441,6 +441,7 @@ struct gpi_dev { struct device *dev; struct resource *res; void __iomem *regs; + void __iomem *ee_base; /*ee register base address*/ u32 max_gpii; /* maximum # of gpii instances available per gpi block */ u32 gpii_mask; /* gpii instances available for apps */ u32 ev_factor; /* ev ring length factor */ @@ -2649,6 +2650,7 @@ static int gpi_probe(struct platform_device *pdev) { struct gpi_dev *gpi_dev; int ret, i; + u32 gpi_ee_offset; gpi_dev = devm_kzalloc(&pdev->dev, sizeof(*gpi_dev), GFP_KERNEL); if (!gpi_dev) @@ -2669,6 +2671,8 @@ static int gpi_probe(struct platform_device *pdev) return -EFAULT; } + gpi_dev->ee_base = gpi_dev->regs; + ret = of_property_read_u32(gpi_dev->dev->of_node, "qcom,max-num-gpii", &gpi_dev->max_gpii); if (ret) { @@ -2683,6 +2687,14 @@ static int gpi_probe(struct platform_device *pdev) return ret; } + ret = of_property_read_u32(gpi_dev->dev->of_node, + "qcom,gpi-ee-offset", &gpi_ee_offset); + if (ret) + GPI_LOG(gpi_dev, "No variable ee offset present\n"); + else + gpi_dev->ee_base = + gpi_dev->ee_base - gpi_ee_offset; + ret = of_property_read_u32(gpi_dev->dev->of_node, "qcom,ev-factor", &gpi_dev->ev_factor); if (ret) { @@ -2732,7 +2744,6 @@ static int gpi_probe(struct platform_device *pdev) if (!gpi_dev->gpiis) return -ENOMEM; - /* setup all the supported gpii */ INIT_LIST_HEAD(&gpi_dev->dma_device.channels); for (i = 0; i < gpi_dev->max_gpii; i++) { @@ -2743,9 +2754,9 @@ static int gpi_probe(struct platform_device *pdev) continue; /* set up ev cntxt register map */ - gpii->ev_cntxt_base_reg = gpi_dev->regs + + gpii->ev_cntxt_base_reg = gpi_dev->ee_base + GPI_GPII_n_EV_CH_k_CNTXT_0_OFFS(i, 0); - gpii->ev_cntxt_db_reg = gpi_dev->regs + + gpii->ev_cntxt_db_reg = gpi_dev->ee_base + GPI_GPII_n_EV_CH_k_DOORBELL_0_OFFS(i, 0); gpii->ev_ring_base_lsb_reg = gpii->ev_cntxt_base_reg + CNTXT_2_RING_BASE_LSB; @@ -2753,11 +2764,11 @@ static int gpi_probe(struct platform_device *pdev) CNTXT_4_RING_RP_LSB; gpii->ev_ring_wp_lsb_reg = gpii->ev_cntxt_base_reg + CNTXT_6_RING_WP_LSB; - gpii->ev_cmd_reg = gpi_dev->regs + + gpii->ev_cmd_reg = gpi_dev->ee_base + GPI_GPII_n_EV_CH_CMD_OFFS(i); - gpii->ieob_src_reg = gpi_dev->regs + + gpii->ieob_src_reg = gpi_dev->ee_base + GPI_GPII_n_CNTXT_SRC_IEOB_IRQ_OFFS(i); - gpii->ieob_clr_reg = gpi_dev->regs + + gpii->ieob_clr_reg = gpi_dev->ee_base + GPI_GPII_n_CNTXT_SRC_IEOB_IRQ_CLR_OFFS(i); /* set up irq */ @@ -2774,9 +2785,9 @@ static int gpi_probe(struct platform_device *pdev) struct gpii_chan *gpii_chan = &gpii->gpii_chan[chan]; /* set up ch cntxt register map */ - gpii_chan->ch_cntxt_base_reg = gpi_dev->regs + + gpii_chan->ch_cntxt_base_reg = gpi_dev->ee_base + GPI_GPII_n_CH_k_CNTXT_0_OFFS(i, chan); - gpii_chan->ch_cntxt_db_reg = gpi_dev->regs + + gpii_chan->ch_cntxt_db_reg = gpi_dev->ee_base + GPI_GPII_n_CH_k_DOORBELL_0_OFFS(i, chan); gpii_chan->ch_ring_base_lsb_reg = gpii_chan->ch_cntxt_base_reg + @@ -2787,7 +2798,7 @@ static int gpi_probe(struct platform_device *pdev) gpii_chan->ch_ring_wp_lsb_reg = gpii_chan->ch_cntxt_base_reg + CNTXT_6_RING_WP_LSB; - gpii_chan->ch_cmd_reg = gpi_dev->regs + + gpii_chan->ch_cmd_reg = gpi_dev->ee_base + GPI_GPII_n_CH_CMD_OFFS(i); /* vchan setup */ @@ -2803,7 +2814,7 @@ static int gpi_probe(struct platform_device *pdev) (unsigned long)gpii); init_completion(&gpii->cmd_completion); gpii->gpii_id = i; - gpii->regs = gpi_dev->regs; + gpii->regs = gpi_dev->ee_base; gpii->gpi_dev = gpi_dev; atomic_set(&gpii->dbg_index, 0); } -- GitLab From 805a14b1d29e4c387fb9137df750eb073e026de6 Mon Sep 17 00:00:00 2001 From: Anmolpreet Kaur Date: Wed, 17 Jul 2019 10:27:11 +0530 Subject: [PATCH 1020/1121] ARM: dts: msm: Add crypto device nodes for atoll Add qcedev and qcrypto device nodes to enable HW crypto engine operations for user and kernel space apps. Change-Id: Iead18e71eb4e6764846d0092c1b80da7825f505e Signed-off-by: Anmolpreet Kaur --- arch/arm64/boot/dts/qcom/atoll.dtsi | 53 +++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index ef8f9ebafa09..e38ae23dc0a5 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -873,6 +873,59 @@ mbox-names = "aop"; }; + qcom_crypto: qcrypto@1de0000 { + compatible = "qcom,qcrypto"; + reg = <0x1de0000 0x20000>, + <0x1dc4000 0x24000>; + reg-names = "crypto-base","crypto-bam-base"; + interrupts = ; + qcom,bam-pipe-pair = <2>; + qcom,ce-hw-instance = <0>; + qcom,ce-device = <0>; + qcom,bam-ee = <0>; + qcom,ce-hw-shared; + qcom,clk-mgmt-sus-res; + qcom,msm-bus,name = "qcrypto-noc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <125 512 0 0>, + <125 512 393600 393600>; + qcom,use-sw-aes-cbc-ecb-ctr-algo; + qcom,use-sw-aes-xts-algo; + qcom,use-sw-aes-ccm-algo; + qcom,use-sw-ahash-algo; + qcom,use-sw-aead-algo; + qcom,use-sw-hmac-algo; + qcom,smmu-s1-enable; + qcom,no-clock-support; + iommus = <&apps_smmu 0x0424 0x0011>, + <&apps_smmu 0x0434 0x0011>; + }; + + qcom_cedev: qcedev@1de0000 { + compatible = "qcom,qcedev"; + reg = <0x1de0000 0x20000>, + <0x1dc4000 0x24000>; + reg-names = "crypto-base","crypto-bam-base"; + interrupts = ; + qcom,bam-pipe-pair = <3>; + qcom,ce-hw-instance = <0>; + qcom,ce-device = <0>; + qcom,ce-hw-shared; + qcom,bam-ee = <0>; + qcom,msm-bus,name = "qcedev-noc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <125 512 0 0>, + <125 512 393600 393600>; + qcom,smmu-s1-enable; + qcom,no-clock-support; + iommus = <&apps_smmu 0x0426 0x0011>, + <&apps_smmu 0x0436 0x0011>; + }; + qcom,msm-rtb { compatible = "qcom,msm-rtb"; qcom,rtb-size = <0x100000>; -- GitLab From a4da8590fc5561379a8c44c6f34277571678f5fd Mon Sep 17 00:00:00 2001 From: Anmolpreet Kaur Date: Wed, 17 Jul 2019 10:31:30 +0530 Subject: [PATCH 1021/1121] ARM: dts: msm: Enable TZ-log driver for atoll Enable the TZ-log device node to enable TZ-log driver to access diag area. Change-Id: If2a1157d8ff1e51260abfb79b4d678261d8f5f78 Signed-off-by: Anmolpreet Kaur --- arch/arm64/boot/dts/qcom/atoll.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index e38ae23dc0a5..c438e8b03886 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -873,6 +873,14 @@ mbox-names = "aop"; }; + qcom_tzlog: tz-log@146aa720 { + compatible = "qcom,tz-log"; + reg = <0x146aa720 0x3000>; + qcom,hyplog-enabled; + hyplog-address-offset = <0x410>; + hyplog-size-offset = <0x414>; + }; + qcom_crypto: qcrypto@1de0000 { compatible = "qcom,qcrypto"; reg = <0x1de0000 0x20000>, -- GitLab From 889e5f7bbbc59916a6ab93092ad2663160b4dc57 Mon Sep 17 00:00:00 2001 From: Anmolpreet Kaur Date: Wed, 17 Jul 2019 10:35:21 +0530 Subject: [PATCH 1022/1121] ARM: dts: msm: Add qrng node for atoll Add QRNG device node to enable the QRNG driver to communicate with /dev/random. Change-Id: I910c802df1c9c87c66d3673ea62c3ba66410ec05 Signed-off-by: Anmolpreet Kaur --- arch/arm64/boot/dts/qcom/atoll.dtsi | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index c438e8b03886..22c1343ae298 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -881,6 +881,21 @@ hyplog-size-offset = <0x414>; }; + qcom_rng: qrng@793000 { + compatible = "qcom,msm-rng"; + reg = <0x793000 0x1000>; + qcom,msm-rng-iface-clk; + qcom,no-qrng-config; + qcom,msm-bus,name = "msm-rng-noc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <1 618 0 0>, /* No vote */ + <1 618 0 300000>; /* 75 MHz */ + clocks = <&clock_gcc GCC_PRNG_AHB_CLK>; + clock-names = "iface_clk"; + }; + qcom_crypto: qcrypto@1de0000 { compatible = "qcom,qcrypto"; reg = <0x1de0000 0x20000>, -- GitLab From 76494536565952c4a1ff5dcb8dd7ecd62e8a4aac Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Tue, 23 Jul 2019 17:26:14 -0700 Subject: [PATCH 1023/1121] ARM: dts: msm: Add USB for SA8195 Virtual Machine Add primary and secondary USB controllers for USB pass through functionality on the SA8195 virtual machine target. Change-Id: I051e220b9abfd3a929a264fc7c0fce07330e9b0b Signed-off-by: Anant Goel --- arch/arm64/boot/dts/qcom/sa8195-vm-usb.dtsi | 217 ++++++++++++++++++++ arch/arm64/boot/dts/qcom/sa8195-vm.dtsi | 49 ++--- 2 files changed, 235 insertions(+), 31 deletions(-) create mode 100644 arch/arm64/boot/dts/qcom/sa8195-vm-usb.dtsi diff --git a/arch/arm64/boot/dts/qcom/sa8195-vm-usb.dtsi b/arch/arm64/boot/dts/qcom/sa8195-vm-usb.dtsi new file mode 100644 index 000000000000..1035d25de40b --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sa8195-vm-usb.dtsi @@ -0,0 +1,217 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include + +&soc { + /* Primary USB port related controller */ + usb0: ssusb@a600000 { + compatible = "qcom,dwc-usb3-msm"; + reg = <0x0a600000 0x100000>; + reg-names = "core_base"; + + iommus = <&apps_smmu 0x140 0x0>; + qcom,smmu-s1-bypass; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + interrupts = <0 489 0>, <0 130 0>, <0 486 0>, <0 488 0>; + interrupt-names = "dp_hs_phy_irq", "pwr_event_irq", + "ss_phy_irq", "dm_hs_phy_irq"; + qcom,use-pdc-interrupts; + + USB3_GDSC-supply = <&usb30_prim_gdsc>; + clocks = <&clock_virt GCC_USB30_PRIM_MASTER_CLK>, + <&clock_virt GCC_CFG_NOC_USB3_PRIM_AXI_CLK>, + <&clock_virt GCC_AGGRE_USB3_PRIM_AXI_CLK>, + <&clock_virt GCC_USB30_PRIM_MOCK_UTMI_CLK>, + <&clock_virt GCC_USB30_PRIM_SLEEP_CLK>, + <&clock_virt GCC_USB3_PRIM_CLKREF_CLK>; + clock-names = "core_clk", "iface_clk", "bus_aggr_clk", + "utmi_clk", "sleep_clk", "xo"; + + resets = <&clock_virt GCC_USB30_PRIM_BCR>; + reset-names = "core_reset"; + + qcom,core-clk-rate = <200000000>; + qcom,core-clk-rate-hs = <66666667>; + qcom,num-gsi-evt-buffs = <0x3>; + qcom,gsi-reg-offset = + <0x0fc /* GSI_GENERAL_CFG */ + 0x110 /* GSI_DBL_ADDR_L */ + 0x120 /* GSI_DBL_ADDR_H */ + 0x130 /* GSI_RING_BASE_ADDR_L */ + 0x144 /* GSI_RING_BASE_ADDR_H */ + 0x1a4>; /* GSI_IF_STS */ + qcom,dwc-usb3-msm-tx-fifo-size = <27696>; + + status = "disabled"; + + dwc3@a600000 { + compatible = "snps,dwc3"; + reg = <0x0a600000 0xcd00>; + interrupts = <0 133 0>; + usb-phy = <&usb2_phy0>, <&usb_nop_phy>; + linux,sysdev_is_parent; + snps,disable-clk-gating; + snps,has-lpm-erratum; + snps,hird-threshold = /bits/ 8 <0x10>; + snps,ssp-u3-u0-quirk; + snps,usb3-u1u2-disable; + usb-core-id = <0>; + tx-fifo-resize; + maximum-speed = "high-speed"; + dr_mode = "otg"; + }; + + usbbam: qcom,usbbam@a704000 { + compatible = "qcom,usb-bam-msm"; + reg = <0xa704000 0x17000>; + interrupts = <0 132 0>; + + qcom,usb-bam-fifo-baseaddr = <0x146bb000>; + qcom,usb-bam-num-pipes = <4>; + qcom,disable-clk-gating; + qcom,usb-bam-override-threshold = <0x4001>; + qcom,usb-bam-max-mbps-highspeed = <400>; + qcom,usb-bam-max-mbps-superspeed = <3600>; + qcom,reset-bam-on-connect; + + status = "disabled"; + + qcom,pipe0 { + label = "ssusb-qdss-in-0"; + qcom,usb-bam-mem-type = <2>; + qcom,dir = <1>; + qcom,pipe-num = <0>; + qcom,peer-bam = <0>; + qcom,peer-bam-physical-address = <0x6064000>; + qcom,src-bam-pipe-index = <0>; + qcom,dst-bam-pipe-index = <0>; + qcom,data-fifo-offset = <0x0>; + qcom,data-fifo-size = <0x1800>; + qcom,descriptor-fifo-offset = <0x1800>; + qcom,descriptor-fifo-size = <0x800>; + }; + }; + }; + + /* Primary USB port related High Speed PHY */ + usb2_phy0: hsphy@88e2000 { + compatible = "qcom,usb-hsphy-snps-femto"; + reg = <0x88e2000 0x110>; + reg-names = "hsusb_phy_base"; + + vdd-supply = <&pm8195_3_l5>; + vdda18-supply = <&pm8195_1_l12>; + vdda33-supply = <&pm8195_3_l16>; + qcom,vdd-voltage-level = <0 880000 880000>; + + clocks = <&clock_gcc RPMH_CXO_CLK>; + clock-names = "ref_clk_src"; + + resets = <&clock_virt GCC_QUSB2PHY_PRIM_BCR>; + reset-names = "phy_reset"; + qcom,param-override-seq = <0x43 0x70>; + + status = "disabled"; + }; + + usb_nop_phy: usb_nop_phy { + compatible = "usb-nop-xceiv"; + }; + + /* Secondary USB port related controller */ + usb1: ssusb@a800000 { + compatible = "qcom,dwc-usb3-msm"; + reg = <0x0a800000 0x100000>; + reg-names = "core_base"; + + iommus = <&apps_smmu 0x160 0x0>; + qcom,smmu-s1-bypass; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + interrupts = <0 491 0>, <0 135 0>, <0 487 0>, <0 490 0>; + interrupt-names = "dp_hs_phy_irq", "pwr_event_irq", + "ss_phy_irq", "dm_hs_phy_irq"; + qcom,use-pdc-interrupts; + + USB3_GDSC-supply = <&usb30_sec_gdsc>; + clocks = <&clock_virt GCC_USB30_SEC_MASTER_CLK>, + <&clock_virt GCC_CFG_NOC_USB3_SEC_AXI_CLK>, + <&clock_virt GCC_AGGRE_USB3_SEC_AXI_CLK>, + <&clock_virt GCC_USB30_SEC_MOCK_UTMI_CLK>, + <&clock_virt GCC_USB30_SEC_SLEEP_CLK>, + <&clock_virt GCC_USB3_SEC_CLKREF_CLK>; + clock-names = "core_clk", "iface_clk", "bus_aggr_clk", + "utmi_clk", "sleep_clk", "xo"; + + resets = <&clock_virt GCC_USB30_SEC_BCR>; + reset-names = "core_reset"; + + qcom,core-clk-rate = <200000000>; + qcom,core-clk-rate-hs = <66666667>; + qcom,num-gsi-evt-buffs = <0x3>; + qcom,gsi-reg-offset = + <0x0fc /* GSI_GENERAL_CFG */ + 0x110 /* GSI_DBL_ADDR_L */ + 0x120 /* GSI_DBL_ADDR_H */ + 0x130 /* GSI_RING_BASE_ADDR_L */ + 0x144 /* GSI_RING_BASE_ADDR_H */ + 0x1a4>; /* GSI_IF_STS */ + qcom,dwc-usb3-msm-tx-fifo-size = <27696>; + qcom,charging-disabled; + + status = "disabled"; + + dwc3@a800000 { + compatible = "snps,dwc3"; + reg = <0x0a800000 0xcd00>; + interrupts = <0 138 0>; + usb-phy = <&usb2_phy1>, <&usb_nop_phy>; + linux,sysdev_is_parent; + snps,disable-clk-gating; + snps,has-lpm-erratum; + snps,hird-threshold = /bits/ 8 <0x10>; + snps,usb3_lpm_capable; + usb-core-id = <1>; + tx-fifo-resize; + maximum-speed = "high-speed"; + dr_mode = "otg"; + }; + }; + + /* Secondary USB port related High Speed PHY */ + usb2_phy1: hsphy@88e3000 { + compatible = "qcom,usb-hsphy-snps-femto"; + reg = <0x88e3000 0x110>; + reg-names = "hsusb_phy_base"; + + vdd-supply = <&pm8195_3_l5>; + vdda18-supply = <&pm8195_1_l12>; + vdda33-supply = <&pm8195_3_l16>; + qcom,vdd-voltage-level = <0 880000 880000>; + + clocks = <&clock_gcc RPMH_CXO_CLK>; + clock-names = "ref_clk_src"; + + resets = <&clock_virt GCC_QUSB2PHY_SEC_BCR>; + reset-names = "phy_reset"; + + status = "disabled"; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/sa8195-vm.dtsi b/arch/arm64/boot/dts/qcom/sa8195-vm.dtsi index 12c910533271..b5dbb9e59264 100644 --- a/arch/arm64/boot/dts/qcom/sa8195-vm.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8195-vm.dtsi @@ -11,7 +11,7 @@ */ #include "skeleton64.dtsi" -#include +#include #include #include #include "quin-vm-common.dtsi" @@ -147,44 +147,31 @@ status = "disabled"; }; - pm8150_l2: regulator-pm8150-l2 { + pm8195_3_l5: regulator-pm8195-3-l5 { compatible = "qcom,stub-regulator"; - regulator-name = "pm8150_l2"; - regulator-min-microvolt = <3072000>; - regulator-max-microvolt = <3072000>; - qcom,init-voltage = <3072000>; - status = "okay"; + regulator-name = "pm8195_3_l5"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <920000>; + qcom,init-voltage = <800000>; + status = "ok"; }; - pm8150_l5: regulator-pm8150-l5 { + pm8195_1_l12: regulator-pm8195-1-l12 { compatible = "qcom,stub-regulator"; - regulator-name = "pm8150_l5"; - regulator-min-microvolt = <880000>; - regulator-max-microvolt = <880000>; - qcom,proxy-consumer-enable; - qcom,proxy-consumer-current = <23800>; - qcom,init-voltage = <880000>; - status = "okay"; - }; - - pm8150_l12: regulator-pm8150-l12 { - compatible = "qcom,stub-regulator"; - regulator-name = "pm8150_l12"; + regulator-name = "pm8195_1_l12"; regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; + regulator-max-microvolt = <1890000>; qcom,init-voltage = <1800000>; - status = "okay"; + status = "ok"; }; - pm8150l_l3: regulator-pm8150l-l3 { + pm8195_3_l16: regulator-pm8195-3-l16 { compatible = "qcom,stub-regulator"; - regulator-name = "pm8150l_l3"; - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <1200000>; - qcom,proxy-consumer-enable; - qcom,proxy-consumer-current = <51800>; - qcom,init-voltage = <1200000>; - status = "okay"; + regulator-name = "pm8195_3_l16"; + regulator-min-microvolt = <2921000>; + regulator-max-microvolt = <3300000>; + qcom,init-voltage = <2921000>; + status = "ok"; }; usb30_prim_gdsc: usb30_prim_gdsc { @@ -203,5 +190,5 @@ #include "sdmshrike-pinctrl.dtsi" #include "sm8150-slpi-pinctrl.dtsi" #include "sa8155-vm-qupv3.dtsi" -#include "sa8155-vm-usb.dtsi" +#include "sa8195-vm-usb.dtsi" #include "sa8155-vm-audio.dtsi" -- GitLab From 90552768f8e1c8aec35b5bc7172462f5c14daf91 Mon Sep 17 00:00:00 2001 From: Sujeev Dias Date: Tue, 4 Jun 2019 14:47:04 -0700 Subject: [PATCH 1024/1121] ARM: dts: msm: register IPCR for early MHI notification During modem error fatal, MHI IPCR require early notification from MHI so device can do early termination to avoid data stall. CRs-Fixed: 2459916 Change-Id: I5ead1df5dc677a1b1049ff732c3478efe73dd8a0 Signed-off-by: Sujeev Dias --- arch/arm64/boot/dts/qcom/sm8150-mhi.dtsi | 5 +++++ arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sm8150-mhi.dtsi b/arch/arm64/boot/dts/qcom/sm8150-mhi.dtsi index 9f53e564ccdf..ee8c5a375547 100644 --- a/arch/arm64/boot/dts/qcom/sm8150-mhi.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150-mhi.dtsi @@ -546,6 +546,11 @@ mhi,mru = <0x8000>; mhi,rsc-parent = <&mhi_netdev_0>; }; + + mhi_qrtr { + mhi,chan = "IPCR"; + mhi,early-notify; + }; }; }; }; diff --git a/arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi b/arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi index 0089c7edd887..fc33d0d98d1d 100644 --- a/arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi @@ -90,7 +90,6 @@ mhi_devices { mhi_qrtr { - mhi,chan = "IPCR"; qcom,net-id = <3>; }; }; -- GitLab From d1d97137f53529a68ce051048c8e44b23022986f Mon Sep 17 00:00:00 2001 From: Gustavo Solaira Date: Thu, 25 Jul 2019 13:05:19 -0700 Subject: [PATCH 1025/1121] defconfig: msm: Add back configurations to SA2150P Add back configurations that were removed from the QCS405 base config to avoid a boot up crash. Change-Id: I229902574aa9269b8cd5c47d5d5db4e3abccb506 Signed-off-by: Gustavo Solaira --- .../configs/vendor/sa2150p-perf_defconfig | 76 ++++++++++++++++++ arch/arm64/configs/vendor/sa2150p_defconfig | 78 +++++++++++++++++++ 2 files changed, 154 insertions(+) diff --git a/arch/arm64/configs/vendor/sa2150p-perf_defconfig b/arch/arm64/configs/vendor/sa2150p-perf_defconfig index 23107f443800..fdcd416ea447 100644 --- a/arch/arm64/configs/vendor/sa2150p-perf_defconfig +++ b/arch/arm64/configs/vendor/sa2150p-perf_defconfig @@ -169,6 +169,21 @@ CONFIG_IP6_NF_FILTER=y CONFIG_IP6_NF_TARGET_REJECT=y CONFIG_IP6_NF_MANGLE=y CONFIG_IP6_NF_RAW=y +CONFIG_BRIDGE_NF_EBTABLES=y +CONFIG_BRIDGE_EBT_BROUTE=y +CONFIG_BRIDGE_EBT_T_FILTER=y +CONFIG_BRIDGE_EBT_T_NAT=y +CONFIG_BRIDGE_EBT_ARP=y +CONFIG_BRIDGE_EBT_IP=y +CONFIG_BRIDGE_EBT_IP6=y +CONFIG_BRIDGE_EBT_ARPREPLY=y +CONFIG_BRIDGE_EBT_DNAT=y +CONFIG_BRIDGE_EBT_SNAT=y +CONFIG_L2TP=y +CONFIG_L2TP_V3=y +CONFIG_L2TP_IP=y +CONFIG_L2TP_ETH=y +CONFIG_BRIDGE=y CONFIG_NET_SCHED=y CONFIG_NET_SCH_HTB=y CONFIG_NET_SCH_PRIO=y @@ -184,9 +199,27 @@ CONFIG_NET_EMATCH_META=y CONFIG_NET_EMATCH_TEXT=y CONFIG_NET_CLS_ACT=y CONFIG_QRTR=y +CONFIG_QRTR_SMD=y +CONFIG_QRTR_USB=y +CONFIG_RMNET_USB=y +CONFIG_BT=y +# CONFIG_BT_BREDR is not set +# CONFIG_BT_LE is not set +# CONFIG_BT_DEBUGFS is not set +CONFIG_MSM_BT_POWER=y +CONFIG_CFG80211=y +CONFIG_CFG80211_INTERNAL_REGDB=y +CONFIG_MAC80211=m +CONFIG_MAC80211_RC_MINSTREL_VHT=y +CONFIG_MAC80211_DEBUGFS=y +CONFIG_RFKILL=y CONFIG_NTAG_NQ=y CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y CONFIG_DMA_CMA=y +CONFIG_MHI_BUS=y +CONFIG_MHI_QCOM=y +CONFIG_MHI_NETDEV=y +CONFIG_MHI_UCI=y CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_BLOCK=y @@ -218,9 +251,31 @@ CONFIG_DM_VERITY=y CONFIG_DM_VERITY_FEC=y CONFIG_NETDEVICES=y CONFIG_DUMMY=y +CONFIG_TUN=y CONFIG_AT803X_PHY=y +CONFIG_PPP=y +CONFIG_PPP_BSDCOMP=y +CONFIG_PPP_DEFLATE=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=y +CONFIG_PPP_MULTILINK=y +CONFIG_PPPOE=y +CONFIG_PPPOL2TP=y +CONFIG_PPPOLAC=y +CONFIG_PPPOPNS=y +CONFIG_PPP_ASYNC=y +CONFIG_PPP_SYNC_TTY=y CONFIG_USB_USBNET=y CONFIG_USB_NET_SMSC75XX=y +CONFIG_ATH10K=m +CONFIG_ATH10K_PCI=m +CONFIG_ATH10K_DEBUG=y +CONFIG_ATH10K_DEBUGFS=y +CONFIG_WCNSS_MEM_PRE_ALLOC=y +CONFIG_CLD_LL_CORE=y +CONFIG_CNSS=y +CONFIG_CNSS_SDIO=y +CONFIG_CLD_HL_SDIO_CORE=y CONFIG_INPUT_EVDEV=y CONFIG_INPUT_EVBUG=m CONFIG_INPUT_KEYRESET=y @@ -232,6 +287,7 @@ CONFIG_INPUT_TABLET=y CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_ATMEL_MXT=y CONFIG_INPUT_MISC=y +CONFIG_INPUT_HBTP_INPUT=y CONFIG_INPUT_QPNP_POWER_ON=y CONFIG_INPUT_UINPUT=y CONFIG_INPUT_GPIO=y @@ -248,6 +304,7 @@ CONFIG_SPI=y CONFIG_SPI_QUP=y CONFIG_SPI_SPIDEV=y CONFIG_SPMI=y +CONFIG_SLIMBUS_MSM_NGD=y CONFIG_PTP_1588_CLOCK=y CONFIG_PINCTRL_QCS405=y CONFIG_FRAGMENTED_GPIO_ADDRESS_SPACE=y @@ -255,6 +312,7 @@ CONFIG_PINCTRL_QCOM_SPMI_PMIC=y CONFIG_GPIO_SYSFS=y CONFIG_POWER_RESET_QCOM=y CONFIG_QCOM_DLOAD_MODE=y +CONFIG_SMB1351_USB_CHARGER=y CONFIG_THERMAL=y CONFIG_THERMAL_WRITABLE_TRIPS=y CONFIG_THERMAL_GOV_USER_SPACE=y @@ -283,6 +341,20 @@ CONFIG_MEDIA_SUPPORT=y CONFIG_MEDIA_CAMERA_SUPPORT=y CONFIG_MEDIA_RADIO_SUPPORT=y CONFIG_MEDIA_CONTROLLER=y +CONFIG_VIDEO_V4L2_SUBDEV_API=y +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_SOC_CAMERA=y +CONFIG_SOC_CAMERA_PLATFORM=y +CONFIG_FB=y +CONFIG_FB_MSM=y +CONFIG_FB_MSM_MDSS=y +CONFIG_FB_MSM_MDSS_WRITEBACK=y +CONFIG_FB_MSM_MDSS_HDMI_PANEL=y +CONFIG_FB_MSM_MDSS_SPI_PANEL=y +CONFIG_FB_MSM_MDSS_RGB_PANEL=y +CONFIG_FB_MSM_MDSS_DSI_CTRL_STATUS=y +CONFIG_FB_MSM_MDSS_XLOG_DEBUG=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_SOUND=y CONFIG_SND=y CONFIG_SND_DYNAMIC_MINORS=y @@ -357,6 +429,7 @@ CONFIG_ION=y CONFIG_QPNP_REVID=y CONFIG_SPS=y CONFIG_SPS_SUPPORT_NDP_BAM=y +CONFIG_QCOM_MDSS_PLL=y CONFIG_QCOM_CLK_SMD_RPM=y CONFIG_SPMI_PMIC_CLKDIV=y CONFIG_MDM_DEBUGCC_QCS405=y @@ -394,10 +467,13 @@ CONFIG_MSM_SYSMON_QMI_COMM=y CONFIG_MSM_PIL_SSR_GENERIC=y CONFIG_MSM_BOOT_STATS=y CONFIG_QCOM_DCC_V2=y +CONFIG_ICNSS=y +CONFIG_ICNSS_QMI=y CONFIG_QCOM_BUS_SCALING=y CONFIG_MSM_TZ_SMMU=y CONFIG_QCOM_GLINK=y CONFIG_QCOM_GLINK_PKT=y +CONFIG_MSM_JTAGV8=y CONFIG_QTI_RPM_STATS_LOG=y CONFIG_MSM_CDSP_LOADER=y CONFIG_QCOM_SMCINVOKE=y diff --git a/arch/arm64/configs/vendor/sa2150p_defconfig b/arch/arm64/configs/vendor/sa2150p_defconfig index 7a0d2382bf97..665586314b19 100644 --- a/arch/arm64/configs/vendor/sa2150p_defconfig +++ b/arch/arm64/configs/vendor/sa2150p_defconfig @@ -174,6 +174,22 @@ CONFIG_IP6_NF_FILTER=y CONFIG_IP6_NF_TARGET_REJECT=y CONFIG_IP6_NF_MANGLE=y CONFIG_IP6_NF_RAW=y +CONFIG_BRIDGE_NF_EBTABLES=y +CONFIG_BRIDGE_EBT_BROUTE=y +CONFIG_BRIDGE_EBT_T_FILTER=y +CONFIG_BRIDGE_EBT_T_NAT=y +CONFIG_BRIDGE_EBT_ARP=y +CONFIG_BRIDGE_EBT_IP=y +CONFIG_BRIDGE_EBT_IP6=y +CONFIG_BRIDGE_EBT_ARPREPLY=y +CONFIG_BRIDGE_EBT_DNAT=y +CONFIG_BRIDGE_EBT_SNAT=y +CONFIG_L2TP=y +CONFIG_L2TP_DEBUGFS=y +CONFIG_L2TP_V3=y +CONFIG_L2TP_IP=y +CONFIG_L2TP_ETH=y +CONFIG_BRIDGE=y CONFIG_NET_SCHED=y CONFIG_NET_SCH_HTB=y CONFIG_NET_SCH_PRIO=y @@ -189,9 +205,28 @@ CONFIG_NET_EMATCH_META=y CONFIG_NET_EMATCH_TEXT=y CONFIG_NET_CLS_ACT=y CONFIG_QRTR=y +CONFIG_QRTR_SMD=y +CONFIG_QRTR_USB=y +CONFIG_RMNET_USB=y +CONFIG_BT=y +# CONFIG_BT_BREDR is not set +# CONFIG_BT_LE is not set +# CONFIG_BT_DEBUGFS is not set +CONFIG_MSM_BT_POWER=y +CONFIG_CFG80211=y +CONFIG_CFG80211_INTERNAL_REGDB=y +CONFIG_MAC80211=m +CONFIG_MAC80211_RC_MINSTREL_VHT=y +CONFIG_MAC80211_DEBUGFS=y +CONFIG_RFKILL=y CONFIG_NTAG_NQ=y CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y CONFIG_DMA_CMA=y +CONFIG_MHI_BUS=y +CONFIG_MHI_DEBUG=y +CONFIG_MHI_QCOM=y +CONFIG_MHI_NETDEV=y +CONFIG_MHI_UCI=y CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_BLOCK=y @@ -223,9 +258,31 @@ CONFIG_DM_VERITY=y CONFIG_DM_VERITY_FEC=y CONFIG_NETDEVICES=y CONFIG_DUMMY=y +CONFIG_TUN=y CONFIG_AT803X_PHY=y +CONFIG_PPP=y +CONFIG_PPP_BSDCOMP=y +CONFIG_PPP_DEFLATE=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=y +CONFIG_PPP_MULTILINK=y +CONFIG_PPPOE=y +CONFIG_PPPOL2TP=y +CONFIG_PPPOLAC=y +CONFIG_PPPOPNS=y +CONFIG_PPP_ASYNC=y +CONFIG_PPP_SYNC_TTY=y CONFIG_USB_USBNET=y CONFIG_USB_NET_SMSC75XX=y +CONFIG_ATH10K=m +CONFIG_ATH10K_PCI=m +CONFIG_ATH10K_DEBUG=y +CONFIG_ATH10K_DEBUGFS=y +CONFIG_WCNSS_MEM_PRE_ALLOC=y +CONFIG_CLD_LL_CORE=y +CONFIG_CNSS=y +CONFIG_CNSS_SDIO=y +CONFIG_CLD_HL_SDIO_CORE=y CONFIG_INPUT_EVDEV=y CONFIG_INPUT_EVBUG=m CONFIG_INPUT_KEYRESET=y @@ -237,6 +294,7 @@ CONFIG_INPUT_TABLET=y CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_ATMEL_MXT=y CONFIG_INPUT_MISC=y +CONFIG_INPUT_HBTP_INPUT=y CONFIG_INPUT_QPNP_POWER_ON=y CONFIG_INPUT_UINPUT=y CONFIG_INPUT_GPIO=y @@ -257,6 +315,7 @@ CONFIG_SPI_QUP=y CONFIG_SPI_SPIDEV=y CONFIG_SPMI=y CONFIG_SPMI_MSM_PMIC_ARB_DEBUG=y +CONFIG_SLIMBUS_MSM_NGD=y CONFIG_PTP_1588_CLOCK=y CONFIG_PINCTRL_QCS405=y CONFIG_FRAGMENTED_GPIO_ADDRESS_SPACE=y @@ -264,6 +323,7 @@ CONFIG_PINCTRL_QCOM_SPMI_PMIC=y CONFIG_GPIO_SYSFS=y CONFIG_POWER_RESET_QCOM=y CONFIG_QCOM_DLOAD_MODE=y +CONFIG_SMB1351_USB_CHARGER=y CONFIG_THERMAL=y CONFIG_THERMAL_WRITABLE_TRIPS=y CONFIG_THERMAL_GOV_USER_SPACE=y @@ -292,6 +352,20 @@ CONFIG_MEDIA_SUPPORT=y CONFIG_MEDIA_CAMERA_SUPPORT=y CONFIG_MEDIA_RADIO_SUPPORT=y CONFIG_MEDIA_CONTROLLER=y +CONFIG_VIDEO_V4L2_SUBDEV_API=y +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_SOC_CAMERA=y +CONFIG_SOC_CAMERA_PLATFORM=y +CONFIG_FB=y +CONFIG_FB_MSM=y +CONFIG_FB_MSM_MDSS=y +CONFIG_FB_MSM_MDSS_WRITEBACK=y +CONFIG_FB_MSM_MDSS_HDMI_PANEL=y +CONFIG_FB_MSM_MDSS_SPI_PANEL=y +CONFIG_FB_MSM_MDSS_RGB_PANEL=y +CONFIG_FB_MSM_MDSS_DSI_CTRL_STATUS=y +CONFIG_FB_MSM_MDSS_XLOG_DEBUG=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_SOUND=y CONFIG_SND=y CONFIG_SND_DYNAMIC_MINORS=y @@ -369,6 +443,7 @@ CONFIG_ION=y CONFIG_QPNP_REVID=y CONFIG_SPS=y CONFIG_SPS_SUPPORT_NDP_BAM=y +CONFIG_QCOM_MDSS_PLL=y CONFIG_QCOM_CLK_SMD_RPM=y CONFIG_SPMI_PMIC_CLKDIV=y CONFIG_MDM_DEBUGCC_QCS405=y @@ -410,6 +485,9 @@ CONFIG_MSM_PIL_SSR_GENERIC=y CONFIG_MSM_BOOT_STATS=y CONFIG_MSM_CORE_HANG_DETECT=y CONFIG_QCOM_DCC_V2=y +CONFIG_ICNSS=y +CONFIG_ICNSS_DEBUG=y +CONFIG_ICNSS_QMI=y CONFIG_QCOM_BUS_SCALING=y CONFIG_MSM_TZ_SMMU=y CONFIG_QCOM_GLINK=y -- GitLab From f0189fe65156bc4675edc4a84dcb8583305f13ae Mon Sep 17 00:00:00 2001 From: Gustavo Solaira Date: Tue, 23 Jul 2019 12:07:39 -0700 Subject: [PATCH 1026/1121] defconfig: msm: Enable SYSVIPC for sa2150p Enable SYSVIPC to allow shmem to be used in user space programs. Change-Id: I518141d9e4ae03e0fda6632cf21aaac54a3ec0f0 Signed-off-by: Gustavo Solaira --- arch/arm64/configs/vendor/sa2150p-perf_defconfig | 1 + arch/arm64/configs/vendor/sa2150p_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm64/configs/vendor/sa2150p-perf_defconfig b/arch/arm64/configs/vendor/sa2150p-perf_defconfig index fdcd416ea447..763c76f69500 100644 --- a/arch/arm64/configs/vendor/sa2150p-perf_defconfig +++ b/arch/arm64/configs/vendor/sa2150p-perf_defconfig @@ -1,3 +1,4 @@ +CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_AUDIT=y CONFIG_NO_HZ=y diff --git a/arch/arm64/configs/vendor/sa2150p_defconfig b/arch/arm64/configs/vendor/sa2150p_defconfig index 665586314b19..f725b5d3683b 100644 --- a/arch/arm64/configs/vendor/sa2150p_defconfig +++ b/arch/arm64/configs/vendor/sa2150p_defconfig @@ -1,3 +1,4 @@ +CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_AUDIT=y CONFIG_NO_HZ=y -- GitLab From 76c91409695490a150ba85c9abfe8521b0452557 Mon Sep 17 00:00:00 2001 From: Tony Truong Date: Thu, 13 Jun 2019 18:06:42 -0700 Subject: [PATCH 1027/1121] msm: pcie: control when PCIe MSI driver can access SNPS registers It is possible PCIe MSI driver will try to access PCIe Synopsys MSI registers while there is no clock provided. Have PCIe core driver control when PCIe MSI driver can access such registers. Change-Id: I74e5fd27a7af4a84eb645d91a3eff890cf3d84d0 Signed-off-by: Tony Truong --- drivers/pci/host/pci-msm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/pci/host/pci-msm.c b/drivers/pci/host/pci-msm.c index 1e17d529dcc3..992cdc9c2976 100644 --- a/drivers/pci/host/pci-msm.c +++ b/drivers/pci/host/pci-msm.c @@ -4180,6 +4180,9 @@ static void msm_pcie_disable(struct msm_pcie_dev_t *dev, u32 options) return; } + /* suspend access to MSI register. resume access in msm_msi_config */ + msm_msi_config_access(dev_get_msi_domain(&dev->dev->dev), false); + dev->link_status = MSM_PCIE_LINK_DISABLED; dev->power_on = false; dev->link_turned_off_counter++; -- GitLab From 89754e5ed45dd4971cfcceaad2c4cbff36765195 Mon Sep 17 00:00:00 2001 From: Chris Lew Date: Fri, 28 Jun 2019 19:04:47 -0700 Subject: [PATCH 1028/1121] net: qrtr: Add support for a mhi device transport Add a transport that uses the mhi device APIs. The mhi device APIs are used to transfer data from a device to the host over MHI. The modem will generally be configured as a device and this transport is intended to be used on the modem controller co-processor. Change-Id: Ie9276fe6c0846581192aff881e59baa5fecf1ca4 Signed-off-by: Chris Lew --- net/qrtr/Kconfig | 9 ++ net/qrtr/Makefile | 3 + net/qrtr/mhi_dev.c | 248 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 260 insertions(+) create mode 100644 net/qrtr/mhi_dev.c diff --git a/net/qrtr/Kconfig b/net/qrtr/Kconfig index c4d5503684fa..b74e6fc2222e 100644 --- a/net/qrtr/Kconfig +++ b/net/qrtr/Kconfig @@ -40,4 +40,13 @@ config QRTR_FIFO Say Y here to support FIFO based ipcrouter channels. FIFO Transport Layer enables IPC Router communication between two virtual machines. +config QRTR_MHI_DEV + tristate "MHI Device IPC Router channels" + depends on MSM_MHI_DEV || (COMPILE_TEST && MSM_MHI_DEV=n) + ---help--- + Say Y here to support MHI base ipcrouter channels for device + endpoint mode. MHI is the transport used for external modem + connections. This driver enables QRTR to run on the modem device + side. + endif # QRTR diff --git a/net/qrtr/Makefile b/net/qrtr/Makefile index 57164b1c32aa..174741c03c4e 100644 --- a/net/qrtr/Makefile +++ b/net/qrtr/Makefile @@ -11,3 +11,6 @@ qrtr-usb-y := usb.o obj-$(CONFIG_QRTR_FIFO) += qrtr-fifo.o qrtr-fifo-y := fifo.o + +obj-$(CONFIG_QRTR_MHI_DEV) += qrtr-mhi-dev.o +qrtr-mhi-dev-y := mhi_dev.o diff --git a/net/qrtr/mhi_dev.c b/net/qrtr/mhi_dev.c new file mode 100644 index 000000000000..90c47e58dace --- /dev/null +++ b/net/qrtr/mhi_dev.c @@ -0,0 +1,248 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include "qrtr.h" + +#define QRTR_MAX_PKT_SIZE SZ_32K + +/* MHI DEV Enums are defined from Host perspective */ +#define QRTR_MHI_DEV_OUT MHI_CLIENT_IPCR_IN +#define QRTR_MHI_DEV_IN MHI_CLIENT_IPCR_OUT + +/** + * struct qrtr_mhi_dev_ep - qrtr mhi device endpoint + * @ep: endpoint + * @dev: device from platform bus + * @out: channel handle from mhi dev + * @out_tre: complete when channel is ready to send + * @out_lock: hold when resetting completion variable + * @in: channel handle from mhi dev + * @buf_in: buffer to hold incoming data + * @net_id: subnet id used by qrtr core + * @rt: realtime option used by qrtr core + */ +struct qrtr_mhi_dev_ep { + struct qrtr_endpoint ep; + struct device *dev; + struct mhi_dev_client *out; + struct completion out_tre; + struct mutex out_lock; /* for out critical sections */ + struct mhi_dev_client *in; + void *buf_in; + + u32 net_id; + bool rt; +}; + +static struct qrtr_mhi_dev_ep *qrtr_mhi_device_endpoint; + +static int qrtr_mhi_dev_send(struct qrtr_endpoint *ep, struct sk_buff *skb) +{ + struct qrtr_mhi_dev_ep *qep; + struct mhi_req req = { 0 }; + int rc; + + qep = container_of(ep, struct qrtr_mhi_dev_ep, ep); + rc = skb_linearize(skb); + if (rc) { + kfree_skb(skb); + return rc; + } + + req.chan = QRTR_MHI_DEV_OUT; + req.client = qep->out; + req.mode = DMA_SYNC; + req.buf = skb->data; + req.len = skb->len; + + do { + wait_for_completion(&qep->out_tre); + + mutex_lock(&qep->out_lock); + rc = mhi_dev_write_channel(&req); + if (rc == 0) + reinit_completion(&qep->out_tre); + mutex_unlock(&qep->out_lock); + } while (!rc); + + if (rc != skb->len) { + dev_err(qep->dev, "send failed rc:%d len:%d\n", rc, skb->len); + kfree_skb(skb); + return rc; + } + + consume_skb(skb); + return 0; +} + +static void qrtr_mhi_dev_read(struct qrtr_mhi_dev_ep *qep) +{ + struct mhi_req req = { 0 }; + int rc; + + req.chan = QRTR_MHI_DEV_IN; + req.client = qep->in; + req.mode = DMA_SYNC; + req.buf = qep->buf_in; + req.len = QRTR_MAX_PKT_SIZE; + + rc = mhi_dev_read_channel(&req); + if (rc < 0) { + dev_err(qep->dev, "failed to read channel %d\n", rc); + return; + } + + rc = qrtr_endpoint_post(&qep->ep, req.buf, req.transfer_len); + if (rc == -EINVAL) + dev_err(qep->dev, "invalid ipcrouter packet\n"); +} + +static void qrtr_mhi_dev_event_cb(struct mhi_dev_client_cb_reason *reason) +{ + struct qrtr_mhi_dev_ep *qep; + + qep = qrtr_mhi_device_endpoint; + if (!qep) + return; + + if (reason->reason == MHI_DEV_TRE_AVAILABLE) { + pr_debug("TRE available event for chan %d\n", reason->ch_id); + if (reason->ch_id == QRTR_MHI_DEV_IN) { + qrtr_mhi_dev_read(qep); + } else { + mutex_lock(&qep->out_lock); + complete_all(&qep->out_tre); + mutex_unlock(&qep->out_lock); + } + } +} + +static int qrtr_mhi_dev_open_channels(struct qrtr_mhi_dev_ep *qep) +{ + int rc; + + /* write channel */ + rc = mhi_dev_open_channel(QRTR_MHI_DEV_OUT, &qep->out, + qrtr_mhi_dev_event_cb); + if (rc < 0) + return rc; + + /* read channel */ + rc = mhi_dev_open_channel(QRTR_MHI_DEV_IN, &qep->in, + qrtr_mhi_dev_event_cb); + if (rc < 0) { + mhi_dev_close_channel(qep->out); + return rc; + } + return 0; +} + +static void qrtr_mhi_dev_close_channels(struct qrtr_mhi_dev_ep *qep) +{ + int rc; + + rc = mhi_dev_close_channel(qep->out); + if (rc < 0) + dev_err(qep->dev, "failed to close out channel %d\n", rc); + + rc = mhi_dev_close_channel(qep->in); + if (rc < 0) + dev_err(qep->dev, "failed to close in channel %d\n", rc); +} + +static void qrtr_mhi_dev_state_cb(struct mhi_dev_client_cb_data *cb_data) +{ + struct qrtr_mhi_dev_ep *qep; + int rc; + + if (!cb_data || !cb_data->user_data) + return; + qep = cb_data->user_data; + + switch (cb_data->ctrl_info) { + case MHI_STATE_CONNECTED: + rc = qrtr_mhi_dev_open_channels(qep); + if (rc) { + dev_err(qep->dev, "open failed %d", rc); + return; + } + + rc = qrtr_endpoint_register(&qep->ep, qep->net_id, qep->rt); + if (rc) { + dev_err(qep->dev, "register failed %d", rc); + qrtr_mhi_dev_close_channels(qep); + } + break; + case MHI_STATE_DISCONNECTED: + qrtr_endpoint_unregister(&qep->ep); + qrtr_mhi_dev_close_channels(qep); + break; + default: + break; + } +} + +static int qrtr_mhi_dev_probe(struct platform_device *pdev) +{ + struct qrtr_mhi_dev_ep *qep; + struct device_node *node; + int rc; + + qep = devm_kzalloc(&pdev->dev, sizeof(*qep), GFP_KERNEL); + if (!qep) + return -ENOMEM; + qep->dev = &pdev->dev; + + node = pdev->dev.of_node; + rc = of_property_read_u32(node, "qcom,net-id", &qep->net_id); + if (rc < 0) + qep->net_id = QRTR_EP_NET_ID_AUTO; + qep->rt = of_property_read_bool(node, "qcom,low-latency"); + + qep->buf_in = devm_kzalloc(&pdev->dev, QRTR_MAX_PKT_SIZE, GFP_KERNEL); + if (!qep->buf_in) + return -ENOMEM; + + qrtr_mhi_device_endpoint = qep; + + mutex_init(&qep->out_lock); + init_completion(&qep->out_tre); + qep->ep.xmit = qrtr_mhi_dev_send; + rc = mhi_register_state_cb(qrtr_mhi_dev_state_cb, qep, + QRTR_MHI_DEV_OUT); + if (rc) + return rc; + + return 0; +} + +static const struct of_device_id qrtr_mhi_dev_match_table[] = { + { .compatible = "qcom,qrtr-mhi-dev"}, + {}, +}; + +static struct platform_driver qrtr_mhi_dev_driver = { + .probe = qrtr_mhi_dev_probe, + .driver = { + .name = "qrtr_mhi_dev", + .of_match_table = qrtr_mhi_dev_match_table, + }, +}; +module_platform_driver(qrtr_mhi_dev_driver); + +MODULE_DESCRIPTION("QTI IPC-Router MHI device interface driver"); +MODULE_LICENSE("GPL v2"); -- GitLab From 3691814d653ed273f1ee61c7dc704c142b728fb5 Mon Sep 17 00:00:00 2001 From: Chris Lew Date: Tue, 9 Jul 2019 16:00:04 -0700 Subject: [PATCH 1029/1121] ARM: dts: msm: Add QRTR MHI DEV device for sdxprairie Add the QRTR MHI DEV transport to enable communication over pcie from the device to the host. Use Net ID 3 to enable QRTR forwarding from the host to the modem co-processor. Change-Id: I8333e3d84e129bed5c88b53f9219dadfa18b61e5 Signed-off-by: Chris Lew --- arch/arm64/boot/dts/qcom/sdxprairie.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdxprairie.dtsi b/arch/arm64/boot/dts/qcom/sdxprairie.dtsi index b85d7f622160..548ca524bb4f 100644 --- a/arch/arm64/boot/dts/qcom/sdxprairie.dtsi +++ b/arch/arm64/boot/dts/qcom/sdxprairie.dtsi @@ -691,6 +691,11 @@ }; }; + qcom,mhi_dev_qrtr { + compatible = "qcom,qrtr-mhi-dev"; + qcom,net-id = <3>; + }; + qcom,glinkpkt { compatible = "qcom,glinkpkt"; -- GitLab From 982cd7627f566ba7768e5dbd0eb4fea005638ad1 Mon Sep 17 00:00:00 2001 From: Chris Lew Date: Tue, 9 Jul 2019 18:12:15 -0700 Subject: [PATCH 1030/1121] defconfig: msm: Enable QRTR MHI DEV for sdxprairie Enable QRTR MHI Device transport to enable QRTR communication from a device configured as an pcie endpoint. Change-Id: Id548deb5d7f8a7044c0631af8dd7ad5e4471ca66 Signed-off-by: Chris Lew --- arch/arm/configs/vendor/sdxprairie-perf_defconfig | 1 + arch/arm/configs/vendor/sdxprairie_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm/configs/vendor/sdxprairie-perf_defconfig b/arch/arm/configs/vendor/sdxprairie-perf_defconfig index d629857a60fe..f5f919ef6b21 100644 --- a/arch/arm/configs/vendor/sdxprairie-perf_defconfig +++ b/arch/arm/configs/vendor/sdxprairie-perf_defconfig @@ -158,6 +158,7 @@ CONFIG_NET_SCH_PRIO=y CONFIG_QRTR=y CONFIG_QRTR_SMD=y CONFIG_QRTR_MHI=y +CONFIG_QRTR_MHI_DEV=y CONFIG_BT=y # CONFIG_BT_BREDR is not set # CONFIG_BT_LE is not set diff --git a/arch/arm/configs/vendor/sdxprairie_defconfig b/arch/arm/configs/vendor/sdxprairie_defconfig index 04b5b0310ce4..f62d039ae7b4 100644 --- a/arch/arm/configs/vendor/sdxprairie_defconfig +++ b/arch/arm/configs/vendor/sdxprairie_defconfig @@ -158,6 +158,7 @@ CONFIG_NET_SCH_PRIO=y CONFIG_QRTR=y CONFIG_QRTR_SMD=y CONFIG_QRTR_MHI=y +CONFIG_QRTR_MHI_DEV=y CONFIG_BT=y # CONFIG_BT_BREDR is not set # CONFIG_BT_LE is not set -- GitLab From 5f530f2b71a6ca7b682e620ed493e814a214e2a6 Mon Sep 17 00:00:00 2001 From: Chris Lew Date: Tue, 9 Jul 2019 17:12:49 -0700 Subject: [PATCH 1031/1121] net: qrtr: Add dynamic node id configuration Add support to configure the node id through defconfig. This is useful for targets that are unable to configure the node id through qrtr-ns because of security reasons. The local node id can still be overridden by the ns if it is capable. Change-Id: Ie9fec2ae276948340f4f5a7e0374d554502a0ee1 Signed-off-by: Chris Lew --- net/qrtr/Kconfig | 11 +++++++++++ net/qrtr/qrtr.c | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/net/qrtr/Kconfig b/net/qrtr/Kconfig index b74e6fc2222e..be1c32e10f18 100644 --- a/net/qrtr/Kconfig +++ b/net/qrtr/Kconfig @@ -14,6 +14,17 @@ config QRTR if QRTR +config QRTR_NODE_ID + int "QRTR Local Node ID" + default 1 + ---help--- + This option is used to configure the QRTR Node ID for the local + processor. The node ID published to other nodes within the system. + This value can be overridden by the name service application. This + option is for configurations where Node ID needs to be customized + but the name service application is not priveleged enough to use + netlink sockets. + config QRTR_SMD tristate "SMD IPC Router channels" depends on RPMSG || (COMPILE_TEST && RPMSG=n) diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c index 2d940d7a2d75..1f96dac37147 100644 --- a/net/qrtr/qrtr.c +++ b/net/qrtr/qrtr.c @@ -122,7 +122,7 @@ static inline struct qrtr_sock *qrtr_sk(struct sock *sk) return container_of(sk, struct qrtr_sock, sk); } -static unsigned int qrtr_local_nid = 1; +static unsigned int qrtr_local_nid = CONFIG_QRTR_NODE_ID; /* for node ids */ static RADIX_TREE(qrtr_nodes, GFP_KERNEL); -- GitLab From 20736a8405d4ab7e53137a5659db1af3457c8798 Mon Sep 17 00:00:00 2001 From: Chris Lew Date: Tue, 9 Jul 2019 18:24:20 -0700 Subject: [PATCH 1032/1121] defconfig: msm: Configure QRTR Node ID for sdxprairie Configure the QRTR Node ID as 2 for sdxprairie since this target may be used as a device to an APQ or MSM host. Change-Id: Ida1699eb39d57406b11dce263b27bf7b98b830de Signed-off-by: Chris Lew --- arch/arm/configs/vendor/sdxprairie-perf_defconfig | 1 + arch/arm/configs/vendor/sdxprairie_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm/configs/vendor/sdxprairie-perf_defconfig b/arch/arm/configs/vendor/sdxprairie-perf_defconfig index f5f919ef6b21..881499923dd6 100644 --- a/arch/arm/configs/vendor/sdxprairie-perf_defconfig +++ b/arch/arm/configs/vendor/sdxprairie-perf_defconfig @@ -156,6 +156,7 @@ CONFIG_VLAN_8021Q=y CONFIG_NET_SCHED=y CONFIG_NET_SCH_PRIO=y CONFIG_QRTR=y +CONFIG_QRTR_NODE_ID=2 CONFIG_QRTR_SMD=y CONFIG_QRTR_MHI=y CONFIG_QRTR_MHI_DEV=y diff --git a/arch/arm/configs/vendor/sdxprairie_defconfig b/arch/arm/configs/vendor/sdxprairie_defconfig index f62d039ae7b4..e17ad78ebc9a 100644 --- a/arch/arm/configs/vendor/sdxprairie_defconfig +++ b/arch/arm/configs/vendor/sdxprairie_defconfig @@ -156,6 +156,7 @@ CONFIG_VLAN_8021Q=y CONFIG_NET_SCHED=y CONFIG_NET_SCH_PRIO=y CONFIG_QRTR=y +CONFIG_QRTR_NODE_ID=2 CONFIG_QRTR_SMD=y CONFIG_QRTR_MHI=y CONFIG_QRTR_MHI_DEV=y -- GitLab From d33025a7865e42c059299fb529bdab5a27137d95 Mon Sep 17 00:00:00 2001 From: Chris Lew Date: Tue, 9 Jul 2019 19:17:44 -0700 Subject: [PATCH 1033/1121] net: qrtr: Send HELLO message on endpoint register Hello message is currently sent in response to a hello message received by the ns. When two procs operate in this slave model, then neither of them exchange the Hello message. This will halt further communication from happening. Update QRTR to send a hello message once a new endpoint is registered. Prevent duplicate Hello messages from reaching the NS because NS will echo the packet back. On two systems running QRTR, this will loopback infinitely. Change-Id: Id8483341717ed3075b426b142b21e018cefbd580 Signed-off-by: Chris Lew --- net/qrtr/mhi.c | 3 +- net/qrtr/qrtr.c | 81 ++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 75 insertions(+), 9 deletions(-) diff --git a/net/qrtr/mhi.c b/net/qrtr/mhi.c index 17a7677e8e40..f78d6d2e1aac 100644 --- a/net/qrtr/mhi.c +++ b/net/qrtr/mhi.c @@ -176,12 +176,11 @@ static int qcom_mhi_qrtr_probe(struct mhi_device *mhi_dev, INIT_LIST_HEAD(&qdev->ul_pkts); spin_lock_init(&qdev->ul_lock); + dev_set_drvdata(&mhi_dev->dev, qdev); rc = qrtr_endpoint_register(&qdev->ep, net_id, rt); if (rc) return rc; - dev_set_drvdata(&mhi_dev->dev, qdev); - dev_dbg(qdev->dev, "Qualcomm MHI QRTR driver probed\n"); return 0; diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c index 1f96dac37147..b5d2f12fc707 100644 --- a/net/qrtr/qrtr.c +++ b/net/qrtr/qrtr.c @@ -151,6 +151,7 @@ static DEFINE_MUTEX(qrtr_port_lock); * @kworker: worker thread for recv work * @task: task to run the worker thread * @read_data: scheduled work for recv work + * @say_hello: scheduled work for initiating hello * @ws: wakeupsource avoid system suspend * @ilc: ipc logging context reference */ @@ -161,6 +162,7 @@ struct qrtr_node { unsigned int nid; unsigned int net_id; atomic_t hello_sent; + atomic_t hello_rcvd; struct radix_tree_root qrtr_tx_flow; struct wait_queue_head resume_tx; @@ -172,6 +174,7 @@ struct qrtr_node { struct kthread_worker kworker; struct task_struct *task; struct kthread_work read_data; + struct kthread_work say_hello; struct wakeup_source *ws; @@ -516,6 +519,10 @@ static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb, kfree_skb(skb); return rc; } + if (atomic_read(&node->hello_sent) && type == QRTR_TYPE_HELLO) { + kfree_skb(skb); + return 0; + } /* If sk is null, this is a forwarded packet and should not wait */ if (!skb->sk) { @@ -876,6 +883,30 @@ static void qrtr_fwd_pkt(struct sk_buff *skb, struct qrtr_cb *cb) qrtr_node_enqueue(node, skb, cb->type, &from, &to, 0); qrtr_node_release(node); } + +static void qrtr_sock_queue_skb(struct qrtr_node *node, struct sk_buff *skb, + struct qrtr_sock *ipc) +{ + struct qrtr_cb *cb = (struct qrtr_cb *)skb->cb; + int rc; + + /* Don't queue HELLO if control port already received */ + if (cb->type == QRTR_TYPE_HELLO) { + if (atomic_read(&node->hello_rcvd)) { + kfree_skb(skb); + return; + } + atomic_inc(&node->hello_rcvd); + } + + rc = sock_queue_rcv_skb(&ipc->sk, skb); + if (rc) { + pr_err("%s: qrtr pkt dropped flow[%d] rc[%d]\n", + __func__, cb->confirm_rx, rc); + kfree_skb(skb); + } +} + /* Handle and route a received packet. * * This will auto-reply with resume-tx packet as necessary. @@ -918,18 +949,40 @@ static void qrtr_node_rx_work(struct kthread_work *work) if (!ipc) { kfree_skb(skb); } else { - if (sock_queue_rcv_skb(&ipc->sk, skb)) { - pr_err("%s qrtr pkt dropped flow[%d]\n", - __func__, cb->confirm_rx); - kfree_skb(skb); - } - + qrtr_sock_queue_skb(node, skb, ipc); qrtr_port_put(ipc); } } } } +static void qrtr_hello_work(struct kthread_work *work) +{ + struct sockaddr_qrtr from = {AF_QIPCRTR, 0, QRTR_PORT_CTRL}; + struct sockaddr_qrtr to = {AF_QIPCRTR, 0, QRTR_PORT_CTRL}; + struct qrtr_ctrl_pkt *pkt; + struct qrtr_node *node; + struct qrtr_sock *ctrl; + struct sk_buff *skb; + + ctrl = qrtr_port_lookup(QRTR_PORT_CTRL); + if (!ctrl) + return; + + skb = qrtr_alloc_ctrl_packet(&pkt); + if (!skb) { + qrtr_port_put(ctrl); + return; + } + + node = container_of(work, struct qrtr_node, say_hello); + pkt->cmd = cpu_to_le32(QRTR_TYPE_HELLO); + from.sq_node = qrtr_local_nid; + to.sq_node = node->nid; + qrtr_node_enqueue(node, skb, QRTR_TYPE_HELLO, &from, &to, 0); + qrtr_port_put(ctrl); +} + /** * qrtr_endpoint_register() - register a new endpoint * @ep: endpoint to register @@ -958,8 +1011,10 @@ int qrtr_endpoint_register(struct qrtr_endpoint *ep, unsigned int net_id, node->nid = QRTR_EP_NID_AUTO; node->ep = ep; atomic_set(&node->hello_sent, 0); + atomic_set(&node->hello_rcvd, 0); kthread_init_work(&node->read_data, qrtr_node_rx_work); + kthread_init_work(&node->say_hello, qrtr_hello_work); kthread_init_worker(&node->kworker); node->task = kthread_run(kthread_worker_fn, &node->kworker, "qrtr_rx"); if (IS_ERR(node->task)) { @@ -981,6 +1036,7 @@ int qrtr_endpoint_register(struct qrtr_endpoint *ep, unsigned int net_id, up_write(&qrtr_node_lock); ep->node = node; + kthread_queue_work(&node->kworker, &node->say_hello); return 0; } EXPORT_SYMBOL_GPL(qrtr_endpoint_register); @@ -1262,6 +1318,17 @@ static int __qrtr_bind(struct socket *sock, qrtr_reset_ports(); mutex_unlock(&qrtr_port_lock); + if (port == QRTR_PORT_CTRL) { + struct qrtr_node *node; + + down_write(&qrtr_node_lock); + list_for_each_entry(node, &qrtr_all_epts, item) { + atomic_set(&node->hello_sent, 0); + atomic_set(&node->hello_rcvd, 0); + } + up_write(&qrtr_node_lock); + } + /* unbind previous, if any */ if (!zapped) qrtr_port_remove(ipc); @@ -1361,7 +1428,7 @@ static int qrtr_bcast_enqueue(struct qrtr_node *node, struct sk_buff *skb, down_read(&qrtr_node_lock); list_for_each_entry(node, &qrtr_all_epts, item) { - if (node->nid == QRTR_EP_NID_AUTO) + if (node->nid == QRTR_EP_NID_AUTO && type != QRTR_TYPE_HELLO) continue; skbn = skb_clone(skb, GFP_KERNEL); if (!skbn) -- GitLab From 5c9c165066de0d0d8d6ad909f6150f988c307bbb Mon Sep 17 00:00:00 2001 From: Chris Lew Date: Tue, 16 Jul 2019 14:45:42 -0700 Subject: [PATCH 1034/1121] net: qrtr: Change the in and out channels MHI's IN channel is QRTR's OUT channel and vice-versa. Change-Id: If16790e629263cfa2787a08326c079b58f42617b Signed-off-by: Chris Lew --- net/qrtr/mhi_dev.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/net/qrtr/mhi_dev.c b/net/qrtr/mhi_dev.c index 90c47e58dace..c4ca18e3688e 100644 --- a/net/qrtr/mhi_dev.c +++ b/net/qrtr/mhi_dev.c @@ -136,16 +136,16 @@ static int qrtr_mhi_dev_open_channels(struct qrtr_mhi_dev_ep *qep) int rc; /* write channel */ - rc = mhi_dev_open_channel(QRTR_MHI_DEV_OUT, &qep->out, + rc = mhi_dev_open_channel(QRTR_MHI_DEV_IN, &qep->in, qrtr_mhi_dev_event_cb); if (rc < 0) return rc; /* read channel */ - rc = mhi_dev_open_channel(QRTR_MHI_DEV_IN, &qep->in, + rc = mhi_dev_open_channel(QRTR_MHI_DEV_OUT, &qep->out, qrtr_mhi_dev_event_cb); if (rc < 0) { - mhi_dev_close_channel(qep->out); + mhi_dev_close_channel(qep->in); return rc; } return 0; @@ -155,13 +155,13 @@ static void qrtr_mhi_dev_close_channels(struct qrtr_mhi_dev_ep *qep) { int rc; - rc = mhi_dev_close_channel(qep->out); - if (rc < 0) - dev_err(qep->dev, "failed to close out channel %d\n", rc); - rc = mhi_dev_close_channel(qep->in); if (rc < 0) dev_err(qep->dev, "failed to close in channel %d\n", rc); + + rc = mhi_dev_close_channel(qep->out); + if (rc < 0) + dev_err(qep->dev, "failed to close out channel %d\n", rc); } static void qrtr_mhi_dev_state_cb(struct mhi_dev_client_cb_data *cb_data) @@ -223,7 +223,7 @@ static int qrtr_mhi_dev_probe(struct platform_device *pdev) init_completion(&qep->out_tre); qep->ep.xmit = qrtr_mhi_dev_send; rc = mhi_register_state_cb(qrtr_mhi_dev_state_cb, qep, - QRTR_MHI_DEV_OUT); + QRTR_MHI_DEV_IN); if (rc) return rc; -- GitLab From 1a79f2584ef87fc186b042c49f4619aec4ddfdf1 Mon Sep 17 00:00:00 2001 From: Jay Jayanna Date: Fri, 19 Jul 2019 15:29:31 -0700 Subject: [PATCH 1035/1121] net: qrtr: Loop on mhi_dev_read_channel until it returns 0 qrtr_mhi_dev_event_cb will be called only once if there is more than one packet at that time. Hence, call mhi_dev_read_channel in a loop until it returns zero. Change-Id: I2f171cb45e66c1c439fcc7d0027c22d0edb4fb19 Signed-off-by: Jay Jayanna --- net/qrtr/mhi_dev.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/net/qrtr/mhi_dev.c b/net/qrtr/mhi_dev.c index c4ca18e3688e..a838c2b61a0f 100644 --- a/net/qrtr/mhi_dev.c +++ b/net/qrtr/mhi_dev.c @@ -93,6 +93,7 @@ static void qrtr_mhi_dev_read(struct qrtr_mhi_dev_ep *qep) { struct mhi_req req = { 0 }; int rc; + int bytes_read; req.chan = QRTR_MHI_DEV_IN; req.client = qep->in; @@ -100,15 +101,18 @@ static void qrtr_mhi_dev_read(struct qrtr_mhi_dev_ep *qep) req.buf = qep->buf_in; req.len = QRTR_MAX_PKT_SIZE; - rc = mhi_dev_read_channel(&req); - if (rc < 0) { - dev_err(qep->dev, "failed to read channel %d\n", rc); - return; - } + do { + bytes_read = mhi_dev_read_channel(&req); + if (bytes_read < 0) { + dev_err(qep->dev, "failed to read channel %d\n", + bytes_read); + return; + } - rc = qrtr_endpoint_post(&qep->ep, req.buf, req.transfer_len); - if (rc == -EINVAL) - dev_err(qep->dev, "invalid ipcrouter packet\n"); + rc = qrtr_endpoint_post(&qep->ep, req.buf, req.transfer_len); + if (rc == -EINVAL) + dev_err(qep->dev, "invalid ipcrouter packet\n"); + } while (bytes_read > 0); } static void qrtr_mhi_dev_event_cb(struct mhi_dev_client_cb_reason *reason) -- GitLab From 276187956c811f48f8213b32e0771500b752ba0e Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Tue, 23 Jul 2019 22:47:55 -0700 Subject: [PATCH 1036/1121] drivers: msm: pinctrl: Add custom TLMM direct connect list feature support Add support to provide a custom list of TLMM GPIOs, associated with hardware IRQs, for direct connect interrupt support. Change-Id: I390f0b6ec52aafe2eac49e8207c7754b9166491e Signed-off-by: Anant Goel --- .../bindings/pinctrl/qcom,sm6150-pinctrl | 6 ++ drivers/pinctrl/qcom/pinctrl-sm6150.c | 58 ++++++++++++++++++- 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm6150-pinctrl b/Documentation/devicetree/bindings/pinctrl/qcom,sm6150-pinctrl index 30fe7bdc947e..ff7848aeee2d 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sm6150-pinctrl +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm6150-pinctrl @@ -46,6 +46,12 @@ SM6150 platform. Value type: Definition: must be 2. Specifying the pin number and flags, as defined in +- dirconn-list: + Usage: optional + Value type: + Definition: a 3-tuple list which contains mapping of GPIO pin to + hardware IRQ, and a boolean for enabling the TLMM direct + connect interrupt for the pin. Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for a general description of GPIO and interrupt bindings. diff --git a/drivers/pinctrl/qcom/pinctrl-sm6150.c b/drivers/pinctrl/qcom/pinctrl-sm6150.c index 792ad988c07f..62da60388784 100644 --- a/drivers/pinctrl/qcom/pinctrl-sm6150.c +++ b/drivers/pinctrl/qcom/pinctrl-sm6150.c @@ -1642,7 +1642,7 @@ static struct msm_dir_conn sm6150_dir_conn[] = { {-1, 209}, }; -static const struct msm_pinctrl_soc_data sm6150_pinctrl = { +static struct msm_pinctrl_soc_data sm6150_pinctrl = { .pins = sm6150_pins, .npins = ARRAY_SIZE(sm6150_pins), .functions = sm6150_functions, @@ -1655,8 +1655,64 @@ static const struct msm_pinctrl_soc_data sm6150_pinctrl = { .dir_conn_irq_base = 216, }; +static int sm6150_pinctrl_dir_conn_probe(struct platform_device *pdev) +{ + const __be32 *prop; + struct msm_dir_conn *dir_conn_list; + uint32_t dir_conn_length, iterator = 0; + int i, length, *dir_conn_entries, num_dir_conns; + + prop = of_get_property(pdev->dev.of_node, "dirconn-list", + &length); + + dir_conn_length = length / sizeof(u32); + + dir_conn_entries = devm_kzalloc(&pdev->dev, + dir_conn_length*sizeof(uint32_t), GFP_KERNEL); + if (!dir_conn_entries) + return -ENOMEM; + + for (i = 0; i < dir_conn_length; i++) + dir_conn_entries[i] = be32_to_cpu(prop[i]); + + if (dir_conn_length % 3) { + dev_err(&pdev->dev, + "Can't parse an entry with fewer than three values\n"); + return -EINVAL; + }; + + num_dir_conns = (dir_conn_length / 3); + + dir_conn_list = devm_kzalloc(&pdev->dev, + num_dir_conns * sizeof(*dir_conn_list), GFP_KERNEL); + if (!dir_conn_list) + return -ENOMEM; + + for (i = 0; i < num_dir_conns; i++) { + dir_conn_list[i].gpio = dir_conn_entries[iterator++]; + dir_conn_list[i].hwirq = dir_conn_entries[iterator++]; + dir_conn_list[i].tlmm_dc = dir_conn_entries[iterator++]; + } + + sm6150_pinctrl.dir_conn = dir_conn_list; + sm6150_pinctrl.n_dir_conns = num_dir_conns; + + return 0; +} + static int sm6150_pinctrl_probe(struct platform_device *pdev) { + int len, ret; + + if (of_find_property(pdev->dev.of_node, "dirconn-list", &len)) { + ret = sm6150_pinctrl_dir_conn_probe(pdev); + if (ret) { + dev_err(&pdev->dev, + "Unable to parse TLMM direct connects\n"); + return ret; + } + } + return msm_pinctrl_probe(pdev, &sm6150_pinctrl); } -- GitLab From 3a86a3ed5d439de87b902679460cd4a464bab45d Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Tue, 23 Jul 2019 23:12:35 -0700 Subject: [PATCH 1037/1121] ARM: dts: msm: Add TLMM GPIOs for direct connect support on SA6155P VM Provide the TLMM GPIO direct connect list for the SA6155P virtual machine target. Change-Id: If6786518470fc8cb9d47ee9bfe49e766b404c2ae Signed-off-by: Anant Goel --- arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi b/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi index 7432a67530ed..b505791ad6eb 100644 --- a/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi @@ -349,3 +349,8 @@ #include "sa6155p-vm-usb.dtsi" #include "sa8155-vm-audio.dtsi" #include "sa6155p-vm-pcie.dtsi" + +&tlmm { + dirconn-list = <100 216 1>, + <99 215 1>; +}; -- GitLab From 963bf84722cd19f128f425e776d985805c0315c3 Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Thu, 25 Jul 2019 16:35:08 -0700 Subject: [PATCH 1038/1121] clk: qcom: Change init level for virtio clock Change the init level for the virtio clock driver from subsys_initcall to subsys_initcall_sync to support driver functionality. Change-Id: Ib9cf39c6522dcd847b00c742ca4916ae4c1da0ff Signed-off-by: Anant Goel --- drivers/clk/qcom/virtio_clk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/qcom/virtio_clk.c b/drivers/clk/qcom/virtio_clk.c index ea1c6fc1835b..3630755e5bcb 100644 --- a/drivers/clk/qcom/virtio_clk.c +++ b/drivers/clk/qcom/virtio_clk.c @@ -718,7 +718,7 @@ static void __exit virtio_clk_fini(void) { unregister_virtio_driver(&virtio_clk_driver); } -subsys_initcall(virtio_clk_init); +subsys_initcall_sync(virtio_clk_init); module_exit(virtio_clk_fini); MODULE_DEVICE_TABLE(virtio, id_table); -- GitLab From 70983ed9d1dd595c3e15957798634d2a5baca14e Mon Sep 17 00:00:00 2001 From: Srikanth Uyyala Date: Fri, 12 Jul 2019 16:11:46 +0530 Subject: [PATCH 1039/1121] msm: camera_v2: reject the late request when request_frame is very late or reg_update is missing for previous frame reject it inform using drop_reconfig flag. Change-Id: Ic7be9c765da63e2c84c4ce2ff05a3cc146f5c2bd Signed-off-by: Srikanth Uyyala --- .../msm/camera_v2/isp/msm_isp_axi_util.c | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c index 73ca32b1f7f8..2d2e33d18f7f 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c @@ -628,12 +628,9 @@ static void msm_isp_update_framedrop_reg(struct msm_vfe_axi_stream *stream_info, MSM_VFE_STREAM_STOP_PERIOD; } - if (stream_info->undelivered_request_cnt > 0 && - drop_reconfig != 1) + if (stream_info->undelivered_request_cnt > 0) stream_info->current_framedrop_period = MSM_VFE_STREAM_STOP_PERIOD; - if (stream_info->controllable_output && drop_reconfig == 1) - stream_info->current_framedrop_period = 1; /* * re-configure the period pattern, only if it's not already * set to what we want @@ -3743,9 +3740,10 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev, (stream_info->undelivered_request_cnt <= MAX_BUFFERS_IN_HW) ) { - pr_debug("%s:%d invalid time to request frame %d\n", + pr_debug("%s:%d invalid time to request frame %d try drop_reconfig\n", __func__, __LINE__, frame_id); vfe_dev->isp_page->drop_reconfig = 1; + return 0; } else if ((vfe_dev->axi_data.src_info[frame_src].active) && ((frame_id == vfe_dev->axi_data.src_info[frame_src].frame_id) || @@ -3753,10 +3751,11 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev, (stream_info->undelivered_request_cnt <= MAX_BUFFERS_IN_HW)) { vfe_dev->isp_page->drop_reconfig = 1; - pr_debug("%s: vfe_%d request_frame %d cur frame id %d pix %d\n", + pr_debug("%s: vfe_%d request_frame %d cur frame id %d pix %d try drop_reconfig\n", __func__, vfe_dev->pdev->id, frame_id, vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id, vfe_dev->axi_data.src_info[VFE_PIX_0].active); + return 0; } else if ((vfe_dev->axi_data.src_info[frame_src].active && (frame_id != vfe_dev->axi_data.src_info[frame_src].frame_id + vfe_dev->axi_data.src_info[frame_src].sof_counter_step)) || @@ -3777,19 +3776,18 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev, if ((frame_src == VFE_PIX_0) && !stream_info->undelivered_request_cnt && MSM_VFE_STREAM_STOP_PERIOD != stream_info->activated_framedrop_period) { + /* wm is reloaded if undelivered_request_cnt is zero. + * As per the hw behavior wm should be disabled or skip writing + * before reload happens other wise wm could start writing from + * middle of the frame and could result in image corruption. + * instead of dropping frame in this error scenario use + * drop_reconfig flag to process the request in next sof. + */ pr_debug("%s:%d vfe %d frame_id %d prev_pattern %x stream_id %x\n", __func__, __LINE__, vfe_dev->pdev->id, frame_id, stream_info->activated_framedrop_period, stream_info->stream_id); - - rc = msm_isp_return_empty_buffer(vfe_dev, stream_info, - user_stream_id, frame_id, buf_index, frame_src); - if (rc < 0) - pr_err("%s:%d failed: return_empty_buffer src %d\n", - __func__, __LINE__, frame_src); - stream_info->current_framedrop_period = - MSM_VFE_STREAM_STOP_PERIOD; - msm_isp_cfg_framedrop_reg(stream_info); + vfe_dev->isp_page->drop_reconfig = 1; return 0; } -- GitLab From 1c6ecf0d358a3adfc6dace14d01ca552be6ae1c0 Mon Sep 17 00:00:00 2001 From: Zhiqiang Tu Date: Thu, 21 Mar 2019 16:12:31 +0800 Subject: [PATCH 1040/1121] regulator: add virtio regulator driver This is virtio regulator frontend driver for guest virtual machine. Change-Id: Ib3be816ea4e03ab3c24d633017f37de4eb702c73 Signed-off-by: Zhiqiang Tu --- drivers/regulator/Kconfig | 6 + drivers/regulator/Makefile | 1 + drivers/regulator/virtio_regulator.c | 659 +++++++++++++++++++++++++++ include/linux/virtio_regulator.h | 40 ++ include/uapi/linux/virtio_ids.h | 1 + 5 files changed, 707 insertions(+) create mode 100644 drivers/regulator/virtio_regulator.c create mode 100644 include/linux/virtio_regulator.h diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index dd881a9394c6..c98b1f1fc0f2 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -1084,5 +1084,11 @@ config REGULATOR_STUB Clients can use the real regulator device names with proper constraint checking while the real driver is being developed. +config VIRTIO_REGULATOR + tristate "Virtio regulator driver" + depends on VIRTIO + ---help--- + This is the virtual regulator driver for virtio. + endif diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 63fe6cdf32f9..c06ffb304781 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -135,5 +135,6 @@ obj-$(CONFIG_REGULATOR_RPM_SMD) += rpm-smd-regulator.o obj-$(CONFIG_REGULATOR_SPM) += spm-regulator.o obj-$(CONFIG_REGULATOR_RPMH) += rpmh-regulator.o obj-$(CONFIG_REGULATOR_STUB) += stub-regulator.o +obj-$(CONFIG_VIRTIO_REGULATOR) += virtio_regulator.o ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG diff --git a/drivers/regulator/virtio_regulator.c b/drivers/regulator/virtio_regulator.c new file mode 100644 index 000000000000..99c587026668 --- /dev/null +++ b/drivers/regulator/virtio_regulator.c @@ -0,0 +1,659 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define pr_fmt(fmt) "%s: " fmt, __func__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define VIRTIO_REGULATOR_TIMEOUT 200 /* miliseconds */ +#define VIRTIO_REGULATOR_MAX_NAME 20 +#define VIRTIO_REGULATOR_VOLTAGE_UNKNOWN 1 + +struct reg_virtio; + +struct virtio_regulator { + struct virtio_device *vdev; + struct virtqueue *vq; + struct completion rsp_avail; + struct mutex lock; + struct reg_virtio *regs; + int regs_count; +}; + +struct reg_virtio { + struct device_node *of_node; + struct regulator_desc rdesc; + struct regulator_dev *rdev; + struct virtio_regulator *vreg; + char name[VIRTIO_REGULATOR_MAX_NAME]; + bool enabled; +}; + +static int virtio_regulator_enable(struct regulator_dev *rdev) +{ + struct reg_virtio *reg = rdev_get_drvdata(rdev); + struct virtio_regulator *vreg = reg->vreg; + struct virtio_regulator_msg *req, *rsp; + struct scatterlist sg[1]; + unsigned int len; + int ret = 0; + + req = kzalloc(sizeof(struct virtio_regulator_msg), GFP_KERNEL); + if (!req) + return -ENOMEM; + + strlcpy(req->name, reg->rdesc.name, sizeof(req->name)); + req->type = cpu_to_virtio32(vreg->vdev, VIRTIO_REGULATOR_T_ENABLE); + sg_init_one(sg, req, sizeof(*req)); + + mutex_lock(&vreg->lock); + + ret = virtqueue_add_outbuf(vreg->vq, sg, 1, req, GFP_KERNEL); + if (ret) { + pr_err("%s: fail to add output buffer\n", reg->rdesc.name); + goto out; + } + + virtqueue_kick(vreg->vq); + + ret = wait_for_completion_timeout(&vreg->rsp_avail, + msecs_to_jiffies(VIRTIO_REGULATOR_TIMEOUT)); + if (!ret) { + ret = -ETIMEDOUT; + goto out; + } + + rsp = virtqueue_get_buf(vreg->vq, &len); + if (!rsp) { + pr_err("%s: fail to get virtqueue buffer\n", reg->rdesc.name); + ret = -EIO; + goto out; + } + + ret = virtio32_to_cpu(vreg->vdev, rsp->result); + + if (!ret) + reg->enabled = true; +out: + mutex_unlock(&vreg->lock); + kfree(req); + + pr_debug("%s return %d\n", reg->rdesc.name, ret); + + return ret; +} + +static int virtio_regulator_disable(struct regulator_dev *rdev) +{ + struct reg_virtio *reg = rdev_get_drvdata(rdev); + struct virtio_regulator *vreg = reg->vreg; + struct virtio_regulator_msg *req, *rsp; + struct scatterlist sg[1]; + unsigned int len; + int ret = 0; + + req = kzalloc(sizeof(struct virtio_regulator_msg), GFP_KERNEL); + if (!req) + return -ENOMEM; + + strlcpy(req->name, reg->rdesc.name, sizeof(req->name)); + req->type = cpu_to_virtio32(vreg->vdev, VIRTIO_REGULATOR_T_DISABLE); + sg_init_one(sg, req, sizeof(*req)); + + mutex_lock(&vreg->lock); + + ret = virtqueue_add_outbuf(vreg->vq, sg, 1, req, GFP_KERNEL); + if (ret) { + pr_err("%s: fail to add output buffer\n", reg->rdesc.name); + goto out; + } + + virtqueue_kick(vreg->vq); + + ret = wait_for_completion_timeout(&vreg->rsp_avail, + msecs_to_jiffies(VIRTIO_REGULATOR_TIMEOUT)); + if (!ret) { + ret = -ETIMEDOUT; + goto out; + } + + rsp = virtqueue_get_buf(vreg->vq, &len); + if (!rsp) { + pr_err("%s: fail to get virtqueue buffer\n", reg->rdesc.name); + ret = -EIO; + goto out; + } + + ret = virtio32_to_cpu(vreg->vdev, rsp->result); + + if (!ret) + reg->enabled = false; +out: + mutex_unlock(&vreg->lock); + kfree(req); + + pr_debug("%s return %d\n", reg->rdesc.name, ret); + + return ret; +} + +static int virtio_regulator_is_enabled(struct regulator_dev *rdev) +{ + struct reg_virtio *reg = rdev_get_drvdata(rdev); + + pr_debug("%s return %d\n", reg->rdesc.name, reg->enabled); + + return reg->enabled; +} + +static int virtio_regulator_set_voltage(struct regulator_dev *rdev, int min_uV, + int max_uV, unsigned int *selector) +{ + struct reg_virtio *reg = rdev_get_drvdata(rdev); + struct virtio_regulator *vreg = reg->vreg; + struct virtio_regulator_msg *req, *rsp; + struct scatterlist sg[1]; + unsigned int len; + int ret = 0; + + req = kzalloc(sizeof(struct virtio_regulator_msg), GFP_KERNEL); + if (!req) + return -ENOMEM; + + strlcpy(req->name, reg->rdesc.name, sizeof(req->name)); + req->type = cpu_to_virtio32(vreg->vdev, VIRTIO_REGULATOR_T_SET_VOLTAGE); + req->data[0] = cpu_to_virtio32(vreg->vdev, DIV_ROUND_UP(min_uV, 1000)); + req->data[1] = cpu_to_virtio32(vreg->vdev, max_uV / 1000); + sg_init_one(sg, req, sizeof(*req)); + + mutex_lock(&vreg->lock); + + ret = virtqueue_add_outbuf(vreg->vq, sg, 1, req, GFP_KERNEL); + if (ret) { + pr_err("%s: fail to add output buffer\n", reg->rdesc.name); + goto out; + } + + virtqueue_kick(vreg->vq); + + ret = wait_for_completion_timeout(&vreg->rsp_avail, + msecs_to_jiffies(VIRTIO_REGULATOR_TIMEOUT)); + if (!ret) { + ret = -ETIMEDOUT; + goto out; + } + + rsp = virtqueue_get_buf(vreg->vq, &len); + if (!rsp) { + pr_err("%s: fail to get virtqueue buffer\n", reg->rdesc.name); + ret = -EIO; + goto out; + } + + ret = virtio32_to_cpu(vreg->vdev, rsp->result); + +out: + mutex_unlock(&vreg->lock); + kfree(req); + + pr_debug("%s return %d\n", reg->rdesc.name, ret); + + return ret; +} + +static int virtio_regulator_get_voltage(struct regulator_dev *rdev) +{ + struct reg_virtio *reg = rdev_get_drvdata(rdev); + struct virtio_regulator *vreg = reg->vreg; + struct virtio_regulator_msg *req, *rsp; + struct scatterlist sg[1]; + unsigned int len; + int ret = 0; + + req = kzalloc(sizeof(struct virtio_regulator_msg), GFP_KERNEL); + if (!req) + return -ENOMEM; + + strlcpy(req->name, reg->rdesc.name, sizeof(req->name)); + req->type = cpu_to_virtio32(vreg->vdev, VIRTIO_REGULATOR_T_GET_VOLTAGE); + sg_init_one(sg, req, sizeof(*req)); + + mutex_lock(&vreg->lock); + + ret = virtqueue_add_outbuf(vreg->vq, sg, 1, req, GFP_KERNEL); + if (ret) { + pr_err("%s: fail to add output buffer\n", reg->rdesc.name); + goto out; + } + + virtqueue_kick(vreg->vq); + + ret = wait_for_completion_timeout(&vreg->rsp_avail, + msecs_to_jiffies(VIRTIO_REGULATOR_TIMEOUT)); + if (!ret) { + ret = -ETIMEDOUT; + goto out; + } + + rsp = virtqueue_get_buf(vreg->vq, &len); + if (!rsp) { + pr_err("%s: fail to get virtqueue buffer\n", reg->rdesc.name); + ret = -EIO; + goto out; + } + + if (rsp->result) { + pr_debug("%s: error response (%d)\n", reg->rdesc.name, + virtio32_to_cpu(vreg->vdev, rsp->result)); + ret = VIRTIO_REGULATOR_VOLTAGE_UNKNOWN; + } else + ret = virtio32_to_cpu(vreg->vdev, rsp->data[0]) * 1000; + +out: + mutex_unlock(&vreg->lock); + kfree(req); + + pr_debug("%s return %d\n", reg->rdesc.name, ret); + + return ret; +} + +static int virtio_regulator_set_mode(struct regulator_dev *rdev, + unsigned int mode) +{ + struct reg_virtio *reg = rdev_get_drvdata(rdev); + struct virtio_regulator *vreg = reg->vreg; + struct virtio_regulator_msg *req, *rsp; + struct scatterlist sg[1]; + unsigned int len; + int ret = 0; + + req = kzalloc(sizeof(struct virtio_regulator_msg), GFP_KERNEL); + if (!req) + return -ENOMEM; + + strlcpy(req->name, reg->rdesc.name, sizeof(req->name)); + req->type = cpu_to_virtio32(vreg->vdev, VIRTIO_REGULATOR_T_SET_MODE); + req->data[0] = cpu_to_virtio32(vreg->vdev, mode); + sg_init_one(sg, req, sizeof(*req)); + + mutex_lock(&vreg->lock); + + ret = virtqueue_add_outbuf(vreg->vq, sg, 1, req, GFP_KERNEL); + if (ret) { + pr_err("%s: fail to add output buffer\n", reg->rdesc.name); + goto out; + } + + virtqueue_kick(vreg->vq); + + ret = wait_for_completion_timeout(&vreg->rsp_avail, + msecs_to_jiffies(VIRTIO_REGULATOR_TIMEOUT)); + if (!ret) { + ret = -ETIMEDOUT; + goto out; + } + + rsp = virtqueue_get_buf(vreg->vq, &len); + if (!rsp) { + pr_err("%s: fail to get virtqueue buffer\n", reg->rdesc.name); + ret = -EIO; + goto out; + } + + ret = virtio32_to_cpu(vreg->vdev, rsp->result); + +out: + mutex_unlock(&vreg->lock); + kfree(req); + + pr_debug("%s return %d\n", reg->rdesc.name, ret); + + return ret; +} + +static unsigned int virtio_regulator_get_mode(struct regulator_dev *rdev) +{ + struct reg_virtio *reg = rdev_get_drvdata(rdev); + struct virtio_regulator *vreg = reg->vreg; + struct virtio_regulator_msg *req, *rsp; + struct scatterlist sg[1]; + unsigned int len; + int ret = 0; + + req = kzalloc(sizeof(struct virtio_regulator_msg), GFP_KERNEL); + if (!req) + return -ENOMEM; + + strlcpy(req->name, reg->rdesc.name, sizeof(req->name)); + req->type = cpu_to_virtio32(vreg->vdev, VIRTIO_REGULATOR_T_GET_MODE); + sg_init_one(sg, req, sizeof(*req)); + + mutex_lock(&vreg->lock); + + ret = virtqueue_add_outbuf(vreg->vq, sg, 1, req, GFP_KERNEL); + if (ret) { + pr_err("%s: fail to add output buffer\n", reg->rdesc.name); + goto out; + } + + virtqueue_kick(vreg->vq); + + ret = wait_for_completion_timeout(&vreg->rsp_avail, + msecs_to_jiffies(VIRTIO_REGULATOR_TIMEOUT)); + if (!ret) { + ret = -ETIMEDOUT; + goto out; + } + + rsp = virtqueue_get_buf(vreg->vq, &len); + if (!rsp) { + pr_err("%s: fail to get virtqueue buffer\n", reg->rdesc.name); + ret = -EIO; + goto out; + } + + if (rsp->result) { + pr_err("%s: error response (%d)\n", reg->rdesc.name, + virtio32_to_cpu(vreg->vdev, rsp->result)); + ret = 0; + } else + ret = virtio32_to_cpu(vreg->vdev, rsp->data[0]); + +out: + mutex_unlock(&vreg->lock); + kfree(req); + + pr_debug("%s return %d\n", reg->rdesc.name, ret); + + return ret; +} + +static int virtio_regulator_set_load(struct regulator_dev *rdev, int load_ua) +{ + struct reg_virtio *reg = rdev_get_drvdata(rdev); + struct virtio_regulator *vreg = reg->vreg; + struct virtio_regulator_msg *req, *rsp; + struct scatterlist sg[1]; + unsigned int len; + int ret = 0; + + req = kzalloc(sizeof(struct virtio_regulator_msg), GFP_KERNEL); + if (!req) + return -ENOMEM; + + strlcpy(req->name, reg->rdesc.name, sizeof(req->name)); + req->type = cpu_to_virtio32(vreg->vdev, VIRTIO_REGULATOR_T_SET_LOAD); + req->data[0] = cpu_to_virtio32(vreg->vdev, load_ua); + sg_init_one(sg, req, sizeof(*req)); + + mutex_lock(&vreg->lock); + + ret = virtqueue_add_outbuf(vreg->vq, sg, 1, req, GFP_KERNEL); + if (ret) { + pr_err("%s: fail to add output buffer\n", reg->rdesc.name); + goto out; + } + + virtqueue_kick(vreg->vq); + + ret = wait_for_completion_timeout(&vreg->rsp_avail, + msecs_to_jiffies(VIRTIO_REGULATOR_TIMEOUT)); + if (!ret) { + ret = -ETIMEDOUT; + goto out; + } + + rsp = virtqueue_get_buf(vreg->vq, &len); + if (!rsp) { + pr_err("%s: fail to get virtqueue buffer\n", reg->rdesc.name); + ret = -EIO; + goto out; + } + + ret = virtio32_to_cpu(vreg->vdev, rsp->result); + +out: + mutex_unlock(&vreg->lock); + kfree(req); + + pr_debug("%s return %d\n", reg->rdesc.name, ret); + + return ret; +} + +static struct regulator_ops virtio_regulator_ops = { + .enable = virtio_regulator_enable, + .disable = virtio_regulator_disable, + .is_enabled = virtio_regulator_is_enabled, + .set_voltage = virtio_regulator_set_voltage, + .get_voltage = virtio_regulator_get_voltage, + .set_mode = virtio_regulator_set_mode, + .get_mode = virtio_regulator_get_mode, + .set_load = virtio_regulator_set_load, +}; + +static void virtio_regulator_isr(struct virtqueue *vq) +{ + struct virtio_regulator *vregulator = vq->vdev->priv; + + complete(&vregulator->rsp_avail); +} + +static int virtio_regulator_init_vqs(struct virtio_regulator *vreg) +{ + struct virtqueue *vqs[1]; + vq_callback_t *cbs[] = { virtio_regulator_isr }; + static const char * const names[] = { "regulator" }; + int ret; + + ret = virtio_find_vqs(vreg->vdev, 1, vqs, cbs, names, NULL); + if (ret) + return ret; + + vreg->vq = vqs[0]; + + return 0; +} + +static int virtio_regulator_allocate_reg(struct virtio_regulator *vreg) +{ + struct device_node *parent_node, *node; + int i, ret; + + vreg->regs_count = 0; + parent_node = vreg->vdev->dev.parent->of_node; + + for_each_available_child_of_node(parent_node, node) { + /* Skip child nodes handled by other drivers. */ + if (of_find_property(node, "compatible", NULL)) + continue; + vreg->regs_count++; + } + + if (vreg->regs_count == 0) { + dev_err(&vreg->vdev->dev, + "could not find any regulator subnodes\n"); + return -ENODEV; + } + + vreg->regs = devm_kcalloc(&vreg->vdev->dev, vreg->regs_count, + sizeof(*vreg->regs), GFP_KERNEL); + if (!vreg->regs) + return -ENOMEM; + + i = 0; + for_each_available_child_of_node(parent_node, node) { + /* Skip child nodes handled by other drivers. */ + if (of_find_property(node, "compatible", NULL)) + continue; + + vreg->regs[i].of_node = node; + vreg->regs[i].vreg = vreg; + + ret = of_property_read_string(node, "regulator-name", + &vreg->regs[i].rdesc.name); + if (ret) { + dev_err(&vreg->vdev->dev, + "could not read regulator-name\n"); + return ret; + } + + i++; + } + + return 0; +} + +static int virtio_regulator_init_reg(struct reg_virtio *reg) +{ + struct device *dev = reg->vreg->vdev->dev.parent; + struct regulator_config reg_config = {}; + struct regulator_init_data *init_data; + int ret = 0; + + reg->rdesc.owner = THIS_MODULE; + reg->rdesc.type = REGULATOR_VOLTAGE; + reg->rdesc.ops = &virtio_regulator_ops; + + init_data = of_get_regulator_init_data(dev, reg->of_node, ®->rdesc); + if (init_data == NULL) + return -ENOMEM; + + init_data->constraints.input_uV = init_data->constraints.max_uV; + init_data->constraints.valid_ops_mask |= REGULATOR_CHANGE_VOLTAGE; + + reg_config.dev = dev; + reg_config.init_data = init_data; + reg_config.of_node = reg->of_node; + reg_config.driver_data = reg; + + reg->rdev = devm_regulator_register(dev, ®->rdesc, ®_config); + if (IS_ERR(reg->rdev)) { + ret = PTR_ERR(reg->rdev); + reg->rdev = NULL; + dev_err(®->vreg->vdev->dev, "fail to register regulator\n"); + return ret; + } + + return ret; +} + +static int virtio_regulator_probe(struct virtio_device *vdev) +{ + struct virtio_regulator *vreg; + unsigned int i; + int ret; + + if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) + return -ENODEV; + + vreg = devm_kzalloc(&vdev->dev, sizeof(struct virtio_regulator), + GFP_KERNEL); + if (!vreg) + return -ENOMEM; + + vdev->priv = vreg; + vreg->vdev = vdev; + mutex_init(&vreg->lock); + init_completion(&vreg->rsp_avail); + + ret = virtio_regulator_init_vqs(vreg); + if (ret) { + dev_err(&vdev->dev, "fail to initialize virtqueue\n"); + return ret; + } + + virtio_device_ready(vdev); + + ret = virtio_regulator_allocate_reg(vreg); + if (ret) { + dev_err(&vdev->dev, "fail to allocate regulators\n"); + goto err_allocate_reg; + } + + for (i = 0; i < vreg->regs_count; i++) { + ret = virtio_regulator_init_reg(&vreg->regs[i]); + if (ret) { + dev_err(&vdev->dev, "fail to initialize regulator %s\n", + vreg->regs[i].rdesc.name); + goto err_init_reg; + } + } + + dev_dbg(&vdev->dev, "virtio regulator probe successfully\n"); + + return 0; + +err_init_reg: +err_allocate_reg: + vdev->config->del_vqs(vdev); + return ret; +} + +static void virtio_regulator_remove(struct virtio_device *vdev) +{ + struct virtio_regulator *vreg = vdev->priv; + void *buf; + + vdev->config->reset(vdev); + while ((buf = virtqueue_detach_unused_buf(vreg->vq)) != NULL) + kfree(buf); + vdev->config->del_vqs(vdev); +} + +static const struct virtio_device_id id_table[] = { + { VIRTIO_ID_REGULATOR, VIRTIO_DEV_ANY_ID }, + { 0 }, +}; + +static unsigned int features[] = { +}; + +static struct virtio_driver virtio_regulator_driver = { + .feature_table = features, + .feature_table_size = ARRAY_SIZE(features), + .driver.name = KBUILD_MODNAME, + .driver.owner = THIS_MODULE, + .id_table = id_table, + .probe = virtio_regulator_probe, + .remove = virtio_regulator_remove, +}; + +static int __init virtio_regulator_init(void) +{ + return register_virtio_driver(&virtio_regulator_driver); +} + +static void __exit virtio_regulator_exit(void) +{ + unregister_virtio_driver(&virtio_regulator_driver); +} +subsys_initcall(virtio_regulator_init); +module_exit(virtio_regulator_exit); + +MODULE_DEVICE_TABLE(virtio, id_table); +MODULE_DESCRIPTION("Virtio regulator driver"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/virtio_regulator.h b/include/linux/virtio_regulator.h new file mode 100644 index 000000000000..1189bbda2a8f --- /dev/null +++ b/include/linux/virtio_regulator.h @@ -0,0 +1,40 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _LINUX_VIRTIO_REGULATOR_H +#define _LINUX_VIRTIO_REGULATOR_H + +#include +#include +#include +#include + +/* Request/response message format */ +struct virtio_regulator_msg { + u8 name[20]; + __virtio32 type; + __virtio32 result; + __virtio32 data[4]; +}; + +/* Request type */ +#define VIRTIO_REGULATOR_T_ENABLE 0 +#define VIRTIO_REGULATOR_T_DISABLE 1 +#define VIRTIO_REGULATOR_T_SET_VOLTAGE 2 +#define VIRTIO_REGULATOR_T_GET_VOLTAGE 3 +#define VIRTIO_REGULATOR_T_SET_CURRENT_LIMIT 4 +#define VIRTIO_REGULATOR_T_GET_CURRENT_LIMIT 5 +#define VIRTIO_REGULATOR_T_SET_MODE 6 +#define VIRTIO_REGULATOR_T_GET_MODE 7 +#define VIRTIO_REGULATOR_T_SET_LOAD 8 + +#endif /* _LINUX_VIRTIO_REGULATOR_H */ diff --git a/include/uapi/linux/virtio_ids.h b/include/uapi/linux/virtio_ids.h index dcdd3421e35c..af8f368f3425 100644 --- a/include/uapi/linux/virtio_ids.h +++ b/include/uapi/linux/virtio_ids.h @@ -44,6 +44,7 @@ #define VIRTIO_ID_VSOCK 19 /* virtio vsock transport */ #define VIRTIO_ID_CRYPTO 20 /* virtio crypto */ #define VIRTIO_ID_CLOCK 30 /* virtio clock */ +#define VIRTIO_ID_REGULATOR 31 /* virtio regulator */ #define VIRTIO_ID_I2C 32 /* virtio i2c */ -- GitLab From 1c232f80b968d2f80748d4ea0467bb0d69a70b99 Mon Sep 17 00:00:00 2001 From: Zhiqiang Tu Date: Wed, 12 Jun 2019 12:35:45 +0800 Subject: [PATCH 1041/1121] defconfig: msm: Enable virtio regulator for QTI Quin GVM Enable virtio regulator for Quin virtual machine. Change-Id: Ib0fe348e6205d2636f19baa2ee34caa4470c1b8e Signed-off-by: Zhiqiang Tu --- arch/arm64/configs/vendor/qti-quin-gvm-perf_defconfig | 1 + arch/arm64/configs/vendor/qti-quin-gvm_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm64/configs/vendor/qti-quin-gvm-perf_defconfig b/arch/arm64/configs/vendor/qti-quin-gvm-perf_defconfig index 1c21491ae274..02122779e16b 100644 --- a/arch/arm64/configs/vendor/qti-quin-gvm-perf_defconfig +++ b/arch/arm64/configs/vendor/qti-quin-gvm-perf_defconfig @@ -327,6 +327,7 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_PROXY_CONSUMER=y CONFIG_REGULATOR_REFGEN=y CONFIG_REGULATOR_STUB=y +CONFIG_VIRTIO_REGULATOR=y CONFIG_MEDIA_SUPPORT=y CONFIG_MEDIA_CAMERA_SUPPORT=y CONFIG_MEDIA_CONTROLLER=y diff --git a/arch/arm64/configs/vendor/qti-quin-gvm_defconfig b/arch/arm64/configs/vendor/qti-quin-gvm_defconfig index 0ab5f39e47ad..2b2f71068c57 100644 --- a/arch/arm64/configs/vendor/qti-quin-gvm_defconfig +++ b/arch/arm64/configs/vendor/qti-quin-gvm_defconfig @@ -339,6 +339,7 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_PROXY_CONSUMER=y CONFIG_REGULATOR_REFGEN=y CONFIG_REGULATOR_STUB=y +CONFIG_VIRTIO_REGULATOR=y CONFIG_MEDIA_SUPPORT=y CONFIG_MEDIA_CAMERA_SUPPORT=y CONFIG_MEDIA_CONTROLLER=y -- GitLab From 9188d6a08a80de5c38772f56e49a5d281ba89417 Mon Sep 17 00:00:00 2001 From: Zhiqiang Tu Date: Mon, 22 Jul 2019 16:38:04 +0800 Subject: [PATCH 1042/1121] ARM: dts: msm: Add virtio regulator on sa6155p virtual machine Add virtio regulator for pass-through devices. Change-Id: I3cd19d1fc28d9afde158fa40f6b06cb51e4ffaf1 Signed-off-by: Zhiqiang Tu --- arch/arm64/boot/dts/qcom/sa6155p-vm-usb.dtsi | 16 +-- arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi | 125 +++++++------------ 2 files changed, 56 insertions(+), 85 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sa6155p-vm-usb.dtsi b/arch/arm64/boot/dts/qcom/sa6155p-vm-usb.dtsi index 3db66cf1455f..ef2dcb739f35 100644 --- a/arch/arm64/boot/dts/qcom/sa6155p-vm-usb.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155p-vm-usb.dtsi @@ -119,9 +119,9 @@ "tune2_efuse_addr", "tcsr_conn_box_spare_0"; - vdd-supply = <&pm6150_l4>; - vdda18-supply = <&pm6150_l11>; - vdda33-supply = <&pm6150_l17>; + vdd-supply = <&L5A>; + vdda18-supply = <&L12A>; + vdda33-supply = <&L13A>; qcom,vdd-voltage-level = <0 925000 975000>; qcom,tune2-efuse-bit-pos = <25>; qcom,tune2-efuse-num-bits = <4>; @@ -159,8 +159,8 @@ reg-names = "qmp_phy_base", "vls_clamp_reg"; - vdd-supply = <&pm6150_l4>; - core-supply = <&pm6150_l11>; + vdd-supply = <&L5A>; + core-supply = <&L12A>; qcom,vdd-voltage-level = <0 925000 975000>; qcom,core-voltage-level = <0 1800000 1800000>; qcom,qmp-phy-init-seq = @@ -370,9 +370,9 @@ reg-names = "qusb_phy_base", "tcsr_conn_box_spare_0"; - vdd-supply = <&pm6150_l4>; - vdda18-supply = <&pm6150_l11>; - vdda33-supply = <&pm6150_l17>; + vdd-supply = <&L5A>; + vdda18-supply = <&L12A>; + vdda33-supply = <&L13A>; qcom,vdd-voltage-level = <0 925000 975000>; qcom,qusb-phy-init-seq = <0xc8 0x80 0xb3 0x84 diff --git a/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi b/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi index 7432a67530ed..2639be0fa8fd 100644 --- a/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi @@ -53,6 +53,54 @@ #reset-cells = <1>; }; + regulator_virt: virtio_regulator@1c700000 { + compatible = "virtio,mmio"; + reg = <0x1c700000 0x1000>; + interrupts = <0 42 0>; + + usb30_prim_gdsc: usb30_prim_gdsc { + regulator-name = "usb30_prim_gdsc"; + }; + + usb20_sec_gdsc: usb20_sec_gdsc { + regulator-name = "usb20_sec_gdsc"; + }; + + pcie_0_gdsc: pcie_0_gdsc { + regulator-name = "pcie_0_gdsc"; + }; + + L2A: pm6155_1_l2: regulator-pm6155-1-l2 { + regulator-name = "ldoa2"; + regulator-min-microvolt = <1650000>; + regulator-max-microvolt = <3100000>; + }; + + L5A: pm6155_1_l5: regulator-pm6155-1-l5 { + regulator-name = "ldoa5"; + regulator-min-microvolt = <875000>; + regulator-max-microvolt = <975000>; + }; + + L10A: pm6155_1_l10: regulator-pm6155-1-l10 { + regulator-name = "ldoa10"; + regulator-min-microvolt = <2950000>; + regulator-max-microvolt = <3312000>; + }; + + L12A: pm6155_1_l12: regulator-pm6155-1-l12 { + regulator-name = "ldoa12"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1890000>; + }; + + L13A: pm6155_1_l13: regulator-pm6155-1-l13 { + regulator-name = "ldoa13"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3230000>; + }; + }; + apps_smmu: apps-smmu@0x15000000 { compatible = "qcom,qsmmu-v500"; reg = <0x15000000 0x80000>, @@ -140,45 +188,6 @@ status = "ok"; }; - usb30_prim_gdsc: usb30_prim_gdsc { - compatible = "qcom,stub-regulator"; - regulator-name = "usb30_prim_gdsc"; - status = "ok"; - }; - - usb20_sec_gdsc: usb20_sec_gdsc { - compatible = "qcom,stub-regulator"; - regulator-name = "usb20_sec_gdsc"; - status = "ok"; - }; - - pm6150_l11: regulator-pm6150-l11 { - compatible = "qcom,stub-regulator"; - regulator-name = "pm6150_l11"; - qcom,hpm-min-load = <10000>; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1890000>; - status = "ok"; - }; - - pm6150_l4: regulator-pm6150-l4 { - compatible = "qcom,stub-regulator"; - regulator-name = "pm6150_l4"; - qcom,hpm-min-load = <10000>; - regulator-min-microvolt = <875000>; - regulator-max-microvolt = <975000>; - status = "ok"; - }; - - pm6150_l17: regulator-pm6150-l17 { - compatible = "qcom,stub-regulator"; - regulator-name = "pm6150_l17"; - qcom,hpm-min-load = <10000>; - regulator-min-microvolt = <3000000>; - regulator-max-microvolt = <3230000>; - status = "ok"; - }; - qcom_seecom: qseecom@86d00000 { compatible = "qcom,qseecom"; reg = <0x86d00000 0xe00000>; @@ -192,38 +201,6 @@ qcom,qsee-reentrancy-support = <2>; }; - pm6155_1_l10: regulator-pm6155-1-l10 { - compatible = "qcom,stub-regulator"; - regulator-name = "pm6155_1_l10"; - regulator-min-microvolt = <2950000>; - regulator-max-microvolt = <3312000>; - status = "ok"; - }; - - pm6155_1_l2: regulator-pm6155-1-l2 { - compatible = "qcom,stub-regulator"; - regulator-name = "pm6155_1_l2"; - regulator-min-microvolt = <1650000>; - regulator-max-microvolt = <3100000>; - status = "ok"; - }; - - pm6155_1_l12: regulator-pm6155-1-l12 { - compatible = "qcom,stub-regulator"; - regulator-name = "pm6155_1_l12"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1890000>; - status = "ok"; - }; - - pm6155_1_l5: regulator-pm6155-1-l5 { - compatible = "qcom,stub-regulator"; - regulator-name = "pm6155_1_l5"; - regulator-min-microvolt = <875000>; - regulator-max-microvolt = <975000>; - status = "ok"; - }; - VDD_CX_LEVEL: VDD_MX_LEVEL: S2A_LEVEL: pm6155_1_s2_level: regulator-pm6155-1-s2-level { compatible = "qcom,stub-regulator"; @@ -234,12 +211,6 @@ = ; }; - pcie_0_gdsc: pcie_0_gdsc { - compatible = "qcom,stub-regulator"; - regulator-name = "pcie_0_gdsc"; - status = "okay"; - }; - vreg_wlan: vreg_wlan { compatible = "qcom,stub-regulator"; regulator-name = "vreg_wlan"; -- GitLab From 94f79810e484144e95a917b1e91c01369f7c5eee Mon Sep 17 00:00:00 2001 From: Jiacheng Zheng Date: Thu, 25 Jul 2019 15:50:13 +0800 Subject: [PATCH 1043/1121] drivers: of: Add early param memrsv We need to do memory hotplug, the most intuitive way is to change dtsi file. But we cannot do that since dtsi is shared among all projects. So we add one more early param to carve out memory for hotplug through command line. Other projects won't be influenced since they do not have this param in their command line. Change-Id: I790a71cb82ecd30302a7d1ba4d2c07fccd5d6d7c Signed-off-by: Jiacheng Zheng --- drivers/of/fdt.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index acf7dfb00840..4b2536a05fbe 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -603,6 +603,52 @@ void *initial_boot_params; static u32 of_fdt_crc32; +/* + * Reserve memory via command line if needed. + */ +static int __init early_memory_reserve(char *p) +{ + phys_addr_t base, size; + int nomap; + char *endp = p; + + while (1) { + base = memparse(endp, &endp); + if (base && (*endp == ',')) { + size = memparse(endp + 1, &endp); + if (size && (*endp == ',')) { + if (memcmp(endp + 1, "nomap", 5) == 0) { + nomap = 1; + endp += 6; + } else if (memcmp(endp + 1, "map", 3) == 0) { + nomap = 0; + endp += 4; + } else + break; + + if (early_init_dt_reserve_memory_arch(base, + size, nomap) == 0) + pr_debug( + "Early reserved memory: region : base %pa, size %ld MiB\n", + &base, (unsigned long)size / SZ_1M); + else + pr_info( + "Early reserved memory: failed : base %pa, size %ld MiB\n", + &base, (unsigned long)size / SZ_1M); + + if (*endp == ';') + endp++; + else + break; + } else + break; + } else + break; + } + return 0; +} +early_param("memrsv", early_memory_reserve); + /** * res_mem_reserve_reg() - reserve all memory described in 'reg' property */ -- GitLab From 5c9de074d7acfff3ae415d78b7771588bdaf80a9 Mon Sep 17 00:00:00 2001 From: Zhiqiang Tu Date: Tue, 2 Jul 2019 08:28:34 +0800 Subject: [PATCH 1044/1121] ARM: dts: msm: Add virtio regulator for sa8155 vm Add virtio regulator for pass-through devices. Change-Id: Ia8bcd7af5ff0d3701ea4d0978fcff4105c26a6e5 Signed-off-by: Zhiqiang Tu --- arch/arm64/boot/dts/qcom/sa8155-vm-usb.dtsi | 20 +- arch/arm64/boot/dts/qcom/sa8155-vm.dtsi | 196 +++++++++----------- 2 files changed, 100 insertions(+), 116 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sa8155-vm-usb.dtsi b/arch/arm64/boot/dts/qcom/sa8155-vm-usb.dtsi index 5e79647ad0f3..90366d5cb5db 100644 --- a/arch/arm64/boot/dts/qcom/sa8155-vm-usb.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8155-vm-usb.dtsi @@ -118,9 +118,9 @@ reg-names = "hsusb_phy_base", "phy_rcal_reg"; - vdd-supply = <&pm8150_l5>; - vdda18-supply = <&pm8150_l12>; - vdda33-supply = <&pm8150_l2>; + vdd-supply = <&pm8150_1_l5>; + vdda18-supply = <&pm8150_1_l12>; + vdda33-supply = <&pm8150_1_l2>; qcom,vdd-voltage-level = <0 880000 880000>; clocks = <&clock_gcc RPMH_CXO_CLK>; @@ -140,10 +140,10 @@ reg = <0x88e8000 0x3000>; reg-names = "qmp_phy_base"; - vdd-supply = <&pm8150_l5>; + vdd-supply = <&pm8150_1_l5>; qcom,vdd-voltage-level = <0 880000 880000>; qcom,vdd-max-load-uA = <47000>; - core-supply = <&pm8150l_l3>; + core-supply = <&pm8150_2_l8>; qcom,vbus-valid-override; qcom,link-training-reset; qcom,qmp-phy-init-seq = @@ -394,9 +394,9 @@ reg-names = "hsusb_phy_base", "phy_rcal_reg"; - vdd-supply = <&pm8150_l5>; - vdda18-supply = <&pm8150_l12>; - vdda33-supply = <&pm8150_l2>; + vdd-supply = <&pm8150_1_l5>; + vdda18-supply = <&pm8150_1_l12>; + vdda33-supply = <&pm8150_1_l2>; qcom,vdd-voltage-level = <0 880000 880000>; clocks = <&clock_gcc RPMH_CXO_CLK>; @@ -417,10 +417,10 @@ reg-names = "qmp_phy_base", "pcs_clamp_enable_reg"; - vdd-supply = <&pm8150_l5>; + vdd-supply = <&pm8150_1_l5>; qcom,vdd-voltage-level = <0 880000 880000>; qcom,vdd-max-load-uA = <47000>; - core-supply = <&pm8150l_l3>; + core-supply = <&pm8150_2_l8>; qcom,vbus-valid-override; qcom,qmp-phy-init-seq = /* */ diff --git a/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi b/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi index 8ec724d101ac..ff028a04be6f 100644 --- a/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi @@ -45,6 +45,96 @@ #reset-cells = <1>; }; + regulator_virt: virtio_regulator@1c700000 { + compatible = "virtio,mmio"; + reg = <0x1c700000 0x1000>; + interrupts = <0 42 0>; + + usb30_prim_gdsc: usb30_prim_gdsc { + regulator-name = "usb30_prim_gdsc"; + }; + + usb30_sec_gdsc: usb30_sec_gdsc { + regulator-name = "usb30_sec_gdsc"; + }; + + pcie_0_gdsc: pcie_0_gdsc { + regulator-name = "pcie_0_gdsc"; + }; + + pcie_1_gdsc: pcie_1_gdsc { + regulator-name = "pcie_1_gdsc"; + }; + + L2A: pm8150_1_l2: regulator-pm8150-1-l2 { + regulator-name = "ldoa2"; + regulator-min-microvolt = <3072000>; + regulator-max-microvolt = <3072000>; + }; + + L5A: pm8150_1_l5: regulator-pm8150-1-l5 { + regulator-name = "ldoa5"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <880000>; + }; + + L12A: pm8150_1_l12: regulator-pm8150-1-l12 { + regulator-name = "ldoa12"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + L17A: pm8150_1_l17: regulator-pm8150-1-l17 { + regulator-name = "ldoa17"; + regulator-min-microvolt = <2704000>; + regulator-max-microvolt = <2960000>; + }; + + L8C: pm8150_2_l8: regulator-pm8150-2-l8 { + regulator-name = "ldoc8"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-allow-set-load; + }; + + L13C: pm8150_2_l13: regulator-pm8150-2-l13 { + regulator-name = "ldoc13"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2960000>; + }; + + L15C: pm8150_2_l15: regulator-pm8150-2-l15 { + regulator-name = "ldoc15"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1904000>; + }; + + L18C: pm8150_2_l18: regulator-pm8150-2-l18 { + regulator-name = "ldoc18"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <880000>; + regulator-allow-set-load; + }; + + S6A: pm8150_1_s6: regulator-pm8150-1-s6 { + regulator-name = "smpa6"; + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <1352000>; + }; + + S4C: pm8150_2_s4: regulator-pm8150-2-s4 { + regulator-name = "smpc4"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1400000>; + }; + + S5C: pm8150_2_s5: regulator-pm8150-2-s5 { + regulator-name = "smpc5"; + regulator-min-microvolt = <1824000>; + regulator-max-microvolt = <2040000>; + }; + }; + apps_smmu: apps-smmu@0x15000000 { compatible = "qcom,qsmmu-v500"; reg = <0x15000000 0x100000>, @@ -149,38 +239,6 @@ status = "disabled"; }; - S6A: pm8150_1_s6: regulator-pm8150-1-s6 { - compatible = "qcom,stub-regulator"; - regulator-name = "pm8150_1_s6"; - regulator-min-microvolt = <600000>; - regulator-max-microvolt = <1352000>; - qcom,init-voltage = <600000>; - }; - - S4C: pm8150_2_s4: regulator-pm8150-2-s4 { - compatible = "qcom,stub-regulator"; - regulator-name = "pm8150_2_s4"; - regulator-min-microvolt = <800000>; - regulator-max-microvolt = <1400000>; - qcom,init-voltage = <800000>; - }; - - S5C: pm8150_2_s5: regulator-pm8150-2-s5 { - compatible = "qcom,stub-regulator"; - regulator-name = "pm8150_2_s5"; - regulator-min-microvolt = <1824000>; - regulator-max-microvolt = <2040000>; - qcom,init-voltage = <1824000>; - }; - - L15C: pm8150_2_l15: regulator-pm8150-2-l15 { - compatible = "qcom,stub-regulator"; - regulator-name = "pm8150_2_l15"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1904000>; - qcom,init-voltage = <1800000>; - }; - vreg_wlan: vreg_wlan { compatible = "qcom,stub-regulator"; regulator-name = "vreg_wlan"; @@ -208,62 +266,6 @@ gpio = <&tlmm 174 0>; }; - pm8150_l2: regulator-pm8150-l2 { - compatible = "qcom,stub-regulator"; - regulator-name = "pm8150_l2"; - regulator-min-microvolt = <3072000>; - regulator-max-microvolt = <3072000>; - qcom,init-voltage = <3072000>; - status = "okay"; - }; - - pm8150_l5: regulator-pm8150-l5 { - compatible = "qcom,stub-regulator"; - regulator-name = "pm8150_l5"; - regulator-min-microvolt = <880000>; - regulator-max-microvolt = <880000>; - qcom,proxy-consumer-enable; - qcom,proxy-consumer-current = <23800>; - qcom,init-voltage = <880000>; - status = "okay"; - }; - - pm8150_l12: regulator-pm8150-l12 { - compatible = "qcom,stub-regulator"; - regulator-name = "pm8150_l12"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - qcom,init-voltage = <1800000>; - status = "okay"; - }; - - pm8150l_l3: regulator-pm8150l-l3 { - compatible = "qcom,stub-regulator"; - regulator-name = "pm8150l_l3"; - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <1200000>; - qcom,proxy-consumer-enable; - qcom,proxy-consumer-current = <51800>; - qcom,init-voltage = <1200000>; - status = "okay"; - }; - - pm8150_2_l8: regulator-pm8150-2-l8 { - compatible = "qcom,stub-regulator"; - regulator-name = "pm8150_2_l8"; - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <1200000>; - status = "okay"; - }; - - pm8150_2_l18: regulator-pm8150-2-l18 { - compatible = "qcom,stub-regulator"; - regulator-name = "pm8150_2_l18"; - regulator-min-microvolt = <880000>; - regulator-max-microvolt = <880000>; - status = "okay"; - }; - VDD_CX_LEVEL: VDD_MMCX_LEVEL: S9C_LEVEL: pm8150_2_s9_level: regulator-pm8150-2-s9-level { compatible = "qcom,stub-regulator"; @@ -274,24 +276,6 @@ = ; }; - pcie_0_gdsc: pcie_0_gdsc { - compatible = "qcom,stub-regulator"; - regulator-name = "pcie_0_gdsc"; - status = "okay"; - }; - - usb30_prim_gdsc: usb30_prim_gdsc { - compatible = "qcom,stub-regulator"; - regulator-name = "usb30_prim_gdsc"; - status = "okay"; - }; - - usb30_sec_gdsc: usb30_sec_gdsc { - compatible = "qcom,stub-regulator"; - regulator-name = "usb30_sec_gdsc"; - status = "okay"; - }; - qcom_seecom: qseecom@87900000 { compatible = "qcom,qseecom"; reg = <0x87900000 0x2200000>; -- GitLab From 62dc88e12edaa2b82ade23565e0338ff177fcb3d Mon Sep 17 00:00:00 2001 From: Ram Chandrasekar Date: Wed, 8 May 2019 12:02:07 -0600 Subject: [PATCH 1045/1121] driver: thermal: bcl_pmic5: Use mitigation level interrupts BCL peripheral will eventually translate all the vbat and ibat interrupts to mitigation level interrupts. And the interrupts also will correspond to the levels instead of the vbat or ibat events. So use these interrupts in HLOS to trigger mitigation. The vbat and ibat will still be registered as sensors, but they wont support interrupts and hence no mitigation for violation. Instead the levels will be registered as interrupts and the mitigation config should be based on this mitigation level sensor. Update devicetree changes to reflect above mentioned design change for all targets those are using bcl_pmic5 driver. Change-Id: I45d2f63f2390eb4c59c45ca7d8aff758e1f88ce0 Signed-off-by: Ram Chandrasekar Signed-off-by: Manaf Meethalavalappu Pallikunhi --- arch/arm64/boot/dts/qcom/pm6150.dtsi | 62 ++++- arch/arm64/boot/dts/qcom/pm6150l.dtsi | 54 +++- arch/arm64/boot/dts/qcom/pm8150b.dtsi | 68 ++++- arch/arm64/boot/dts/qcom/pm8150l.dtsi | 60 ++++- arch/arm64/boot/dts/qcom/pmi632.dtsi | 68 ++++- arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi | 3 + arch/arm64/boot/dts/qcom/sa6155-pmic.dtsi | 8 +- .../dts/qcom/sdmmagpie-thermal-overlay.dtsi | 31 ++- .../boot/dts/qcom/sm6150-thermal-overlay.dtsi | 31 ++- .../boot/dts/qcom/sm8150-thermal-overlay.dtsi | 84 ++---- .../dts/qcom/trinket-thermal-overlay.dtsi | 208 ++++----------- drivers/thermal/qcom/bcl_pmic5.c | 250 ++++++++---------- 12 files changed, 515 insertions(+), 412 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/pm6150.dtsi b/arch/arm64/boot/dts/qcom/pm6150.dtsi index 087aa21910ce..e198ed897b55 100644 --- a/arch/arm64/boot/dts/qcom/pm6150.dtsi +++ b/arch/arm64/boot/dts/qcom/pm6150.dtsi @@ -449,15 +449,11 @@ compatible = "qcom,bcl-v5"; reg = <0x1d00 0x100>; interrupts = <0x0 0x1d 0x0 IRQ_TYPE_NONE>, - <0x0 0x1d 0x1 IRQ_TYPE_NONE>, - <0x0 0x1d 0x0 IRQ_TYPE_NONE>, <0x0 0x1d 0x1 IRQ_TYPE_NONE>, <0x0 0x1d 0x2 IRQ_TYPE_NONE>; - interrupt-names = "bcl-ibat-lvl0", - "bcl-ibat-lvl1", - "bcl-vbat-lvl0", - "bcl-vbat-lvl1", - "bcl-vbat-lvl2"; + interrupt-names = "bcl-lvl0", + "bcl-lvl1", + "bcl-lvl2"; #thermal-sensor-cells = <1>; }; @@ -564,7 +560,7 @@ }; pm6150-ibat-lvl0 { - polling-delay-passive = <100>; + polling-delay-passive = <0>; polling-delay = <0>; thermal-governor = "step_wise"; thermal-sensors = <&pm6150_bcl 0>; @@ -596,7 +592,7 @@ }; pm6150-vbat-lvl0 { - polling-delay-passive = <100>; + polling-delay-passive = <0>; polling-delay = <0>; thermal-governor = "low_limits_cap"; thermal-sensors = <&pm6150_bcl 2>; @@ -646,6 +642,54 @@ }; }; + pm6150-bcl-lvl0 { + polling-delay-passive = <100>; + polling-delay = <0>; + thermal-governor = "step_wise"; + thermal-sensors = <&pm6150_bcl 5>; + wake-capable-sensor; + + trips { + bcl_lvl0: bcl-lvl0 { + temperature = <1>; + hysteresis = <1>; + type = "passive"; + }; + }; + }; + + pm6150-bcl-lvl1 { + polling-delay-passive = <100>; + polling-delay = <0>; + thermal-governor = "step_wise"; + thermal-sensors = <&pm6150_bcl 6>; + wake-capable-sensor; + + trips { + bcl_lvl1: bcl-lvl1 { + temperature = <1>; + hysteresis = <1>; + type = "passive"; + }; + }; + }; + + pm6150-bcl-lvl2 { + polling-delay-passive = <100>; + polling-delay = <0>; + thermal-governor = "step_wise"; + thermal-sensors = <&pm6150_bcl 7>; + wake-capable-sensor; + + trips { + bcl_lvl2: bcl-lvl2 { + temperature = <1>; + hysteresis = <1>; + type = "passive"; + }; + }; + }; + soc { polling-delay-passive = <100>; polling-delay = <0>; diff --git a/arch/arm64/boot/dts/qcom/pm6150l.dtsi b/arch/arm64/boot/dts/qcom/pm6150l.dtsi index 64672673a4f9..17f0a5dfb704 100644 --- a/arch/arm64/boot/dts/qcom/pm6150l.dtsi +++ b/arch/arm64/boot/dts/qcom/pm6150l.dtsi @@ -46,9 +46,9 @@ interrupts = <0x4 0x3d 0x0 IRQ_TYPE_NONE>, <0x4 0x3d 0x1 IRQ_TYPE_NONE>, <0x4 0x3d 0x2 IRQ_TYPE_NONE>; - interrupt-names = "bcl-vbat-lvl0", - "bcl-vbat-lvl1", - "bcl-vbat-lvl2"; + interrupt-names = "bcl-lvl0", + "bcl-lvl1", + "bcl-lvl2"; #thermal-sensor-cells = <1>; }; @@ -511,4 +511,52 @@ }; }; }; + + pm6150l-bcl-lvl0 { + polling-delay-passive = <100>; + polling-delay = <0>; + thermal-governor = "step_wise"; + thermal-sensors = <&pm6150l_bcl 5>; + wake-capable-sensor; + + trips { + l_bcl_lvl0: l-bcl-lvl0 { + temperature = <1>; + hysteresis = <1>; + type = "passive"; + }; + }; + }; + + pm6150l-bcl-lvl1 { + polling-delay-passive = <100>; + polling-delay = <0>; + thermal-governor = "step_wise"; + thermal-sensors = <&pm6150l_bcl 6>; + wake-capable-sensor; + + trips { + l_bcl_lvl1: l-bcl-lvl1 { + temperature = <1>; + hysteresis = <1>; + type = "passive"; + }; + }; + }; + + pm6150l-bcl-lvl2 { + polling-delay-passive = <100>; + polling-delay = <0>; + thermal-governor = "step_wise"; + thermal-sensors = <&pm6150l_bcl 7>; + wake-capable-sensor; + + trips { + l_bcl_lvl2: l-bcl-lvl2 { + temperature = <1>; + hysteresis = <1>; + type = "passive"; + }; + }; + }; }; diff --git a/arch/arm64/boot/dts/qcom/pm8150b.dtsi b/arch/arm64/boot/dts/qcom/pm8150b.dtsi index 2c1cea2daef5..e1ff572b262d 100644 --- a/arch/arm64/boot/dts/qcom/pm8150b.dtsi +++ b/arch/arm64/boot/dts/qcom/pm8150b.dtsi @@ -365,15 +365,11 @@ compatible = "qcom,bcl-v5"; reg = <0x1d00 0x100>; interrupts = <0x2 0x1d 0x0 IRQ_TYPE_NONE>, - <0x2 0x1d 0x1 IRQ_TYPE_NONE>, - <0x2 0x1d 0x0 IRQ_TYPE_NONE>, <0x2 0x1d 0x1 IRQ_TYPE_NONE>, <0x2 0x1d 0x2 IRQ_TYPE_NONE>; - interrupt-names = "bcl-ibat-lvl0", - "bcl-ibat-lvl1", - "bcl-vbat-lvl0", - "bcl-vbat-lvl1", - "bcl-vbat-lvl2"; + interrupt-names = "bcl-lvl0", + "bcl-lvl1", + "bcl-lvl2"; #thermal-sensor-cells = <1>; }; @@ -603,7 +599,7 @@ }; pm8150b-ibat-lvl0 { - polling-delay-passive = <100>; + polling-delay-passive = <0>; polling-delay = <0>; thermal-governor = "step_wise"; thermal-sensors = <&pm8150b_bcl 0>; @@ -619,7 +615,7 @@ }; pm8150b-ibat-lvl1 { - polling-delay-passive = <100>; + polling-delay-passive = <0>; polling-delay = <0>; thermal-governor = "step_wise"; thermal-sensors = <&pm8150b_bcl 1>; @@ -635,7 +631,7 @@ }; pm8150b-vbat-lvl0 { - polling-delay-passive = <100>; + polling-delay-passive = <0>; polling-delay = <0>; thermal-governor = "low_limits_cap"; thermal-sensors = <&pm8150b_bcl 2>; @@ -652,7 +648,7 @@ }; pm8150b-vbat-lvl1 { - polling-delay-passive = <100>; + polling-delay-passive = <0>; polling-delay = <0>; thermal-governor = "low_limits_cap"; thermal-sensors = <&pm8150b_bcl 3>; @@ -669,7 +665,7 @@ }; pm8150b-vbat-lvl2 { - polling-delay-passive = <100>; + polling-delay-passive = <0>; polling-delay = <0>; thermal-governor = "low_limits_cap"; thermal-sensors = <&pm8150b_bcl 4>; @@ -685,6 +681,54 @@ }; }; + pm8150b-bcl-lvl0 { + polling-delay-passive = <100>; + polling-delay = <0>; + thermal-governor = "step_wise"; + thermal-sensors = <&pm8150b_bcl 5>; + wake-capable-sensor; + + trips { + b_bcl_lvl0: b-bcl-lvl0 { + temperature = <1>; + hysteresis = <1>; + type = "passive"; + }; + }; + }; + + pm8150b-bcl-lvl1 { + polling-delay-passive = <100>; + polling-delay = <0>; + thermal-governor = "step_wise"; + thermal-sensors = <&pm8150b_bcl 6>; + wake-capable-sensor; + + trips { + b_bcl_lvl1: b-bcl-lvl1 { + temperature = <1>; + hysteresis = <1>; + type = "passive"; + }; + }; + }; + + pm8150b-bcl-lvl2 { + polling-delay-passive = <100>; + polling-delay = <0>; + thermal-governor = "step_wise"; + thermal-sensors = <&pm8150b_bcl 7>; + wake-capable-sensor; + + trips { + b_bcl_lvl2: b-bcl-lvl2 { + temperature = <1>; + hysteresis = <1>; + type = "passive"; + }; + }; + }; + soc { polling-delay-passive = <100>; polling-delay = <0>; diff --git a/arch/arm64/boot/dts/qcom/pm8150l.dtsi b/arch/arm64/boot/dts/qcom/pm8150l.dtsi index 96e20a8df850..3586af695f4f 100644 --- a/arch/arm64/boot/dts/qcom/pm8150l.dtsi +++ b/arch/arm64/boot/dts/qcom/pm8150l.dtsi @@ -117,9 +117,9 @@ interrupts = <0x4 0x3d 0x0 IRQ_TYPE_NONE>, <0x4 0x3d 0x1 IRQ_TYPE_NONE>, <0x4 0x3d 0x2 IRQ_TYPE_NONE>; - interrupt-names = "bcl-vbat-lvl0", - "bcl-vbat-lvl1", - "bcl-vbat-lvl2"; + interrupt-names = "bcl-lvl0", + "bcl-lvl1", + "bcl-lvl2"; #thermal-sensor-cells = <1>; }; @@ -464,7 +464,7 @@ }; pm8150l-vph-lvl0 { - polling-delay-passive = <100>; + polling-delay-passive = <0>; polling-delay = <0>; thermal-governor = "low_limits_cap"; thermal-sensors = <&pm8150l_bcl 2>; @@ -481,7 +481,7 @@ }; pm8150l-vph-lvl1 { - polling-delay-passive = <100>; + polling-delay-passive = <0>; polling-delay = <0>; thermal-governor = "low_limits_cap"; thermal-sensors = <&pm8150l_bcl 3>; @@ -498,7 +498,7 @@ }; pm8150l-vph-lvl2 { - polling-delay-passive = <100>; + polling-delay-passive = <0>; polling-delay = <0>; thermal-governor = "low_limits_cap"; thermal-sensors = <&pm8150l_bcl 4>; @@ -513,4 +513,52 @@ }; }; }; + + pm8150l-bcl-lvl0 { + polling-delay-passive = <100>; + polling-delay = <0>; + thermal-governor = "step_wise"; + thermal-sensors = <&pm8150l_bcl 5>; + wake-capable-sensor; + + trips { + l_bcl_lvl0: l-bcl-lvl0 { + temperature = <1>; + hysteresis = <1>; + type = "passive"; + }; + }; + }; + + pm8150l-bcl-lvl1 { + polling-delay-passive = <100>; + polling-delay = <0>; + thermal-governor = "step_wise"; + thermal-sensors = <&pm8150l_bcl 6>; + wake-capable-sensor; + + trips { + l_bcl_lvl1: l-bcl-lvl1 { + temperature = <1>; + hysteresis = <1>; + type = "passive"; + }; + }; + }; + + pm8150l-bcl-lvl2 { + polling-delay-passive = <100>; + polling-delay = <0>; + thermal-governor = "step_wise"; + thermal-sensors = <&pm8150l_bcl 7>; + wake-capable-sensor; + + trips { + l_bcl_lvl2: l-bcl-lvl2 { + temperature = <1>; + hysteresis = <1>; + type = "passive"; + }; + }; + }; }; diff --git a/arch/arm64/boot/dts/qcom/pmi632.dtsi b/arch/arm64/boot/dts/qcom/pmi632.dtsi index f97fe75e7fe0..41ddd00c89e1 100644 --- a/arch/arm64/boot/dts/qcom/pmi632.dtsi +++ b/arch/arm64/boot/dts/qcom/pmi632.dtsi @@ -394,15 +394,11 @@ compatible = "qcom,bcl-v5"; reg = <0x3d00 0x100>; interrupts = <0x2 0x3d 0x0 IRQ_TYPE_NONE>, - <0x2 0x3d 0x1 IRQ_TYPE_NONE>, - <0x2 0x3d 0x0 IRQ_TYPE_NONE>, <0x2 0x3d 0x1 IRQ_TYPE_NONE>, <0x2 0x3d 0x2 IRQ_TYPE_NONE>; - interrupt-names = "bcl-ibat-lvl0", - "bcl-ibat-lvl1", - "bcl-vbat-lvl0", - "bcl-vbat-lvl1", - "bcl-vbat-lvl2"; + interrupt-names = "bcl-lvl0", + "bcl-lvl1", + "bcl-lvl2"; qcom,ibat-use-qg-adc-5a; #thermal-sensor-cells = <1>; }; @@ -636,7 +632,7 @@ }; pmi632-ibat-lvl0 { - polling-delay-passive = <100>; + polling-delay-passive = <0>; polling-delay = <0>; thermal-governor = "step_wise"; thermal-sensors = <&bcl_sensor 0>; @@ -652,7 +648,7 @@ }; pmi632-ibat-lvl1 { - polling-delay-passive = <100>; + polling-delay-passive = <0>; polling-delay = <0>; thermal-governor = "step_wise"; thermal-sensors = <&bcl_sensor 1>; @@ -668,7 +664,7 @@ }; pmi632-vbat-lvl0 { - polling-delay-passive = <100>; + polling-delay-passive = <0>; polling-delay = <0>; thermal-governor = "low_limits_cap"; thermal-sensors = <&bcl_sensor 2>; @@ -685,7 +681,7 @@ }; pmi632-vbat-lvl1 { - polling-delay-passive = <100>; + polling-delay-passive = <0>; polling-delay = <0>; thermal-governor = "low_limits_cap"; thermal-sensors = <&bcl_sensor 3>; @@ -702,7 +698,7 @@ }; pmi632-vbat-lvl2 { - polling-delay-passive = <100>; + polling-delay-passive = <0>; polling-delay = <0>; thermal-governor = "low_limits_cap"; thermal-sensors = <&bcl_sensor 4>; @@ -718,6 +714,54 @@ }; }; + pmi632-bcl-lvl0 { + polling-delay-passive = <100>; + polling-delay = <0>; + thermal-governor = "step_wise"; + thermal-sensors = <&bcl_sensor 5>; + wake-capable-sensor; + + trips { + bcl_lvl0: bcl-lvl0 { + temperature = <1>; + hysteresis = <1>; + type = "passive"; + }; + }; + }; + + pmi632-bcl-lvl1 { + polling-delay-passive = <100>; + polling-delay = <0>; + thermal-governor = "step_wise"; + thermal-sensors = <&bcl_sensor 6>; + wake-capable-sensor; + + trips { + bcl_lvl1: bcl-lvl1 { + temperature = <1>; + hysteresis = <1>; + type = "passive"; + }; + }; + }; + + pmi632-bcl-lvl2 { + polling-delay-passive = <100>; + polling-delay = <0>; + thermal-governor = "step_wise"; + thermal-sensors = <&bcl_sensor 7>; + wake-capable-sensor; + + trips { + bcl_lvl2: bcl-lvl2 { + temperature = <1>; + hysteresis = <1>; + type = "passive"; + }; + }; + }; + soc { polling-delay-passive = <100>; polling-delay = <0>; diff --git a/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi b/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi index 0c561f420fa1..e28e211fd5cf 100644 --- a/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi +++ b/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi @@ -79,6 +79,9 @@ /delete-node/ pm8150b-vbat-lvl0; /delete-node/ pm8150b-vbat-lvl1; /delete-node/ pm8150b-vbat-lvl2; + /delete-node/ pm8150b-bcl-lvl0; + /delete-node/ pm8150b-bcl-lvl1; + /delete-node/ pm8150b-bcl-lvl2; /delete-node/ soc; }; diff --git a/arch/arm64/boot/dts/qcom/sa6155-pmic.dtsi b/arch/arm64/boot/dts/qcom/sa6155-pmic.dtsi index 3e00782bcd68..737ab8022869 100644 --- a/arch/arm64/boot/dts/qcom/sa6155-pmic.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155-pmic.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -137,9 +137,15 @@ /delete-node/ pm6150-vbat-lvl0; /delete-node/ pm6150-vbat-lvl1; /delete-node/ pm6150-vbat-lvl2; + /delete-node/ pm6150-bcl-lvl0; + /delete-node/ pm6150-bcl-lvl1; + /delete-node/ pm6150-bcl-lvl2; /delete-node/ pm6150l-vph-lvl0; /delete-node/ pm6150l-vph-lvl1; /delete-node/ pm6150l-vph-lvl2; + /delete-node/ pm6150l-bcl-lvl0; + /delete-node/ pm6150l-bcl-lvl1; + /delete-node/ pm6150l-bcl-lvl2; /delete-node/ xo-therm; /delete-node/ sdm-therm; /delete-node/ conn-therm; diff --git a/arch/arm64/boot/dts/qcom/sdmmagpie-thermal-overlay.dtsi b/arch/arm64/boot/dts/qcom/sdmmagpie-thermal-overlay.dtsi index f47d16937319..37c22bca3baf 100644 --- a/arch/arm64/boot/dts/qcom/sdmmagpie-thermal-overlay.dtsi +++ b/arch/arm64/boot/dts/qcom/sdmmagpie-thermal-overlay.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -125,16 +125,16 @@ }; }; - pm6150-vbat-lvl0 { + pm6150-bcl-lvl0 { cooling-maps { vbat_cpu6 { - trip = <&vbat_lvl0>; + trip = <&bcl_lvl0>; cooling-device = <&CPU6 THERMAL_MAX_LIMIT THERMAL_MAX_LIMIT>; }; vbat_cpu7 { - trip = <&vbat_lvl0>; + trip = <&bcl_lvl0>; cooling-device = <&CPU7 THERMAL_MAX_LIMIT THERMAL_MAX_LIMIT>; @@ -142,16 +142,33 @@ }; }; - pm6150-ibat-lvl0 { + pm6150-bcl-lvl1 { cooling-maps { ibat_cpu6 { - trip = <&ibat_lvl0>; + trip = <&bcl_lvl1>; cooling-device = <&CPU6 THERMAL_MAX_LIMIT THERMAL_MAX_LIMIT>; }; ibat_cpu7 { - trip = <&ibat_lvl0>; + trip = <&bcl_lvl1>; + cooling-device = + <&CPU7 THERMAL_MAX_LIMIT + THERMAL_MAX_LIMIT>; + }; + }; + }; + + pm6150-bcl-lvl2 { + cooling-maps { + ibat_cpu6 { + trip = <&bcl_lvl2>; + cooling-device = + <&CPU6 THERMAL_MAX_LIMIT + THERMAL_MAX_LIMIT>; + }; + ibat_cpu7 { + trip = <&bcl_lvl2>; cooling-device = <&CPU7 THERMAL_MAX_LIMIT THERMAL_MAX_LIMIT>; diff --git a/arch/arm64/boot/dts/qcom/sm6150-thermal-overlay.dtsi b/arch/arm64/boot/dts/qcom/sm6150-thermal-overlay.dtsi index f47d16937319..37c22bca3baf 100644 --- a/arch/arm64/boot/dts/qcom/sm6150-thermal-overlay.dtsi +++ b/arch/arm64/boot/dts/qcom/sm6150-thermal-overlay.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -125,16 +125,16 @@ }; }; - pm6150-vbat-lvl0 { + pm6150-bcl-lvl0 { cooling-maps { vbat_cpu6 { - trip = <&vbat_lvl0>; + trip = <&bcl_lvl0>; cooling-device = <&CPU6 THERMAL_MAX_LIMIT THERMAL_MAX_LIMIT>; }; vbat_cpu7 { - trip = <&vbat_lvl0>; + trip = <&bcl_lvl0>; cooling-device = <&CPU7 THERMAL_MAX_LIMIT THERMAL_MAX_LIMIT>; @@ -142,16 +142,33 @@ }; }; - pm6150-ibat-lvl0 { + pm6150-bcl-lvl1 { cooling-maps { ibat_cpu6 { - trip = <&ibat_lvl0>; + trip = <&bcl_lvl1>; cooling-device = <&CPU6 THERMAL_MAX_LIMIT THERMAL_MAX_LIMIT>; }; ibat_cpu7 { - trip = <&ibat_lvl0>; + trip = <&bcl_lvl1>; + cooling-device = + <&CPU7 THERMAL_MAX_LIMIT + THERMAL_MAX_LIMIT>; + }; + }; + }; + + pm6150-bcl-lvl2 { + cooling-maps { + ibat_cpu6 { + trip = <&bcl_lvl2>; + cooling-device = + <&CPU6 THERMAL_MAX_LIMIT + THERMAL_MAX_LIMIT>; + }; + ibat_cpu7 { + trip = <&bcl_lvl2>; cooling-device = <&CPU7 THERMAL_MAX_LIMIT THERMAL_MAX_LIMIT>; diff --git a/arch/arm64/boot/dts/qcom/sm8150-thermal-overlay.dtsi b/arch/arm64/boot/dts/qcom/sm8150-thermal-overlay.dtsi index 9c8b8ea200f7..643bb84e3669 100644 --- a/arch/arm64/boot/dts/qcom/sm8150-thermal-overlay.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150-thermal-overlay.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -154,149 +154,107 @@ }; }; - pm8150b-vbat-lvl0 { + pm8150b-bcl-lvl0 { cooling-maps { vbat_cpu4 { - trip = <&vbat_lvl0>; + trip = <&b_bcl_lvl0>; cooling-device = <&CPU4 THERMAL_MAX_LIMIT THERMAL_MAX_LIMIT>; }; vbat_cpu5 { - trip = <&vbat_lvl0>; + trip = <&b_bcl_lvl0>; cooling-device = <&CPU5 THERMAL_MAX_LIMIT THERMAL_MAX_LIMIT>; }; vbat_gpu0 { - trip = <&vbat_lvl0>; + trip = <&b_bcl_lvl0>; cooling-device = <&msm_gpu 2 2>; }; }; }; - pm8150b-vbat-lvl1 { + pm8150b-bcl-lvl1 { cooling-maps { vbat_cpu6 { - trip = <&vbat_lvl1>; + trip = <&b_bcl_lvl1>; cooling-device = <&CPU6 THERMAL_MAX_LIMIT THERMAL_MAX_LIMIT>; }; vbat_cpu7 { - trip = <&vbat_lvl1>; + trip = <&b_bcl_lvl1>; cooling-device = <&CPU7 THERMAL_MAX_LIMIT THERMAL_MAX_LIMIT>; }; vbat_gpu1 { - trip = <&vbat_lvl1>; + trip = <&b_bcl_lvl1>; cooling-device = <&msm_gpu 4 4>; }; }; }; - pm8150b-vbat-lvl2 { + pm8150b-bcl-lvl2 { cooling-maps { vbat_gpu2 { - trip = <&vbat_lvl2>; + trip = <&b_bcl_lvl2>; cooling-device = <&msm_gpu THERMAL_MAX_LIMIT THERMAL_MAX_LIMIT>; }; }; }; - pm8150b-ibat-lvl0 { - cooling-maps { - ibat_cpu4 { - trip = <&ibat_lvl0>; - cooling-device = - <&CPU4 THERMAL_MAX_LIMIT - THERMAL_MAX_LIMIT>; - }; - ibat_cpu5 { - trip = <&ibat_lvl0>; - cooling-device = - <&CPU5 THERMAL_MAX_LIMIT - THERMAL_MAX_LIMIT>; - }; - ibat_gpu0 { - trip = <&ibat_lvl0>; - cooling-device = <&msm_gpu 2 2>; - }; - }; - }; - - pm8150b-ibat-lvl1 { - cooling-maps { - ibat_cpu6 { - trip = <&ibat_lvl1>; - cooling-device = - <&CPU6 THERMAL_MAX_LIMIT - THERMAL_MAX_LIMIT>; - }; - ibat_cpu7 { - trip = <&ibat_lvl1>; - cooling-device = - <&CPU7 THERMAL_MAX_LIMIT - THERMAL_MAX_LIMIT>; - }; - ibat_gpu1 { - trip = <&ibat_lvl1>; - cooling-device = <&msm_gpu 4 4>; - }; - }; - }; - - pm8150l-vph-lvl0 { + pm8150l-bcl-lvl0 { disable-thermal-zone; cooling-maps { vph_cpu4 { - trip = <&vph_lvl0>; + trip = <&l_bcl_lvl0>; cooling-device = <&CPU4 THERMAL_MAX_LIMIT THERMAL_MAX_LIMIT>; }; vph_cpu5 { - trip = <&vph_lvl0>; + trip = <&l_bcl_lvl0>; cooling-device = <&CPU5 THERMAL_MAX_LIMIT THERMAL_MAX_LIMIT>; }; vph_gpu0 { - trip = <&vph_lvl0>; + trip = <&l_bcl_lvl0>; cooling-device = <&msm_gpu 2 2>; }; }; }; - pm8150l-vph-lvl1 { + pm8150l-bcl-lvl1 { disable-thermal-zone; cooling-maps { vph_cpu6 { - trip = <&vph_lvl1>; + trip = <&l_bcl_lvl1>; cooling-device = <&CPU6 THERMAL_MAX_LIMIT THERMAL_MAX_LIMIT>; }; vph_cpu7 { - trip = <&vph_lvl1>; + trip = <&l_bcl_lvl1>; cooling-device = <&CPU7 THERMAL_MAX_LIMIT THERMAL_MAX_LIMIT>; }; vph_gpu1 { - trip = <&vph_lvl1>; + trip = <&l_bcl_lvl1>; cooling-device = <&msm_gpu 4 4>; }; }; }; - pm8150l-vph-lvl2 { + pm8150l-bcl-lvl2 { disable-thermal-zone; cooling-maps { vph_gpu2 { - trip = <&vph_lvl2>; + trip = <&l_bcl_lvl2>; cooling-device = <&msm_gpu THERMAL_MAX_LIMIT THERMAL_MAX_LIMIT>; }; diff --git a/arch/arm64/boot/dts/qcom/trinket-thermal-overlay.dtsi b/arch/arm64/boot/dts/qcom/trinket-thermal-overlay.dtsi index cc055b4a542d..1c3a5fe6a950 100644 --- a/arch/arm64/boot/dts/qcom/trinket-thermal-overlay.dtsi +++ b/arch/arm64/boot/dts/qcom/trinket-thermal-overlay.dtsi @@ -125,52 +125,52 @@ }; }; - pmi632-vbat-lvl0 { + pmi632-bcl-lvl0 { cooling-maps { - vbat_cpu0 { - trip = <&pmi632_vbat_lvl0>; + cpu0_cdev { + trip = <&bcl_lvl0>; cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-6) (THERMAL_MAX_LIMIT-6)>; }; - vbat_cpu1 { - trip = <&pmi632_vbat_lvl0>; + cpu1_cdev { + trip = <&bcl_lvl0>; cooling-device = <&CPU1 (THERMAL_MAX_LIMIT-6) (THERMAL_MAX_LIMIT-6)>; }; - vbat_cpu2 { - trip = <&pmi632_vbat_lvl0>; + cpu2_cdev { + trip = <&bcl_lvl0>; cooling-device = <&CPU2 (THERMAL_MAX_LIMIT-6) (THERMAL_MAX_LIMIT-6)>; }; - vbat_cpu3 { - trip = <&pmi632_vbat_lvl0>; + cpu3_cdev { + trip = <&bcl_lvl0>; cooling-device = <&CPU3 (THERMAL_MAX_LIMIT-6) (THERMAL_MAX_LIMIT-6)>; }; - vbat_cpu4 { - trip = <&pmi632_vbat_lvl0>; + cpu4_cdev { + trip = <&bcl_lvl0>; cooling-device = <&CPU4 (THERMAL_MAX_LIMIT-6) (THERMAL_MAX_LIMIT-6)>; }; - vbat_cpu5 { - trip = <&pmi632_vbat_lvl0>; + cpu5_cdev { + trip = <&bcl_lvl0>; cooling-device = <&CPU5 (THERMAL_MAX_LIMIT-6) (THERMAL_MAX_LIMIT-6)>; }; - vbat_cpu6 { - trip = <&pmi632_vbat_lvl0>; + cpu6_cdev { + trip = <&bcl_lvl0>; cooling-device = <&CPU6 (THERMAL_MAX_LIMIT-6) (THERMAL_MAX_LIMIT-6)>; }; - vbat_cpu7 { - trip = <&pmi632_vbat_lvl0>; + cpu7_cdev { + trip = <&bcl_lvl0>; cooling-device = <&CPU7 (THERMAL_MAX_LIMIT-6) (THERMAL_MAX_LIMIT-6)>; @@ -178,52 +178,52 @@ }; }; - pmi632-vbat-lvl1 { + pmi632-bcl-lvl1 { cooling-maps { - vbat_cpu0 { - trip = <&pmi632_vbat_lvl1>; + cpu0_cdev { + trip = <&bcl_lvl1>; cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-5) (THERMAL_MAX_LIMIT-5)>; }; - vbat_cpu1 { - trip = <&pmi632_vbat_lvl1>; + cpu1_cdev { + trip = <&bcl_lvl1>; cooling-device = <&CPU1 (THERMAL_MAX_LIMIT-5) (THERMAL_MAX_LIMIT-5)>; }; - vbat_cpu2 { - trip = <&pmi632_vbat_lvl1>; + cpu2_cdev { + trip = <&bcl_lvl1>; cooling-device = <&CPU2 (THERMAL_MAX_LIMIT-5) (THERMAL_MAX_LIMIT-5)>; }; - vbat_cpu3 { - trip = <&pmi632_vbat_lvl1>; + cpu3_cdev { + trip = <&bcl_lvl1>; cooling-device = <&CPU3 (THERMAL_MAX_LIMIT-5) (THERMAL_MAX_LIMIT-5)>; }; - vbat_cpu4 { - trip = <&pmi632_vbat_lvl1>; + cpu4_cdev { + trip = <&bcl_lvl1>; cooling-device = <&CPU4 (THERMAL_MAX_LIMIT-5) (THERMAL_MAX_LIMIT-5)>; }; - vbat_cpu5 { - trip = <&pmi632_vbat_lvl1>; + cpu5_cdev { + trip = <&bcl_lvl1>; cooling-device = <&CPU5 (THERMAL_MAX_LIMIT-5) (THERMAL_MAX_LIMIT-5)>; }; - vbat_cpu6 { - trip = <&pmi632_vbat_lvl1>; + cpu6_cdev { + trip = <&bcl_lvl1>; cooling-device = <&CPU6 THERMAL_MAX_LIMIT THERMAL_MAX_LIMIT>; }; - vbat_cpu7 { - trip = <&pmi632_vbat_lvl1>; + cpu7_cdev { + trip = <&bcl_lvl1>; cooling-device = <&CPU7 THERMAL_MAX_LIMIT THERMAL_MAX_LIMIT>; @@ -231,158 +231,52 @@ }; }; - pmi632-vbat-lvl2 { + pmi632-bcl-lvl2 { cooling-maps { - vbat_cpu0 { - trip = <&pmi632_vbat_lvl2>; + cpu0_cdev { + trip = <&bcl_lvl2>; cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-5) (THERMAL_MAX_LIMIT-5)>; }; - vbat_cpu1 { - trip = <&pmi632_vbat_lvl2>; + cpu1_cdev { + trip = <&bcl_lvl2>; cooling-device = <&CPU1 (THERMAL_MAX_LIMIT-5) (THERMAL_MAX_LIMIT-5)>; }; - vbat_cpu2 { - trip = <&pmi632_vbat_lvl2>; + cpu2_cdev { + trip = <&bcl_lvl2>; cooling-device = <&CPU2 (THERMAL_MAX_LIMIT-5) (THERMAL_MAX_LIMIT-5)>; }; - vbat_cpu3 { - trip = <&pmi632_vbat_lvl2>; + cpu3_cdev { + trip = <&bcl_lvl2>; cooling-device = <&CPU3 (THERMAL_MAX_LIMIT-5) (THERMAL_MAX_LIMIT-5)>; }; - vbat_cpu4 { - trip = <&pmi632_vbat_lvl2>; + cpu4_cdev { + trip = <&bcl_lvl2>; cooling-device = <&CPU4 THERMAL_MAX_LIMIT THERMAL_MAX_LIMIT>; }; - vbat_cpu5 { - trip = <&pmi632_vbat_lvl2>; + cpu5_cdev { + trip = <&bcl_lvl2>; cooling-device = <&CPU5 THERMAL_MAX_LIMIT THERMAL_MAX_LIMIT>; }; - vbat_cpu6 { - trip = <&pmi632_vbat_lvl2>; + cpu6_cdev { + trip = <&bcl_lvl2>; cooling-device = <&CPU6 THERMAL_MAX_LIMIT THERMAL_MAX_LIMIT>; }; - vbat_cpu7 { - trip = <&pmi632_vbat_lvl2>; - cooling-device = - <&CPU7 THERMAL_MAX_LIMIT - THERMAL_MAX_LIMIT>; - }; - }; - }; - - pmi632-ibat-lvl0 { - cooling-maps { - ibat_cpu0 { - trip = <&pmi632_ibat_lvl0>; - cooling-device = - <&CPU0 (THERMAL_MAX_LIMIT-6) - (THERMAL_MAX_LIMIT-6)>; - }; - ibat_cpu1 { - trip = <&pmi632_ibat_lvl0>; - cooling-device = - <&CPU1 (THERMAL_MAX_LIMIT-6) - (THERMAL_MAX_LIMIT-6)>; - }; - ibat_cpu2 { - trip = <&pmi632_ibat_lvl0>; - cooling-device = - <&CPU2 (THERMAL_MAX_LIMIT-6) - (THERMAL_MAX_LIMIT-6)>; - }; - ibat_cpu3 { - trip = <&pmi632_ibat_lvl0>; - cooling-device = - <&CPU3 (THERMAL_MAX_LIMIT-6) - (THERMAL_MAX_LIMIT-6)>; - }; - ibat_cpu4 { - trip = <&pmi632_ibat_lvl0>; - cooling-device = - <&CPU4 (THERMAL_MAX_LIMIT-6) - (THERMAL_MAX_LIMIT-6)>; - }; - ibat_cpu5 { - trip = <&pmi632_ibat_lvl0>; - cooling-device = - <&CPU5 (THERMAL_MAX_LIMIT-6) - (THERMAL_MAX_LIMIT-6)>; - }; - ibat_cpu6 { - trip = <&pmi632_ibat_lvl0>; - cooling-device = - <&CPU6 (THERMAL_MAX_LIMIT-6) - (THERMAL_MAX_LIMIT-6)>; - }; - ibat_cpu7 { - trip = <&pmi632_ibat_lvl0>; - cooling-device = - <&CPU7 (THERMAL_MAX_LIMIT-6) - (THERMAL_MAX_LIMIT-6)>; - }; - }; - }; - - pmi632-ibat-lvl1 { - cooling-maps { - ibat_cpu0 { - trip = <&pmi632_ibat_lvl1>; - cooling-device = - <&CPU0 (THERMAL_MAX_LIMIT-5) - (THERMAL_MAX_LIMIT-5)>; - }; - ibat_cpu1 { - trip = <&pmi632_ibat_lvl1>; - cooling-device = - <&CPU1 (THERMAL_MAX_LIMIT-5) - (THERMAL_MAX_LIMIT-5)>; - }; - ibat_cpu2 { - trip = <&pmi632_ibat_lvl1>; - cooling-device = - <&CPU2 (THERMAL_MAX_LIMIT-5) - (THERMAL_MAX_LIMIT-5)>; - }; - ibat_cpu3 { - trip = <&pmi632_ibat_lvl1>; - cooling-device = - <&CPU3 (THERMAL_MAX_LIMIT-5) - (THERMAL_MAX_LIMIT-5)>; - }; - ibat_cpu4 { - trip = <&pmi632_ibat_lvl1>; - cooling-device = - <&CPU4 (THERMAL_MAX_LIMIT-5) - (THERMAL_MAX_LIMIT-5)>; - }; - ibat_cpu5 { - trip = <&pmi632_ibat_lvl1>; - cooling-device = - <&CPU5 (THERMAL_MAX_LIMIT-5) - (THERMAL_MAX_LIMIT-5)>; - }; - ibat_cpu6 { - trip = <&pmi632_ibat_lvl1>; - cooling-device = - <&CPU6 THERMAL_MAX_LIMIT - THERMAL_MAX_LIMIT>; - }; - ibat_cpu7 { - trip = <&pmi632_ibat_lvl1>; + cpu7_cdev { + trip = <&bcl_lvl2>; cooling-device = <&CPU7 THERMAL_MAX_LIMIT THERMAL_MAX_LIMIT>; diff --git a/drivers/thermal/qcom/bcl_pmic5.c b/drivers/thermal/qcom/bcl_pmic5.c index a8118cc74839..8ba988cd35b3 100644 --- a/drivers/thermal/qcom/bcl_pmic5.c +++ b/drivers/thermal/qcom/bcl_pmic5.c @@ -31,7 +31,7 @@ #define BCL_DRIVER_NAME "bcl_pmic5" #define BCL_MONITOR_EN 0x46 -#define BCL_IRQ_STATUS 0x09 +#define BCL_IRQ_STATUS 0x08 #define BCL_IBAT_HIGH 0x4B #define BCL_IBAT_TOO_HIGH 0x4C @@ -43,12 +43,9 @@ #define BCL_VBAT_COMP_LOW 0x49 #define BCL_VBAT_COMP_TLOW 0x4A -#define BCL_IRQ_VCMP_L0 0x1 -#define BCL_IRQ_VCMP_L1 0x2 -#define BCL_IRQ_VCMP_L2 0x4 -#define BCL_IRQ_IBAT_L0 0x10 -#define BCL_IRQ_IBAT_L1 0x20 -#define BCL_IRQ_IBAT_L2 0x40 +#define BCL_IRQ_L0 0x1 +#define BCL_IRQ_L1 0x2 +#define BCL_IRQ_L2 0x4 #define BCL_VBAT_SCALING_UV 49827 #define BCL_VBAT_NO_READING 127 @@ -64,6 +61,9 @@ enum bcl_dev_type { BCL_VBAT_LVL0, BCL_VBAT_LVL1, BCL_VBAT_LVL2, + BCL_LVL0, + BCL_LVL1, + BCL_LVL2, BCL_TYPE_MAX, }; @@ -73,6 +73,9 @@ static char bcl_int_names[BCL_TYPE_MAX][25] = { "bcl-vbat-lvl0", "bcl-vbat-lvl1", "bcl-vbat-lvl2", + "bcl-lvl0", + "bcl-lvl1", + "bcl-lvl2", }; struct bcl_device; @@ -361,117 +364,83 @@ static int bcl_read_vbat(void *data, int *adc_value) return ret; } -static irqreturn_t bcl_handle_irq(int irq, void *data) +static int bcl_set_lbat(void *data, int low, int high) { - struct bcl_peripheral_data *perph_data = + struct bcl_peripheral_data *bat_data = (struct bcl_peripheral_data *)data; - unsigned int irq_status = 0; - int ret; - bool notify = false; - struct bcl_device *bcl_perph; - mutex_lock(&perph_data->state_trans_lock); - if (!perph_data->irq_enabled) { - pr_err("irq:%d not in expected state\n", irq); - disable_irq_nosync(irq); - perph_data->irq_enabled = false; - goto exit_intr; - } - mutex_unlock(&perph_data->state_trans_lock); + mutex_lock(&bat_data->state_trans_lock); - bcl_perph = perph_data->dev; - ret = bcl_read_register(bcl_perph, BCL_IRQ_STATUS, &irq_status); - if (ret) { - disable_irq_nosync(irq); - perph_data->irq_enabled = false; - return IRQ_HANDLED; + if (high == INT_MAX && + bat_data->irq_num && bat_data->irq_enabled) { + disable_irq_nosync(bat_data->irq_num); + bat_data->irq_enabled = false; + pr_debug("lbat[%d]: disable irq:%d\n", + bat_data->type, + bat_data->irq_num); + } else if (high != INT_MAX && + bat_data->irq_num && !bat_data->irq_enabled) { + enable_irq(bat_data->irq_num); + bat_data->irq_enabled = true; + pr_debug("lbat[%d]: enable irq:%d\n", + bat_data->type, + bat_data->irq_num); } - pr_debug("Irq:%d triggered for bcl type:%d. status:%u\n", - irq, perph_data->type, irq_status); - switch (perph_data->type) { - case BCL_VBAT_LVL0: /* BCL L0 interrupt */ - if ((irq_status & BCL_IRQ_VCMP_L0) && - (bcl_perph->param[BCL_VBAT_LVL0].tz_dev)) { - of_thermal_handle_trip( - bcl_perph->param[BCL_VBAT_LVL0].tz_dev); - notify = true; - } - if ((irq_status & BCL_IRQ_IBAT_L0) && - (bcl_perph->param[BCL_IBAT_LVL0].tz_dev)) { - of_thermal_handle_trip( - bcl_perph->param[BCL_IBAT_LVL0].tz_dev); - notify = true; - } + + mutex_unlock(&bat_data->state_trans_lock); + + return 0; +} + +static int bcl_read_lbat(void *data, int *adc_value) +{ + int ret = 0; + unsigned int val = 0; + struct bcl_peripheral_data *bat_data = + (struct bcl_peripheral_data *)data; + struct bcl_device *bcl_perph = bat_data->dev; + + *adc_value = val; + ret = bcl_read_register(bcl_perph, BCL_IRQ_STATUS, &val); + if (ret) + goto bcl_read_exit; + switch (bat_data->type) { + case BCL_LVL0: + *adc_value = val & BCL_IRQ_L0; break; - case BCL_VBAT_LVL1: /* BCL L1 interrupt */ - if ((irq_status & BCL_IRQ_VCMP_L1) && - (bcl_perph->param[BCL_VBAT_LVL1].tz_dev)) { - of_thermal_handle_trip( - bcl_perph->param[BCL_VBAT_LVL1].tz_dev); - - /* - * There is a possibility that just vbat_l1 be the - * source of bcl event. So trigger Vbat_l0 in - * those case. - */ - if (!(irq_status & BCL_IRQ_VCMP_L0) && - (bcl_perph->param[BCL_VBAT_LVL0].tz_dev)) - of_thermal_handle_trip( - bcl_perph->param[BCL_VBAT_LVL0].tz_dev); - notify = true; - } - if ((irq_status & BCL_IRQ_IBAT_L1) && - (bcl_perph->param[BCL_IBAT_LVL1].tz_dev)) { - of_thermal_handle_trip( - bcl_perph->param[BCL_IBAT_LVL1].tz_dev); - - /* - * There is a possibility that just ibat_l1 be the - * source of bcl event. So trigger ibat_l0 in - * those case. - */ - if (!(irq_status & BCL_IRQ_IBAT_L0) && - (bcl_perph->param[BCL_IBAT_LVL0].tz_dev)) - of_thermal_handle_trip( - bcl_perph->param[BCL_IBAT_LVL0].tz_dev); - notify = true; - } + case BCL_LVL1: + *adc_value = val & BCL_IRQ_L1; break; - case BCL_VBAT_LVL2: /* BCL L2 interrupt */ - if ((irq_status & BCL_IRQ_VCMP_L2) && - (bcl_perph->param[BCL_VBAT_LVL2].tz_dev)) { - of_thermal_handle_trip( - bcl_perph->param[BCL_VBAT_LVL2].tz_dev); - - /* - * There is a possibility that just vbat_l2 be the - * source of bcl event. So trigger Vbat_l0 and vbat_l1 - * in those case. - */ - if (!(irq_status & BCL_IRQ_VCMP_L1) && - (bcl_perph->param[BCL_VBAT_LVL1].tz_dev)) - of_thermal_handle_trip( - bcl_perph->param[BCL_VBAT_LVL1].tz_dev); - if (!(irq_status & BCL_IRQ_VCMP_L0) && - (bcl_perph->param[BCL_VBAT_LVL0].tz_dev)) - of_thermal_handle_trip( - bcl_perph->param[BCL_VBAT_LVL0].tz_dev); - notify = true; - } + case BCL_LVL2: + *adc_value = val & BCL_IRQ_L2; break; default: - pr_err("Invalid type%d for interrupt:%d\n", - perph_data->type, irq); - break; + pr_err("Invalid sensor type:%d\n", bat_data->type); + ret = -ENODEV; + goto bcl_read_exit; } - if (!notify) - pr_err_ratelimited("Irq:%d triggered. status:%u\n", - irq, irq_status); + bat_data->last_val = *adc_value; + pr_debug("lbat:%d val:%d\n", bat_data->type, + bat_data->last_val); - return IRQ_HANDLED; +bcl_read_exit: + return ret; +} + +static irqreturn_t bcl_handle_irq(int irq, void *data) +{ + struct bcl_peripheral_data *perph_data = + (struct bcl_peripheral_data *)data; + unsigned int irq_status = 0; + struct bcl_device *bcl_perph; + + bcl_perph = perph_data->dev; + bcl_read_register(bcl_perph, BCL_IRQ_STATUS, &irq_status); + pr_debug("Irq:%d triggered for bcl type:%s. status:%u\n", + irq, bcl_int_names[perph_data->type], + irq_status); + of_thermal_handle_trip(perph_data->tz_dev); -exit_intr: - mutex_unlock(&perph_data->state_trans_lock); return IRQ_HANDLED; } @@ -533,15 +502,15 @@ static void bcl_vbat_init(struct platform_device *pdev, enum bcl_dev_type type, struct bcl_device *bcl_perph) { struct bcl_peripheral_data *vbat = &bcl_perph->param[type]; - irqreturn_t (*handle)(int, void *) = bcl_handle_irq; mutex_init(&vbat->state_trans_lock); vbat->type = type; vbat->dev = bcl_perph; - bcl_fetch_trip(pdev, type, vbat, handle); vbat->ops.get_temp = bcl_read_vbat; vbat->ops.set_trips = bcl_set_vbat; vbat->ops.get_trip_temp = bcl_get_vbat_trip; + vbat->irq_num = 0; + vbat->irq_enabled = false; vbat->tz_dev = thermal_zone_of_sensor_register(&pdev->dev, type, vbat, &vbat->ops); if (IS_ERR(vbat->tz_dev)) { @@ -570,35 +539,10 @@ static void bcl_ibat_init(struct platform_device *pdev, mutex_init(&ibat->state_trans_lock); ibat->type = type; ibat->dev = bcl_perph; - bcl_fetch_trip(pdev, type, ibat, NULL); - if (ibat->irq_num <= 0) - return; - + ibat->irq_num = 0; + ibat->irq_enabled = false; ibat->ops.get_temp = bcl_read_ibat; ibat->ops.set_trips = bcl_set_ibat; - - switch (type) { - case BCL_IBAT_LVL0: - if (!bcl_perph->param[BCL_VBAT_LVL0].irq_num || - ibat->irq_num != - bcl_perph->param[BCL_VBAT_LVL0].irq_num) { - pr_err("ibat[%d]: irq %d mismatch\n", - type, ibat->irq_num); - return; - } - break; - case BCL_IBAT_LVL1: - if (!bcl_perph->param[BCL_VBAT_LVL1].irq_num || - ibat->irq_num != - bcl_perph->param[BCL_VBAT_LVL1].irq_num) { - pr_err("ibat[%d]: irq %d mismatch\n", - type, ibat->irq_num); - return; - } - break; - default: - return; - } ibat->tz_dev = thermal_zone_of_sensor_register(&pdev->dev, type, ibat, &ibat->ops); if (IS_ERR(ibat->tz_dev)) { @@ -618,6 +562,41 @@ static void bcl_probe_ibat(struct platform_device *pdev, bcl_ibat_init(pdev, BCL_IBAT_LVL1, bcl_perph); } +static void bcl_lvl_init(struct platform_device *pdev, + enum bcl_dev_type type, struct bcl_device *bcl_perph) +{ + struct bcl_peripheral_data *lbat = &bcl_perph->param[type]; + + mutex_init(&lbat->state_trans_lock); + lbat->type = type; + lbat->dev = bcl_perph; + bcl_fetch_trip(pdev, type, lbat, bcl_handle_irq); + if (lbat->irq_num <= 0) + return; + + lbat->ops.get_temp = bcl_read_lbat; + lbat->ops.set_trips = bcl_set_lbat; + + lbat->tz_dev = thermal_zone_of_sensor_register(&pdev->dev, + type, lbat, &lbat->ops); + if (IS_ERR(lbat->tz_dev)) { + pr_debug("lbat:[%s] register failed. err:%ld\n", + bcl_int_names[type], + PTR_ERR(lbat->tz_dev)); + lbat->tz_dev = NULL; + return; + } + thermal_zone_device_update(lbat->tz_dev, THERMAL_DEVICE_UP); +} + +static void bcl_probe_lvls(struct platform_device *pdev, + struct bcl_device *bcl_perph) +{ + bcl_lvl_init(pdev, BCL_LVL0, bcl_perph); + bcl_lvl_init(pdev, BCL_LVL1, bcl_perph); + bcl_lvl_init(pdev, BCL_LVL2, bcl_perph); +} + static void bcl_configure_bcl_peripheral(struct bcl_device *bcl_perph) { bcl_write_register(bcl_perph, BCL_MONITOR_EN, BIT(7)); @@ -663,6 +642,7 @@ static int bcl_probe(struct platform_device *pdev) bcl_get_devicetree_data(pdev, bcl_perph); bcl_probe_vbat(pdev, bcl_perph); bcl_probe_ibat(pdev, bcl_perph); + bcl_probe_lvls(pdev, bcl_perph); bcl_configure_bcl_peripheral(bcl_perph); dev_set_drvdata(&pdev->dev, bcl_perph); -- GitLab From 88afe5d70acee39f93d4d74942d4ef67cc2b5384 Mon Sep 17 00:00:00 2001 From: Manaf Meethalavalappu Pallikunhi Date: Fri, 19 Jul 2019 12:09:51 +0530 Subject: [PATCH 1046/1121] defconfig: msm: Update thermal drivers for ATOLL Disable CX peak current limiting cooling device driver and enable QMI sensor driver for ATOLL. Change-Id: I5695a3036a434a6ddd2de100175b163c5ebc0d91 Signed-off-by: Manaf Meethalavalappu Pallikunhi --- arch/arm64/configs/vendor/atoll-perf_defconfig | 2 +- arch/arm64/configs/vendor/atoll_defconfig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/configs/vendor/atoll-perf_defconfig b/arch/arm64/configs/vendor/atoll-perf_defconfig index 3257015246d7..60d5ced35b1b 100644 --- a/arch/arm64/configs/vendor/atoll-perf_defconfig +++ b/arch/arm64/configs/vendor/atoll-perf_defconfig @@ -371,11 +371,11 @@ CONFIG_QTI_THERMAL_LIMITS_DCVS=y CONFIG_QTI_VIRTUAL_SENSOR=y CONFIG_QTI_AOP_REG_COOLING_DEVICE=y CONFIG_QTI_QMI_COOLING_DEVICE=y +CONFIG_QTI_QMI_SENSOR=y CONFIG_REGULATOR_COOLING_DEVICE=y CONFIG_QTI_BCL_PMIC5=y CONFIG_QTI_BCL_SOC_DRIVER=y CONFIG_QTI_ADC_TM=y -CONFIG_QTI_CX_IPEAK_COOLING_DEVICE=y CONFIG_MFD_I2C_PMIC=y CONFIG_MFD_SPMI_PMIC=y CONFIG_REGULATOR_FIXED_VOLTAGE=y diff --git a/arch/arm64/configs/vendor/atoll_defconfig b/arch/arm64/configs/vendor/atoll_defconfig index d7694e7d1d38..fb51877064cd 100644 --- a/arch/arm64/configs/vendor/atoll_defconfig +++ b/arch/arm64/configs/vendor/atoll_defconfig @@ -392,11 +392,11 @@ CONFIG_QTI_THERMAL_LIMITS_DCVS=y CONFIG_QTI_VIRTUAL_SENSOR=y CONFIG_QTI_AOP_REG_COOLING_DEVICE=y CONFIG_QTI_QMI_COOLING_DEVICE=y +CONFIG_QTI_QMI_SENSOR=y CONFIG_REGULATOR_COOLING_DEVICE=y CONFIG_QTI_BCL_PMIC5=y CONFIG_QTI_BCL_SOC_DRIVER=y CONFIG_QTI_ADC_TM=y -CONFIG_QTI_CX_IPEAK_COOLING_DEVICE=y CONFIG_MFD_I2C_PMIC=y CONFIG_MFD_SPMI_PMIC=y CONFIG_REGULATOR_FIXED_VOLTAGE=y -- GitLab From 263b5a40f17fb158570e85bbb9be5150ba84d8d6 Mon Sep 17 00:00:00 2001 From: Manaf Meethalavalappu Pallikunhi Date: Fri, 19 Jul 2019 12:18:25 +0530 Subject: [PATCH 1047/1121] ARM: dts: msm: Add QMI cooling device for ATOLL Add QMI cooling devices for ATOLL. These cooling devices will be used to apply cold temperature voltage restriction and other mitigation for remote subsystems. Change-Id: I2b70be1cd9ba69ea5ade963b5489aa8a862fbd7e Signed-off-by: Manaf Meethalavalappu Pallikunhi --- arch/arm64/boot/dts/qcom/atoll-thermal.dtsi | 53 +++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/atoll-thermal.dtsi b/arch/arm64/boot/dts/qcom/atoll-thermal.dtsi index 3397ad51b4b2..12a619563603 100644 --- a/arch/arm64/boot/dts/qcom/atoll-thermal.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll-thermal.dtsi @@ -13,6 +13,59 @@ #include +&soc { + qmi-tmd-devices { + compatible = "qcom,qmi-cooling-devices"; + + modem { + qcom,instance-id = <0x0>; + + modem_pa: modem_pa { + qcom,qmi-dev-name = "pa"; + #cooling-cells = <2>; + }; + + modem_proc: modem_proc { + qcom,qmi-dev-name = "modem"; + #cooling-cells = <2>; + }; + + modem_current: modem_current { + qcom,qmi-dev-name = "modem_current"; + #cooling-cells = <2>; + }; + + modem_skin: modem_skin { + qcom,qmi-dev-name = "modem_skin"; + #cooling-cells = <2>; + }; + + modem_vdd: modem_vdd { + qcom,qmi-dev-name = "cpuv_restriction_cold"; + #cooling-cells = <2>; + }; + }; + + adsp { + qcom,instance-id = <0x1>; + + adsp_vdd: adsp_vdd { + qcom,qmi-dev-name = "cpuv_restriction_cold"; + #cooling-cells = <2>; + }; + }; + + cdsp { + qcom,instance-id = <0x43>; + + cdsp_vdd: cdsp_vdd { + qcom,qmi-dev-name = "cpuv_restriction_cold"; + #cooling-cells = <2>; + }; + }; + }; +}; + &thermal_zones { aoss-0-usr { polling-delay-passive = <0>; -- GitLab From a373fb659f80d41d07bee328738836a8a6b1f64c Mon Sep 17 00:00:00 2001 From: Deepak Kumar Date: Thu, 11 Jul 2019 13:46:38 +0530 Subject: [PATCH 1048/1121] msm: kgsl: Ensure GPU gdscs are off in SLUMBER and during hard reset Poll gdsc status to ensure it's off before transitioning to SLUMBER and during hard reset. This is needed to make sure that next wake-up is indeed a fresh start and doesn't fail (especially during recovery from fault) because of stale state. Change-Id: I064038c59315a9b8aa10c7dd4a45354f0f5e5447 Signed-off-by: Deepak Kumar --- drivers/gpu/msm/adreno.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index e30933ce93e6..3afbb50e60d3 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -3971,6 +3971,9 @@ static void adreno_iommu_sync(struct kgsl_device *device, bool sync) struct scm_desc desc = {0}; int ret; + if (!ADRENO_QUIRK(ADRENO_DEVICE(device), ADRENO_QUIRK_IOMMU_SYNC)) + return; + if (sync == true) { mutex_lock(&kgsl_mmu_sync); desc.args[0] = true; @@ -3987,25 +3990,29 @@ static void adreno_iommu_sync(struct kgsl_device *device, bool sync) } } -static void _regulator_disable(struct kgsl_regulator *regulator, bool poll) +static void +_regulator_disable(struct kgsl_regulator *regulator, unsigned int timeout) { - unsigned long wait_time = jiffies + msecs_to_jiffies(200); + unsigned long wait_time; if (IS_ERR_OR_NULL(regulator->reg)) return; regulator_disable(regulator->reg); - if (poll == false) - return; + wait_time = jiffies + msecs_to_jiffies(timeout); + /* Poll for regulator status to ensure it's OFF */ while (!time_after(jiffies, wait_time)) { if (!regulator_is_enabled(regulator->reg)) return; - cpu_relax(); + usleep_range(10, 100); } - KGSL_CORE_ERR("regulator '%s' still on after 200ms\n", regulator->name); + if (!regulator_is_enabled(regulator->reg)) + return; + + KGSL_CORE_ERR("regulator '%s' disable timed out\n", regulator->name); } static void adreno_regulator_disable_poll(struct kgsl_device *device) @@ -4013,18 +4020,13 @@ static void adreno_regulator_disable_poll(struct kgsl_device *device) struct adreno_device *adreno_dev = ADRENO_DEVICE(device); struct kgsl_pwrctrl *pwr = &device->pwrctrl; int i; - - /* Fast path - hopefully we don't need this quirk */ - if (!ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_IOMMU_SYNC)) { - for (i = KGSL_MAX_REGULATORS - 1; i >= 0; i--) - _regulator_disable(&pwr->regulators[i], false); - return; - } + unsigned int timeout = + ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_IOMMU_SYNC) ? 200 : 5000; adreno_iommu_sync(device, true); - for (i = 0; i < KGSL_MAX_REGULATORS; i++) - _regulator_disable(&pwr->regulators[i], true); + for (i = KGSL_MAX_REGULATORS - 1; i >= 0; i--) + _regulator_disable(&pwr->regulators[i], timeout); adreno_iommu_sync(device, false); } -- GitLab From 443c3fc462cd344210fd338a73bf4d1f077f2362 Mon Sep 17 00:00:00 2001 From: Odelu Kukatla Date: Fri, 26 Jul 2019 12:28:47 +0530 Subject: [PATCH 1049/1121] ARM: dts: msm: Change display rsc to use AWAKE votes for ATOLL Since display RSC does not have dedicated ACTIVE_TCS, we need to send AWAKE state request as well. Change-Id: Ie8e93bb9d9c771ed36be422e95f07e4d2c1c39c5 Signed-off-by: Odelu Kukatla --- arch/arm64/boot/dts/qcom/atoll-bus.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/atoll-bus.dtsi b/arch/arm64/boot/dts/qcom/atoll-bus.dtsi index 2b38acb511bb..105b298ce10b 100644 --- a/arch/arm64/boot/dts/qcom/atoll-bus.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll-bus.dtsi @@ -51,7 +51,7 @@ cell-id = ; label = "disp_rsc"; qcom,rsc-dev; - qcom,req_state = <2>; + qcom,req_state = <3>; }; /*BCMs*/ -- GitLab From ae225cbe313071069de296e45ed6eb13685c2e18 Mon Sep 17 00:00:00 2001 From: Kaushal Kumar Date: Fri, 26 Jul 2019 13:22:14 +0530 Subject: [PATCH 1050/1121] defconfig: msm: change BLK_DEV_LOOP_MIN_COUNT's value for Trinket Change BLK_DEV_LOOP_MIN_COUNT's value from 8 to 16 for Trinket SoC. From android version 'Q', android API level has moved from 28 to 29. With this upgrade, android VTS testcase 'VtsKernelLoopConfigTest' expects BLK_DEV_LOOP_MIN_COUNT to be 16. Change-Id: If409abe90c1e9ae4df572c84d1442b105aed0fdc Signed-off-by: Kaushal Kumar --- arch/arm64/configs/vendor/trinket-perf_defconfig | 1 + arch/arm64/configs/vendor/trinket_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm64/configs/vendor/trinket-perf_defconfig b/arch/arm64/configs/vendor/trinket-perf_defconfig index ada21ac70ca0..12a80e1685b8 100644 --- a/arch/arm64/configs/vendor/trinket-perf_defconfig +++ b/arch/arm64/configs/vendor/trinket-perf_defconfig @@ -258,6 +258,7 @@ CONFIG_DMA_CMA=y CONFIG_ZRAM=y CONFIG_ZRAM_DEDUP=y CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=16 CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_HDCP_QSEECOM=y diff --git a/arch/arm64/configs/vendor/trinket_defconfig b/arch/arm64/configs/vendor/trinket_defconfig index ed1eac7f348d..c6594d91cd3c 100644 --- a/arch/arm64/configs/vendor/trinket_defconfig +++ b/arch/arm64/configs/vendor/trinket_defconfig @@ -267,6 +267,7 @@ CONFIG_DMA_CMA=y CONFIG_ZRAM=y CONFIG_ZRAM_DEDUP=y CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=16 CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_HDCP_QSEECOM=y -- GitLab From 56a791feec57e8d78d44ff6c7f590c24a6f81d34 Mon Sep 17 00:00:00 2001 From: Hardik Arya Date: Mon, 22 Jul 2019 15:24:43 +0530 Subject: [PATCH 1051/1121] diag: Do not include unallocated buffer to md table Currently there is a possibility of copying apps data buffer to diag_md table after getting freed. The patch adds buffer to table only when buffer is allocated. Change-Id: Ie78a74f64cb3c3e3a49077f8ed33b3f2662ea29e Signed-off-by: Hardik Arya --- drivers/char/diag/diag_memorydevice.c | 20 +++++++++++++++++--- drivers/char/diag/diagfwd.c | 3 +++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/char/diag/diag_memorydevice.c b/drivers/char/diag/diag_memorydevice.c index 3d2bcf7dc9dd..b44410250420 100644 --- a/drivers/char/diag/diag_memorydevice.c +++ b/drivers/char/diag/diag_memorydevice.c @@ -175,7 +175,7 @@ int diag_md_write(int id, unsigned char *buf, int len, int ctx) { int i, peripheral, pid = 0; uint8_t found = 0; - unsigned long flags; + unsigned long flags, flags_sec; struct diag_md_info *ch = NULL; struct diag_md_session_t *session_info = NULL; @@ -207,6 +207,16 @@ int diag_md_write(int id, unsigned char *buf, int len, int ctx) } spin_lock_irqsave(&ch->lock, flags); + if (peripheral == APPS_DATA) { + spin_lock_irqsave(&driver->diagmem_lock, flags_sec); + if (!hdlc_data.allocated && !non_hdlc_data.allocated) { + spin_unlock_irqrestore(&driver->diagmem_lock, + flags_sec); + spin_unlock_irqrestore(&ch->lock, flags); + mutex_unlock(&driver->md_session_lock); + return -EINVAL; + } + } for (i = 0; i < ch->num_tbl_entries && !found; i++) { if (ch->tbl[i].buf != buf) continue; @@ -218,14 +228,16 @@ int diag_md_write(int id, unsigned char *buf, int len, int ctx) ch->tbl[i].len = 0; ch->tbl[i].ctx = 0; } - spin_unlock_irqrestore(&ch->lock, flags); if (found) { + if (peripheral == APPS_DATA) + spin_unlock_irqrestore(&driver->diagmem_lock, + flags_sec); + spin_unlock_irqrestore(&ch->lock, flags); mutex_unlock(&driver->md_session_lock); return -ENOMEM; } - spin_lock_irqsave(&ch->lock, flags); for (i = 0; i < ch->num_tbl_entries && !found; i++) { if (ch->tbl[i].len == 0) { ch->tbl[i].buf = buf; @@ -235,6 +247,8 @@ int diag_md_write(int id, unsigned char *buf, int len, int ctx) diag_ws_on_read(DIAG_WS_MUX, len); } } + if (peripheral == APPS_DATA) + spin_unlock_irqrestore(&driver->diagmem_lock, flags_sec); spin_unlock_irqrestore(&ch->lock, flags); mutex_unlock(&driver->md_session_lock); diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c index ffc360bccea2..fe9027eaf478 100644 --- a/drivers/char/diag/diagfwd.c +++ b/drivers/char/diag/diagfwd.c @@ -1862,6 +1862,9 @@ static int diagfwd_mux_write_done(unsigned char *buf, int len, int buf_ctxt, DIAG_LOG(DIAG_DEBUG_PERIPHERALS, "No apps data buffer is allocated to be freed\n"); if (temp) { + DIAG_LOG(DIAG_DEBUG_PERIPHERALS, + "Freeing Apps data buffer after write done hdlc.allocated: %d, non_hdlc.allocated: %d\n", + hdlc_data.allocated, non_hdlc_data.allocated); diagmem_free(driver, temp->buf, POOL_TYPE_HDLC); temp->buf = NULL; temp->len = 0; -- GitLab From c6e1e1f4817402d369ff06ef31cc95f699669588 Mon Sep 17 00:00:00 2001 From: Sriharsha Allenki Date: Fri, 26 Jul 2019 15:49:02 +0530 Subject: [PATCH 1052/1121] ARM: dts: msm: Disable io-coherency for GSI on Trinket Trinket does not support io-coherency. So, disable io-coherency when allocating buffers for GSI in usb driver. Change-Id: Id8659bfdf432d14ea2114b1d9b316d4e1107f848 Signed-off-by: Sriharsha Allenki --- arch/arm64/boot/dts/qcom/trinket-usb.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/qcom/trinket-usb.dtsi b/arch/arm64/boot/dts/qcom/trinket-usb.dtsi index 5a7c14dd4bb8..bb5087492c11 100644 --- a/arch/arm64/boot/dts/qcom/trinket-usb.dtsi +++ b/arch/arm64/boot/dts/qcom/trinket-usb.dtsi @@ -54,6 +54,7 @@ 0x144 /* GSI_RING_BASE_ADDR_H */ 0x1a4>; /* GSI_IF_STS */ qcom,dwc-usb3-msm-tx-fifo-size = <21288>; + qcom,gsi-disable-io-coherency; qcom,msm-bus,name = "usb0"; qcom,msm-bus,num-cases = <4>; -- GitLab From 24381c5122155cfdd8a46759f2cb5a6905846a6b Mon Sep 17 00:00:00 2001 From: Sean Tranchetti Date: Fri, 26 Jul 2019 11:20:47 -0600 Subject: [PATCH 1053/1121] net: qualcomm: rmnet: Avoid *_hdr() helpers while adding linear GSO These various helpers rely on the network_offset and transport_offset fields in the SKB being set to appropriate values, and they might not be set appropriately in all cases (e.g. reusing the coalesced SKB from the lower levels). Access the headers for updating the GSO information directly via skb->data to ensure the correct bytes are updated. Change-Id: I4ac2b3118c190587d8178b1d780c9ec842438c86 Signed-off-by: Sean Tranchetti --- drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c index cfef7e9c4c8d..e83a5737a415 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c @@ -664,30 +664,32 @@ static void rmnet_map_gso_stamp(struct sk_buff *skb, struct rmnet_map_coal_metadata *coal_meta) { struct skb_shared_info *shinfo = skb_shinfo(skb); - struct iphdr *iph = ip_hdr(skb); + unsigned char *data = skb->data; __sum16 pseudo; u16 pkt_len = skb->len - coal_meta->ip_len; bool ipv4 = coal_meta->ip_proto == 4; if (ipv4) { + struct iphdr *iph = (struct iphdr *)data; + pseudo = ~csum_tcpudp_magic(iph->saddr, iph->daddr, pkt_len, coal_meta->trans_proto, 0); } else { - struct ipv6hdr *ip6h = ipv6_hdr(skb); + struct ipv6hdr *ip6h = (struct ipv6hdr *)data; pseudo = ~csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, pkt_len, coal_meta->trans_proto, 0); } if (coal_meta->trans_proto == IPPROTO_TCP) { - struct tcphdr *tp = tcp_hdr(skb); + struct tcphdr *tp = (struct tcphdr *)(data + coal_meta->ip_len); tp->check = pseudo; shinfo->gso_type = (ipv4) ? SKB_GSO_TCPV4 : SKB_GSO_TCPV6; skb->csum_offset = offsetof(struct tcphdr, check); } else { - struct udphdr *up = udp_hdr(skb); + struct udphdr *up = (struct udphdr *)(data + coal_meta->ip_len); up->check = pseudo; shinfo->gso_type = SKB_GSO_UDP_L4; -- GitLab From 48e9b7f89097c1cb3b6ff048f5b0a184245ca156 Mon Sep 17 00:00:00 2001 From: Gustavo Solaira Date: Wed, 24 Jul 2019 12:09:27 -0700 Subject: [PATCH 1054/1121] ARM: dts: msm: Enable QCA6390 for SA515M CCARD boards Enable the QCA6390 WLAN chip for SA515M CCARD boards connected over PCIe. Change-Id: I74bccae336b03bd939475f1a2f974c664d9cfd91 Signed-off-by: Gustavo Solaira --- arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi | 11 +++++++++++ arch/arm64/boot/dts/qcom/sdxprairie-regulator.dtsi | 9 +++++++++ 2 files changed, 20 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi b/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi index 0c561f420fa1..015934236bd8 100644 --- a/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi +++ b/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi @@ -182,3 +182,14 @@ regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; }; + +&cnss_qca6390 { + vdd-wlan-ctrl1-supply = <&vreg_conn_pa>; + vdd-wlan-aon-supply = <&pmxprairie_s3>; + vdd-wlan-rfa1-supply = <&pmxprairie_s2>; + vdd-wlan-rfa3-supply = <&pmxprairie_s4>; + qcom,vdd-wlan-ctrl1-info = <0 0 0 0>; + qcom,vdd-wlan-aon-info = <950000 950000 0 0>; + qcom,vdd-wlan-rfa1-info = <1350000 1350000 0 0>; + qcom,vdd-wlan-rfa3-info = <1904000 1904000 450000 0>; +}; diff --git a/arch/arm64/boot/dts/qcom/sdxprairie-regulator.dtsi b/arch/arm64/boot/dts/qcom/sdxprairie-regulator.dtsi index 817bef3db90a..99a5d9774dbd 100644 --- a/arch/arm64/boot/dts/qcom/sdxprairie-regulator.dtsi +++ b/arch/arm64/boot/dts/qcom/sdxprairie-regulator.dtsi @@ -508,4 +508,13 @@ gpio = <&tlmm 102 GPIO_ACTIVE_HIGH>; enable-active-high; }; + + /* PWR_CTR1_VDD_PA supply */ + vreg_conn_pa: vreg_conn_pa { + compatible = "regulator-fixed"; + regulator-name = "vreg_conn_pa"; + startup-delay-us = <4000>; + enable-active-high; + gpio = <&pmxprairie_gpios 2 GPIO_ACTIVE_HIGH>; + }; }; -- GitLab From 6844c231ba80dcb03ceaa7fac289bd761dda516c Mon Sep 17 00:00:00 2001 From: Patrick Daly Date: Fri, 26 Jul 2019 14:36:58 -0700 Subject: [PATCH 1055/1121] arm: mm: Set dma_ops_setup only for IOMMU_DOMAIN_DMA Commit ef027fed4de0 ("arm: dma-mapping: don't attach the clients to smmu device by default") changed the behavior such that iommu clients need to attach manually, except for the case of IOMMU_DOMAIN_DMA. There is a similar requirement for detach, so modify dma_ops_setup accordingly. Change-Id: I41117215e14552abbc621433eef16a44a33cd386 Signed-off-by: Patrick Daly --- arch/arm/mm/dma-mapping.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 204a63061aa6..1a4d48a38416 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -2718,10 +2718,13 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size, if (dev->dma_ops) return; - if (arm_setup_iommu_dma_ops(dev, dma_base, size, iommu)) + if (arm_setup_iommu_dma_ops(dev, dma_base, size, iommu)) { dma_ops = arm_get_iommu_dma_map_ops(coherent); - else + dev->archdata.dma_ops_setup = true; + } else { dma_ops = arm_get_dma_map_ops(coherent); + dev->archdata.dma_ops_setup = false; + } set_dma_ops(dev, dma_ops); @@ -2731,7 +2734,6 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size, dev->dma_ops = xen_dma_ops; } #endif - dev->archdata.dma_ops_setup = true; } EXPORT_SYMBOL(arch_setup_dma_ops); -- GitLab From a9b54b307ec981fa6ada5fea5f81ddce6afffc9c Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Fri, 26 Jul 2019 20:12:13 -0700 Subject: [PATCH 1056/1121] ARM: dts: msm: Include display for SA8195P ADP STAR Include the SA8195P ADP STAR specific display file for display support on the SA8195P ADP STAR target. Change-Id: Ic862c7c1a84fd3400338f8e707edf2caa11c6347 Signed-off-by: Anant Goel --- arch/arm64/boot/dts/qcom/sa8195p-adp-star.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/qcom/sa8195p-adp-star.dtsi b/arch/arm64/boot/dts/qcom/sa8195p-adp-star.dtsi index 31187172cde3..2255a453122f 100644 --- a/arch/arm64/boot/dts/qcom/sa8195p-adp-star.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8195p-adp-star.dtsi @@ -11,6 +11,7 @@ */ #include +#include "sa8195p-adp-star-display.dtsi" &qupv3_se0_spi { status = "ok"; -- GitLab From 76308090966f7ea5bafdf23596817cebe35b4b42 Mon Sep 17 00:00:00 2001 From: Ashok Vuyyuru Date: Thu, 25 Jul 2019 16:34:54 +0530 Subject: [PATCH 1057/1121] msm: ipa3: Fix to recycle ODL consumer pipe SKB buffer Because of not recycling the SKB used for ODL consumer pipe causing the skb over panic when resusing it. Add changes to recycle ODL consumer pipe skb buffer before reusing it. Change-Id: I086fee15766f9442dcc7bb57df3c17986822e43f Signed-off-by: Ashok Vuyyuru --- drivers/platform/msm/ipa/ipa_v3/ipa_dp.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c index f7315eb50bc1..7e3d9f3a2db7 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c @@ -3308,11 +3308,14 @@ static int ipa3_odu_rx_pyld_hdlr(struct sk_buff *rx_skb, static int ipa3_odl_dpl_rx_pyld_hdlr(struct sk_buff *rx_skb, struct ipa3_sys_context *sys) { - if (WARN(!sys->ep->client_notify, "sys->ep->client_notify is NULL\n")) + if (WARN(!sys->ep->client_notify, "sys->ep->client_notify is NULL\n")) { dev_kfree_skb_any(rx_skb); - else + } else { sys->ep->client_notify(sys->ep->priv, IPA_RECEIVE, (unsigned long)(rx_skb)); + /*Recycle the SKB before reusing it*/ + ipa3_skb_recycle(rx_skb); + } return 0; } -- GitLab From 9d196dead2db7b108b4a7ac9c802789fa186be24 Mon Sep 17 00:00:00 2001 From: Zhiqiang Tu Date: Sat, 27 Jul 2019 16:58:29 +0800 Subject: [PATCH 1058/1121] clk: qcom: Add usb and pcie virtio clocks for sa8195p Add clocks required by usb and pcie pass-through on sa8195p virtual machine. Change-Id: Ibeddc2b97f6365766797310601a12336380ab2a6 Signed-off-by: Zhiqiang Tu --- drivers/clk/qcom/virtio_clk_sa8195p.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/clk/qcom/virtio_clk_sa8195p.c b/drivers/clk/qcom/virtio_clk_sa8195p.c index 2be46624a73d..90c07bf8f7ca 100644 --- a/drivers/clk/qcom/virtio_clk_sa8195p.c +++ b/drivers/clk/qcom/virtio_clk_sa8195p.c @@ -45,11 +45,26 @@ static const char * const sa8195p_gcc_virtio_clocks[] = { [GCC_CFG_NOC_USB3_PRIM_AXI_CLK] = "gcc_cfg_noc_usb3_prim_axi_clk", [GCC_AGGRE_USB3_PRIM_AXI_CLK] = "gcc_aggre_usb3_prim_axi_clk", [GCC_USB30_PRIM_MOCK_UTMI_CLK] = "gcc_usb30_prim_mock_utmi_clk", + [GCC_USB30_PRIM_SLEEP_CLK] = "gcc_usb30_prim_sleep_clk", + [GCC_USB3_PRIM_PHY_AUX_CLK] = "gcc_usb3_prim_phy_aux_clk", + [GCC_USB3_PRIM_PHY_PIPE_CLK] = "gcc_usb3_prim_phy_pipe_clk", + [GCC_USB3_PRIM_CLKREF_CLK] = "gcc_usb3_prim_clkref_en", + [GCC_USB3_PRIM_PHY_COM_AUX_CLK] = "gcc_usb3_prim_phy_com_aux_clk", + [GCC_USB30_SEC_MASTER_CLK] = "gcc_usb30_sec_master_clk", + [GCC_CFG_NOC_USB3_SEC_AXI_CLK] = "gcc_cfg_noc_usb3_sec_axi_clk", + [GCC_AGGRE_USB3_SEC_AXI_CLK] = "gcc_aggre_usb3_sec_axi_clk", + [GCC_USB30_SEC_MOCK_UTMI_CLK] = "gcc_usb30_sec_mock_utmi_clk", + [GCC_USB30_SEC_SLEEP_CLK] = "gcc_usb30_sec_sleep_clk", + [GCC_USB3_SEC_PHY_AUX_CLK] = "gcc_usb3_sec_phy_aux_clk", + [GCC_USB3_SEC_PHY_PIPE_CLK] = "gcc_usb3_sec_phy_pipe_clk", + [GCC_USB3_SEC_CLKREF_CLK] = "gcc_usb3_sec_clkref_en", + [GCC_USB3_SEC_PHY_COM_AUX_CLK] = "gcc_usb3_sec_phy_com_aux_clk", [GCC_PCIE_0_PIPE_CLK] = "gcc_pcie_0_pipe_clk", [GCC_PCIE_0_AUX_CLK] = "gcc_pcie_0_aux_clk", [GCC_PCIE_0_CFG_AHB_CLK] = "gcc_pcie_0_cfg_ahb_clk", [GCC_PCIE_0_MSTR_AXI_CLK] = "gcc_pcie_0_mstr_axi_clk", [GCC_PCIE_0_SLV_AXI_CLK] = "gcc_pcie_0_slv_axi_clk", + [GCC_PCIE_0_CLKREF_CLK] = "gcc_pcie_0_clkref_en", [GCC_PCIE_0_SLV_Q2A_AXI_CLK] = "gcc_pcie_0_slv_q2a_axi_clk", [GCC_AGGRE_NOC_PCIE_TBU_CLK] = "gcc_aggre_noc_pcie_tbu_clk", [GCC_PCIE0_PHY_REFGEN_CLK] = "gcc_pcie0_phy_refgen_clk", @@ -60,7 +75,9 @@ static const char * const sa8195p_gcc_virtio_clocks[] = { static const char * const sa8195p_gcc_virtio_resets[] = { [GCC_QUSB2PHY_PRIM_BCR] = "gcc_qusb2phy_prim_bcr", + [GCC_QUSB2PHY_SEC_BCR] = "gcc_qusb2phy_sec_bcr", [GCC_USB30_PRIM_BCR] = "gcc_usb30_prim_master_clk", + [GCC_USB30_SEC_BCR] = "gcc_usb30_sec_master_clk", [GCC_PCIE_0_BCR] = "gcc_pcie_0_mstr_axi_clk", [GCC_PCIE_0_PHY_BCR] = "gcc_pcie_0_phy_bcr", }; -- GitLab From 9b913d10616c4dba8c6176787fb314af3c3a8645 Mon Sep 17 00:00:00 2001 From: Zhiqiang Tu Date: Thu, 25 Jul 2019 12:02:38 +0800 Subject: [PATCH 1059/1121] ARM: dts: msm: Enable virtio clock for sa8195 vm Replace hab based virtual clock with virtio clock for sa8195 virtual machine. Change-Id: I677acfc60b1c73034a49566dfa6b30f889ca70ed Signed-off-by: Zhiqiang Tu --- arch/arm64/boot/dts/qcom/sa8195-vm.dtsi | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sa8195-vm.dtsi b/arch/arm64/boot/dts/qcom/sa8195-vm.dtsi index 738b8b39cc4a..1f0c3ded4e0f 100644 --- a/arch/arm64/boot/dts/qcom/sa8195-vm.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8195-vm.dtsi @@ -31,16 +31,19 @@ }; &soc { - clock_virt: qcom,virt-gcc { - compatible = "qcom,virt-clk-sm8150-gcc"; + clock_virt: qcom,virtio-gcc { + compatible = "virtio,mmio"; + reg = <0x1c200000 0x1000>; + interrupts = <0 48 0>; #clock-cells = <1>; #reset-cells = <1>; }; - clock_virt_scc: qcom,virt-scc { - compatible = "qcom,virt-clk-sm8150-scc"; + clock_virt_scc: qcom,virtio-scc { + compatible = "virtio,mmio"; + reg = <0x1c300000 0x1000>; + interrupts = <0 49 0>; #clock-cells = <1>; - #reset-cells = <1>; }; apps_smmu: apps-smmu@0x15000000 { -- GitLab From f4f2f6674735b2a57c1ea3f8d36b0cfac1594ebf Mon Sep 17 00:00:00 2001 From: Mukesh Kumar Savaliya Date: Wed, 6 Feb 2019 00:50:08 +0530 Subject: [PATCH 1060/1121] serial: msm_geni_serial: Enhance debug logs and support This patch adds useful and optimal debug logs at correct places. Also adds HW version check and rectifies existing logs. In addition added support to extract FW and HW verion from the adb shell which can help in future debug. Change-Id: I0c9fb55bf78bf34b2ae9071d36f5ec9703be2778 Signed-off-by: Mukesh Kumar Savaliya --- drivers/platform/msm/qcom-geni-se.c | 8 +- drivers/tty/serial/msm_geni_serial.c | 124 ++++++++++++++++++++++----- 2 files changed, 108 insertions(+), 24 deletions(-) diff --git a/drivers/platform/msm/qcom-geni-se.c b/drivers/platform/msm/qcom-geni-se.c index 0e296c313e92..835899e37842 100644 --- a/drivers/platform/msm/qcom-geni-se.c +++ b/drivers/platform/msm/qcom-geni-se.c @@ -1568,6 +1568,8 @@ void geni_se_dump_dbg_regs(struct se_geni_rsc *rsc, void __iomem *base, { u32 m_cmd0 = 0; u32 m_irq_status = 0; + u32 s_cmd0 = 0; + u32 s_irq_status = 0; u32 geni_status = 0; u32 geni_ios = 0; u32 dma_rx_irq = 0; @@ -1594,10 +1596,12 @@ void geni_se_dump_dbg_regs(struct se_geni_rsc *rsc, void __iomem *base, } m_cmd0 = geni_read_reg(base, SE_GENI_M_CMD0); m_irq_status = geni_read_reg(base, SE_GENI_M_IRQ_STATUS); + s_cmd0 = geni_read_reg(base, SE_GENI_S_CMD0); + s_irq_status = geni_read_reg(base, SE_GENI_S_IRQ_STATUS); geni_status = geni_read_reg(base, SE_GENI_STATUS); geni_ios = geni_read_reg(base, SE_GENI_IOS); - dma_rx_irq = geni_read_reg(base, SE_DMA_TX_IRQ_STAT); - dma_tx_irq = geni_read_reg(base, SE_DMA_RX_IRQ_STAT); + dma_tx_irq = geni_read_reg(base, SE_DMA_TX_IRQ_STAT); + dma_rx_irq = geni_read_reg(base, SE_DMA_RX_IRQ_STAT); rx_fifo_status = geni_read_reg(base, SE_GENI_RX_FIFO_STATUS); tx_fifo_status = geni_read_reg(base, SE_GENI_TX_FIFO_STATUS); se_dma_dbg = geni_read_reg(base, SE_DMA_DEBUG_REG0); diff --git a/drivers/tty/serial/msm_geni_serial.c b/drivers/tty/serial/msm_geni_serial.c index 594e7515308e..1ef869d940f2 100644 --- a/drivers/tty/serial/msm_geni_serial.c +++ b/drivers/tty/serial/msm_geni_serial.c @@ -133,6 +133,14 @@ #define UART_CONSOLE_RX_WM (2) #define QUP_VER (0x20050000) +struct msm_geni_serial_ver_info { + int hw_major_ver; + int hw_minor_ver; + int hw_step_ver; + int m_fw_ver; + int s_fw_ver; +}; + struct msm_geni_serial_port { struct uart_port uport; char name[20]; @@ -169,6 +177,7 @@ struct msm_geni_serial_port { int ioctl_count; int edge_count; bool manual_flow; + struct msm_geni_serial_ver_info ver_info; }; static const struct uart_ops msm_geni_serial_pops; @@ -193,6 +202,7 @@ static void msm_geni_serial_stop_rx(struct uart_port *uport); static int msm_geni_serial_runtime_resume(struct device *dev); static int msm_geni_serial_runtime_suspend(struct device *dev); static int uart_line_id; +static int msm_geni_serial_get_ver_info(struct uart_port *uport); #define GET_DEV_PORT(uport) \ container_of(uport, struct msm_geni_serial_port, uport) @@ -326,7 +336,7 @@ static void wait_for_transfers_inflight(struct uart_port *uport) static int vote_clock_on(struct uart_port *uport) { struct msm_geni_serial_port *port = GET_DEV_PORT(uport); - int usage_count = atomic_read(&uport->dev->power.usage_count); + int usage_count; int ret = 0; ret = msm_geni_serial_power_on(uport); @@ -335,15 +345,18 @@ static int vote_clock_on(struct uart_port *uport) return ret; } port->ioctl_count++; - IPC_LOG_MSG(port->ipc_log_pwr, "%s%s ioctl %d usage_count %d\n", - __func__, current->comm, port->ioctl_count, usage_count); + usage_count = atomic_read(&uport->dev->power.usage_count); + IPC_LOG_MSG(port->ipc_log_pwr, + "%s :%s ioctl:%d usage_count:%d edge-Count:%d\n", + __func__, current->comm, port->ioctl_count, + usage_count, port->edge_count); return 0; } static int vote_clock_off(struct uart_port *uport) { struct msm_geni_serial_port *port = GET_DEV_PORT(uport); - int usage_count = atomic_read(&uport->dev->power.usage_count); + int usage_count; if (!pm_runtime_enabled(uport->dev)) { dev_err(uport->dev, "RPM not available.Can't enable clocks\n"); @@ -360,7 +373,8 @@ static int vote_clock_off(struct uart_port *uport) wait_for_transfers_inflight(uport); port->ioctl_count--; msm_geni_serial_power_off(uport); - IPC_LOG_MSG(port->ipc_log_pwr, "%s%s ioctl %d usage_count %d\n", + usage_count = atomic_read(&uport->dev->power.usage_count); + IPC_LOG_MSG(port->ipc_log_pwr, "%s:%s ioctl:%d usage_count:%d\n", __func__, current->comm, port->ioctl_count, usage_count); return 0; }; @@ -395,7 +409,8 @@ static void msm_geni_serial_break_ctl(struct uart_port *uport, int ctl) if (!uart_console(uport) && device_pending_suspend(uport)) { IPC_LOG_MSG(port->ipc_log_misc, - "%s.Device is suspended.\n", __func__); + "%s.Device is suspended, %s\n", + __func__, current->comm); return; } @@ -418,9 +433,14 @@ static unsigned int msm_geni_serial_get_mctrl(struct uart_port *uport) { u32 geni_ios = 0; unsigned int mctrl = TIOCM_DSR | TIOCM_CAR; + struct msm_geni_serial_port *port = GET_DEV_PORT(uport); - if (device_pending_suspend(uport)) + if (!uart_console(uport) && device_pending_suspend(uport)) { + IPC_LOG_MSG(port->ipc_log_misc, + "%s.Device is suspended, %s\n", + __func__, current->comm); return TIOCM_DSR | TIOCM_CAR | TIOCM_CTS; + } geni_ios = geni_read_reg_nolog(uport->membase, SE_GENI_IOS); if (!(geni_ios & IO2_DATA_IN)) @@ -442,7 +462,8 @@ static void msm_geni_serial_set_mctrl(struct uart_port *uport, if (device_pending_suspend(uport)) { IPC_LOG_MSG(port->ipc_log_misc, - "%s.Device is suspended.\n", __func__); + "%s.Device is suspended, %s: mctrl=0x%x\n", + __func__, current->comm, mctrl); return; } if (!(mctrl & TIOCM_RTS)) { @@ -455,6 +476,10 @@ static void msm_geni_serial_set_mctrl(struct uart_port *uport, SE_UART_MANUAL_RFR); /* Write to flow control must complete before return to client*/ mb(); + IPC_LOG_MSG(port->ipc_log_misc, + "%s:%s, mctrl=0x%x, manual_rfr=0x%x, flow=%s\n", + __func__, current->comm, mctrl, uart_manual_rfr, + (port->manual_flow ? "OFF" : "ON")); } static const char *msm_geni_serial_get_type(struct uart_port *uport) @@ -884,6 +909,7 @@ static void msm_geni_serial_start_tx(struct uart_port *uport) struct msm_geni_serial_port *msm_port = GET_DEV_PORT(uport); unsigned int geni_status; unsigned int geni_ios; + static unsigned int ios_log_limit; if (!uart_console(uport) && !pm_runtime_active(uport->dev)) { IPC_LOG_MSG(msm_port->ipc_log_misc, @@ -926,9 +952,11 @@ static void msm_geni_serial_start_tx(struct uart_port *uport) return; check_flow_ctrl: geni_ios = geni_read_reg_nolog(uport->membase, SE_GENI_IOS); - if (!(geni_ios & IO2_DATA_IN)) + if (++ios_log_limit % 5 == 0) { IPC_LOG_MSG(msm_port->ipc_log_misc, "%s: ios: 0x%08x\n", - __func__, geni_ios); + __func__, geni_ios); + ios_log_limit = 0; + } exit_start_tx: if (!uart_console(uport)) msm_geni_serial_power_off(uport); @@ -1076,9 +1104,10 @@ static void start_rx_sequencer(struct uart_port *uport) * go through. */ mb(); - geni_status = geni_read_reg_nolog(uport->membase, SE_GENI_STATUS); exit_start_rx_sequencer: - IPC_LOG_MSG(port->ipc_log_misc, "%s 0x%x\n", __func__, geni_status); + geni_status = geni_read_reg_nolog(uport->membase, SE_GENI_STATUS); + IPC_LOG_MSG(port->ipc_log_misc, "%s: 0x%x, dma_dbg:0x%x\n", __func__, + geni_status, geni_read_reg(uport->membase, SE_DMA_DEBUG_REG0)); } static void msm_geni_serial_start_rx(struct uart_port *uport) @@ -1176,6 +1205,8 @@ static void stop_rx_sequencer(struct uart_port *uport) DMA_RX_BUF_SIZE); port->rx_dma = (dma_addr_t)NULL; } + geni_status = geni_read_reg_nolog(uport->membase, SE_GENI_STATUS); + IPC_LOG_MSG(port->ipc_log_misc, "%s: 0x%x\n", __func__, geni_status); } static void msm_geni_serial_stop_rx(struct uart_port *uport) @@ -1712,16 +1743,6 @@ static int msm_geni_serial_startup(struct uart_port *uport) } } - if (unlikely(get_se_proto(uport->membase) != UART)) { - dev_err(uport->dev, "%s: Invalid FW %d loaded.\n", - __func__, get_se_proto(uport->membase)); - ret = -ENXIO; - goto exit_startup; - } - IPC_LOG_MSG(msm_port->ipc_log_misc, "%s: FW Ver:0x%x%x\n", - __func__, - get_se_m_fw(uport->membase), get_se_s_fw(uport->membase)); - get_tx_fifo_size(msm_port); if (!msm_port->port_setup) { if (msm_geni_serial_port_setup(uport)) @@ -2050,6 +2071,23 @@ static ssize_t msm_geni_serial_xfer_mode_store(struct device *dev, static DEVICE_ATTR(xfer_mode, 0644, msm_geni_serial_xfer_mode_show, msm_geni_serial_xfer_mode_store); +static ssize_t ver_info_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct msm_geni_serial_port *port = platform_get_drvdata(pdev); + ssize_t ret = 0; + int len = (sizeof(struct msm_geni_serial_ver_info) * 2); + + ret = snprintf(buf, len, "FW ver=0x%x%x, HW ver=%d.%d.%d\n", + port->ver_info.m_fw_ver, port->ver_info.m_fw_ver, + port->ver_info.hw_major_ver, port->ver_info.hw_minor_ver, + port->ver_info.hw_step_ver); + + return ret; +} +static DEVICE_ATTR_RO(ver_info); + #if defined(CONFIG_SERIAL_CORE_CONSOLE) || defined(CONFIG_CONSOLE_POLL) static int __init msm_geni_console_setup(struct console *co, char *options) { @@ -2349,6 +2387,43 @@ static const struct of_device_id msm_geni_device_tbl[] = { {}, }; +static int msm_geni_serial_get_ver_info(struct uart_port *uport) +{ + int hw_ver, ret = 0; + struct msm_geni_serial_port *msm_port = GET_DEV_PORT(uport); + + se_geni_clks_on(&msm_port->serial_rsc); + /* Basic HW and FW info */ + if (unlikely(get_se_proto(uport->membase) != UART)) { + dev_err(uport->dev, "%s: Invalid FW %d loaded.\n", + __func__, get_se_proto(uport->membase)); + ret = -ENXIO; + goto exit_ver_info; + } + + msm_port->ver_info.m_fw_ver = get_se_m_fw(uport->membase); + msm_port->ver_info.s_fw_ver = get_se_s_fw(uport->membase); + IPC_LOG_MSG(msm_port->ipc_log_misc, "%s: FW Ver:0x%x%x\n", + __func__, + msm_port->ver_info.m_fw_ver, msm_port->ver_info.s_fw_ver); + + hw_ver = geni_se_qupv3_hw_version(msm_port->wrapper_dev, + &msm_port->ver_info.hw_major_ver, + &msm_port->ver_info.hw_minor_ver, + &msm_port->ver_info.hw_step_ver); + if (hw_ver) + dev_err(uport->dev, "%s:Err getting HW version %d\n", + __func__, hw_ver); + else + IPC_LOG_MSG(msm_port->ipc_log_misc, "%s: HW Ver:%x.%x.%x\n", + __func__, msm_port->ver_info.hw_major_ver, + msm_port->ver_info.hw_minor_ver, + msm_port->ver_info.hw_step_ver); +exit_ver_info: + se_geni_clks_off(&msm_port->serial_rsc); + return ret; +} + static int msm_geni_serial_probe(struct platform_device *pdev) { int ret = 0; @@ -2571,8 +2646,13 @@ static int msm_geni_serial_probe(struct platform_device *pdev) line, uport->fifosize, is_console); device_create_file(uport->dev, &dev_attr_loopback); device_create_file(uport->dev, &dev_attr_xfer_mode); + device_create_file(uport->dev, &dev_attr_ver_info); msm_geni_serial_debug_init(uport, is_console); dev_port->port_setup = false; + ret = msm_geni_serial_get_ver_info(uport); + if (ret) + goto exit_geni_serial_probe; + ret = uart_add_one_port(drv, uport); if (!ret) { if (strcmp(id->compatible, "qcom,msm-geni-console") == 0) -- GitLab From c588252255968d647b15c2db3fc054baafe2147b Mon Sep 17 00:00:00 2001 From: Kiran Gunda Date: Thu, 4 Jul 2019 16:58:09 +0530 Subject: [PATCH 1061/1121] ARM: dts: msm: add PM6150/PM6150L rpmh regulators for atoll Add regulator devices for atoll as RPMh regulators. This ensures that consumers are able to modify the physical state of PMIC regulators. Change-Id: I91442b92a6d8a4edd0e28ed40aa67cfc5926227d Signed-off-by: Kiran Gunda --- arch/arm64/boot/dts/qcom/atoll-regulator.dtsi | 838 ++++++++++++++++++ arch/arm64/boot/dts/qcom/atoll-rumi.dtsi | 2 - arch/arm64/boot/dts/qcom/atoll.dtsi | 2 +- 3 files changed, 839 insertions(+), 3 deletions(-) create mode 100644 arch/arm64/boot/dts/qcom/atoll-regulator.dtsi diff --git a/arch/arm64/boot/dts/qcom/atoll-regulator.dtsi b/arch/arm64/boot/dts/qcom/atoll-regulator.dtsi new file mode 100644 index 000000000000..133af309bfcf --- /dev/null +++ b/arch/arm64/boot/dts/qcom/atoll-regulator.dtsi @@ -0,0 +1,838 @@ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +&soc { + rpmh-regulator-cxlvl { + compatible = "qcom,rpmh-arc-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "cx.lvl"; + pm6150l-s1-level-parent-supply = <&VDD_MX_LEVEL>; + pm6150l-s1-level_ao-parent-supply = <&VDD_MX_LEVEL_AO>; + VDD_CX_LEVEL: + S1C_LEVEL: + pm6150l_s1_level: regulator-pm6150l-s1-level { + regulator-name = "pm6150l_s1_level"; + qcom,set = ; + regulator-min-microvolt = + ; + regulator-max-microvolt = + ; + qcom,init-voltage-level = + ; + qcom,min-dropout-voltage-level = <(-1)>; + }; + + VDD_CX_LEVEL_AO: + S1C_LEVEL_AO: + pm6150l_s1_level_ao: regulator-pm6150l-s1-level-ao { + regulator-name = "pm6150l_s1_level_ao"; + qcom,set = ; + regulator-min-microvolt = + ; + regulator-max-microvolt = + ; + qcom,init-voltage-level = + ; + qcom,min-dropout-voltage-level = <(-1)>; + }; + }; + + rpmh-regulator-gfxlvl { + compatible = "qcom,rpmh-arc-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "gfx.lvl"; + VDD_GFX_LEVEL: + S2A_LEVEL: + pm6150_s2_level: regulator-pm6150-s2-level { + regulator-name = "pm6150_s2_level"; + qcom,set = ; + regulator-min-microvolt = + ; + regulator-max-microvolt = + ; + qcom,init-voltage-level = + ; + }; + }; + + rpmh-regulator-mxlvl { + compatible = "qcom,rpmh-arc-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "mx.lvl"; + VDD_MX_LEVEL: + S3A_LEVEL: + pm6150_s3_level: regulator-pm6150-s3-level { + regulator-name = "pm6150_s3_level"; + qcom,set = ; + regulator-min-microvolt = + ; + regulator-max-microvolt = + ; + qcom,init-voltage-level = + ; + }; + + VDD_MX_LEVEL_AO: + S3A_LEVEL_AO: + pm6150_s3_level_ao: regulator-pm6150-s3-level-ao { + regulator-name = "pm6150_s3_level_ao"; + qcom,set = ; + regulator-min-microvolt = + ; + regulator-max-microvolt = + ; + qcom,init-voltage-level = + ; + }; + }; + + rpmh-regulator-smpa1 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "smpa1"; + S1A: + pm6150_s1: regulator-pm6150-s1 { + regulator-name = "pm6150_s1"; + qcom,set = ; + regulator-min-microvolt = <1128000>; + regulator-max-microvolt = <1128000>; + qcom,init-voltage = <1128000>; + }; + }; + + rpmh-regulator-smpa4 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "smpa4"; + S4A: + pm6150_s4: regulator-pm6150-s4 { + regulator-name = "pm6150_s4"; + qcom,set = ; + regulator-min-microvolt = <824000>; + regulator-max-microvolt = <1120000>; + qcom,init-voltage = <824000>; + }; + }; + + rpmh-regulator-smpa5 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "smpa5"; + S5A: + pm6150_s5: regulator-pm6150-s5 { + regulator-name = "pm6150_s5"; + qcom,set = ; + regulator-min-microvolt = <1744000>; + regulator-max-microvolt = <2040000>; + qcom,init-voltage = <1744000>; + }; + }; + + rpmh-regulator-ldoa1 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoa1"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L1A: + pm6150_l1: regulator-pm6150-l1 { + regulator-name = "pm6150_l1"; + qcom,set = ; + regulator-min-microvolt = <1178000>; + regulator-max-microvolt = <1256000>; + qcom,init-voltage = <1178000>; + qcom,init-mode = + ; + }; + }; + + rpmh-regulator-ldoa2 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoa2"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L2A: + pm6150_l2: regulator-pm6150-l2 { + regulator-name = "pm6150_l2"; + qcom,set = ; + regulator-min-microvolt = <944000>; + regulator-max-microvolt = <1056000>; + qcom,init-voltage = <944000>; + qcom,init-mode = + ; + }; + }; + + rpmh-regulator-ldoa3 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoa3"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L3A: + pm6150_l3: regulator-pm6150-l3 { + regulator-name = "pm6150_l3"; + qcom,set = ; + regulator-min-microvolt = <968000>; + regulator-max-microvolt = <1064000>; + qcom,init-voltage = <968000>; + qcom,init-mode = + ; + }; + }; + + rpmh-regulator-ldoa4 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoa4"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L4A: + pm6150_l4: regulator-pm6150-l4 { + regulator-name = "pm6150_l4"; + qcom,set = ; + regulator-min-microvolt = <824000>; + regulator-max-microvolt = <928000>; + qcom,init-voltage = <824000>; + qcom,init-mode = + ; + }; + }; + + rpmh-regulator-ldoa5 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoa5"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L5A: + pm6150_l5: regulator-pm6150-l5 { + regulator-name = "pm6150_l5"; + qcom,set = ; + regulator-min-microvolt = <2496000>; + regulator-max-microvolt = <3000000>; + qcom,init-voltage = <2496000>; + qcom,init-mode = + ; + }; + }; + + rpmh-regulator-ldoa6 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoa6"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L6A: + pm6150_l6: regulator-pm6150-l6 { + regulator-name = "pm6150_l6"; + qcom,set = ; + regulator-min-microvolt = <568000>; + regulator-max-microvolt = <648000>; + qcom,init-voltage = <568000>; + qcom,init-mode = + ; + }; + }; + + rpmh-regulator-lmxlvl { + compatible = "qcom,rpmh-arc-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "lmx.lvl"; + L7A_LEVEL: + pm6150_l7_level: regulator-pm6150-l7-level { + regulator-name = "pm6150_l7_level"; + qcom,set = ; + regulator-min-microvolt = + ; + regulator-max-microvolt = + ; + qcom,init-voltage-level = + ; + }; + }; + + rpmh-regulator-lcxlvl { + compatible = "qcom,rpmh-arc-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "lcx.lvl"; + L8A_LEVEL: + pm6150_l8_level: regulator-pm6150-l8-level { + regulator-name = "pm6150_l8_level"; + qcom,set = ; + regulator-min-microvolt = + ; + regulator-max-microvolt = + ; + qcom,init-voltage-level = + ; + }; + }; + + rpmh-regulator-ldoa9 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoa9"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L9A: + pm6150_l9: regulator-pm6150-l9 { + regulator-name = "pm6150_l9"; + qcom,set = ; + regulator-min-microvolt = <488000>; + regulator-max-microvolt = <800000>; + qcom,init-voltage = <488000>; + qcom,init-mode = + ; + }; + }; + + rpmh-regulator-ldoa10 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoa10"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L10A: + pm6150_l10: regulator-pm6150-l10 { + regulator-name = "pm6150_l10"; + qcom,set = ; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1832000>; + qcom,init-voltage = <1800000>; + qcom,init-mode = + ; + }; + }; + + rpmh-regulator-ldoa11 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoa11"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L11A: + pm6150_l11: regulator-pm6150-l11 { + regulator-name = "pm6150_l11"; + qcom,set = ; + regulator-min-microvolt = <1696000>; + regulator-max-microvolt = <1904000>; + qcom,init-voltage = <1696000>; + qcom,init-mode = + ; + }; + }; + + rpmh-regulator-ldoa12 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoa12"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L12A: + pm6150_l12: regulator-pm6150-l12 { + regulator-name = "pm6150_l12"; + qcom,set = ; + regulator-min-microvolt = <1696000>; + regulator-max-microvolt = <1952000>; + qcom,init-voltage = <1696000>; + qcom,init-mode = + ; + }; + }; + + rpmh-regulator-ldoa13 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoa13"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L13A: + pm6150_l13: regulator-pm6150-l13 { + regulator-name = "pm6150_l13"; + qcom,set = ; + regulator-min-microvolt = <1696000>; + regulator-max-microvolt = <1904000>; + qcom,init-voltage = <1696000>; + qcom,init-mode = + ; + }; + }; + + rpmh-regulator-ldoa14 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoa14"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L14A: + pm6150_l14: regulator-pm6150-l14 { + regulator-name = "pm6150_l14"; + qcom,set = ; + regulator-min-microvolt = <1728000>; + regulator-max-microvolt = <1832000>; + qcom,init-voltage = <1728000>; + qcom,init-mode = + ; + }; + }; + + rpmh-regulator-ldoa15 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoa15"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L15A: + pm6150_l15: regulator-pm6150-l15 { + regulator-name = "pm6150_l15"; + qcom,set = ; + regulator-min-microvolt = <1696000>; + regulator-max-microvolt = <1904000>; + qcom,init-voltage = <1696000>; + qcom,init-mode = + ; + }; + }; + + rpmh-regulator-ldoa16 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoa16"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L16A: + pm6150_l16: regulator-pm6150-l16 { + regulator-name = "pm6150_l16"; + qcom,set = ; + regulator-min-microvolt = <2496000>; + regulator-max-microvolt = <3304000>; + qcom,init-voltage = <2496000>; + qcom,init-mode = + ; + }; + }; + + rpmh-regulator-ldoa17 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoa17"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L17A: + pm6150_l17: regulator-pm6150-l17 { + regulator-name = "pm6150_l17"; + qcom,set = ; + regulator-min-microvolt = <2920000>; + regulator-max-microvolt = <3232000>; + qcom,init-voltage = <2920000>; + qcom,init-mode = + ; + }; + }; + + rpmh-regulator-ldoa18 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoa18"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L18A: + pm6150_l18: regulator-pm6150-l18 { + regulator-name = "pm6150_l18"; + qcom,set = ; + regulator-min-microvolt = <2496000>; + regulator-max-microvolt = <3304000>; + qcom,init-voltage = <2496000>; + qcom,init-mode = + ; + }; + }; + + rpmh-regulator-ldoa19 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoa19"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L19A: + pm6150_l19: regulator-pm6150-l19 { + regulator-name = "pm6150_l19"; + qcom,set = ; + regulator-min-microvolt = <2696000>; + regulator-max-microvolt = <3304000>; + qcom,init-voltage = <2696000>; + qcom,init-mode = + ; + }; + }; + + rpmh-regulator-msslvl { + compatible = "qcom,rpmh-arc-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "mss.lvl"; + VDD_MSS_LEVEL: + S7C_LEVEL: + pm6150l_s7_level: regulator-pm6150l-s7-level { + regulator-name = "pm6150l_s7_level"; + qcom,set = ; + regulator-min-microvolt = + ; + regulator-max-microvolt = + ; + qcom,init-voltage-level = + ; + }; + }; + + rpmh-regulator-smpc8 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "smpc8"; + S8C: + pm6150l_s8: regulator-pm6150l-s8 { + regulator-name = "pm6150l_s8"; + qcom,set = ; + regulator-min-microvolt = <1120000>; + regulator-max-microvolt = <1408000>; + qcom,init-voltage = <1120000>; + }; + }; + + rpmh-regulator-ldoc1 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoc1"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L1C: + pm6150l_l1: regulator-pm6150l-l1 { + regulator-name = "pm6150l_l1"; + qcom,set = ; + regulator-min-microvolt = <1616000>; + regulator-max-microvolt = <1984000>; + qcom,init-voltage = <1616000>; + qcom,init-mode = + ; + }; + }; + + rpmh-regulator-ldoc2 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoc2"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L2C: + pm6150l_l2: regulator-pm6150l-l2 { + regulator-name = "pm6150l_l2"; + qcom,set = ; + regulator-min-microvolt = <1168000>; + regulator-max-microvolt = <1304000>; + qcom,init-voltage = <1168000>; + qcom,init-mode = + ; + }; + }; + + rpmh-regulator-ldoc3 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoc3"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L3C: + pm6150l_l3: regulator-pm6150l-l3 { + regulator-name = "pm6150l_l3"; + qcom,set = ; + regulator-min-microvolt = <1144000>; + regulator-max-microvolt = <1304000>; + qcom,init-voltage = <1144000>; + qcom,init-mode = + ; + }; + }; + + rpmh-regulator-ldoc4 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoc4"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L4C: + pm6150l_l4: regulator-pm6150l-l4 { + regulator-name = "pm6150l_l4"; + qcom,set = ; + regulator-min-microvolt = <1648000>; + regulator-max-microvolt = <3304000>; + qcom,init-voltage = <1648000>; + qcom,init-mode = + ; + }; + }; + + rpmh-regulator-ldoc5 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoc5"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L5C: + pm6150l_l5: regulator-pm6150l-l5 { + regulator-name = "pm6150l_l5"; + qcom,set = ; + regulator-min-microvolt = <1648000>; + regulator-max-microvolt = <3304000>; + qcom,init-voltage = <1648000>; + qcom,init-mode = + ; + }; + }; + + rpmh-regulator-ldoc6 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoc6"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L6C: + pm6150l_l6: regulator-pm6150l-l6 { + regulator-name = "pm6150l_l6"; + qcom,set = ; + regulator-min-microvolt = <2696000>; + regulator-max-microvolt = <3304000>; + qcom,init-voltage = <2696000>; + qcom,init-mode = + ; + }; + }; + + rpmh-regulator-ldoc7 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoc7"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L7C: + pm6150l_l7: regulator-pm6150l-l7 { + regulator-name = "pm6150l_l7"; + qcom,set = ; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3312000>; + qcom,init-voltage = <3000000>; + qcom,init-mode = + ; + }; + }; + + rpmh-regulator-ldoc8 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoc8"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L8C: + pm6150l_l8: regulator-pm6150l-l8 { + regulator-name = "pm6150l_l8"; + qcom,set = ; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1904000>; + qcom,init-voltage = <1800000>; + qcom,init-mode = + ; + }; + }; + + rpmh-regulator-ldoc9 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoc9"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L9C: + pm6150l_l9: regulator-pm6150l-l9 { + regulator-name = "pm6150l_l9"; + qcom,set = ; + regulator-min-microvolt = <2952000>; + regulator-max-microvolt = <3304000>; + qcom,init-voltage = <2952000>; + qcom,init-mode = + ; + }; + }; + + rpmh-regulator-ldoc10 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoc10"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L10C: + pm6150l_l10: regulator-pm6150l-l10 { + regulator-name = "pm6150l_l10"; + qcom,set = ; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3400000>; + qcom,init-voltage = <3000000>; + qcom,init-mode = + ; + }; + }; + + rpmh-regulator-ldoc11 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "ldoc11"; + qcom,regulator-type = "pmic5-ldo"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + L11C: + pm6150l_l11: regulator-pm6150l-l11 { + regulator-name = "pm6150l_l11"; + qcom,set = ; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3400000>; + qcom,init-voltage = <3000000>; + qcom,init-mode = + ; + }; + }; + + rpmh-regulator-bobc1 { + compatible = "qcom,rpmh-vrm-regulator"; + mboxes = <&apps_rsc 0>; + qcom,resource-name = "bobc1"; + qcom,regulator-type = "pmic5-bob"; + qcom,supported-modes = + ; + qcom,mode-threshold-currents = <0 1>; + qcom,send-defaults; + BOB: + pm6150l_bob: regulator-pm6150l-bob { + regulator-name = "pm6150l_bob"; + qcom,set = ; + regulator-min-microvolt = <3008000>; + regulator-max-microvolt = <3960000>; + qcom,init-voltage = <3008000>; + qcom,init-mode = + ; + }; + + BOB_AO: + pm6150l_bob_ao: regulator-pm6150l-bob_ao { + regulator-name = "pm6150l_bob_ao"; + qcom,set = ; + regulator-min-microvolt = <3008000>; + regulator-max-microvolt = <3960000>; + qcom,init-voltage = <3008000>; + qcom,init-mode = + ; + }; + }; + + refgen: refgen-regulator@88e7000 { + compatible = "qcom,refgen-regulator"; + reg = <0x88e7000 0x60>; + regulator-name = "refgen"; + regulator-enable-ramp-delay = <5>; + proxy-supply = <&refgen>; + qcom,proxy-consumer-enable; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/atoll-rumi.dtsi b/arch/arm64/boot/dts/qcom/atoll-rumi.dtsi index 1d0c58235836..bd99744a8040 100644 --- a/arch/arm64/boot/dts/qcom/atoll-rumi.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll-rumi.dtsi @@ -53,8 +53,6 @@ }; }; -#include "atoll-stub-regulator.dtsi" - &sdhc_1 { vdd-supply = <&pm6150_l19>; qcom,vdd-voltage-level = <2950000 2950000>; diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index ad5db7e0d42d..0814da5e6d82 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -2429,7 +2429,7 @@ #include "atoll-pinctrl.dtsi" #include "atoll-pm.dtsi" #include "atoll-coresight.dtsi" -#include "atoll-stub-regulator.dtsi" +#include "atoll-regulator.dtsi" #include "atoll-usb.dtsi" #include "atoll-vidc.dtsi" -- GitLab From 5449a6c9c587eb00bef8078af92f6a2546706855 Mon Sep 17 00:00:00 2001 From: Kiran Gunda Date: Thu, 11 Jul 2019 20:20:49 +0530 Subject: [PATCH 1062/1121] ARM: dts: msm: Add pm8008 support for atoll Add pm8008 peripherals and regulators for atoll. Also add the required configuration to enable the pm8008. Change-Id: I7640cbb1a67cb13ad3ef8cb6b705f5a0c0b443eb Signed-off-by: Kiran Gunda --- arch/arm64/boot/dts/qcom/atoll-rumi.dtsi | 4 ++ arch/arm64/boot/dts/qcom/atoll.dtsi | 86 ++++++++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/atoll-rumi.dtsi b/arch/arm64/boot/dts/qcom/atoll-rumi.dtsi index bd99744a8040..dddba5043f51 100644 --- a/arch/arm64/boot/dts/qcom/atoll-rumi.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll-rumi.dtsi @@ -140,3 +140,7 @@ maximum-speed = "high-speed"; }; }; + +&qupv3_se9_i2c { + status = "disabled"; +}; diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index 0814da5e6d82..4e44a9d90904 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -2590,3 +2590,89 @@ }; #include "atoll-thermal.dtsi" + + +&qupv3_se9_i2c { + status = "ok"; + #include "pm8008.dtsi" +}; + +&tlmm { + pm8008_active: pm8008_active { + mux { + pins = "gpio42"; + function = "gpio"; + }; + + config { + pins = "gpio42"; + bias-pull-up; + output-high; + drive-strength = <2>; + }; + }; +}; + +&pm8008_gpios { + gpio1_active { + pm8008_gpio1_active: pm8008_gpio1_active { + pins = "gpio1"; + function = "normal"; + power-source = <1>; + bias-disable; + input-enable; + }; + }; +}; + +&pm8008_chip { + pinctrl-names = "default"; + pinctrl-0 = <&pm8008_active>; +}; + +&pm8008_regulators { + vdd_l1_l2-supply = <&S8C>; + vdd_l3_l4-supply = <&BOB>; + vdd_l5-supply = <&S5A>; + vdd_l6-supply = <&BOB>; + vdd_l7-supply = <&BOB>; +}; + +&pm8008_9 { + /* GPIO1 pinctrl config */ + pinctrl-names = "default"; + pinctrl-0 = <&pm8008_gpio1_active>; +}; + +&L1P { + regulator-max-microvolt = <1104000>; + qcom,min-dropout-voltage = <225000>; +}; + +&L2P { + regulator-max-microvolt = <1200000>; + qcom,min-dropout-voltage = <75000>; +}; + +&L3P { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + qcom,min-dropout-voltage = <200000>; +}; + +&L4P { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + qcom,min-dropout-voltage = <200000>; +}; + +&L5P { + regulator-max-microvolt = <1800000>; + qcom,min-dropout-voltage = <200000>; +}; + +&L6P { + regulator-max-microvolt = <2800000>; + qcom,min-dropout-voltage = <300000>; +}; + -- GitLab From 5c76adbbff750555a0669c8fb48c9270c198517b Mon Sep 17 00:00:00 2001 From: Mayank Grover Date: Mon, 29 Jul 2019 12:17:01 +0530 Subject: [PATCH 1063/1121] drivers: soc: qcom: Update atoll SCT entry for modem SS Update atoll sct entry for modem Subsystem, to make it align with recommendation from hardware team. Change-Id: I3396bc49c4a2af5caf5abca998ab407883af05a3 Signed-off-by: Mayank Grover --- drivers/soc/qcom/llcc-atoll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/soc/qcom/llcc-atoll.c b/drivers/soc/qcom/llcc-atoll.c index b4be7589692c..a57b70ea3631 100644 --- a/drivers/soc/qcom/llcc-atoll.c +++ b/drivers/soc/qcom/llcc-atoll.c @@ -58,7 +58,7 @@ static struct llcc_slice_config atoll_data[] = { SCT_ENTRY("cpuss", 1, 1, 256, 1, 0, 0xF, 0x0, 0, 0, 0, 1, 1), - SCT_ENTRY("modem", 8, 8, 256, 0, 0, 0xF, 0x0, 0, 0, 0, 1, 0), + SCT_ENTRY("modem", 8, 8, 128, 1, 0, 0xF, 0x0, 0, 0, 0, 1, 0), SCT_ENTRY("gpuhtw", 11, 11, 128, 1, 0, 0xF, 0x0, 0, 0, 0, 1, 0), SCT_ENTRY("gpu", 12, 12, 128, 1, 0, 0xF, 0x0, 0, 0, 0, 1, 0), }; -- GitLab From 1cfb7c3f89e7809764776a290d2c3b4a1badd65b Mon Sep 17 00:00:00 2001 From: Deepak Kumar Date: Fri, 12 Jul 2019 12:28:55 +0530 Subject: [PATCH 1064/1121] msm: kgsl: Don't deassert GBIF halt before GPU gdsc goes off During adreno_stop, GBIF halt is asserted to halt any new transaction from GPU before GPU power collapse but in current code it was cleared immediately which can allow few GPU transactions to go through before gdsc is turned-off and can result in issues. To avoid this situation don't deassert this halt before GPU gdsc goes off. It will deassert automatically when gdsc goes off but in case gdsc doesn't toggle as its a shared resource deassert this during adreno_start to ensure wake-up doesn't fail. Change-Id: If0a892470d04a0f3a79a1ea882ee5bfd16ad24ed Signed-off-by: Deepak Kumar --- drivers/gpu/msm/adreno.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index e30933ce93e6..ed786b318dae 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -1954,6 +1954,17 @@ static int _adreno_start(struct adreno_device *adreno_dev) if (regulator_left_on) _soft_reset(adreno_dev); + /* + * During adreno_stop, GBIF halt is asserted to ensure + * no further transaction can go through GPU before GPU + * headswitch is turned off. + * + * This halt is deasserted once headswitch goes off but + * incase headswitch doesn't goes off clear GBIF halt + * here to ensure GPU wake-up doesn't fail because of + * halted GPU transactions. + */ + adreno_deassert_gbif_halt(adreno_dev); if (adreno_is_a640v1(adreno_dev)) { ret = adreno_program_smmu_aperture(device); @@ -2312,8 +2323,15 @@ static int adreno_stop(struct kgsl_device *device) adreno_clear_pending_transactions(device); - /* The halt is not cleared in the above function if we have GBIF */ - adreno_deassert_gbif_halt(adreno_dev); + /* + * The halt is not cleared in the above function if we have GBIF. + * Clear it here if GMU is enabled as GMU stop needs access to + * system memory to stop. For non-GMU targets, we don't need to + * clear it as it will get cleared automatically once headswitch + * goes OFF immediately after adreno_stop. + */ + if (gmu_core_gpmu_isenabled(device)) + adreno_deassert_gbif_halt(adreno_dev); kgsl_mmu_stop(&device->mmu); -- GitLab From f3966d24ef007c0ac4113416b92f19e122743f65 Mon Sep 17 00:00:00 2001 From: Prudhvi Yarlagadda Date: Thu, 18 Jul 2019 15:26:25 +0530 Subject: [PATCH 1065/1121] ARM: dts: msm: Add slimbus instance for ATOLL Add the SLIMBus instance that is used to enable BT/FM functionality. Change-Id: Ic38d6a8361cf8233efeae7ceacba4a6fe5e49271 Signed-off-by: Prudhvi Yarlagadda --- arch/arm64/boot/dts/qcom/atoll.dtsi | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index ef8f9ebafa09..b80cecea06c6 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -2242,6 +2242,28 @@ qcom,firmware-name = "venus"; memory-region = <&pil_video_mem>; }; + + slim_aud: slim@62ec0000 { + cell-index = <1>; + compatible = "qcom,slim-ngd"; + reg = <0x62ec0000 0x2c000>, + <0x62e84000 0x2a000>; + reg-names = "slimbus_physical", "slimbus_bam_physical"; + interrupts = , + ; + interrupt-names = "slimbus_irq", "slimbus_bam_irq"; + qcom,apps-ch-pipes = <0x700000>; + qcom,ea-pc = <0x340>; + qcom,iommu-s1-bypass; + status = "ok"; + + iommu_slim_aud_ctrl_cb: qcom,iommu_slim_ctrl_cb { + compatible = "qcom,iommu-slim-ctrl-cb"; + iommus = <&apps_smmu 0x1026 0x0>, + <&apps_smmu 0x102f 0x0>, + <&apps_smmu 0x1030 0x1>; + }; + }; }; #include "atoll-gdsc.dtsi" -- GitLab From 568641fbf611a8115c63ec6f4174a1f849813387 Mon Sep 17 00:00:00 2001 From: Chandana Kishori Chiluveru Date: Thu, 25 Jul 2019 14:15:40 +0530 Subject: [PATCH 1066/1121] ARM: dts: msm: Remove extcon and PHY nodes on atoll RUMI This change will remove extcon handle from atoll base dtsi file, add extcon handle to corresponding IDP file. Also disable unused dtsi nodes from atoll rumi dtsi file. Change-Id: I1df92fd89000a7929aeb6fef36a89c6582333448 Signed-off-by: Chandana Kishori Chiluveru --- arch/arm64/boot/dts/qcom/atoll-idp.dtsi | 8 ++++++++ arch/arm64/boot/dts/qcom/atoll-rumi.dtsi | 15 +++++++++++++++ arch/arm64/boot/dts/qcom/atoll.dtsi | 8 -------- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/atoll-idp.dtsi b/arch/arm64/boot/dts/qcom/atoll-idp.dtsi index a9c5ba4e4177..a2bfa96448c0 100644 --- a/arch/arm64/boot/dts/qcom/atoll-idp.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll-idp.dtsi @@ -57,6 +57,14 @@ }; }; +&usb0 { + extcon = <&pm6150_pdphy>, <&pm6150_charger>; +}; + +&usb_qmp_dp_phy { + extcon = <&pm6150_pdphy>; +}; + &spmi_bus { qcom,pm6150l@4 { pm6150l_adc_tm_iio: adc_tm@3400 { diff --git a/arch/arm64/boot/dts/qcom/atoll-rumi.dtsi b/arch/arm64/boot/dts/qcom/atoll-rumi.dtsi index 1d0c58235836..81178c60bb70 100644 --- a/arch/arm64/boot/dts/qcom/atoll-rumi.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll-rumi.dtsi @@ -141,4 +141,19 @@ usb-phy = <&usb_emu_phy>, <&usb_nop_phy>; maximum-speed = "high-speed"; }; + qcom,usbbam@a704000 { + status = "disabled"; + }; +}; + +&qusb_phy0 { + status = "disabled"; +}; + +&usb_qmp_dp_phy { + status = "disabled"; +}; + +&pm6150_pdphy { + status = "disabled"; }; diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index ad5db7e0d42d..31cc1e97b74d 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -2433,14 +2433,6 @@ #include "atoll-usb.dtsi" #include "atoll-vidc.dtsi" -&usb0 { - extcon = <&pm6150_pdphy>, <&pm6150_charger>; -}; - -&usb_qmp_dp_phy { - extcon = <&pm6150_pdphy>; -}; - &pm6150_vadc { pinctrl-names = "default"; pinctrl-0 = <&nvm_therm_default &sdm_skin_therm_default>; -- GitLab From 0d17cada912537fd02cdd6e154d1106d3e7c72bf Mon Sep 17 00:00:00 2001 From: Amit Blay Date: Mon, 29 Jul 2019 08:19:03 +0300 Subject: [PATCH 1067/1121] soc: qcom: scm_qcpe: Add tolerance to HAB failures 1) Don't execute SCM over HAB if HAB channel is yet to be opened. 2) Allow is_scm_armv8() function to retry in case of an HAB related error. Change-Id: I42c5cfe836ecb57921f101ce6ff2ab6bd2203686 Signed-off-by: Amit Blay --- drivers/soc/qcom/scm_qcpe.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/drivers/soc/qcom/scm_qcpe.c b/drivers/soc/qcom/scm_qcpe.c index 4ae30c0559eb..fef882816b10 100644 --- a/drivers/soc/qcom/scm_qcpe.c +++ b/drivers/soc/qcom/scm_qcpe.c @@ -239,6 +239,18 @@ static int scm_call_qcpe(u32 fn_id, struct scm_desc *desc, bool atomic) fn_id, desc->arginfo, desc->args[0], desc->args[1], desc->args[2], desc->args[3], desc->x5); + if (!opened) { + if (!atomic) { + if (scm_qcpe_hab_open()) { + pr_err("HAB channel re-open failed\n"); + return -ENODEV; + } + } else { + pr_err("HAB channel is not opened\n"); + return -ENODEV; + } + } + smc_params.fn_id = fn_id | scm_version_mask; smc_params.arginfo = desc->arginfo; smc_params.args[0] = desc->args[0]; @@ -324,6 +336,8 @@ bool is_scm_armv8(void) { int ret; u64 ret1, x0; + bool ret_scm_version; + bool save_scm_version; struct scm_desc desc = {0}; @@ -346,6 +360,7 @@ bool is_scm_armv8(void) desc.args[0] = x0; ret = scm_call_qcpe(x0 | SMC64_MASK, &desc, true); + save_scm_version = (ret == -ENODEV) ? false : true; ret1 = desc.ret[0]; @@ -357,6 +372,7 @@ bool is_scm_armv8(void) desc.args[0] = x0; ret = scm_call_qcpe(x0, &desc, true); + save_scm_version = (ret == -ENODEV) ? false : true; if (ret || !ret1) scm_version = SCM_LEGACY; @@ -368,8 +384,15 @@ bool is_scm_armv8(void) pr_debug("scm_call: scm version is %x, mask is %x\n", scm_version, scm_version_mask); - return (scm_version == SCM_ARMV8_32) || + ret_scm_version = (scm_version == SCM_ARMV8_32) || (scm_version == SCM_ARMV8_64); + + /* Don't cache the scm_version in case error is due to hab issues. */ + /* In this case, allow a later retry. */ + if (!save_scm_version) + scm_version = SCM_UNKNOWN; + + return ret_scm_version; } /* -- GitLab From 125650f4662ae2391c9d4f107519e6400c340427 Mon Sep 17 00:00:00 2001 From: Chandana Kishori Chiluveru Date: Wed, 24 Jul 2019 15:01:20 +0530 Subject: [PATCH 1068/1121] usb: phy: snps: Turn off CXO clock from msm_hsphy_dpdm_regulator_enable dpdm_regulator_enable() function turn on the CXO clk to program the phy registers to put PHY in non-driving mode for charger detection. In charger connected case phy driver voting for CXO clock in dpdm_regulator_enable but does not disabling it which is preventing the system from vdd minimization. Hence fix this issue by turning off the CXO clk from dpdm_regulator_enable. Change-Id: Ib3a04eedcef625443077199d5920884f114db82d Signed-off-by: Chandana Kishori Chiluveru --- drivers/usb/phy/phy-msm-snps-hs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/phy/phy-msm-snps-hs.c b/drivers/usb/phy/phy-msm-snps-hs.c index e5dc7e47f744..5fdb47b35e1b 100644 --- a/drivers/usb/phy/phy-msm-snps-hs.c +++ b/drivers/usb/phy/phy-msm-snps-hs.c @@ -594,6 +594,7 @@ static int msm_hsphy_dpdm_regulator_enable(struct regulator_dev *rdev) UTMI_PHY_DATAPATH_CTRL_OVERRIDE_EN, UTMI_PHY_DATAPATH_CTRL_OVERRIDE_EN); + msm_hsphy_enable_clocks(phy, false); phy->dpdm_enable = true; } mutex_unlock(&phy->phy_lock); @@ -612,7 +613,6 @@ static int msm_hsphy_dpdm_regulator_disable(struct regulator_dev *rdev) mutex_lock(&phy->phy_lock); if (phy->dpdm_enable) { if (!phy->cable_connected) { - msm_hsphy_enable_clocks(phy, false); ret = msm_hsphy_enable_power(phy, false); if (ret < 0) { mutex_unlock(&phy->phy_lock); -- GitLab From a1b7d2769edb07721e664b9bae863217a7cca7df Mon Sep 17 00:00:00 2001 From: Abir Ghosh Date: Mon, 29 Jul 2019 13:40:29 +0530 Subject: [PATCH 1069/1121] qbt: Add ioctls to acquire and release wakelock Add new ioctls to acquire and release kernel wakelock. Change-Id: I181bec508eccc6ad388d684d05c9719885992e82 Signed-off-by: Abir Ghosh --- drivers/soc/qcom/qbt1000.c | 28 +++++++++++++++++++++++++++- include/uapi/linux/qbt1000.h | 2 ++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/drivers/soc/qcom/qbt1000.c b/drivers/soc/qcom/qbt1000.c index 84ec2e05ed74..fdd20f3ca5ac 100644 --- a/drivers/soc/qcom/qbt1000.c +++ b/drivers/soc/qcom/qbt1000.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -117,6 +117,7 @@ struct qbt1000_drvdata { enum fd_indication_mode fd_ind_mode; bool ipc_is_stale; bool gestures_enabled; + atomic_t wakelock_acquired; }; /* @@ -311,6 +312,11 @@ static int qbt1000_release(struct inode *inode, struct file *file) } drvdata = file->private_data; atomic_inc(&drvdata->available); + if (atomic_read(&drvdata->wakelock_acquired) != 0) { + pr_debug("Releasing wakelock\n"); + pm_relax(drvdata->dev); + atomic_set(&drvdata->wakelock_acquired, 0); + } return 0; } @@ -589,6 +595,25 @@ static long qbt1000_ioctl( } break; } + case QBT1000_ACQUIRE_WAKELOCK: + { + if (atomic_read(&drvdata->wakelock_acquired) == 0) { + pr_debug("Acquiring wakelock\n"); + pm_stay_awake(drvdata->dev); + } + atomic_inc(&drvdata->wakelock_acquired); + break; + } + case QBT1000_RELEASE_WAKELOCK: + { + if (atomic_read(&drvdata->wakelock_acquired) == 0) + break; + if (atomic_dec_and_test(&drvdata->wakelock_acquired)) { + pr_debug("Releasing wakelock\n"); + pm_relax(drvdata->dev); + } + break; + } default: pr_err("invalid cmd %d\n", cmd); rc = -ENOIOCTLCMD; @@ -1234,6 +1259,7 @@ static int qbt1000_probe(struct platform_device *pdev) goto end; atomic_set(&drvdata->available, 1); + atomic_set(&drvdata->wakelock_acquired, 0); mutex_init(&drvdata->mutex); mutex_init(&drvdata->fw_events_mutex); diff --git a/include/uapi/linux/qbt1000.h b/include/uapi/linux/qbt1000.h index 0012d23029ce..41c6a0bfcbbb 100644 --- a/include/uapi/linux/qbt1000.h +++ b/include/uapi/linux/qbt1000.h @@ -21,6 +21,8 @@ enum qbt1000_commands { QBT1000_CONFIGURE_POWER_KEY = 104 }; #define QBT1000_ENABLE_GESTURES 105 +#define QBT1000_ACQUIRE_WAKELOCK 106 +#define QBT1000_RELEASE_WAKELOCK 107 /* * enum qbt1000_fw_event - -- GitLab From 2bcfdc6d71886e0a8b01e57ae8c3752567941c3e Mon Sep 17 00:00:00 2001 From: Mitul Golani Date: Thu, 4 Jul 2019 12:40:28 +0530 Subject: [PATCH 1070/1121] defconfig: msm: Decide UART sampling rate based on config As earlycon can't have QUP HW version awareness, decision for UART sampling rate is taken based on the configuration. Change-Id: I2a8674752bcd360e47a90c3c718d4bede7af0dc4 Signed-off-by: Mitul Golani --- arch/arm64/configs/vendor/atoll-perf_defconfig | 1 + arch/arm64/configs/vendor/atoll_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm64/configs/vendor/atoll-perf_defconfig b/arch/arm64/configs/vendor/atoll-perf_defconfig index 3257015246d7..4b240fe2948f 100644 --- a/arch/arm64/configs/vendor/atoll-perf_defconfig +++ b/arch/arm64/configs/vendor/atoll-perf_defconfig @@ -325,6 +325,7 @@ CONFIG_INPUT_UINPUT=y # CONFIG_LEGACY_PTYS is not set # CONFIG_DEVMEM is not set CONFIG_SERIAL_MSM_GENI=y +CONFIG_SERIAL_MSM_WITH_HALF_SAMPLING=y CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM_MSM_LEGACY=y # CONFIG_DEVPORT is not set diff --git a/arch/arm64/configs/vendor/atoll_defconfig b/arch/arm64/configs/vendor/atoll_defconfig index d7694e7d1d38..e7fc3309f422 100644 --- a/arch/arm64/configs/vendor/atoll_defconfig +++ b/arch/arm64/configs/vendor/atoll_defconfig @@ -344,6 +344,7 @@ CONFIG_INPUT_UINPUT=y # CONFIG_DEVMEM is not set CONFIG_SERIAL_MSM_GENI=y CONFIG_SERIAL_MSM_GENI_CONSOLE=y +CONFIG_SERIAL_MSM_WITH_HALF_SAMPLING=y CONFIG_SERIAL_DEV_BUS=y CONFIG_TTY_PRINTK=y CONFIG_HW_RANDOM=y -- GitLab From d9a61a682d92facc5c1757ee35e5e3b2a82ec727 Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Wed, 17 Jul 2019 16:35:43 -0700 Subject: [PATCH 1071/1121] drivers: soc: qcom: Enable the virtual subsystem notification driver Enable compilation for the virtual subsystem notification driver which supports communicating subsystem state across VMs. Change-Id: I736b6d8407fc25a3ca81872c24e5d19c3884aa20 Signed-off-by: Anant Goel --- drivers/soc/qcom/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index 30df5ddfca4a..951f4e541e58 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -70,6 +70,7 @@ ifdef CONFIG_MSM_SUBSYSTEM_RESTART obj-y += subsystem_restart.o obj-y += ramdump.o obj-y += microdump_collector.o + obj-$(CONFIG_QTI_GVM_QUIN) += subsystem_notif_virt.o endif obj-$(CONFIG_QCOM_EUD) += eud.o obj-$(CONFIG_QSEE_IPC_IRQ) += qsee_ipc_irq.o -- GitLab From 4c174449e34e27ace78c2c26347e7642821b3640 Mon Sep 17 00:00:00 2001 From: Anant Goel Date: Wed, 29 May 2019 11:29:03 -0700 Subject: [PATCH 1072/1121] ARM: dts: msm: Update compatible string for SCC on the SA 8195 target Update the compatible string for the SSC clock controller to align it with the SA 8195 target requirements. Change-Id: I5713f9fdc286d576f74cd124ac11d9181afa9c58 Signed-off-by: Anant Goel --- arch/arm64/boot/dts/qcom/sa8195p.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sa8195p.dtsi b/arch/arm64/boot/dts/qcom/sa8195p.dtsi index 318d8a5e00a7..6fae09a904b5 100644 --- a/arch/arm64/boot/dts/qcom/sa8195p.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8195p.dtsi @@ -209,6 +209,10 @@ compatible = "qcom,rpmh-clk-sm8150"; }; +&clock_scc { + compatible = "qcom,scc-sa8195"; +}; + &ufsphy_mem { compatible = "qcom,ufs-phy-qmp-v4"; vdda-phy-supply = <&pm8195_3_l5>; -- GitLab From 7fbea767ca698318ede69576af0f1503ece59d4c Mon Sep 17 00:00:00 2001 From: Odelu Kukatla Date: Fri, 12 Jul 2019 14:48:37 +0530 Subject: [PATCH 1073/1121] clk: qcom: osm: Add support for OSM clocks for ATOLL ATOLL has 6-2 cores configuration, add the necessary clock changes to support 6-2 core configuration using the new compatible. Change-Id: I9d0cc2b56777eb7db9b9f72a34d149812322b0bb Signed-off-by: Odelu Kukatla --- .../devicetree/bindings/arm/msm/qcom,osm.txt | 3 ++- drivers/clk/qcom/clk-cpu-osm.c | 14 +++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt b/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt index 4b6881370435..6a8128765ff7 100644 --- a/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt +++ b/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt @@ -12,7 +12,8 @@ Properties: Definition: must be "qcom,clk-cpu-osm" or "qcom,clk-cpu-osm-sdmshrike" or "qcom,clk-cpu-osm-sm6150" or "qcom,clk-cpu-osm-sdmmagpie" or - "qcom,clk-cpu-osm-trinket". + "qcom,clk-cpu-osm-trinket" or + "qcom,clk-cpu-osm-atoll". - reg Usage: required diff --git a/drivers/clk/qcom/clk-cpu-osm.c b/drivers/clk/qcom/clk-cpu-osm.c index 8d49a370ce99..a397013479f1 100644 --- a/drivers/clk/qcom/clk-cpu-osm.c +++ b/drivers/clk/qcom/clk-cpu-osm.c @@ -89,6 +89,7 @@ static bool is_sdmshrike; static bool is_sm6150; static bool is_sdmmagpie; static bool is_trinket; +static bool is_atoll; static inline struct clk_osm *to_clk_osm(struct clk_hw *_hw) { @@ -1031,7 +1032,8 @@ static int clk_osm_resources_init(struct platform_device *pdev) return -ENOMEM; } - if (is_sdmshrike || is_sm6150 || is_sdmmagpie || is_trinket) + if (is_sdmshrike || is_sm6150 || is_sdmmagpie || + is_trinket || is_atoll) return 0; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, @@ -1124,9 +1126,13 @@ static int clk_cpu_osm_driver_probe(struct platform_device *pdev) is_sdmshrike = of_device_is_compatible(pdev->dev.of_node, "qcom,clk-cpu-osm-sdmshrike"); + + is_atoll = of_device_is_compatible(pdev->dev.of_node, + "qcom,clk-cpu-osm-atoll"); + if (is_sdmshrike) clk_cpu_osm_driver_sdmshrike_fixup(); - else if (is_sm6150 || is_sdmmagpie) + else if (is_sm6150 || is_sdmmagpie || is_atoll) clk_cpu_osm_driver_sm6150_fixup(); else if (is_trinket) clk_cpu_osm_driver_trinket_fixup(); @@ -1183,7 +1189,8 @@ static int clk_cpu_osm_driver_probe(struct platform_device *pdev) return rc; } - if (!is_sdmshrike && !is_sm6150 && !is_sdmmagpie && !is_trinket) { + if (!is_sdmshrike && !is_sm6150 && !is_sdmmagpie && + !is_trinket && !is_atoll) { rc = clk_osm_read_lut(pdev, &perfpcl_clk); if (rc) { dev_err(&pdev->dev, "Unable to read OSM LUT for perf plus cluster, rc=%d\n", @@ -1265,6 +1272,7 @@ static const struct of_device_id match_table[] = { { .compatible = "qcom,clk-cpu-osm-sdmmagpie" }, { .compatible = "qcom,clk-cpu-osm-trinket" }, { .compatible = "qcom,clk-cpu-osm-sdmshrike" }, + { .compatible = "qcom,clk-cpu-osm-atoll" }, {} }; -- GitLab From 82fd90b26e1891da5c0c7377cdf75a3100e94817 Mon Sep 17 00:00:00 2001 From: Odelu Kukatla Date: Fri, 12 Jul 2019 15:11:43 +0530 Subject: [PATCH 1074/1121] ARM: dts: msm: Enable the OSM clock controller for ATOLL Add the cpucc clock node to enable the OSM clock controller driver for ATOLL. Change-Id: Ic4e9c170e3b414274eaed2a23f69df6e6457ba9f Signed-off-by: Odelu Kukatla --- arch/arm64/boot/dts/qcom/atoll.dtsi | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index bf9082faf01a..774ee2a9510c 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -13,6 +13,7 @@ #include "skeleton64.dtsi" #include #include +#include #include #include #include @@ -1541,6 +1542,17 @@ #reset-cells = <1>; }; + clock_cpucc: qcom,cpucc@18321000 { + compatible = "qcom,clk-cpu-osm-atoll"; + reg = <0x18321000 0x1400>, + <0x18323000 0x1400>, + <0x18325800 0x1400>; + reg-names = "osm_l3_base", "osm_pwrcl_base", + "osm_perfcl_base"; + #clock-cells = <1>; + status = "disabled"; + }; + tcsr_mutex_block: syscon@01F40000 { compatible = "syscon"; reg = <0x01F40000 0x20000>; -- GitLab From 4a213daacaf85b59d049aaf18d500487b5c9f362 Mon Sep 17 00:00:00 2001 From: Gustavo Solaira Date: Wed, 17 Jul 2019 12:39:02 -0700 Subject: [PATCH 1075/1121] ARM: dts: msm: Enable PPS gpio for SA515M CCARD boards Enable pulse per second GPIO device node for SA515M automotive CCARD boards. Change-Id: I4df470308259f151296c79ff0e32b364df195dc4 Signed-off-by: Gustavo Solaira --- arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi | 8 ++++++++ arch/arm64/boot/dts/qcom/sdxprairie-pinctrl.dtsi | 12 ++++++++++++ 2 files changed, 20 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi b/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi index 0c561f420fa1..faf6723dace9 100644 --- a/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi +++ b/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi @@ -68,6 +68,14 @@ asoc-codec = <&tlv320aic3x_codec>, <&stub_codec>; asoc-codec-names = "tlv320aic3x-codec", "msm-stub-codec.1"; }; + + pps { + compatible = "pps-gpio"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pps>; + gpios = <&tlmm 32 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; }; /* delete pm8150b nodes */ diff --git a/arch/arm64/boot/dts/qcom/sdxprairie-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sdxprairie-pinctrl.dtsi index c29c95dc5635..2ba4e8fefb26 100644 --- a/arch/arm64/boot/dts/qcom/sdxprairie-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/sdxprairie-pinctrl.dtsi @@ -1488,5 +1488,17 @@ }; }; }; + + pinctrl_pps: ppsgrp { + mux { + pins = "gpio32"; + function = "nav_gpio"; + }; + + config { + pins = "gpio32"; + bias-pull-down; + }; + }; }; }; -- GitLab From 204e49ad209e7b7780a5172214d1275e0ff6476b Mon Sep 17 00:00:00 2001 From: Gustavo Solaira Date: Mon, 29 Jul 2019 11:56:35 -0700 Subject: [PATCH 1076/1121] ARM: dts: msm: Set ethernet PHY reset delay for SA515M CCARD Set the Micrel PHY reset delay to 10 ms according to the specification of the chip. Change-Id: Ia808b170b3dce73ca9101eb004f7237e4b617b8f Signed-off-by: Gustavo Solaira --- arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi b/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi index 0c561f420fa1..973c01370d5f 100644 --- a/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi +++ b/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi @@ -176,6 +176,7 @@ /delete-property/ vreg_rgmii-supply; pinctrl-names = "default"; pinctrl-0 = <&vreg_rgmii_off_default>; + qcom,phy-reset-delay-msecs = <10>; }; &vreg_rgmii_io_pads { -- GitLab From a91d193f40af597a1a724841b0253a1df3fdb7ca Mon Sep 17 00:00:00 2001 From: Sean Tranchetti Date: Mon, 8 Jul 2019 13:44:50 -0600 Subject: [PATCH 1077/1121] net: qualcomm: rmnet: Pass on bad csum segments When receiving coalesced frames from hardware where there are segments marked has having invalid L4 checksums, the RmNet driver should pass these on to the network stack instead of silently dropping them. This allows the statistics maintained by the network stack to accurately represent the data flow. Change-Id: I9e520060a2854492ef158fffecfe60b0fe587265 Signed-off-by: Sean Tranchetti --- .../qualcomm/rmnet/rmnet_descriptor.c | 161 +++++++++++++----- .../ethernet/qualcomm/rmnet/rmnet_map_data.c | 137 ++++++++++----- 2 files changed, 210 insertions(+), 88 deletions(-) diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c index c936049cc1dd..acf5abdb7f12 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c @@ -389,7 +389,6 @@ static void rmnet_frag_gso_stamp(struct sk_buff *skb, bool ipv4 = frag_desc->ip_proto == 4; if (ipv4) { - iph->tot_len = htons(skb->len); iph->check = 0; iph->check = ip_fast_csum(iph, iph->ihl); pseudo = ~csum_tcpudp_magic(iph->saddr, iph->daddr, @@ -398,8 +397,6 @@ static void rmnet_frag_gso_stamp(struct sk_buff *skb, } else { struct ipv6hdr *ip6h = (struct ipv6hdr *)iph; - /* Payload length includes any extension headers */ - ip6h->payload_len = htons(skb->len - sizeof(*ip6h)); pseudo = ~csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, pkt_len, frag_desc->trans_proto, 0); } @@ -415,7 +412,6 @@ static void rmnet_frag_gso_stamp(struct sk_buff *skb, struct udphdr *up = (struct udphdr *) ((u8 *)iph + frag_desc->ip_len); - up->len = htons(pkt_len); up->check = pseudo; shinfo->gso_type = SKB_GSO_UDP_L4; skb->csum_offset = offsetof(struct udphdr, check); @@ -440,6 +436,7 @@ static struct sk_buff *rmnet_alloc_skb(struct rmnet_frag_descriptor *frag_desc, /* Use the exact sizes if we know them (i.e. RSB/RSC, rmnet_perf) */ if (frag_desc->hdrs_valid) { u16 hdr_len = frag_desc->ip_len + frag_desc->trans_len; + u16 data_len = frag_desc->gso_size * frag_desc->gso_segs; head_skb = alloc_skb(hdr_len + RMNET_MAP_DEAGGR_HEADROOM, GFP_ATOMIC); @@ -449,9 +446,31 @@ static struct sk_buff *rmnet_alloc_skb(struct rmnet_frag_descriptor *frag_desc, skb_reserve(head_skb, RMNET_MAP_DEAGGR_HEADROOM); skb_put_data(head_skb, frag_desc->hdr_ptr, hdr_len); skb_reset_network_header(head_skb); - if (frag_desc->trans_len) + + /* Update header lengths after RSB/RSC/perf */ + if (frag_desc->ip_proto == 4) { + struct iphdr *iph = ip_hdr(head_skb); + __be16 tot_len = htons(hdr_len + data_len); + + csum_replace2(&iph->check, iph->tot_len, tot_len); + iph->tot_len = tot_len; + } else { + struct ipv6hdr *ip6h = ipv6_hdr(head_skb); + + ip6h->payload_len = htons(hdr_len + data_len - + sizeof(*ip6h)); + } + + if (frag_desc->trans_len) { skb_set_transport_header(head_skb, frag_desc->ip_len); + if (frag_desc->trans_proto == IPPROTO_UDP) { + struct udphdr *uh = udp_hdr(head_skb); + + uh->len = htons(data_len + sizeof(*uh)); + } + } + /* Packets that have no data portion don't need any frags */ if (hdr_len == skb_frag_size(&frag_desc->frag)) goto skip_frags; @@ -548,8 +567,52 @@ static struct sk_buff *rmnet_alloc_skb(struct rmnet_frag_descriptor *frag_desc, } /* Handle csum offloading */ - if (frag_desc->csum_valid) + if (frag_desc->csum_valid) { head_skb->ip_summed = CHECKSUM_UNNECESSARY; + } else if (frag_desc->hdrs_valid && + (frag_desc->trans_proto == IPPROTO_TCP || + frag_desc->trans_proto == IPPROTO_UDP)) { + /* Unfortunately, we have to fake a bad checksum here, since + * the original bad value is lost by the hardware. The only + * reliable way to do it is to calculate the actual checksum + * and corrupt it. + */ + __sum16 *check; + __wsum csum; + unsigned int offset = skb_transport_offset(head_skb); + __sum16 pseudo; + + /* Calculate pseudo header */ + if (frag_desc->ip_proto == 4) { + struct iphdr *iph = ip_hdr(head_skb); + + pseudo = ~csum_tcpudp_magic(iph->saddr, iph->daddr, + head_skb->len - + frag_desc->ip_len, + frag_desc->trans_proto, 0); + } else { + struct ipv6hdr *ip6h = ipv6_hdr(head_skb); + + pseudo = ~csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, + head_skb->len - + frag_desc->ip_len, + frag_desc->trans_proto, 0); + } + + if (frag_desc->trans_proto == IPPROTO_TCP) + check = &tcp_hdr(head_skb)->check; + else + check = &udp_hdr(head_skb)->check; + + *check = pseudo; + csum = skb_checksum(head_skb, offset, head_skb->len - offset, + 0); + /* Add 1 to corrupt. This cannot produce a final value of 0 + * since csum_fold() can't return a value of 0xFFFF + */ + *check = csum16_add(csum_fold(csum), htons(1)); + head_skb->ip_summed = CHECKSUM_NONE; + } /* Handle any rmnet_perf metadata */ if (frag_desc->hash) { @@ -582,8 +645,8 @@ EXPORT_SYMBOL(rmnet_frag_deliver); static void __rmnet_frag_segment_data(struct rmnet_frag_descriptor *coal_desc, struct rmnet_port *port, - struct list_head *list, - u8 pkt_id) + struct list_head *list, u8 pkt_id, + bool csum_valid) { struct rmnet_priv *priv = netdev_priv(coal_desc->dev); struct rmnet_frag_descriptor *new_frag; @@ -623,7 +686,7 @@ static void __rmnet_frag_segment_data(struct rmnet_frag_descriptor *coal_desc, } new_frag->hdr_ptr = hdr_start; - new_frag->csum_valid = true; + new_frag->csum_valid = csum_valid; priv->stats.coal.coal_reconstruct++; /* Update meta information to move past the data we just segmented */ @@ -753,38 +816,62 @@ rmnet_frag_segment_coal_data(struct rmnet_frag_descriptor *coal_desc, return; } + /* Fast-forward the case where we have 1 NLO (i.e. 1 packet length), + * no checksum errors, and are allowing GRO. We can just reuse this + * descriptor unchanged. + */ + if (gro && coal_hdr->num_nlos == 1 && coal_hdr->csum_valid) { + coal_desc->csum_valid = true; + coal_desc->hdr_ptr = rmnet_frag_data_ptr(coal_desc); + coal_desc->gso_size = ntohs(coal_hdr->nl_pairs[0].pkt_len); + coal_desc->gso_size -= coal_desc->ip_len + coal_desc->trans_len; + coal_desc->gso_segs = coal_hdr->nl_pairs[0].num_packets; + list_add_tail(&coal_desc->list, list); + return; + } + /* Segment the coalesced descriptor into new packets */ for (nlo = 0; nlo < coal_hdr->num_nlos; nlo++) { pkt_len = ntohs(coal_hdr->nl_pairs[nlo].pkt_len); pkt_len -= coal_desc->ip_len + coal_desc->trans_len; coal_desc->gso_size = pkt_len; for (pkt = 0; pkt < coal_hdr->nl_pairs[nlo].num_packets; - pkt++, total_pkt++) { - nlo_err_mask <<= 1; - if (nlo_err_mask & (1ULL << 63)) { + pkt++, total_pkt++, nlo_err_mask >>= 1) { + bool csum_err = nlo_err_mask & 1; + + /* Segment the packet if we're not sending the larger + * packet up the stack. + */ + if (!gro) { + coal_desc->gso_segs = 1; + if (csum_err) + priv->stats.coal.coal_csum_err++; + + __rmnet_frag_segment_data(coal_desc, port, + list, total_pkt, + !csum_err); + continue; + } + + if (csum_err) { priv->stats.coal.coal_csum_err++; /* Segment out the good data */ - if (gro && coal_desc->gso_segs) + if (coal_desc->gso_segs) __rmnet_frag_segment_data(coal_desc, port, list, - total_pkt); - - /* skip over bad packet */ - coal_desc->data_offset += pkt_len; - coal_desc->pkt_id = total_pkt + 1; + total_pkt, + true); + + /* Segment out the bad checksum */ + coal_desc->gso_segs = 1; + __rmnet_frag_segment_data(coal_desc, port, + list, total_pkt, + false); } else { coal_desc->gso_segs++; - /* Segment the packet if we aren't sending the - * larger packet up the stack. - */ - if (!gro) - __rmnet_frag_segment_data(coal_desc, - port, - list, - total_pkt); } } @@ -792,25 +879,9 @@ rmnet_frag_segment_coal_data(struct rmnet_frag_descriptor *coal_desc, * the previous one, if we haven't done so. NLOs only switch * when the packet length changes. */ - if (gro && coal_desc->gso_segs) { - /* Fast forward the (hopefully) common case. - * Frames with only one NLO (i.e. one packet length) and - * no checksum errors don't need to be segmented here. - * We can just pass off the original skb. - */ - if (coal_desc->gso_size * coal_desc->gso_segs == - skb_frag_size(&coal_desc->frag) - - coal_desc->ip_len - coal_desc->trans_len) { - coal_desc->hdr_ptr = - rmnet_frag_data_ptr(coal_desc); - coal_desc->csum_valid = true; - list_add_tail(&coal_desc->list, list); - return; - } - + if (coal_desc->gso_segs) __rmnet_frag_segment_data(coal_desc, port, list, - total_pkt); - } + total_pkt, true); } } @@ -891,7 +962,7 @@ rmnet_frag_data_check_coal_header(struct rmnet_frag_descriptor *frag_desc, u8 err = coal_hdr->nl_pairs[i].csum_error_bitmap; u8 pkt = coal_hdr->nl_pairs[i].num_packets; - mask |= ((u64)err) << (7 - i) * 8; + mask |= ((u64)err) << (8 * i); /* Track total packets in frame */ pkts += pkt; diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c index cfef7e9c4c8d..b6ed1778b88f 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c @@ -703,10 +703,12 @@ static void rmnet_map_gso_stamp(struct sk_buff *skb, static void __rmnet_map_segment_coal_skb(struct sk_buff *coal_skb, struct rmnet_map_coal_metadata *coal_meta, - struct sk_buff_head *list, u8 pkt_id) + struct sk_buff_head *list, u8 pkt_id, + bool csum_valid) { struct sk_buff *skbn; struct rmnet_priv *priv = netdev_priv(coal_skb->dev); + __sum16 *check = NULL; u32 alloc_len; /* We can avoid copying the data if the SKB we got from the lower-level @@ -733,8 +735,12 @@ __rmnet_map_segment_coal_skb(struct sk_buff *coal_skb, struct tcphdr *th = tcp_hdr(skbn); th->seq = htonl(ntohl(th->seq) + coal_meta->data_offset); + check = &th->check; } else if (coal_meta->trans_proto == IPPROTO_UDP) { - udp_hdr(skbn)->len = htons(skbn->len); + struct udphdr *uh = udp_hdr(skbn); + + uh->len = htons(skbn->len); + check = &uh->check; } /* Push IP header and update necessary fields */ @@ -754,7 +760,44 @@ __rmnet_map_segment_coal_skb(struct sk_buff *coal_skb, sizeof(struct ipv6hdr)); } - skbn->ip_summed = CHECKSUM_UNNECESSARY; + /* Handle checksum status */ + if (likely(csum_valid)) { + skbn->ip_summed = CHECKSUM_UNNECESSARY; + } else if (check) { + /* Unfortunately, we have to fake a bad checksum here, since + * the original bad value is lost by the hardware. The only + * reliable way to do it is to calculate the actual checksum + * and corrupt it. + */ + __wsum csum; + unsigned int offset = skb_transport_offset(skbn); + __sum16 pseudo; + + /* Calculate pseudo header */ + if (coal_meta->ip_proto == 4) { + struct iphdr *iph = ip_hdr(skbn); + + pseudo = ~csum_tcpudp_magic(iph->saddr, iph->daddr, + skbn->len - + coal_meta->ip_len, + coal_meta->trans_proto, 0); + } else { + struct ipv6hdr *ip6h = ipv6_hdr(skbn); + + pseudo = ~csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, + skbn->len - coal_meta->ip_len, + coal_meta->trans_proto, 0); + } + + *check = pseudo; + csum = skb_checksum(skbn, offset, skbn->len - offset, 0); + /* Add 1 to corrupt. This cannot produce a final value of 0 + * since csum_fold() can't return a value of 0xFFFF. + */ + *check = csum16_add(csum_fold(csum), htons(1)); + skbn->ip_summed = CHECKSUM_NONE; + } + skbn->dev = coal_skb->dev; priv->stats.coal.coal_reconstruct++; @@ -891,39 +934,65 @@ static void rmnet_map_segment_coal_skb(struct sk_buff *coal_skb, return; } + /* Fast-forward the case where we have 1 NLO (i.e. 1 packet length), + * no checksum errors, and are allowing GRO. We can just reuse this + * SKB unchanged. + */ + if (gro && coal_hdr->num_nlos == 1 && coal_hdr->csum_valid) { + rmnet_map_move_headers(coal_skb); + coal_skb->ip_summed = CHECKSUM_UNNECESSARY; + coal_meta.data_len = ntohs(coal_hdr->nl_pairs[0].pkt_len); + coal_meta.data_len -= coal_meta.ip_len + coal_meta.trans_len; + coal_meta.pkt_count = coal_hdr->nl_pairs[0].num_packets; + if (coal_meta.pkt_count > 1) + rmnet_map_gso_stamp(coal_skb, &coal_meta); + + __skb_queue_tail(list, coal_skb); + return; + } + /* Segment the coalesced SKB into new packets */ for (nlo = 0; nlo < coal_hdr->num_nlos; nlo++) { pkt_len = ntohs(coal_hdr->nl_pairs[nlo].pkt_len); pkt_len -= coal_meta.ip_len + coal_meta.trans_len; coal_meta.data_len = pkt_len; for (pkt = 0; pkt < coal_hdr->nl_pairs[nlo].num_packets; - pkt++, total_pkt++) { - nlo_err_mask <<= 1; - if (nlo_err_mask & (1ULL << 63)) { + pkt++, total_pkt++, nlo_err_mask >>= 1) { + bool csum_err = nlo_err_mask & 1; + + /* Segment the packet if we're not sending the larger + * packet up the stack. + */ + if (!gro) { + coal_meta.pkt_count = 1; + if (csum_err) + priv->stats.coal.coal_csum_err++; + + __rmnet_map_segment_coal_skb(coal_skb, + &coal_meta, list, + total_pkt, + !csum_err); + continue; + } + + if (csum_err) { priv->stats.coal.coal_csum_err++; /* Segment out the good data */ - if (gro && coal_meta.pkt_count) { + if (gro && coal_meta.pkt_count) __rmnet_map_segment_coal_skb(coal_skb, &coal_meta, list, - total_pkt); - } - - /* skip over bad packet */ - coal_meta.data_offset += pkt_len; - coal_meta.pkt_id = total_pkt + 1; + total_pkt, + true); + + /* Segment out the bad checksum */ + coal_meta.pkt_count = 1; + __rmnet_map_segment_coal_skb(coal_skb, + &coal_meta, list, + total_pkt, false); } else { coal_meta.pkt_count++; - - /* Segment the packet if we aren't sending the - * larger packet up the stack. - */ - if (!gro) - __rmnet_map_segment_coal_skb(coal_skb, - &coal_meta, - list, - total_pkt); } } @@ -931,27 +1000,9 @@ static void rmnet_map_segment_coal_skb(struct sk_buff *coal_skb, * the previous one, if we haven't done so. NLOs only switch * when the packet length changes. */ - if (gro && coal_meta.pkt_count) { - /* Fast forward the (hopefully) common case. - * Frames with only one NLO (i.e. one packet length) and - * no checksum errors don't need to be segmented here. - * We can just pass off the original skb. - */ - if (pkt_len * coal_meta.pkt_count == - coal_skb->len - coal_meta.ip_len - - coal_meta.trans_len) { - rmnet_map_move_headers(coal_skb); - coal_skb->ip_summed = CHECKSUM_UNNECESSARY; - if (coal_meta.pkt_count > 1) - rmnet_map_gso_stamp(coal_skb, - &coal_meta); - __skb_queue_tail(list, coal_skb); - return; - } - + if (coal_meta.pkt_count) __rmnet_map_segment_coal_skb(coal_skb, &coal_meta, list, - total_pkt); - } + total_pkt, true); } } @@ -1031,7 +1082,7 @@ static int rmnet_map_data_check_coal_header(struct sk_buff *skb, u8 err = coal_hdr->nl_pairs[i].csum_error_bitmap; u8 pkt = coal_hdr->nl_pairs[i].num_packets; - mask |= ((u64)err) << (7 - i) * 8; + mask |= ((u64)err) << (8 * i); /* Track total packets in frame */ pkts += pkt; -- GitLab From 8145c43a705c9c9df97e8aa9372b35f4bc567223 Mon Sep 17 00:00:00 2001 From: Ramachandran Venkataramani Date: Tue, 9 Jul 2019 10:31:52 -0700 Subject: [PATCH 1078/1121] clk: qcom: gcc: Add video clock resets for sdmshrike Add AXI0 and AXI1 video clock resets on GCC in sdmshrike required for video functionality. Change-Id: I9dbe54ad4fff87ff7c156ab2e53e9424ce745753 Signed-off-by: Ramachandran Venkataramani --- drivers/clk/qcom/gcc-sdmshrike.c | 2 ++ include/dt-bindings/clock/qcom,gcc-sdmshrike.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/drivers/clk/qcom/gcc-sdmshrike.c b/drivers/clk/qcom/gcc-sdmshrike.c index 1d42142095fc..ec5cd2cd6266 100644 --- a/drivers/clk/qcom/gcc-sdmshrike.c +++ b/drivers/clk/qcom/gcc-sdmshrike.c @@ -5051,6 +5051,8 @@ static const struct qcom_reset_map gcc_sdmshrike_resets[] = { [GCC_USB30_SEC_BCR] = { 0x10000 }, [GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x6a000 }, [GCC_VIDEO_AXIC_CLK_BCR] = { 0xb02c, 2 }, + [GCC_VIDEO_AXI0_CLK_BCR] = { 0xb024, 2 }, + [GCC_VIDEO_AXI1_CLK_BCR] = { 0xb028, 2 }, }; diff --git a/include/dt-bindings/clock/qcom,gcc-sdmshrike.h b/include/dt-bindings/clock/qcom,gcc-sdmshrike.h index deeb23e72cc2..d1905dc61429 100644 --- a/include/dt-bindings/clock/qcom,gcc-sdmshrike.h +++ b/include/dt-bindings/clock/qcom,gcc-sdmshrike.h @@ -304,6 +304,8 @@ #define GCC_USB30_SEC_BCR 39 #define GCC_USB_PHY_CFG_AHB2PHY_BCR 40 #define GCC_VIDEO_AXIC_CLK_BCR 41 +#define GCC_VIDEO_AXI0_CLK_BCR 42 +#define GCC_VIDEO_AXI1_CLK_BCR 43 #define MMCX_CLK 0 #endif -- GitLab From f62825f17f58d18a686394448d9be0642eb73fa6 Mon Sep 17 00:00:00 2001 From: Gustavo Solaira Date: Fri, 26 Jul 2019 16:32:53 -0700 Subject: [PATCH 1079/1121] ARM: dts: msm: Disable UART_4 on SA515M CCARD boards Disable this UART port on CCARD since it is not being used and it conflicts with other devices. Change-Id: I66cac770eb63944f13cce07bda52dda2abee1921 Signed-off-by: Gustavo Solaira --- arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi b/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi index 015934236bd8..a9e670f09c10 100644 --- a/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi +++ b/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi @@ -105,10 +105,6 @@ status = "okay"; }; -&blsp1_uart4a_hs { - status = "okay"; -}; - &vbus_detect { status = "okay"; }; -- GitLab From ba2d925fe42b0fa67e761bec4ba715df8feedd2a Mon Sep 17 00:00:00 2001 From: Zhiqiang Tu Date: Thu, 25 Jul 2019 16:41:22 +0800 Subject: [PATCH 1080/1121] ARM: dts: msm: Enable virtio clock for sa6155p vm Replace hab based virtual clock with virtio clock for sa6155p virtual machine. Change-Id: I8b1d59800b73fe5204f353772e81bb80a6b0fe23 Signed-off-by: Zhiqiang Tu --- arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi b/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi index 2639be0fa8fd..0f3828af7956 100644 --- a/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi @@ -41,16 +41,19 @@ }; &soc { - clock_virt: qcom,virt-gcc { - compatible = "qcom,virt-clk-sm6150-gcc"; + clock_virt: qcom,virtio-gcc { + compatible = "virtio,mmio"; + reg = <0x1c200000 0x1000>; + interrupts = <0 48 0>; #clock-cells = <1>; #reset-cells = <1>; }; - clock_virt_scc: qcom,virt-scc { - compatible = "qcom,virt-clk-sm6150-scc"; + clock_virt_scc: qcom,virtio-scc { + compatible = "virtio,mmio"; + reg = <0x1c300000 0x1000>; + interrupts = <0 49 0>; #clock-cells = <1>; - #reset-cells = <1>; }; regulator_virt: virtio_regulator@1c700000 { -- GitLab From 5180cfdffb83c06c9f001c2425de9111e00a7209 Mon Sep 17 00:00:00 2001 From: Omkar Savagaonkar Date: Thu, 25 Jul 2019 19:50:19 +0530 Subject: [PATCH 1081/1121] iommu: arm-smmu: Add hibernation callbacks to pm_ops Add required callbacks(thaw and restore), to pm_ops for hibernation to function properly. arm-smmu driver has to be restored before any dependent client drivers are restored. Hence use early variant callbacks. Change-Id: I3f3dba5753e0b0efe1e32fd3d16fc4373574efa5 Signed-off-by: Omkar Savagaonkar --- drivers/iommu/arm-smmu.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index f921a63d49e7..0b5502856bb4 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -4997,7 +4997,11 @@ static int __maybe_unused arm_smmu_pm_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(arm_smmu_pm_ops, NULL, arm_smmu_pm_resume); +static const struct dev_pm_ops arm_smmu_pm_ops = { + .resume = arm_smmu_pm_resume, + .thaw_early = arm_smmu_pm_resume, + .restore_early = arm_smmu_pm_resume, +}; static struct platform_driver arm_smmu_driver = { .driver = { -- GitLab From 427195c5367145c869836a92a37e2cc62ebaaafc Mon Sep 17 00:00:00 2001 From: Ajay Agarwal Date: Tue, 30 Jul 2019 11:54:39 +0530 Subject: [PATCH 1082/1121] Revert "defconfig: QCS405: Enable USB diag_bridge, QRTR and RMNET host drivers" This reverts commit 4ff5de1ac782f46366ae8503c9485477c224d68b. USB diagfwd, diag_brigde, QRTR transport and RmNet data drivers are required for SA2150p target. Clean them for QCS405. Change-Id: Ifbb17e352bc0bd903c36be7342561b6385be9401 Signed-off-by: Ajay Agarwal --- arch/arm64/configs/vendor/qcs405-perf_defconfig | 3 --- arch/arm64/configs/vendor/qcs405_defconfig | 3 --- 2 files changed, 6 deletions(-) diff --git a/arch/arm64/configs/vendor/qcs405-perf_defconfig b/arch/arm64/configs/vendor/qcs405-perf_defconfig index fdcd416ea447..566555ddcfea 100644 --- a/arch/arm64/configs/vendor/qcs405-perf_defconfig +++ b/arch/arm64/configs/vendor/qcs405-perf_defconfig @@ -200,8 +200,6 @@ CONFIG_NET_EMATCH_TEXT=y CONFIG_NET_CLS_ACT=y CONFIG_QRTR=y CONFIG_QRTR_SMD=y -CONFIG_QRTR_USB=y -CONFIG_RMNET_USB=y CONFIG_BT=y # CONFIG_BT_BREDR is not set # CONFIG_BT_LE is not set @@ -390,7 +388,6 @@ CONFIG_USB_SERIAL=y CONFIG_USB_EHSET_TEST_FIXTURE=y CONFIG_USB_LINK_LAYER_TEST=y CONFIG_USB_TYPEC_MUX_NXP5150A=y -CONFIG_USB_QCOM_DIAG_BRIDGE=y CONFIG_NOP_USB_XCEIV=y CONFIG_MSM_SNPS_FEMTO_PHY=y CONFIG_USB_MSM_SSPHY=y diff --git a/arch/arm64/configs/vendor/qcs405_defconfig b/arch/arm64/configs/vendor/qcs405_defconfig index 665586314b19..ac035ea258f5 100644 --- a/arch/arm64/configs/vendor/qcs405_defconfig +++ b/arch/arm64/configs/vendor/qcs405_defconfig @@ -206,8 +206,6 @@ CONFIG_NET_EMATCH_TEXT=y CONFIG_NET_CLS_ACT=y CONFIG_QRTR=y CONFIG_QRTR_SMD=y -CONFIG_QRTR_USB=y -CONFIG_RMNET_USB=y CONFIG_BT=y # CONFIG_BT_BREDR is not set # CONFIG_BT_LE is not set @@ -401,7 +399,6 @@ CONFIG_USB_SERIAL=y CONFIG_USB_EHSET_TEST_FIXTURE=y CONFIG_USB_LINK_LAYER_TEST=y CONFIG_USB_TYPEC_MUX_NXP5150A=y -CONFIG_USB_QCOM_DIAG_BRIDGE=y CONFIG_NOP_USB_XCEIV=y CONFIG_MSM_SNPS_FEMTO_PHY=y CONFIG_USB_MSM_SSPHY=y -- GitLab From 8681184defdeea4cb2d8b106a98e0809d6559732 Mon Sep 17 00:00:00 2001 From: Zhenhua Huang Date: Tue, 30 Jul 2019 10:47:35 +0800 Subject: [PATCH 1083/1121] ARM: dts: msm: update the memory map to v5 on atoll Update the memory map regions according to V5 on atoll. Change-Id: I1ad52daf2fe7b860f49f678043e7505614f9acc8 Signed-off-by: Zhenhua Huang --- arch/arm64/boot/dts/qcom/atoll.dtsi | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index ef8f9ebafa09..c0b1c01fd884 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -510,61 +510,61 @@ pil_camera_mem: camera_region@8e000000 { compatible = "removed-dma-pool"; no-map; - reg = <0 0x8e000000 0 0x500000>; + reg = <0 0x8e400000 0 0x500000>; }; pil_modem_mem: modem_region@86000000 { compatible = "removed-dma-pool"; no-map; - reg = <0 0x86000000 0 0x8000000>; + reg = <0 0x86000000 0 0x8400000>; }; pil_video_mem: pil_video_region@8ea00000 { compatible = "removed-dma-pool"; no-map; - reg = <0 0x8ea00000 0 0x500000>; + reg = <0 0x8ee00000 0 0x500000>; }; pil_cdsp_mem: cdsp_regions@8ef00000 { compatible = "removed-dma-pool"; no-map; - reg = <0 0x8ef00000 0 0x1e00000>; + reg = <0 0x8f300000 0 0x1e00000>; }; pil_adsp_mem: pil_adsp_region@90d00000 { compatible = "removed-dma-pool"; no-map; - reg = <0 0x90d00000 0 0x2800000>; + reg = <0 0x91100000 0 0x2800000>; }; wlan_fw_mem: wlan_fw_region@93500000 { compatible = "removed-dma-pool"; no-map; - reg = <0 0x93500000 0 0x200000>; + reg = <0 0x93900000 0 0x200000>; }; npu_mem: npu_region@8e500000 { compatible = "removed-dma-pool"; no-map; - reg = <0 0x8e500000 0 0x500000>; + reg = <0 0x8e900000 0 0x500000>; }; pil_ipa_fw_mem: ipa_fw_region@93700000 { compatible = "removed-dma-pool"; no-map; - reg = <0 0x93700000 0 0x10000>; + reg = <0 0x93b00000 0 0x10000>; }; pil_ipa_gsi_mem: ipa_gsi_region@93710000 { compatible = "removed-dma-pool"; no-map; - reg = <0 0x93710000 0 0x5000>; + reg = <0 0x93b10000 0 0x5000>; }; pil_gpu_mem: gpu_region@93715000 { compatible = "removed-dma-pool"; no-map; - reg = <0 0x93715000 0 0x2000>; + reg = <0 0x93b15000 0 0x2000>; }; qseecom_mem: qseecom_region@9e000000 { @@ -576,7 +576,7 @@ cdsp_sec_mem: cdsp_sec_regions@0x9f400000 { compatible = "removed-dma-pool"; no-map; - reg = <0 0x9f400000 0 0xc00000>; + reg = <0 0x9f400000 0 0x1e00000>; }; secure_display_memory: secure_display_region { -- GitLab From 70f9e86d9c24673af5df59e34c8b574634fcce68 Mon Sep 17 00:00:00 2001 From: Manoj Prabhu B Date: Tue, 30 Jul 2019 12:13:24 +0530 Subject: [PATCH 1084/1121] diag: dci: Validate pkt length before parsing for full header Few commands with smaller length than dci packet request header can fail due to present header length check. Modify the length check to cater to smaller length packets. Change-Id: Icf2e45b4eb1be0f2a15f47e58baffe86ece20a1d Signed-off-by: Manoj Prabhu B --- drivers/char/diag/diag_dci.c | 126 +++++++++++++++++++++++------------ 1 file changed, 85 insertions(+), 41 deletions(-) diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c index 32566697f599..366eaf277578 100644 --- a/drivers/char/diag/diag_dci.c +++ b/drivers/char/diag/diag_dci.c @@ -726,32 +726,47 @@ int diag_dci_query_event_mask(struct diag_dci_client_tbl *entry, return ((*event_mask_ptr & byte_mask) == byte_mask) ? 1 : 0; } -static int diag_dci_filter_commands(struct diag_pkt_header_t *header) +static int diag_dci_filter_commands(struct diag_pkt_header_t *header, + int header_len) { if (!header) return -ENOMEM; - switch (header->cmd_code) { - case 0x7d: /* Msg Mask Configuration */ - case 0x73: /* Log Mask Configuration */ - case 0x81: /* Event Mask Configuration */ - case 0x82: /* Event Mask Change */ - case 0x60: /* Event Mask Toggle */ - return 1; - } + if (header_len <= 0) + return -EIO; - if (header->cmd_code == 0x4b && header->subsys_id == 0x12) { - switch (header->subsys_cmd_code) { - case 0x60: /* Extended Event Mask Config */ - case 0x61: /* Extended Msg Mask Config */ - case 0x62: /* Extended Log Mask Config */ - case 0x20C: /* Set current Preset ID */ - case 0x20D: /* Get current Preset ID */ - case 0x218: /* HDLC Disabled Command */ + if (header_len) { + switch (header->cmd_code) { + case 0x7d: /* Msg Mask Configuration */ + case 0x73: /* Log Mask Configuration */ + case 0x81: /* Event Mask Configuration */ + case 0x82: /* Event Mask Change */ + case 0x60: /* Event Mask Toggle */ + DIAG_LOG(DIAG_DEBUG_DCI, + "diag: command not supported: %d\n", + header->cmd_code); return 1; } } + if (header_len >= (3*sizeof(uint8_t))) { + if (header->cmd_code == 0x4b && header->subsys_id == 0x12) { + switch (header->subsys_cmd_code) { + case 0x60: /* Extended Event Mask Config */ + case 0x61: /* Extended Msg Mask Config */ + case 0x62: /* Extended Log Mask Config */ + case 0x20C: /* Set current Preset ID */ + case 0x20D: /* Get current Preset ID */ + case 0x218: /* HDLC Disabled Command */ + DIAG_LOG(DIAG_DEBUG_DCI, + "diag: command not supported %d %d %d\n", + header->cmd_code, header->subsys_id, + header->subsys_cmd_code); + return 1; + } + } + } + return 0; } @@ -1800,7 +1815,7 @@ int diag_dci_send_handshake_pkt(int index) static int diag_dci_process_apps_pkt(struct diag_pkt_header_t *pkt_header, unsigned char *req_buf, int req_len, - int tag) + int tag, int pkt_header_len) { uint8_t cmd_code, subsys_id, i, goto_download = 0; uint8_t header_len = sizeof(struct diag_dci_pkt_header_t); @@ -1810,12 +1825,16 @@ static int diag_dci_process_apps_pkt(struct diag_pkt_header_t *pkt_header, unsigned char *payload_ptr = driver->apps_dci_buf + header_len; struct diag_dci_pkt_header_t dci_header; - if (!pkt_header || !req_buf || req_len <= 0 || tag < 0) + if (!pkt_header || !req_buf || req_len <= 0 || tag < 0 || + pkt_header_len <= 0) return -EIO; - cmd_code = pkt_header->cmd_code; - subsys_id = pkt_header->subsys_id; - ss_cmd_code = pkt_header->subsys_cmd_code; + if (pkt_header_len >= (sizeof(uint8_t))) + cmd_code = pkt_header->cmd_code; + if (pkt_header_len >= (2 * sizeof(uint8_t))) + subsys_id = pkt_header->subsys_id; + if (pkt_header_len >= (3 * sizeof(uint8_t))) + ss_cmd_code = pkt_header->subsys_cmd_code; if (cmd_code == DIAG_CMD_DOWNLOAD) { *payload_ptr = DIAG_CMD_DOWNLOAD; @@ -1936,7 +1955,7 @@ static int diag_dci_process_apps_pkt(struct diag_pkt_header_t *pkt_header, static int diag_process_dci_pkt_rsp(unsigned char *buf, int len) { int ret = DIAG_DCI_TABLE_ERR; - int common_cmd = 0; + int common_cmd = 0, header_len = 0; struct diag_pkt_header_t *header = NULL; unsigned char *temp = buf; unsigned char *req_buf = NULL; @@ -1952,8 +1971,7 @@ static int diag_process_dci_pkt_rsp(unsigned char *buf, int len) if (!buf) return -EIO; - if (len < (sizeof(struct dci_pkt_req_t) + - sizeof(struct diag_pkt_header_t)) || + if (len < sizeof(struct dci_pkt_req_t) || len > DCI_REQ_BUF_SIZE) { pr_err("diag: dci: Invalid length %d len in %s", len, __func__); return -EIO; @@ -1964,13 +1982,6 @@ static int diag_process_dci_pkt_rsp(unsigned char *buf, int len) read_len += sizeof(struct dci_pkt_req_t); req_len -= sizeof(struct dci_pkt_req_t); req_buf = temp; /* Start of the Request */ - header = (struct diag_pkt_header_t *)temp; - read_len += sizeof(struct diag_pkt_header_t); - if (read_len >= DCI_REQ_BUF_SIZE) { - pr_err("diag: dci: In %s, invalid read_len: %d\n", __func__, - read_len); - return -EIO; - } mutex_lock(&driver->dci_mutex); dci_entry = diag_dci_get_client_entry(req_hdr.client_id); @@ -1981,11 +1992,40 @@ static int diag_process_dci_pkt_rsp(unsigned char *buf, int len) return DIAG_DCI_NO_REG; } + header = (void *)temp; + header_len = len - sizeof(struct dci_pkt_req_t); + if (header_len <= 0) { + mutex_unlock(&driver->dci_mutex); + return -EIO; + } + if (header_len >= sizeof(uint8_t)) { + header->cmd_code = (uint16_t)(*(uint8_t *)temp); + read_len += sizeof(uint8_t); + } + if (header_len >= (2 * sizeof(uint8_t))) { + temp += sizeof(uint8_t); + header->subsys_id = (uint16_t)(*(uint8_t *)temp); + read_len += sizeof(uint8_t); + } + if (header_len == (3 * sizeof(uint8_t))) { + temp += sizeof(uint8_t); + header->subsys_cmd_code = (uint16_t)(*(uint8_t *)temp); + read_len += sizeof(uint8_t); + } else if (header_len >= + (2 * sizeof(uint8_t)) + sizeof(uint16_t)) { + temp += sizeof(uint8_t); + header->subsys_cmd_code = (uint16_t)(*(uint16_t *)temp); + read_len += sizeof(uint16_t); + } + if (read_len > DCI_REQ_BUF_SIZE) { + pr_err("diag: dci: In %s, invalid read_len: %d\n", __func__, + read_len); + mutex_unlock(&driver->dci_mutex); + return -EIO; + } + /* Check if the command is allowed on DCI */ - if (diag_dci_filter_commands(header)) { - pr_debug("diag: command not supported %d %d %d", - header->cmd_code, header->subsys_id, - header->subsys_cmd_code); + if (diag_dci_filter_commands(header, header_len)) { mutex_unlock(&driver->dci_mutex); return DIAG_DCI_SEND_DATA_FAIL; } @@ -2039,14 +2079,18 @@ static int diag_process_dci_pkt_rsp(unsigned char *buf, int len) /* Check if it is a dedicated Apps command */ ret = diag_dci_process_apps_pkt(header, req_buf, req_len, - req_entry->tag); + req_entry->tag, header_len); if ((ret == DIAG_DCI_NO_ERROR && !common_cmd) || ret < 0) return ret; - reg_entry.cmd_code = header->cmd_code; - reg_entry.subsys_id = header->subsys_id; - reg_entry.cmd_code_hi = header->subsys_cmd_code; - reg_entry.cmd_code_lo = header->subsys_cmd_code; + if (header_len >= (sizeof(uint8_t))) + reg_entry.cmd_code = header->cmd_code; + if (header_len >= (2 * sizeof(uint8_t))) + reg_entry.subsys_id = header->subsys_id; + if (header_len >= (3 * sizeof(uint8_t))) { + reg_entry.cmd_code_hi = header->subsys_cmd_code; + reg_entry.cmd_code_lo = header->subsys_cmd_code; + } mutex_lock(&driver->cmd_reg_mutex); temp_entry = diag_cmd_search(®_entry, ALL_PROC); -- GitLab From fa88c2431ad6a148c12cc1da3821ea96048b8a51 Mon Sep 17 00:00:00 2001 From: Archit Saxena Date: Fri, 26 Jul 2019 16:46:31 +0530 Subject: [PATCH 1085/1121] ARM: dts: msm: Cleanup existing dts of 403 Cleanup existing dts of 403 and add new dts for 401. Change-Id: I74e50418080b5cf8570bcc43b5968645101ed2c8 Signed-off-by: Archit Saxena --- arch/arm64/boot/dts/qcom/Makefile | 1 + arch/arm64/boot/dts/qcom/qcs401-iot-sku5.dts | 52 ++++++++++++++++++++ arch/arm64/boot/dts/qcom/qcs401.dtsi | 28 +---------- arch/arm64/boot/dts/qcom/qcs403.dtsi | 13 ----- arch/arm64/boot/dts/qcom/qcs404-iot-sku3.dts | 4 +- arch/arm64/boot/dts/qcom/qcs404.dtsi | 2 +- 6 files changed, 58 insertions(+), 42 deletions(-) create mode 100644 arch/arm64/boot/dts/qcom/qcs401-iot-sku5.dts diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index 2c1d9863bd0f..d2437bdc7015 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -10,6 +10,7 @@ dtb-$(CONFIG_ARCH_QCOM) += msm8996-mtp.dtb dtb-$(CONFIG_ARCH_QCS403) += qcs403-iot-sku1.dtb \ qcs403-iot-sku3.dtb \ qcs403-iot-sku5.dtb \ + qcs401-iot-sku5.dtb \ qcs404-iot-sku3.dtb \ qcs404-iot-sku5.dtb \ qcs404-iot-sku6.dtb diff --git a/arch/arm64/boot/dts/qcom/qcs401-iot-sku5.dts b/arch/arm64/boot/dts/qcom/qcs401-iot-sku5.dts new file mode 100644 index 000000000000..b3f3c128abcd --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs401-iot-sku5.dts @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "qcs403.dtsi" +#include "qcs405-audio-overlay.dtsi" +#include "qcs405-geni-ir-overlay.dtsi" +#include "qcs405-pinctrl.dtsi" +#include "qcs405-circular-pca9956.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. QCS401 sEVB/SLT IOT"; + compatible = "qcom,qcs401-iot", "qcom,qcs401", "qcom,iot"; + qcom,board-id = <0x010020 0x2>; +}; +#include "qcs405-mdss-panels.dtsi" + +&mdss_mdp { + qcom,mdss-pref-prim-intf = "dsi"; +}; + +&mdss_dsi { + hw-config = "single_dsi"; +}; + +&mdss_dsi0 { + qcom,dsi-pref-prim-pan = <&dsi_hx8394d_720_vid>; + pinctrl-names = "mdss_default", "mdss_sleep"; + pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; + pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; + + qcom,platform-te-gpio = <&tlmm 41 0>; + qcom,platform-reset-gpio = <&tlmm 39 0>; + qcom,platform-bklight-en-gpio = <&tlmm 48 0>; +}; + +&dsi_hx8394d_720_vid { + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_tlmm_gpio"; + qcom,mdss-dsi-bl-pmic-bank-select = <0>; + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; +}; diff --git a/arch/arm64/boot/dts/qcom/qcs401.dtsi b/arch/arm64/boot/dts/qcom/qcs401.dtsi index abf0c5893a2b..06387ed9e2e3 100644 --- a/arch/arm64/boot/dts/qcom/qcs401.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs401.dtsi @@ -11,7 +11,7 @@ * GNU General Public License for more details. */ -#include "qcs405.dtsi" +#include "qcs403.dtsi" / { model = "Qualcomm Technologies, Inc. QCS401"; @@ -20,29 +20,5 @@ }; &soc { - /delete-node/ qcom,msm-cpufreq; - - msm_cpufreq: qcom,msm-cpufreq { - compatible = "qcom,msm-cpufreq"; - clock-names = "cpu0_clk"; - clocks = <&clock_cpu APCS_MUX_CLK>; - - qcom,cpufreq-table = - < 1094400 >, - < 1248000 >, - < 1401600 >; - }; - - /delete-node/ qcom,cpu0-computemon; - - cpu0_computemon: qcom,cpu0-computemon { - compatible = "qcom,arm-cpu-mon"; - qcom,cpulist = <&CPU0 &CPU1>; - qcom,target-dev = <&cpu0_cpu_ddr_latfloor>; - qcom,core-dev-table = - < 1094400 MHZ_TO_MBPS( 297, 8) >, - < 1248000 MHZ_TO_MBPS( 597, 8) >, - < 1401600 MHZ_TO_MBPS( 710, 8) >; - }; + /delete-node/ qcom,turing@800000; }; - diff --git a/arch/arm64/boot/dts/qcom/qcs403.dtsi b/arch/arm64/boot/dts/qcom/qcs403.dtsi index b005e60fb741..70f1c135f7db 100644 --- a/arch/arm64/boot/dts/qcom/qcs403.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs403.dtsi @@ -61,19 +61,6 @@ }; }; - /delete-node/ qcom,msm-cpufreq; - - msm_cpufreq: qcom,msm-cpufreq { - compatible = "qcom,msm-cpufreq"; - clock-names = "cpu0_clk"; - clocks = <&clock_cpu APCS_MUX_CLK>; - - qcom,cpufreq-table = - < 1094400 >, - < 1248000 >, - < 1401600 >; - }; - /delete-node/ qcom,cpu0-computemon; cpu0_computemon: qcom,cpu0-computemon { diff --git a/arch/arm64/boot/dts/qcom/qcs404-iot-sku3.dts b/arch/arm64/boot/dts/qcom/qcs404-iot-sku3.dts index 44178118e543..227e63721fe9 100644 --- a/arch/arm64/boot/dts/qcom/qcs404-iot-sku3.dts +++ b/arch/arm64/boot/dts/qcom/qcs404-iot-sku3.dts @@ -18,8 +18,8 @@ #include "qcs405-circular-pca9956.dtsi" / { - model = "Qualcomm Technologies, Inc. QCS403 SSRD IOT"; - compatible = "qcom,qcs403-iot", "qcom,qcs403", "qcom,iot"; + model = "Qualcomm Technologies, Inc. QCS404 SSRD IOT"; + compatible = "qcom,qcs404-iot", "qcom,qcs404", "qcom,iot"; qcom,board-id = <0x010020 0x4>; }; diff --git a/arch/arm64/boot/dts/qcom/qcs404.dtsi b/arch/arm64/boot/dts/qcom/qcs404.dtsi index 52b9c16ac1af..bcf08143cbae 100644 --- a/arch/arm64/boot/dts/qcom/qcs404.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs404.dtsi @@ -14,7 +14,7 @@ #include "qcs405.dtsi" / { - model = "Qualcomm Technologies, Inc. QCS403"; + model = "Qualcomm Technologies, Inc. QCS404"; qcom,msm-name = "QCS404"; qcom,msm-id = <410 0x0>; -- GitLab From 0fa9505e3b0064ba981da3a28ffdc452d37c8808 Mon Sep 17 00:00:00 2001 From: Zhenhua Huang Date: Tue, 23 Jul 2019 15:48:04 +0800 Subject: [PATCH 1086/1121] ARM: dts: qcom: Add iommu bus voting details for atoll Add iommu bus voting details to vote for the bus clock rate required to access iommu registers on atoll. Change-Id: Ib6a526b52145ab4758d007aa6680024e6aac75dd Signed-off-by: Zhenhua Huang --- .../boot/dts/qcom/msm-arm-smmu-atoll.dtsi | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm-arm-smmu-atoll.dtsi b/arch/arm64/boot/dts/qcom/msm-arm-smmu-atoll.dtsi index d96746cce5cd..694742ea76fd 100644 --- a/arch/arm64/boot/dts/qcom/msm-arm-smmu-atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/msm-arm-smmu-atoll.dtsi @@ -10,6 +10,7 @@ * GNU General Public License for more details. */ #include +#include &soc { kgsl_smmu: arm,smmu-kgsl@5040000 { @@ -138,6 +139,17 @@ <0x15182200 0x8>; reg-names = "base", "status-reg"; qcom,stream-id-range = <0x0 0x400>; + qcom,msm-bus,name = "apps_smmu"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,active-only; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + , + , + <0 0>, + , + , + <0 1000>; }; anoc_2_tbu: anoc_2_tbu@0x15189000 { @@ -146,6 +158,17 @@ <0x15182208 0x8>; reg-names = "base", "status-reg"; qcom,stream-id-range = <0x400 0x400>; + qcom,msm-bus,name = "apps_smmu"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,active-only; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + , + , + <0 0>, + , + , + <0 1000>; }; mnoc_hf_0_tbu: mnoc_hf_0_tbu@0x1518d000 { @@ -156,6 +179,17 @@ qcom,stream-id-range = <0x800 0x400>; qcom,regulator-names = "vdd"; vdd-supply = <&hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc>; + qcom,msm-bus,name = "mnoc_hf_0_tbu"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,active-only; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + , + , + <0 0>, + , + , + <0 1000>; }; mnoc_sf_0_tbu: mnoc_sf_0_tbu@0x15191000 { @@ -166,6 +200,17 @@ qcom,stream-id-range = <0xc00 0x400>; qcom,regulator-names = "vdd"; vdd-supply = <&hlos1_vote_mmnoc_mmu_tbu_sf_gdsc>; + qcom,msm-bus,name = "mnoc_sf_0_tbu"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,active-only; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + , + , + <0 0>, + , + , + <0 1000>; }; lpass_noc_tbu: lpass_noc_tbu@0x15195000 { @@ -174,6 +219,17 @@ <0x15182220 0x8>; reg-names = "base", "status-reg"; qcom,stream-id-range = <0x1000 0x400>; + qcom,msm-bus,name = "apps_smmu"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,active-only; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + , + , + <0 0>, + , + , + <0 1000>; }; compute_dsp_0_tbu: compute_dsp_0_tbu@0x15199000 { @@ -183,6 +239,17 @@ reg-names = "base", "status-reg"; qcom,stream-id-range = <0x1400 0x400>; /* No GDSC */ + qcom,msm-bus,name = "apps_smmu"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,active-only; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + , + , + <0 0>, + , + , + <0 1000>; }; }; -- GitLab From 5e3b7b62c24169543db580d2130f181c49d82013 Mon Sep 17 00:00:00 2001 From: Sumeet Sahu Date: Thu, 21 Mar 2019 18:42:09 +0530 Subject: [PATCH 1087/1121] drivers: net: qti-can: Add ASYNC probe and power notification Add ASYNC probe and power notification to the firmware. Change-Id: I641b13b456e6279c2245ff2ebdd6922c6283da5b Signed-off-by: Sumeet Sahu Signed-off-by: Aishwarya Prasad --- drivers/net/can/spi/qti-can.c | 90 ++++++++++++++++++++++++++++++----- 1 file changed, 79 insertions(+), 11 deletions(-) diff --git a/drivers/net/can/spi/qti-can.c b/drivers/net/can/spi/qti-can.c index 738caea83ffe..3c4aeefea4a4 100644 --- a/drivers/net/can/spi/qti-can.c +++ b/drivers/net/can/spi/qti-can.c @@ -126,6 +126,8 @@ struct spi_miso { /* TLV for MISO line */ #define CMD_END_BOOT_ROM_UPGRADE 0x9B #define CMD_END_FW_UPDATE_FILE 0x9C #define CMD_UPDATE_TIME_INFO 0x9D +#define CMD_SUSPEND_EVENT 0x9E +#define CMD_RESUME_EVENT 0x9F #define IOCTL_RELEASE_CAN_BUFFER (SIOCDEVPRIVATE + 0) #define IOCTL_ENABLE_BUFFERING (SIOCDEVPRIVATE + 1) @@ -172,8 +174,8 @@ struct can_add_filter_resp { struct can_receive_frame { u8 can_if; - u64 ts; - u32 mid; + __le64 ts; + __le32 mid; u8 dlc; u8 data[8]; } __packed; @@ -188,7 +190,7 @@ struct can_config_bit_timing { } __packed; struct can_time_info { - u64 time; + __le64 time; } __packed; static struct can_bittiming_const rh850_bittiming_const = { @@ -231,7 +233,7 @@ static struct can_bittiming_const qti_can_data_bittiming_const = { struct vehicle_property { int id; - u64 ts; + __le64 ts; int zone; int val_type; u32 data_len; @@ -333,7 +335,8 @@ static void qti_can_receive_frame(struct qti_can *priv_data, for (i = 0; i < cf->can_dlc; i++) cf->data[i] = frame->data[i]; - nsec = ms_to_ktime(le64_to_cpu(frame->ts) + priv_data->time_diff); + nsec = ms_to_ktime(le64_to_cpu(frame->ts) + + priv_data->time_diff); skt = skb_hwtstamps(skb); skt->hwtstamp = nsec; skb->tstamp = nsec; @@ -620,6 +623,30 @@ static int qti_can_query_firmware_version(struct qti_can *priv_data) return ret; } +static int qti_can_notify_power_events(struct qti_can *priv_data, u8 event_type) +{ + char *tx_buf, *rx_buf; + int ret; + struct spi_mosi *req; + + mutex_lock(&priv_data->spi_lock); + tx_buf = priv_data->tx_buf; + rx_buf = priv_data->rx_buf; + memset(tx_buf, 0, XFER_BUFFER_SIZE); + memset(rx_buf, 0, XFER_BUFFER_SIZE); + priv_data->xfer_length = XFER_BUFFER_SIZE; + + req = (struct spi_mosi *)tx_buf; + req->cmd = event_type; + req->len = 0; + req->seq = atomic_inc_return(&priv_data->msg_seq); + + ret = qti_can_do_spi_transaction(priv_data); + mutex_unlock(&priv_data->spi_lock); + + return ret; +} + static int qti_can_set_bitrate(struct net_device *netdev) { char *tx_buf, *rx_buf; @@ -1088,6 +1115,11 @@ static int qti_can_do_blocking_ioctl(struct net_device *netdev, return -EFAULT; } + if (ioctl_data->len < 0) { + LOGDE("ioctl_data->len is: %d\n", ioctl_data->len); + return -EINVAL; + } + /* Regular NULL check will fail here as ioctl_data is at * some offset */ @@ -1098,6 +1130,11 @@ static int qti_can_do_blocking_ioctl(struct net_device *netdev, } LOGDI("%s len %d\n", __func__, len); + if (len > 64 || len < 0) { + LOGDE("len value[%d] is not correct!!\n", len); + return -EINVAL; + } + priv_data->wait_cmd = spi_cmd; priv_data->cmd_result = -1; reinit_completion(&priv_data->response_completion); @@ -1380,6 +1417,8 @@ static int qti_can_probe(struct spi_device *spi) gpio_direction_output(priv_data->reset, 1); /* wait for controller to come up after reset */ msleep(priv_data->reset_delay_msec); + } else { + msleep(priv_data->reset_delay_msec); } priv_data->support_can_fd = of_property_read_bool(spi->dev.of_node, @@ -1486,19 +1525,47 @@ static int qti_can_remove(struct spi_device *spi) static int qti_can_suspend(struct device *dev) { struct spi_device *spi = to_spi_device(dev); + struct qti_can *priv_data = NULL; + u8 power_event = CMD_SUSPEND_EVENT; + int ret = 0; - enable_irq_wake(spi->irq); - return 0; + if (spi) { + priv_data = spi_get_drvdata(spi); + enable_irq_wake(spi->irq); + } else { + ret = -1; + } + + if (priv_data && !(ret < 0)) + ret = qti_can_notify_power_events(priv_data, power_event); + + return ret; } static int qti_can_resume(struct device *dev) { struct spi_device *spi = to_spi_device(dev); - struct qti_can *priv_data = spi_get_drvdata(spi); + struct qti_can *priv_data = NULL; + int ret = 0; + u8 power_event = CMD_RESUME_EVENT; - disable_irq_wake(spi->irq); - qti_can_rx_message(priv_data); - return 0; + if (spi) { + priv_data = spi_get_drvdata(spi); + disable_irq_wake(spi->irq); + + if (priv_data) + qti_can_rx_message(priv_data); + else + ret = -1; + + } else { + ret = -1; + } + + if (priv_data && !(ret < 0)) + ret = qti_can_notify_power_events(priv_data, power_event); + + return ret; } static const struct dev_pm_ops qti_can_dev_pm_ops = { @@ -1515,6 +1582,7 @@ static struct spi_driver qti_can_driver = { #ifdef CONFIG_PM .pm = &qti_can_dev_pm_ops, #endif + .probe_type = PROBE_PREFER_ASYNCHRONOUS, }, .probe = qti_can_probe, .remove = qti_can_remove, -- GitLab From 976445dfd493b13441a0d1e761396e6574fa722e Mon Sep 17 00:00:00 2001 From: Aishwarya Prasad Date: Tue, 30 Jul 2019 14:38:25 +0530 Subject: [PATCH 1088/1121] drivers: net: can: Add non-blocking call for end upgrade ioctl Add non-blocking call to avoid the return value error. Change-Id: Ib849b57bdb574603aa3b296404eb0a8d564389de Signed-off-by: Aishwarya Prasad --- drivers/net/can/spi/qti-can.c | 38 ++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/spi/qti-can.c b/drivers/net/can/spi/qti-can.c index 3c4aeefea4a4..b4ffa2031369 100644 --- a/drivers/net/can/spi/qti-can.c +++ b/drivers/net/can/spi/qti-can.c @@ -1073,6 +1073,40 @@ static int qti_can_convert_ioctl_cmd_to_spi_cmd(int ioctl_cmd) return -EINVAL; } +static int qti_can_end_fwupgrade_ioctl(struct net_device *netdev, + struct ifreq *ifr, int cmd) +{ + int spi_cmd, ret; + + struct qti_can *priv_data; + struct qti_can_netdev_privdata *netdev_priv_data; + struct spi_device *spi; + int len = 0; + u8 *data = NULL; + + netdev_priv_data = netdev_priv(netdev); + priv_data = netdev_priv_data->qti_can; + spi = priv_data->spidev; + spi_cmd = qti_can_convert_ioctl_cmd_to_spi_cmd(cmd); + LOGDI("%s spi_cmd %x\n", __func__, spi_cmd); + if (spi_cmd < 0) { + LOGDE("%s wrong command %d\n", __func__, cmd); + return spi_cmd; + } + + if (!ifr) + return -EINVAL; + + mutex_lock(&priv_data->spi_lock); + LOGDI("%s len %d\n", __func__, len); + + ret = qti_can_send_spi_locked(priv_data, spi_cmd, len, data); + + mutex_unlock(&priv_data->spi_lock); + + return ret; +} + static int qti_can_do_blocking_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) { @@ -1208,10 +1242,12 @@ static int qti_can_netdev_do_ioctl(struct net_device *netdev, qti_can_frame_filter(netdev, ifr, cmd); ret = 0; break; + case IOCTL_END_FIRMWARE_UPGRADE: + ret = qti_can_end_fwupgrade_ioctl(netdev, ifr, cmd); + break; case IOCTL_GET_FW_BR_VERSION: case IOCTL_BEGIN_FIRMWARE_UPGRADE: case IOCTL_FIRMWARE_UPGRADE_DATA: - case IOCTL_END_FIRMWARE_UPGRADE: case IOCTL_BEGIN_BOOT_ROM_UPGRADE: case IOCTL_BOOT_ROM_UPGRADE_DATA: case IOCTL_END_BOOT_ROM_UPGRADE: -- GitLab From f4622de69302b496c44525bc172b25f40efa6209 Mon Sep 17 00:00:00 2001 From: Yimin Peng Date: Tue, 30 Jul 2019 17:31:43 +0800 Subject: [PATCH 1089/1121] defconfig: msm: enable spmi pmic pinctrl for QTI Quin GVM Enable pmic pinctrl based on virtio spmi. Change-Id: I7ebd119d7ae356458028a2cb9186fdf0cbc4f5e6 Signed-off-by: Yimin Peng --- arch/arm64/configs/vendor/qti-quin-gvm-perf_defconfig | 2 ++ arch/arm64/configs/vendor/qti-quin-gvm_defconfig | 2 ++ 2 files changed, 4 insertions(+) diff --git a/arch/arm64/configs/vendor/qti-quin-gvm-perf_defconfig b/arch/arm64/configs/vendor/qti-quin-gvm-perf_defconfig index 11b0d60e4112..e8bc579182ba 100644 --- a/arch/arm64/configs/vendor/qti-quin-gvm-perf_defconfig +++ b/arch/arm64/configs/vendor/qti-quin-gvm-perf_defconfig @@ -310,6 +310,7 @@ CONFIG_SPI_SPIDEV=y CONFIG_SPMI=y CONFIG_PTP_1588_CLOCK=y CONFIG_PINCTRL_SX150X=y +CONFIG_PINCTRL_QCOM_SPMI_PMIC=y CONFIG_PINCTRL_SM8150=y CONFIG_PINCTRL_SDMSHRIKE=y CONFIG_PINCTRL_SM6150=y @@ -323,6 +324,7 @@ CONFIG_THERMAL=y CONFIG_THERMAL_WRITABLE_TRIPS=y CONFIG_THERMAL_GOV_USER_SPACE=y CONFIG_THERMAL_GOV_LOW_LIMITS=y +CONFIG_MFD_SPMI_PMIC=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_PROXY_CONSUMER=y diff --git a/arch/arm64/configs/vendor/qti-quin-gvm_defconfig b/arch/arm64/configs/vendor/qti-quin-gvm_defconfig index c6fa0e9008c3..f9a7e58bcaef 100644 --- a/arch/arm64/configs/vendor/qti-quin-gvm_defconfig +++ b/arch/arm64/configs/vendor/qti-quin-gvm_defconfig @@ -322,6 +322,7 @@ CONFIG_SPI_SPIDEV=y CONFIG_SPMI=y CONFIG_PTP_1588_CLOCK=y CONFIG_PINCTRL_SX150X=y +CONFIG_PINCTRL_QCOM_SPMI_PMIC=y CONFIG_PINCTRL_SM8150=y CONFIG_PINCTRL_SDMSHRIKE=y CONFIG_PINCTRL_SM6150=y @@ -335,6 +336,7 @@ CONFIG_THERMAL=y CONFIG_THERMAL_WRITABLE_TRIPS=y CONFIG_THERMAL_GOV_USER_SPACE=y CONFIG_THERMAL_GOV_LOW_LIMITS=y +CONFIG_MFD_SPMI_PMIC=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_PROXY_CONSUMER=y -- GitLab From a7ad979219dfa3b8b5224fc042412834486d58f6 Mon Sep 17 00:00:00 2001 From: Chandan Kumar Jha Date: Thu, 18 Jul 2019 20:12:30 +0530 Subject: [PATCH 1090/1121] ARM: dts: msm: Add dtsi support for v150_110 camera Camera CAMNOC, ICP, IPE, BPS, CDM, SMMU, JPEG, IFE, PPI nodes are added for chipsets having v150_110 camera. Change-Id: Iea631ba2f7a48fa1a144769097acdc865cfbbbdc Signed-off-by: Chandan Kumar Jha --- .../bindings/media/video/msm-cam-ppi.txt | 102 ++ arch/arm64/boot/dts/qcom/atoll-camera.dtsi | 869 ++++++++++++++++++ 2 files changed, 971 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/video/msm-cam-ppi.txt create mode 100644 arch/arm64/boot/dts/qcom/atoll-camera.dtsi diff --git a/Documentation/devicetree/bindings/media/video/msm-cam-ppi.txt b/Documentation/devicetree/bindings/media/video/msm-cam-ppi.txt new file mode 100644 index 000000000000..aeed60fa6055 --- /dev/null +++ b/Documentation/devicetree/bindings/media/video/msm-cam-ppi.txt @@ -0,0 +1,102 @@ +* Qualcomm Technologies, Inc. MSM camera PPI + +======================= +Required Node Structure +======================= +The camera PPI node must be described in First level of device nodes. The +first level describe the overall PPI node structure. + +====================================== +First Level Node - PPI device +====================================== + +- compatible + Usage: required + Value type: + Definition: Should be "qcom,ppi-v1.0", + "qcom,ppi-v1.1", "qcom,ppi-v1.2", + "qcom,ppi-v2.0", "qcom,ppi". + +- cell-index: ppi hardware core index + Usage: required + Value type: + Definition: Should specify the Hardware index id. + +- reg + Usage: required + Value type: + Definition: offset and length of the register set + for the device for the ppi operating in + compatible mode. + +- reg-names + Usage: required + Value type: + Definition: Should specify relevant names to each + reg property defined. + +- reg-cam-base + Usage: required + Value type: + Definition: offset of PPI in camera hw block + +- interrupts + Usage: required + Value type: + Definition: Interrupt associated with PPI HW. + +- interrupt-names + Usage: required + Value type: + Definition: Name of the interrupt. + +- clock-names + Usage: required + Value type: + Definition: List of clock names required for PPI HW. + +- clock-rates + Usage: required + Value type: + Definition: List of clock rates in Hz for PPI HW. + +- clock-cntl-level + Usage: required + Value type: + Definition: All different clock level node can support. + +- clocks + Usage: required + Value type: + Definition: all clock phandle and source clocks. + +- regulator-names + Usage: required + Value type: + Definition: name of the voltage regulators required for the device. + +- gdscr-supply + Usage: required + Value type: + Definition: should contain gdsr regulator used for PPI clocks. + +Example: + qcom,ppi0@ace0000 { + cell-index = <0>; + compatible = "qcom,ppi170"; + reg-names = "ppi"; + reg = <0xace0000 0x200>; + reg-cam-base = <0xe0000>; + interrupt-names = "ppi"; + interrupts = <0 202 0>; + regulator-names = "gdscr", "refgen"; + gdscr-supply = <&titan_top_gdsc>; + clocks = <&clock_camcc CAM_CC_CPHY_RX_CLK_SRC>, + <&clock_camcc CAM_CC_PPI0_CLK>, + <&clock_camcc CAM_CC_CSI0PHYTIMER_CLK_SRC>, + <&clock_camcc CAM_CC_CSI0PHYTIMER_CLK>; + clock-names = "cphy_rx_clk_src", "ppi0_clk" + clock-rates = <400000000 0 300000000 0>; + clock-cntl-level = "turbo"; + status = "ok"; +}; diff --git a/arch/arm64/boot/dts/qcom/atoll-camera.dtsi b/arch/arm64/boot/dts/qcom/atoll-camera.dtsi new file mode 100644 index 000000000000..05665defb5b2 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/atoll-camera.dtsi @@ -0,0 +1,869 @@ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + qcom,cam-req-mgr { + compatible = "qcom,cam-req-mgr"; + status = "ok"; + }; + + qcom,cam_smmu { + compatible = "qcom,msm-cam-smmu"; + status = "ok"; + + msm_cam_smmu_ife { + compatible = "qcom,msm-cam-smmu-cb"; + iommus = <&apps_smmu 0x820 0x0>, + <&apps_smmu 0x840 0x0>, + <&apps_smmu 0x860 0x0>; + label = "ife"; + ife_iova_mem_map: iova-mem-map { + /* IO region is approximately 3.4 GB */ + iova-mem-region-io { + iova-region-name = "io"; + iova-region-start = <0x7400000>; + iova-region-len = <0xd8c00000>; + iova-region-id = <0x3>; + status = "ok"; + }; + }; + }; + + msm_cam_smmu_lrme { + compatible = "qcom,msm-cam-smmu-cb"; + iommus = <&apps_smmu 0x0cc0 0x0>, + <&apps_smmu 0x0d40 0x0>; + label = "lrme"; + lrme_iova_mem_map: iova-mem-map { + iova-mem-region-shared { + /* Shared region is 100MB long */ + iova-region-name = "shared"; + iova-region-start = <0x7400000>; + iova-region-len = <0x6400000>; + iova-region-id = <0x1>; + status = "ok"; + }; + /* IO region is approximately 3.3 GB */ + iova-mem-region-io { + iova-region-name = "io"; + iova-region-start = <0xd800000>; + iova-region-len = <0xd2800000>; + iova-region-id = <0x3>; + status = "ok"; + }; + }; + }; + + msm_cam_smmu_jpeg { + compatible = "qcom,msm-cam-smmu-cb"; + iommus = <&apps_smmu 0xd80 0x20>, + <&apps_smmu 0xda0 0x20>; + label = "jpeg"; + jpeg_iova_mem_map: iova-mem-map { + /* IO region is approximately 3.4 GB */ + iova-mem-region-io { + iova-region-name = "io"; + iova-region-start = <0x7400000>; + iova-region-len = <0xd8c00000>; + iova-region-id = <0x3>; + status = "ok"; + }; + }; + }; + + msm_cam_icp_fw { + compatible = "qcom,msm-cam-smmu-fw-dev"; + label="icp"; + memory-region = <&pil_camera_mem>; + }; + + msm_cam_smmu_icp { + compatible = "qcom,msm-cam-smmu-cb"; + iommus = <&apps_smmu 0x0ce2 0x0>, + <&apps_smmu 0x0c80 0x0>, + <&apps_smmu 0x0ca0 0x0>, + <&apps_smmu 0x0d00 0x0>, + <&apps_smmu 0x0d20 0x0>; + label = "icp"; + icp_iova_mem_map: iova-mem-map { + iova-mem-region-firmware { + /* Firmware region is 5MB */ + iova-region-name = "firmware"; + iova-region-start = <0x0>; + iova-region-len = <0x500000>; + iova-region-id = <0x0>; + status = "ok"; + }; + + iova-mem-region-shared { + /* Shared region is 150MB long */ + iova-region-name = "shared"; + iova-region-start = <0x7400000>; + iova-region-len = <0x9600000>; + iova-region-id = <0x1>; + iova-granularity = <0x15>; + status = "ok"; + }; + + iova-mem-region-secondary-heap { + /* Secondary heap region is 1MB long */ + iova-region-name = "secheap"; + iova-region-start = <0x10A00000>; + iova-region-len = <0x100000>; + iova-region-id = <0x4>; + status = "ok"; + }; + + iova-mem-region-io { + /* IO region is approximately 3 GB */ + iova-region-name = "io"; + iova-region-start = <0x10B11000>; + iova-region-len = <0xCF4EF000>; + iova-region-id = <0x3>; + status = "ok"; + }; + + iova-mem-qdss-region { + /* qdss region is approximately 64K */ + iova-region-name = "qdss"; + iova-region-start = <0x10B00000>; + iova-region-len = <0x10000>; + iova-region-id = <0x5>; + qdss-phy-addr = <0x16790000>; + status = "ok"; + }; + }; + }; + + msm_cam_smmu_cpas_cdm { + compatible = "qcom,msm-cam-smmu-cb"; + iommus = <&apps_smmu 0x0d60 0x0>, + <&apps_smmu 0x0d61 0x0>; + label = "cpas-cdm0"; + cpas_cdm_iova_mem_map: iova-mem-map { + iova-mem-region-io { + /* IO region is approximately 3.4 GB */ + iova-region-name = "io"; + iova-region-start = <0x7400000>; + iova-region-len = <0xd8c00000>; + iova-region-id = <0x3>; + status = "ok"; + }; + }; + }; + + msm_cam_smmu_secure { + compatible = "qcom,msm-cam-smmu-cb"; + label = "cam-secure"; + qcom,secure-cb; + }; + }; + + qcom,cam-cpas@ac40000 { + cell-index = <0>; + compatible = "qcom,cam-cpas"; + label = "cpas"; + arch-compat = "cpas_top"; + status = "ok"; + reg-names = "cam_cpas_top", "cam_camnoc"; + reg = <0xac40000 0x1000>, + <0xac42000 0x5000>; + reg-cam-base = <0x40000 0x42000>; + interrupt-names = "cpas_camnoc"; + interrupts = <0 459 0>; + qcom,cpas-hw-ver = <0x150110>; /* Titan v150 v1.1.0 */ + camnoc-axi-min-ib-bw = <3000000000>; + regulator-names = "camss-vdd"; + camss-vdd-supply = <&titan_top_gdsc>; + clock-names = "gcc_ahb_clk", + "gcc_axi_clk", + "soc_ahb_clk", + "slow_ahb_clk_src", + "cpas_ahb_clk", + "camnoc_axi_clk"; + clocks = <&clock_gcc GCC_CAMERA_AHB_CLK>, + <&clock_gcc GCC_CAMERA_HF_AXI_CLK>, + <&clock_camcc CAM_CC_SOC_AHB_CLK>, + <&clock_camcc CAM_CC_SLOW_AHB_CLK_SRC>, + <&clock_camcc CAM_CC_CPAS_AHB_CLK>, + <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>; + src-clock-name = "slow_ahb_clk_src"; + clock-rates = <0 0 0 0 0 0>, + <0 0 0 80000000 0 0>, + <0 0 0 80000000 0 0>, + <0 0 0 80000000 0 0>, + <0 0 0 80000000 0 0>, + <0 0 0 80000000 0 0>, + <0 0 0 80000000 0 0>; + clock-cntl-level = "suspend", "minsvs", "lowsvs", "svs", + "svs_l1", "nominal", "turbo"; + //qcom,cam-cx-ipeak = <&cx_ipeak_lm 2>; + qcom,msm-bus,name = "cam_ahb"; + qcom,msm-bus,num-cases = <7>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + , + , + , + , + , + , + ; + vdd-corners = ; + vdd-corner-ahb-mapping = "suspend", "suspend", + "minsvs", "lowsvs", "svs", "svs_l1", + "nominal", "nominal", "nominal", + "turbo", "turbo"; + client-id-based; + client-names = + "csiphy0", "csiphy1", "csiphy2", "csiphy3", + "csid0", "csid1", "csid2", "cci0", + "ife0", "ife1", "ife2", "ipe0", + "ipe1", "cam-cdm-intf0", "cpas-cdm0", "bps0", + "icp0", "jpeg-dma0", "jpeg-enc0", "lrmecpas0"; + client-axi-port-names = + "cam_hf_1", "cam_hf_2", "cam_hf_2", "cam_hf_2", + "cam_hf_1", "cam_hf_2", "cam_hf_2", "cam_sf_1", + "cam_hf_1", "cam_hf_2", "cam_hf_2", "cam_sf_1", + "cam_sf_1", "cam_sf_1", "cam_sf_1", "cam_sf_1", + "cam_sf_1", "cam_sf_1", "cam_sf_1", "cam_sf_1"; + client-bus-camnoc-based; + qcom,axi-port-list { + qcom,axi-port1 { + qcom,axi-port-name = "cam_hf_1"; + qcom,axi-port-mnoc { + qcom,msm-bus,name = "cam_hf_1_mnoc"; + qcom,msm-bus-vector-dyn-vote; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + , + ; + }; + qcom,axi-port-camnoc { + qcom,msm-bus,name = "cam_hf_1_camnoc"; + qcom,msm-bus-vector-dyn-vote; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + , + ; + }; + }; + qcom,axi-port2 { + qcom,axi-port-name = "cam_hf_2"; + qcom,axi-port-mnoc { + qcom,msm-bus,name = "cam_hf_2_mnoc"; + qcom,msm-bus-vector-dyn-vote; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + , + ; + }; + qcom,axi-port-camnoc { + qcom,msm-bus,name = "cam_hf_2_camnoc"; + qcom,msm-bus-vector-dyn-vote; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + , + ; + }; + }; + qcom,axi-port3 { + qcom,axi-port-name = "cam_sf_1"; + qcom,axi-port-mnoc { + qcom,msm-bus,name = "cam_sf_1_mnoc"; + qcom,msm-bus-vector-dyn-vote; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + , + ; + }; + qcom,axi-port-camnoc { + qcom,msm-bus,name = "cam_sf_1_camnoc"; + qcom,msm-bus-vector-dyn-vote; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + , + ; + }; + }; + }; + }; + + + qcom,cam-icp { + compatible = "qcom,cam-icp"; + compat-hw-name = "qcom,a5", + "qcom,ipe0", + "qcom,bps"; + num-a5 = <1>; + num-ipe = <1>; + num-bps = <1>; + icp_pc_en; + status = "ok"; + }; + + cam_a5: qcom,a5@ac00000 { + cell-index = <0>; + compatible = "qcom,cam-a5"; + reg = <0xac00000 0x6000>, + <0xac10000 0x8000>, + <0xac18000 0x3000>; + reg-names = "a5_qgic", "a5_sierra", "a5_csr"; + reg-cam-base = <0x00000 0x10000 0x18000>; + interrupts = <0 463 0>; + interrupt-names = "a5"; + regulator-names = "camss-vdd"; + camss-vdd-supply = <&titan_top_gdsc>; + clock-names = "gcc_cam_ahb_clk", + "gcc_cam_axi_clk", + "soc_fast_ahb", + "soc_ahb_clk", + "cpas_ahb_clk", + "camnoc_axi_clk", + "icp_clk", + "icp_clk_src"; + clocks = <&clock_gcc GCC_CAMERA_AHB_CLK>, + <&clock_gcc GCC_CAMERA_HF_AXI_CLK>, + <&clock_camcc CAM_CC_FAST_AHB_CLK_SRC>, + <&clock_camcc CAM_CC_SOC_AHB_CLK>, + <&clock_camcc CAM_CC_CPAS_AHB_CLK>, + <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>, + <&clock_camcc CAM_CC_ICP_CLK>, + <&clock_camcc CAM_CC_ICP_CLK_SRC>; + + clock-rates = + <0 0 200000000 0 0 0 0 360000000>, + <0 0 200000000 0 0 0 0 600000000>; + clock-cntl-level = "svs", "turbo"; + fw_name = "CAMERA_ICP.elf"; + ubwc-cfg = <0x73 0x1CF>; + status = "ok"; + }; + + cam_ipe0: qcom,ipe0 { + cell-index = <0>; + compatible = "qcom,cam-ipe"; + reg = <0xac87000 0x3000>; + reg-names = "ipe0_top"; + reg-cam-base = <0x87000>; + regulator-names = "ipe0-vdd"; + ipe0-vdd-supply = <&ipe_0_gdsc>; + clock-names = "ipe_0_ahb_clk", + "ipe_0_areg_clk", + "ipe_0_axi_clk", + "ipe_0_clk", + "ipe_0_clk_src"; + src-clock-name = "ipe_0_clk_src"; + clocks = <&clock_camcc CAM_CC_IPE_0_AHB_CLK>, + <&clock_camcc CAM_CC_IPE_0_AREG_CLK>, + <&clock_camcc CAM_CC_IPE_0_AXI_CLK>, + <&clock_camcc CAM_CC_IPE_0_CLK>, + <&clock_camcc CAM_CC_IPE_0_CLK_SRC>; + + clock-rates = + <0 0 0 0 360000000>, + <0 0 0 0 432000000>, + <0 0 0 0 540000000>, + <0 0 0 0 600000000>; + clock-cntl-level = "svs", + "svs_l1", "nominal", "turbo"; + status = "ok"; + }; + + cam_bps: qcom,bps { + cell-index = <0>; + compatible = "qcom,cam-bps"; + reg = <0xac6f000 0x3000>; + reg-names = "bps_top"; + reg-cam-base = <0x6f000>; + regulator-names = "bps-vdd"; + bps-vdd-supply = <&bps_gdsc>; + clock-names = "bps_ahb_clk", + "bps_areg_clk", + "bps_axi_clk", + "bps_clk", + "bps_clk_src"; + src-clock-name = "bps_clk_src"; + clocks = <&clock_camcc CAM_CC_BPS_AHB_CLK>, + <&clock_camcc CAM_CC_BPS_AREG_CLK>, + <&clock_camcc CAM_CC_BPS_AXI_CLK>, + <&clock_camcc CAM_CC_BPS_CLK>, + <&clock_camcc CAM_CC_BPS_CLK_SRC>; + + clock-rates = + <0 0 0 0 360000000>, + <0 0 0 0 432000000>, + <0 0 0 0 480000000>, + <0 0 0 0 600000000>; + clock-cntl-level = "svs", + "svs_l1", "nominal", "turbo"; + status = "ok"; + }; + + qcom,cam-cdm-intf { + compatible = "qcom,cam-cdm-intf"; + cell-index = <0>; + label = "cam-cdm-intf"; + num-hw-cdm = <1>; + cdm-client-names = "vfe", + "jpegdma", + "jpegenc", + "lrmecdm"; + status = "ok"; + }; + + qcom,cpas-cdm0@ac48000 { + cell-index = <0>; + compatible = "qcom,cam170-cpas-cdm0"; + label = "cpas-cdm"; + reg = <0xac48000 0x1000>; + reg-names = "cpas-cdm"; + reg-cam-base = <0x48000>; + interrupts = <0 469 0>; + interrupt-names = "cpas-cdm"; + regulator-names = "camss"; + camss-supply = <&titan_top_gdsc>; + clock-names = "gcc_camera_ahb", + "gcc_camera_axi", + "cam_cc_soc_ahb_clk", + "cam_cc_cpas_ahb_clk", + "cam_cc_camnoc_axi_clk"; + clocks = <&clock_gcc GCC_CAMERA_AHB_CLK>, + <&clock_gcc GCC_CAMERA_HF_AXI_CLK>, + <&clock_camcc CAM_CC_SOC_AHB_CLK>, + <&clock_camcc CAM_CC_CPAS_AHB_CLK>, + <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>; + clock-rates = <0 0 0 0 0>; + clock-cntl-level = "svs"; + cdm-client-names = "ife"; + status = "ok"; + }; + + qcom,cam-isp { + compatible = "qcom,cam-isp"; + arch-compat = "ife"; + status = "ok"; + }; + + cam_csid0: qcom,csid0@acb3000 { + cell-index = <0>; + compatible = "qcom,csid170"; + reg-names = "csid"; + reg = <0xacb3000 0x1000>; + reg-cam-base = <0xb3000>; + interrupt-names = "csid"; + interrupts = <0 464 0>; + regulator-names = "camss", "ife0"; + camss-supply = <&titan_top_gdsc>; + ife0-supply = <&ife_0_gdsc>; + clock-names = "camera_ahb", + "camera_axi", + "soc_ahb_clk", + "cpas_ahb_clk", + "slow_ahb_clk_src", + "ife_csid_clk", + "ife_csid_clk_src", + "ife_cphy_rx_clk", + "cphy_rx_clk_src", + "ife_clk", + "ife_clk_src", + "camnoc_axi_clk", + "ife_axi_clk"; + clocks = <&clock_gcc GCC_CAMERA_AHB_CLK>, + <&clock_gcc GCC_CAMERA_HF_AXI_CLK>, + <&clock_camcc CAM_CC_SOC_AHB_CLK>, + <&clock_camcc CAM_CC_CPAS_AHB_CLK>, + <&clock_camcc CAM_CC_SLOW_AHB_CLK_SRC>, + <&clock_camcc CAM_CC_IFE_0_CSID_CLK>, + <&clock_camcc CAM_CC_IFE_0_CSID_CLK_SRC>, + <&clock_camcc CAM_CC_IFE_0_CPHY_RX_CLK>, + <&clock_camcc CAM_CC_CPHY_RX_CLK_SRC>, + <&clock_camcc CAM_CC_IFE_0_CLK>, + <&clock_camcc CAM_CC_IFE_0_CLK_SRC>, + <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>, + <&clock_camcc CAM_CC_IFE_0_AXI_CLK>; + clock-rates = + <0 0 0 0 0 0 270000000 0 0 0 360000000 0 0>, + <0 0 0 0 0 0 480000000 0 0 0 600000000 0 0>; + clock-cntl-level = "svs", "turbo"; + src-clock-name = "ife_csid_clk_src"; + ppi-enable; + status = "ok"; + }; + + cam_vfe0: qcom,vfe0@acaf000 { + cell-index = <0>; + compatible = "qcom,vfe170"; + reg-names = "ife", "cam_camnoc"; + reg = <0xacaf000 0x4000>, + <0xac42000 0x5000>; + reg-cam-base = <0xaf000 0x42000>; + interrupt-names = "ife"; + interrupts = <0 465 0>; + regulator-names = "camss", "ife0"; + camss-supply = <&titan_top_gdsc>; + ife0-supply = <&ife_0_gdsc>; + clock-names = "camera_ahb", + "camera_axi", + "soc_ahb_clk", + "cpas_ahb_clk", + "slow_ahb_clk_src", + "ife_clk", + "ife_clk_src", + "camnoc_axi_clk", + "ife_axi_clk"; + clocks = <&clock_gcc GCC_CAMERA_AHB_CLK>, + <&clock_gcc GCC_CAMERA_HF_AXI_CLK>, + <&clock_camcc CAM_CC_SOC_AHB_CLK>, + <&clock_camcc CAM_CC_CPAS_AHB_CLK>, + <&clock_camcc CAM_CC_SLOW_AHB_CLK_SRC>, + <&clock_camcc CAM_CC_IFE_0_CLK>, + <&clock_camcc CAM_CC_IFE_0_CLK_SRC>, + <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>, + <&clock_camcc CAM_CC_IFE_0_AXI_CLK>; + clock-rates = + <0 0 0 0 0 0 360000000 0 0>, + <0 0 0 0 0 0 432000000 0 0>, + <0 0 0 0 0 0 600000000 0 0>; + clock-cntl-level = "svs", "svs_l1", "turbo"; + src-clock-name = "ife_clk_src"; + clock-names-option = "ife_dsp_clk"; + clocks-option = <&clock_camcc CAM_CC_IFE_0_DSP_CLK>; + clock-rates-option = <600000000>; + status = "ok"; + }; + + cam_csid1: qcom,csid1@acba000 { + cell-index = <1>; + compatible = "qcom,csid170"; + reg-names = "csid"; + reg = <0xacba000 0x1000>; + reg-cam-base = <0xba000>; + interrupt-names = "csid"; + interrupts = <0 466 0>; + regulator-names = "camss", "ife1"; + camss-supply = <&titan_top_gdsc>; + ife1-supply = <&ife_1_gdsc>; + clock-names = "camera_ahb", + "camera_axi", + "soc_ahb_clk", + "cpas_ahb_clk", + "slow_ahb_clk_src", + "ife_csid_clk", + "ife_csid_clk_src", + "ife_cphy_rx_clk", + "cphy_rx_clk_src", + "ife_clk", + "ife_clk_src", + "camnoc_axi_clk", + "ife_axi_clk"; + clocks = <&clock_gcc GCC_CAMERA_AHB_CLK>, + <&clock_gcc GCC_CAMERA_HF_AXI_CLK>, + <&clock_camcc CAM_CC_SOC_AHB_CLK>, + <&clock_camcc CAM_CC_CPAS_AHB_CLK>, + <&clock_camcc CAM_CC_SLOW_AHB_CLK_SRC>, + <&clock_camcc CAM_CC_IFE_1_CSID_CLK>, + <&clock_camcc CAM_CC_IFE_1_CSID_CLK_SRC>, + <&clock_camcc CAM_CC_IFE_1_CPHY_RX_CLK>, + <&clock_camcc CAM_CC_CPHY_RX_CLK_SRC>, + <&clock_camcc CAM_CC_IFE_1_CLK>, + <&clock_camcc CAM_CC_IFE_1_CLK_SRC>, + <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>, + <&clock_camcc CAM_CC_IFE_1_AXI_CLK>; + clock-rates = + <0 0 0 0 0 0 270000000 0 0 0 360000000 0 0>, + <0 0 0 0 0 0 480000000 0 0 0 600000000 0 0>; + clock-cntl-level = "svs", "turbo"; + src-clock-name = "ife_csid_clk_src"; + ppi-enable; + status = "ok"; + }; + + cam_vfe1: qcom,vfe1@acb6000 { + cell-index = <1>; + compatible = "qcom,vfe170"; + reg-names = "ife", "cam_camnoc"; + reg = <0xacb6000 0x4000>, + <0xac42000 0x5000>; + reg-cam-base = <0xb6000 0x42000>; + interrupt-names = "ife"; + interrupts = <0 467 0>; + regulator-names = "camss", "ife1"; + camss-supply = <&titan_top_gdsc>; + ife1-supply = <&ife_1_gdsc>; + clock-names = "camera_ahb", + "camera_axi", + "soc_ahb_clk", + "cpas_ahb_clk", + "slow_ahb_clk_src", + "ife_clk", + "ife_clk_src", + "camnoc_axi_clk", + "ife_axi_clk"; + clocks = <&clock_gcc GCC_CAMERA_AHB_CLK>, + <&clock_gcc GCC_CAMERA_HF_AXI_CLK>, + <&clock_camcc CAM_CC_SOC_AHB_CLK>, + <&clock_camcc CAM_CC_CPAS_AHB_CLK>, + <&clock_camcc CAM_CC_SLOW_AHB_CLK_SRC>, + <&clock_camcc CAM_CC_IFE_1_CLK>, + <&clock_camcc CAM_CC_IFE_1_CLK_SRC>, + <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>, + <&clock_camcc CAM_CC_IFE_1_AXI_CLK>; + clock-rates = + <0 0 0 0 0 0 360000000 0 0>, + <0 0 0 0 0 0 432000000 0 0>, + <0 0 0 0 0 0 600000000 0 0>; + clock-cntl-level = "svs", "svs_l1", "turbo"; + src-clock-name = "ife_clk_src"; + clock-names-option = "ife_dsp_clk"; + clocks-option = <&clock_camcc CAM_CC_IFE_1_DSP_CLK>; + clock-rates-option = <600000000>; + status = "ok"; + }; + + cam_csid_lite: qcom,csid-lite@acc8000 { + cell-index = <2>; + compatible = "qcom,csid-lite170"; + reg-names = "csid-lite"; + reg = <0xacc8000 0x1000>; + reg-cam-base = <0xc8000>; + interrupt-names = "csid-lite"; + interrupts = <0 473 0>; + regulator-names = "camss"; + camss-supply = <&titan_top_gdsc>; + clock-names = "camera_ahb", + "camera_axi", + "soc_ahb_clk", + "cpas_ahb_clk", + "slow_ahb_clk_src", + "ife_csid_clk", + "ife_csid_clk_src", + "ife_cphy_rx_clk", + "cphy_rx_clk_src", + "ife_clk", + "ife_clk_src", + "camnoc_axi_clk"; + clocks = <&clock_gcc GCC_CAMERA_AHB_CLK>, + <&clock_gcc GCC_CAMERA_HF_AXI_CLK>, + <&clock_camcc CAM_CC_SOC_AHB_CLK>, + <&clock_camcc CAM_CC_CPAS_AHB_CLK>, + <&clock_camcc CAM_CC_SLOW_AHB_CLK_SRC>, + <&clock_camcc CAM_CC_IFE_LITE_CSID_CLK>, + <&clock_camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>, + <&clock_camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>, + <&clock_camcc CAM_CC_CPHY_RX_CLK_SRC>, + <&clock_camcc CAM_CC_IFE_LITE_CLK>, + <&clock_camcc CAM_CC_IFE_LITE_CLK_SRC>, + <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>; + clock-rates = + <0 0 0 0 0 0 270000000 0 0 0 360000000 0>, + <0 0 0 0 0 0 480000000 0 0 0 600000000 0>; + clock-cntl-level = "svs", "turbo"; + src-clock-name = "ife_csid_clk_src"; + ppi-enable; + status = "ok"; + }; + + cam_vfe_lite: qcom,vfe-lite@acc4000 { + cell-index = <2>; + compatible = "qcom,vfe-lite170"; + reg-names = "ife-lite"; + reg = <0xacc4000 0x4000>; + reg-cam-base = <0xc4000>; + interrupt-names = "ife-lite"; + interrupts = <0 472 0>; + regulator-names = "camss"; + camss-supply = <&titan_top_gdsc>; + clock-names = "camera_ahb", + "camera_axi", + "soc_ahb_clk", + "cpas_ahb_clk", + "slow_ahb_clk_src", + "ife_clk", + "ife_clk_src", + "camnoc_axi_clk"; + clocks = <&clock_gcc GCC_CAMERA_AHB_CLK>, + <&clock_gcc GCC_CAMERA_HF_AXI_CLK>, + <&clock_camcc CAM_CC_SOC_AHB_CLK>, + <&clock_camcc CAM_CC_CPAS_AHB_CLK>, + <&clock_camcc CAM_CC_SLOW_AHB_CLK_SRC>, + <&clock_camcc CAM_CC_IFE_LITE_CLK>, + <&clock_camcc CAM_CC_IFE_LITE_CLK_SRC>, + <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>; + clock-rates = + <0 0 0 0 0 0 360000000 0>, + <0 0 0 0 0 0 432000000 0>, + <0 0 0 0 0 0 600000000 0>; + clock-cntl-level = "svs", "svs_l1", "turbo"; + src-clock-name = "ife_clk_src"; + status = "ok"; + }; + + qcom,cam-jpeg { + compatible = "qcom,cam-jpeg"; + compat-hw-name = "qcom,jpegenc", + "qcom,jpegdma"; + num-jpeg-enc = <1>; + num-jpeg-dma = <1>; + status = "ok"; + }; + + cam_jpeg_enc: qcom,jpegenc@ac4e000 { + cell-index = <0>; + compatible = "qcom,cam_jpeg_enc"; + reg-names = "jpege_hw"; + reg = <0xac4e000 0x4000>; + reg-cam-base = <0x4e000>; + interrupt-names = "jpeg"; + interrupts = <0 474 0>; + regulator-names = "camss-vdd"; + camss-vdd-supply = <&titan_top_gdsc>; + clock-names = "camera_ahb", + "camera_axi", + "soc_ahb_clk", + "cpas_ahb_clk", + "camnoc_axi_clk", + "jpegenc_clk_src", + "jpegenc_clk"; + clocks = <&clock_gcc GCC_CAMERA_AHB_CLK>, + <&clock_gcc GCC_CAMERA_HF_AXI_CLK>, + <&clock_camcc CAM_CC_SOC_AHB_CLK>, + <&clock_camcc CAM_CC_CPAS_AHB_CLK>, + <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>, + <&clock_camcc CAM_CC_JPEG_CLK_SRC>, + <&clock_camcc CAM_CC_JPEG_CLK>; + + clock-rates = <0 0 0 0 0 600000000 0>; + src-clock-name = "jpegenc_clk_src"; + clock-cntl-level = "turbo"; + status = "ok"; + }; + + cam_jpeg_dma: qcom,jpegdma@ac52000 { + cell-index = <0>; + compatible = "qcom,cam_jpeg_dma"; + reg-names = "jpegdma_hw"; + reg = <0xac52000 0x4000>; + reg-cam-base = <0x52000>; + interrupt-names = "jpegdma"; + interrupts = <0 475 0>; + regulator-names = "camss-vdd"; + camss-vdd-supply = <&titan_top_gdsc>; + clock-names = "camera_ahb", + "camera_axi", + "soc_ahb_clk", + "cpas_ahb_clk", + "camnoc_axi_clk", + "jpegdma_clk_src", + "jpegdma_clk"; + clocks = <&clock_gcc GCC_CAMERA_AHB_CLK>, + <&clock_gcc GCC_CAMERA_HF_AXI_CLK>, + <&clock_camcc CAM_CC_SOC_AHB_CLK>, + <&clock_camcc CAM_CC_CPAS_AHB_CLK>, + <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>, + <&clock_camcc CAM_CC_JPEG_CLK_SRC>, + <&clock_camcc CAM_CC_JPEG_CLK>; + + clock-rates = <0 0 0 0 0 600000000 0>; + src-clock-name = "jpegdma_clk_src"; + clock-cntl-level = "turbo"; + status = "ok"; + }; + + cam_ppi0: qcom,ppi0@ace0000 { + cell-index = <0>; + compatible = "qcom,ppi170"; + reg-names = "ppi"; + reg = <0xace0000 0x200>; + reg-cam-base = <0xe0000>; + interrupt-names = "ppi"; + interrupts = <0 170 0>; + clocks = <&clock_camcc CAM_CC_CSIPHY0_CLK>; + clock-names = "csiphy0_clk"; + status = "ok"; + }; + + cam_ppi1: qcom,ppi0@ace0200 { + cell-index = <1>; + compatible = "qcom,ppi170"; + reg-names = "ppi"; + reg = <0xace0200 0x200>; + reg-cam-base = <0xe0200>; + interrupt-names = "ppi"; + interrupts = <0 171 0>; + clocks = <&clock_camcc CAM_CC_CSIPHY1_CLK>; + clock-names = "csiphy1_clk"; + status = "ok"; + }; + + cam_ppi2: qcom,ppi0@ace0400 { + cell-index = <2>; + compatible = "qcom,ppi170"; + reg-names = "ppi"; + reg = <0xace0400 0x200>; + reg-cam-base = <0xe0400>; + interrupt-names = "ppi"; + interrupts = <0 172 0>; + clocks = <&clock_camcc CAM_CC_CSIPHY2_CLK>; + clock-names = "csiphy2_clk"; + status = "ok"; + }; + + cam_ppi3: qcom,ppi0@ace0600 { + cell-index = <3>; + compatible = "qcom,ppi170"; + reg-names = "ppi"; + reg = <0xace0600 0x200>; + reg-cam-base = <0xe00600>; + interrupt-names = "ppi"; + interrupts = <0 173 0>; + clocks = <&clock_camcc CAM_CC_CSIPHY3_CLK>; + clock-names = "csiphy3_clk"; + status = "ok"; + }; +}; -- GitLab From ccb9d46f8d46ec31cc8a872ed2deca3c457f54cf Mon Sep 17 00:00:00 2001 From: Sahil Chandna Date: Mon, 29 Jul 2019 19:53:49 +0530 Subject: [PATCH 1091/1121] power: smb1390-psy: Add support to identify CP model name Add power supply property POWER_SUPPLY_PROP_MODEL_NAME to indicate the CP model name. Change-Id: Ib1f2b48a80af1bf0bf506a7e2335890ec984bb0a Signed-off-by: Sahil Chandna --- drivers/power/supply/qcom/smb1390-charger-psy.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/power/supply/qcom/smb1390-charger-psy.c b/drivers/power/supply/qcom/smb1390-charger-psy.c index 3aede4f148d9..5a37125dcd45 100644 --- a/drivers/power/supply/qcom/smb1390-charger-psy.c +++ b/drivers/power/supply/qcom/smb1390-charger-psy.c @@ -1236,6 +1236,7 @@ static enum power_supply_property smb1390_charge_pump_props[] = { POWER_SUPPLY_PROP_CHIP_VERSION, POWER_SUPPLY_PROP_PARALLEL_OUTPUT_MODE, POWER_SUPPLY_PROP_MIN_ICL, + POWER_SUPPLY_PROP_MODEL_NAME, }; static int smb1390_get_prop(struct power_supply *psy, @@ -1331,6 +1332,10 @@ static int smb1390_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_MIN_ICL: val->intval = chip->min_ilim_ua; break; + case POWER_SUPPLY_PROP_MODEL_NAME: + val->strval = (chip->pmic_rev_id->rev4 > 2) ? "SMB1390_V3" : + "SMB1390_V2"; + break; default: smb1390_dbg(chip, PR_MISC, "charge pump power supply get prop %d not supported\n", prop); -- GitLab From 26968a6158485225bbc3ad0dc8716db3b8933170 Mon Sep 17 00:00:00 2001 From: Jayadev K Date: Tue, 30 Jul 2019 21:02:16 +0530 Subject: [PATCH 1092/1121] ARM: dts: qcom: Add HS-I2S device tree support on SA8155-VM Adding device nodes and pinctrl definitions for HS-I2S driver Change-Id: I8a622c9521a0d0f12b7f24e0a359381576992142 Signed-off-by: Jayadev K --- .../boot/dts/qcom/sa8155-vm-pinctrl.dtsi | 447 ++++++++++++++++++ arch/arm64/boot/dts/qcom/sa8155-vm.dtsi | 47 ++ 2 files changed, 494 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sa8155-vm-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sa8155-vm-pinctrl.dtsi index 919fcc057493..2c54f126b126 100644 --- a/arch/arm64/boot/dts/qcom/sa8155-vm-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8155-vm-pinctrl.dtsi @@ -21,5 +21,452 @@ interrupt-controller; #interrupt-cells = <2>; }; + + hs1_i2s_mclk { + hs1_i2s_mclk_sleep: hs1_i2s_mclk_sleep { + mux { + pins = "gpio155"; + function = "gpio"; + }; + + config { + pins = "gpio155"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + hs1_i2s_mclk_active: hs1_i2s_mclk_active { + mux { + pins = "gpio155"; + function = "hs1_mi2s"; + }; + + config { + pins = "gpio155"; + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + output-high; + }; + }; + }; + + hs1_i2s_sck { + hs1_i2s_sck_sleep: hs1_i2s_sck_sleep { + mux { + pins = "gpio156"; + function = "gpio"; + }; + + config { + pins = "gpio156"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + hs1_i2s_sck_active: hs1_i2s_sck_active { + mux { + pins = "gpio156"; + function = "hs1_mi2s"; + }; + + config { + pins = "gpio156"; + drive-strength = <8>; /* 4 mA */ + bias-disable; /* NO PULL */ + output-high; + }; + }; + }; + + hs1_i2s_ws { + hs1_i2s_ws_sleep: hs1_i2s_ws_sleep { + mux { + pins = "gpio157"; + function = "gpio"; + }; + + config { + pins = "gpio157"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + hs1_i2s_ws_active: hs1_i2s_ws_active { + mux { + pins = "gpio157"; + function = "hs1_mi2s"; + }; + + config { + pins = "gpio157"; + drive-strength = <8>; /* 4 mA */ + bias-disable; /* NO PULL */ + output-high; + }; + }; + }; + + hs1_i2s_data0 { + hs1_i2s_data0_sleep: hs1_i2s_data0_sleep { + mux { + pins = "gpio158"; + function = "sleep"; + }; + + config { + pins = "gpio158"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + hs1_i2s_data0_active: hs1_i2s_data0_active { + mux { + pins = "gpio158"; + function = "hs1_mi2s"; + }; + + config { + pins = "gpio158"; + drive-strength = <8>; /* 4 mA */ + bias-disable; /* NO PULL */ + output-high; + }; + }; + }; + + hs1_i2s_data1 { + hs1_i2s_data1_sleep: hs1_i2s_data1_sleep { + mux { + pins = "gpio159"; + function = "gpio"; + }; + + config { + pins = "gpio159"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + hs1_i2s_data1_active: hs1_i2s_data1_active { + mux { + pins = "gpio159"; + function = "hs1_mi2s"; + }; + + config { + pins = "gpio159"; + drive-strength = <8>; /* 4 mA */ + bias-disable; /* NO PULL */ + }; + }; + }; + + hs2_i2s_mclk { + hs2_i2s_mclk_sleep: hs2_i2s_mclk_sleep { + mux { + pins = "gpio160"; + function = "gpio"; + }; + + config { + pins = "gpio160"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + hs2_i2s_mclk_active: hs2_i2s_mclk_active { + mux { + pins = "gpio160"; + function = "hs2_mi2s"; + }; + + config { + pins = "gpio160"; + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + output-high; + }; + }; + }; + + hs2_i2s_sck { + hs2_i2s_sck_sleep: hs2_i2s_sck_sleep { + mux { + pins = "gpio161"; + function = "gpio"; + }; + + config { + pins = "gpio161"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + hs2_i2s_sck_active: hs2_i2s_sck_active { + mux { + pins = "gpio161"; + function = "hs2_mi2s"; + }; + + config { + pins = "gpio161"; + drive-strength = <8>; /* 4 mA */ + bias-disable; /* NO PULL */ + output-high; + }; + }; + }; + + hs2_i2s_ws { + hs2_i2s_ws_sleep: hs2_i2s_ws_sleep { + mux { + pins = "gpio162"; + function = "gpio"; + }; + + config { + pins = "gpio162"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + hs2_i2s_ws_active: hs2_i2s_ws_active { + mux { + pins = "gpio162"; + function = "hs2_mi2s"; + }; + + config { + pins = "gpio162"; + drive-strength = <8>; /* 4 mA */ + bias-disable; /* NO PULL */ + output-high; + }; + }; + }; + + hs2_i2s_data0 { + hs2_i2s_data0_sleep: hs2_i2s_data0_sleep { + mux { + pins = "gpio163"; + function = "gpio"; + }; + + config { + pins = "gpio163"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + hs2_i2s_data0_active: hs2_i2s_data0_active { + mux { + pins = "gpio163"; + function = "hs2_mi2s"; + }; + + config { + pins = "gpio163"; + drive-strength = <8>; /* 4 mA */ + bias-disable; /* NO PULL */ + output-high; + }; + }; + }; + + hs2_i2s_data1 { + hs2_i2s_data1_sleep: hs2_i2s_data1_sleep { + mux { + pins = "gpio164"; + function = "gpio"; + }; + + config { + pins = "gpio164"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + hs2_i2s_data1_active: hs2_i2s_data1_active { + mux { + pins = "gpio164"; + function = "hs2_mi2s"; + }; + + config { + pins = "gpio164"; + drive-strength = <8>; /* 4 mA */ + bias-disable; /* NO PULL */ + }; + }; + }; + + hs3_i2s_mclk { + hs3_i2s_mclk_sleep: hs3_i2s_mclk_sleep { + mux { + pins = "gpio125"; + function = "gpio"; + }; + + config { + pins = "gpio125"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + hs3_i2s_mclk_active: hs3_i2s_mclk_active { + mux { + pins = "gpio125"; + function = "hs3_mi2s"; + }; + + config { + pins = "gpio125"; + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + output-high; + }; + }; + }; + + hs3_i2s_sck { + hs3_i2s_sck_sleep: hs3_i2s_sck_sleep { + mux { + pins = "gpio165"; + function = "gpio"; + }; + + config { + pins = "gpio165"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + hs3_i2s_sck_active: hs3_i2s_sck_active { + mux { + pins = "gpio165"; + function = "hs3_mi2s"; + }; + + config { + pins = "gpio165"; + drive-strength = <8>; /* 4 mA */ + bias-disable; /* NO PULL */ + output-high; + }; + }; + }; + + hs3_i2s_ws { + hs3_i2s_ws_sleep: hs3_i2s_ws_sleep { + mux { + pins = "gpio166"; + function = "gpio"; + }; + + config { + pins = "gpio166"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + hs3_i2s_ws_active: hs3_i2s_ws_active { + mux { + pins = "gpio166"; + function = "hs3_mi2s"; + }; + + config { + pins = "gpio166"; + drive-strength = <8>; /* 4 mA */ + bias-disable; /* NO PULL */ + output-high; + }; + }; + }; + + hs3_i2s_data0 { + hs3_i2s_data0_sleep: hs3_i2s_data0_sleep { + mux { + pins = "gpio167"; + function = "gpio"; + }; + + config { + pins = "gpio167"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + hs3_i2s_data0_active: hs3_i2s_data0_active { + mux { + pins = "gpio167"; + function = "hs3_mi2s"; + }; + + config { + pins = "gpio167"; + drive-strength = <8>; /* 4 mA */ + bias-disable; /* NO PULL */ + output-high; + }; + }; + }; + + hs3_i2s_data1 { + hs3_i2s_data1_sleep: hs3_i2s_data1_sleep { + mux { + pins = "gpio168"; + function = "gpio"; + }; + + config { + pins = "gpio168"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + hs3_i2s_data1_active: hs3_i2s_data1_active { + mux { + pins = "gpio168"; + function = "hs3_mi2s"; + }; + + config { + pins = "gpio168"; + drive-strength = <8>; /* 4 mA */ + bias-disable; /* NO PULL */ + }; + }; + }; }; diff --git a/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi b/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi index 8ec724d101ac..502d596af1eb 100644 --- a/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi @@ -29,6 +29,53 @@ }; &soc { + hsi2s: qcom,hsi2s { + compatible = "qcom,sa8155-hsi2s", "qcom,hsi2s"; + number-of-interfaces = <3>; + reg = <0x172C0000 0x28000>, + <0x17080000 0xE000>; + reg-names = "lpa_if", "lpass_tcsr"; + interrupts = ; + bit-clock-hz = <20000000>; + interrupt-interval-ms = <10>; + + sdr0: qcom,hs0_i2s { + compatible = "qcom,hsi2s-interface"; + minor-number = <0>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&hs1_i2s_mclk_active &hs1_i2s_sck_active + &hs1_i2s_ws_active &hs1_i2s_data0_active + &hs1_i2s_data1_active>; + pinctrl-1 = <&hs1_i2s_mclk_sleep &hs1_i2s_sck_sleep + &hs1_i2s_ws_sleep &hs1_i2s_data0_sleep + &hs1_i2s_data1_sleep>; + }; + + sdr1: qcom,hs1_i2s { + compatible = "qcom,hsi2s-interface"; + minor-number = <1>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&hs2_i2s_mclk_active &hs2_i2s_sck_active + &hs2_i2s_ws_active &hs2_i2s_data0_active + &hs2_i2s_data1_active>; + pinctrl-1 = <&hs2_i2s_mclk_sleep &hs2_i2s_sck_sleep + &hs2_i2s_ws_sleep &hs2_i2s_data0_sleep + &hs2_i2s_data1_sleep>; + }; + + sdr2: qcom,hs2_i2s { + compatible = "qcom,hsi2s-interface"; + minor-number = <2>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&hs3_i2s_mclk_active &hs3_i2s_sck_active + &hs3_i2s_ws_active &hs3_i2s_data0_active + &hs3_i2s_data1_active>; + pinctrl-1 = <&hs3_i2s_mclk_sleep &hs3_i2s_sck_sleep + &hs3_i2s_ws_sleep &hs3_i2s_data0_sleep + &hs3_i2s_data1_sleep>; + }; + }; + clock_virt: qcom,virtio-gcc { compatible = "virtio,mmio"; reg = <0x1c200000 0x1000>; -- GitLab From 70313ed3d3015143de361930143ce98b422cd0e9 Mon Sep 17 00:00:00 2001 From: Pratham Pratap Date: Wed, 24 Jul 2019 18:15:34 +0530 Subject: [PATCH 1093/1121] usb: dwc3-msm: Fix maximum_speed determination Currently driver is setting the user override speed to maximum speed by checking if override speed is less than the maximum speed. But this check will fail if the maximum speed supported by the controller is super-speed and user is trying to set it to super-speed from a lower speed. Fix this by checking if override speed is equal to or less than maximum speed. Change-Id: Id71cf163548e213ec0180d7f3107395feed2f483 Signed-off-by: Pratham Pratap --- drivers/usb/dwc3/dwc3-msm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index 2d731c3e1a11..fc58287b45c9 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -2874,7 +2874,7 @@ static void dwc3_resume_work(struct work_struct *w) dwc->maximum_speed = USB_SPEED_HIGH; if (mdwc->override_usb_speed && - mdwc->override_usb_speed < dwc->maximum_speed) { + mdwc->override_usb_speed <= dwc->maximum_speed) { dwc->maximum_speed = mdwc->override_usb_speed; dwc->gadget.max_speed = dwc->maximum_speed; dbg_event(0xFF, "override_speed", -- GitLab From 89822ecf3dde0318fe758dccb3aece5202b0dc82 Mon Sep 17 00:00:00 2001 From: Jayadev K Date: Thu, 25 Jul 2019 21:18:00 +0530 Subject: [PATCH 1094/1121] ARM: dts: qcom: Add new properties for HS-I2S node Adding 'bit-clock-hz' and 'interrupt-interval-ms' properties in the HS-I2S device node in order to calculate periodic length of the DMA buffer. Change-Id: I5c7bea30fe197071f07205d5be41682bf8723ef9 Signed-off-by: Jayadev K --- Documentation/devicetree/bindings/sound/qcom,hsi2s.txt | 2 ++ arch/arm64/boot/dts/qcom/sa6155-adp-air.dtsi | 2 ++ arch/arm64/boot/dts/qcom/sa6155-adp-star.dtsi | 2 ++ arch/arm64/boot/dts/qcom/sa8155.dtsi | 2 ++ 4 files changed, 8 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/qcom,hsi2s.txt b/Documentation/devicetree/bindings/sound/qcom,hsi2s.txt index 237f2857f646..f3331cb6e376 100644 --- a/Documentation/devicetree/bindings/sound/qcom,hsi2s.txt +++ b/Documentation/devicetree/bindings/sound/qcom,hsi2s.txt @@ -15,6 +15,8 @@ Required properties: - interrupts : Interrupt number used by this interface - clocks : Core clocks used by this interface - clock-names : Clock names for each core clock + - bit-clock-hz : Default bit clock frequency in hertz + - interrupt-interval-ms : Default interrupt interval in milliseconds * HS-I2S interface nodes diff --git a/arch/arm64/boot/dts/qcom/sa6155-adp-air.dtsi b/arch/arm64/boot/dts/qcom/sa6155-adp-air.dtsi index 3912d090e2f3..e86b8deb8f57 100644 --- a/arch/arm64/boot/dts/qcom/sa6155-adp-air.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155-adp-air.dtsi @@ -64,6 +64,8 @@ clock-names = "core_clk", "wr0_mem_clk", "wr1_mem_clk", "wr2_mem_clk", "csr_hclk"; + bit-clock-hz = <20000000>; + interrupt-interval-ms = <10>; sdr0: qcom,hs0_i2s { compatible = "qcom,hsi2s-interface"; diff --git a/arch/arm64/boot/dts/qcom/sa6155-adp-star.dtsi b/arch/arm64/boot/dts/qcom/sa6155-adp-star.dtsi index 08b15e83d218..be1b682abcfc 100644 --- a/arch/arm64/boot/dts/qcom/sa6155-adp-star.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155-adp-star.dtsi @@ -57,6 +57,8 @@ clock-names = "core_clk", "wr0_mem_clk", "wr1_mem_clk", "wr2_mem_clk", "csr_hclk"; + bit-clock-hz = <20000000>; + interrupt-interval-ms = <10>; sdr0: qcom,hs0_i2s { compatible = "qcom,hsi2s-interface"; diff --git a/arch/arm64/boot/dts/qcom/sa8155.dtsi b/arch/arm64/boot/dts/qcom/sa8155.dtsi index 4ed5e2d102e5..95fa47b280ac 100644 --- a/arch/arm64/boot/dts/qcom/sa8155.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8155.dtsi @@ -506,6 +506,8 @@ <0x17080000 0xE000>; reg-names = "lpa_if", "lpass_tcsr"; interrupts = ; + bit-clock-hz = <20000000>; + interrupt-interval-ms = <10>; sdr0: qcom,hs0_i2s { compatible = "qcom,hsi2s-interface"; -- GitLab From 8f344f9d94a498bff3a8cc5848c5c2ab6d21c15d Mon Sep 17 00:00:00 2001 From: Jayadev K Date: Thu, 25 Jul 2019 21:24:41 +0530 Subject: [PATCH 1095/1121] ARM: dts: qcom: Modify pinctrl settings for HS-I2S device nodes Reversing the direction of data lines of the HS-I2S interfaces on SA6155. Change-Id: I2705c23c59c364602c267694067be49f76f2420f Signed-off-by: Jayadev K --- arch/arm64/boot/dts/qcom/sm6150-pinctrl.dtsi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sm6150-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sm6150-pinctrl.dtsi index df5960c939e9..037e57511850 100644 --- a/arch/arm64/boot/dts/qcom/sm6150-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/sm6150-pinctrl.dtsi @@ -1821,7 +1821,7 @@ pins = "gpio38"; drive-strength = <4>; /* 4 mA */ bias-no-pull; - input-enable; + output-high; }; }; }; @@ -1849,7 +1849,7 @@ pins = "gpio39"; drive-strength = <4>; /* 4 mA */ bias-no-pull; - output-high; + input-enable; }; }; }; @@ -1905,7 +1905,7 @@ pins = "gpio26"; drive-strength = <4>; /* 4 mA */ bias-no-pull; - input-enable; + output-high; }; }; }; @@ -1933,7 +1933,7 @@ pins = "gpio27"; drive-strength = <4>; /* 4 mA */ bias-no-pull; - output-high; + input-enable; }; }; }; -- GitLab From 58cbe281bbf3ea1079d8e4238a4d9fdfa119157c Mon Sep 17 00:00:00 2001 From: Hareesh Gundu Date: Tue, 23 Jul 2019 19:54:14 +0530 Subject: [PATCH 1096/1121] msm: kgsl: Remove extra call to turn off interrupts The interrupts were being turned off twice when going to SLUMBER. Change-Id: I3a5080ce37d19cee09ec5e7c38403cb5a7ed8080 Signed-off-by: Harshdeep Dhatt Signed-off-by: Hareesh Gundu --- drivers/gpu/msm/kgsl_pwrctrl.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c index 3bb141ed1bbc..1332749eb63e 100644 --- a/drivers/gpu/msm/kgsl_pwrctrl.c +++ b/drivers/gpu/msm/kgsl_pwrctrl.c @@ -2990,7 +2990,6 @@ _slumber(struct kgsl_device *device) kgsl_pwrctrl_clk_set_options(device, false); kgsl_pwrctrl_disable(device); kgsl_pwrscale_sleep(device); - kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF); kgsl_pwrctrl_set_state(device, KGSL_STATE_SLUMBER); pm_qos_update_request(&device->pwrctrl.pm_qos_req_dma, PM_QOS_DEFAULT_VALUE); -- GitLab From eed9647d7622912c5eabf46135a550be5b7dc60e Mon Sep 17 00:00:00 2001 From: Mayank Grover Date: Mon, 29 Jul 2019 12:24:52 +0530 Subject: [PATCH 1097/1121] ARM: dts: msm: Add support for EUD for atoll Add support for eud for atoll. Change-Id: I3540a56b3ee29a9194f5d6a14ae411d9e533102a Signed-off-by: Mayank Grover --- arch/arm64/boot/dts/qcom/atoll.dtsi | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index bf9082faf01a..b3d90bc752a8 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -998,6 +998,20 @@ 0x10100 0x10100 0x25900 0x25900>; }; + eud: qcom,msm-eud@88e0000 { + compatible = "qcom,msm-eud"; + interrupt-names = "eud_irq"; + interrupts = ; + reg = <0x88e0000 0x2000>, + <0x88e2000 0x1000>; + reg-names = "eud_base", "eud_mode_mgr2"; + qcom,secure-eud-en; + qcom,eud-clock-vote-req; + clocks = <&clock_gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>; + clock-names = "eud_ahb2phy_clk"; + status = "ok"; + }; + qcom,chd_sliver { compatible = "qcom,core-hang-detect"; label = "silver"; -- GitLab From e28db38eca1330466ea2e171212b6415c126a6e9 Mon Sep 17 00:00:00 2001 From: Manaf Meethalavalappu Pallikunhi Date: Wed, 31 Jul 2019 17:04:20 +0530 Subject: [PATCH 1098/1121] ARM: dts: msm: Update core isolation thermal zone thresholds for SA6155 Update core isolation thermal zone thresholds for both SA6155 and SA6155P based on latest recommendation. Change-Id: I280b84af6fb9747ecd971e1e54228d0505f3beb4 Signed-off-by: Manaf Meethalavalappu Pallikunhi --- arch/arm64/boot/dts/qcom/sa6155.dtsi | 56 +++++++++++++++++++++++++++ arch/arm64/boot/dts/qcom/sa6155p.dtsi | 56 +++++++++++++++++++++++++++ 2 files changed, 112 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sa6155.dtsi b/arch/arm64/boot/dts/qcom/sa6155.dtsi index 1bf14ec01b4a..b59622839485 100644 --- a/arch/arm64/boot/dts/qcom/sa6155.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155.dtsi @@ -118,6 +118,62 @@ }; }; }; + + cpuss-0-step { + trips { + cpu45-config { + temperature = <115000>; + }; + }; + }; + + cpuss-1-step { + trips { + cpu23-config { + temperature = <115000>; + }; + }; + }; + + cpuss-2-step { + trips { + cpu01-config { + temperature = <115000>; + }; + }; + }; + + cpu-1-0-step { + trips { + cpu6-0-config { + temperature = <115000>; + }; + }; + }; + + cpu-1-1-step { + trips { + cpu6-1-config { + temperature = <115000>; + }; + }; + }; + + cpu-1-2-step { + trips { + cpu7-0-config { + temperature = <115000>; + }; + }; + }; + + cpu-1-3-step { + trips { + cpu7-1-config { + temperature = <115000>; + }; + }; + }; }; /* GPU power level overrides */ diff --git a/arch/arm64/boot/dts/qcom/sa6155p.dtsi b/arch/arm64/boot/dts/qcom/sa6155p.dtsi index 48d82ceec6ba..5d233dd7021a 100644 --- a/arch/arm64/boot/dts/qcom/sa6155p.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155p.dtsi @@ -146,6 +146,62 @@ }; }; }; + + cpuss-0-step { + trips { + cpu45-config { + temperature = <115000>; + }; + }; + }; + + cpuss-1-step { + trips { + cpu23-config { + temperature = <115000>; + }; + }; + }; + + cpuss-2-step { + trips { + cpu01-config { + temperature = <115000>; + }; + }; + }; + + cpu-1-0-step { + trips { + cpu6-0-config { + temperature = <115000>; + }; + }; + }; + + cpu-1-1-step { + trips { + cpu6-1-config { + temperature = <115000>; + }; + }; + }; + + cpu-1-2-step { + trips { + cpu7-0-config { + temperature = <115000>; + }; + }; + }; + + cpu-1-3-step { + trips { + cpu7-1-config { + temperature = <115000>; + }; + }; + }; }; /* GPU power level overrides */ -- GitLab From 3f960fc89a7d4d91a6c89c085582d2f00331640e Mon Sep 17 00:00:00 2001 From: Zhen Kong Date: Mon, 29 Jul 2019 16:53:14 -0700 Subject: [PATCH 1099/1121] qseecom: correct range check in __qseecom_update_qteec_req_buf Make change to validate if there exists enough space to write a struct qseecom_param_memref instead of a unit32 value, in the request buffer in __qseecom_update_qteec_req_buf. Change-Id: I4e092f7aa2b23648c2cedfada311828b9ceb35dc Signed-off-by: Zhen Kong --- drivers/misc/qseecom.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c index 02422cdbb5a8..b3aeedf37bf0 100644 --- a/drivers/misc/qseecom.c +++ b/drivers/misc/qseecom.c @@ -6734,9 +6734,11 @@ static int __qseecom_update_qteec_req_buf(struct qseecom_qteec_modfd_req *req, for (i = 0; i < MAX_ION_FD; i++) { if (req->ifd_data[i].fd > 0) { ion_fd = req->ifd_data[i].fd; - if ((req->req_len < sizeof(uint32_t)) || + if ((req->req_len < + sizeof(struct qseecom_param_memref)) || (req->ifd_data[i].cmd_buf_offset > - req->req_len - sizeof(uint32_t))) { + req->req_len - + sizeof(struct qseecom_param_memref))) { pr_err("Invalid offset/req len 0x%x/0x%x\n", req->req_len, req->ifd_data[i].cmd_buf_offset); -- GitLab From 21e4f1a36d0067ab60ba3b8edd946e065707cd15 Mon Sep 17 00:00:00 2001 From: Michael Adisumarta Date: Wed, 31 Jul 2019 16:38:23 -0700 Subject: [PATCH 1100/1121] msm: ipa: Enable qmi send request to remove last connection Change the if condition to be inclusive to allow remove_offload ioctl to send the rmv_offload_request through qmi on the last connection. Change-Id: I6eec7799fd1a76ab168bc588b3e9c74dbfd215fd Signed-off-by: Michael Adisumarta --- drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c index 64830b5af1b7..141ae9daa47c 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c @@ -1048,7 +1048,7 @@ int ipa3_qmi_rmv_offload_request_send( ipa3_qmi_ctx->num_ipa_offload_connection); /* max as num_ipa_offload_connection */ - if (req->filter_handle_list_len >= + if (req->filter_handle_list_len > ipa3_qmi_ctx->num_ipa_offload_connection) { IPAWANDBG( "cur(%d), req_rmv(%d)\n", -- GitLab From 0176bc99211c7c7fa293362191608703a7021ff4 Mon Sep 17 00:00:00 2001 From: Subbaraman Narayanamurthy Date: Wed, 31 Jul 2019 19:54:35 -0700 Subject: [PATCH 1101/1121] dt-bindings: batterydata: add SOH range property Add "qcom,soh-range" property to battery profile data so that SOH based multiple profile loading can be supported. Change-Id: I62a580ed527b4cacc489a033d437f5e3c416c112 Signed-off-by: Subbaraman Narayanamurthy --- .../devicetree/bindings/batterydata/batterydata.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/batterydata/batterydata.txt b/Documentation/devicetree/bindings/batterydata/batterydata.txt index 8224139e7d8f..4509d6cfae21 100644 --- a/Documentation/devicetree/bindings/batterydata/batterydata.txt +++ b/Documentation/devicetree/bindings/batterydata/batterydata.txt @@ -146,6 +146,12 @@ Profile data node optional properties: Element 1 - FV value for soft warm. - qcom,batt-age-level: Battery age level. This is used only when multiple profile loading is supported. +- qcom,soh-range: A tuple entry to specify the values of SOH range that + the battery profile has to be used for. This needs to + be specified along with "qcom,batt-age-level" for the + proper functionality. + Element 0 - SOH minimum level. + Element 1 - SOH maximum level. - qcom,taper-fcc: A bool property to enable gradual reduction in FCC in steps of pre-configured value, whenever step charging thresholds are crossed-over. -- GitLab From 1d903d178bac2449e572f1ab5ef6d9df661d92e8 Mon Sep 17 00:00:00 2001 From: Anmolpreet Kaur Date: Tue, 23 Jul 2019 17:00:15 +0530 Subject: [PATCH 1102/1121] ARM: dts: msm: Add inline crypto engine node for atoll Add Inline Crypto Engine device node and crypto support for Embedded MultiMediaCard and Universal Flash storage, to support File Based Encryption. Change-Id: If9365d537fd2443f61022c486fdda6dc573d9058 Signed-off-by: Anmolpreet Kaur --- arch/arm64/boot/dts/qcom/atoll.dtsi | 47 +++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index bf9082faf01a..0b9e56da3ec3 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -984,6 +984,51 @@ qcom,rtb-size = <0x100000>; }; + ufs_ice: ufsice@1d90000 { + compatible = "qcom,ice"; + reg = <0x1d90000 0x8000>; + qcom,enable-ice-clk; + clock-names = "ufs_core_clk", "bus_clk", + "iface_clk", "ice_core_clk"; + clocks = <&clock_gcc GCC_UFS_PHY_AXI_CLK>, + <&clock_gcc GCC_UFS_MEM_CLKREF_CLK>, + <&clock_gcc GCC_UFS_PHY_AHB_CLK>, + <&clock_gcc GCC_UFS_PHY_ICE_CORE_CLK>; + qcom,op-freq-hz = <0>, <0>, <0>, <300000000>; + vdd-hba-supply = <&ufs_phy_gdsc>; + qcom,msm-bus,name = "ufs_ice_noc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <1 757 0 0>, /* No vote */ + <1 757 1000 0>; /* Max. bandwidth */ + qcom,bus-vector-names = "MIN", + "MAX"; + qcom,instance-type = "ufs"; + }; + + sdcc1_ice: sdcc1ice@7c8000{ + compatible = "qcom,ice"; + reg = <0x7c8000 0x8000>; + qcom,enable-ice-clk; + clock-names = "ice_core_clk_src", "ice_core_clk", + "bus_clk", "iface_clk"; + clocks = <&clock_gcc GCC_SDCC1_ICE_CORE_CLK_SRC>, + <&clock_gcc GCC_SDCC1_ICE_CORE_CLK>, + <&clock_gcc GCC_SDCC1_AHB_CLK>, + <&clock_gcc GCC_SDCC1_APPS_CLK>; + qcom,op-freq-hz = <300000000>, <0>, <0>, <0>; + qcom,msm-bus,name = "sdcc_ice_noc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <1 608 0 0>, /* No vote */ + <1 608 1000 0>; /* Max. bandwidth */ + qcom,bus-vector-names = "MIN", + "MAX"; + qcom,instance-type = "sdcc"; + }; + wdog: qcom,wdt@17c10000{ compatible = "qcom,msm-watchdog"; reg = <0x17c10000 0x1000>; @@ -2117,6 +2162,7 @@ interrupts = , ; interrupt-names = "hc_irq", "pwr_irq"; + sdhc-msm-crypto = <&sdcc1_ice>; qcom,bus-width = <8>; qcom,large-address-bus; @@ -2195,6 +2241,7 @@ interrupts = <0 265 0>; phys = <&ufsphy_mem>; phy-names = "ufsphy"; + ufs-qcom-crypto = <&ufs_ice>; lanes-per-direction = <1>; dev-ref-clk-freq = <0>; /* 19.2 MHz */ -- GitLab From 2580d48d10dc124bf414c0a297989504f660cb53 Mon Sep 17 00:00:00 2001 From: Yimin Peng Date: Wed, 24 Jul 2019 16:11:48 +0800 Subject: [PATCH 1103/1121] spmi: pmic_arb: add virtio spmi driver for VM platforms The virtio spmi-pmic frontend driver communicates with its backend to support pmic clients virtualization. Change-Id: I937e6ecf76dd4962654fd8b92209ff971b8f4227 Signed-off-by: Yimin Peng --- .../bindings/spmi/qcom,viospmi-pmic-arb.txt | 38 + drivers/spmi/Kconfig | 10 + drivers/spmi/Makefile | 1 + drivers/spmi/viospmi-pmic-arb.c | 976 ++++++++++++++++++ include/linux/virtio_spmi.h | 77 ++ include/uapi/linux/virtio_ids.h | 1 + 6 files changed, 1103 insertions(+) create mode 100644 Documentation/devicetree/bindings/spmi/qcom,viospmi-pmic-arb.txt create mode 100644 drivers/spmi/viospmi-pmic-arb.c create mode 100644 include/linux/virtio_spmi.h diff --git a/Documentation/devicetree/bindings/spmi/qcom,viospmi-pmic-arb.txt b/Documentation/devicetree/bindings/spmi/qcom,viospmi-pmic-arb.txt new file mode 100644 index 000000000000..2221ecea91cd --- /dev/null +++ b/Documentation/devicetree/bindings/spmi/qcom,viospmi-pmic-arb.txt @@ -0,0 +1,38 @@ +QTI Virtio SPMI controller (Virtio PMIC Arbiter) + +The Virtio SPMI PMIC Arbiter is a frontend proxy based on backend virtio device. + +Required properties: +- compatible : should be "qcom,viospmi-pmic-arb". +- #address-cells : must be set to 2 +- #size-cells : must be set to 0 +- interrupt-controller : boolean indicator that the PMIC arbiter is an interrupt controller +- #interrupt-cells : must be set to 4. Interrupts are specified as a 4-tuple: + cell 1: slave ID for the requested interrupt (0-15) + cell 2: peripheral ID for requested interrupt (0-255) + cell 3: the requested peripheral interrupt (0-7) + cell 4: interrupt flags indicating level-sense information, as defined in + dt-bindings/interrupt-controller/irq.h + +Example Virtio PMIC-Arbiter: + + spmi_bus: qcom,spmi { + compatible = "qcom,viospmi-pmic-arb"; + interrupt-names = "periph_irq"; + interrupts = ; + qcom,ee = <0>; + #address-cells = <2>; + #size-cells = <0>; + interrupt-controller; + #interrupt-cells = <4>; + cell-index = <0>; + }; + + viospmi: virtio-spmi@c440000 { + compatible = "virtio,mmio"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xc440000 0x1100>; + interrupts = ; + status = "okay"; + }; diff --git a/drivers/spmi/Kconfig b/drivers/spmi/Kconfig index 711d5f6067b2..a7e909ca2b7d 100644 --- a/drivers/spmi/Kconfig +++ b/drivers/spmi/Kconfig @@ -34,6 +34,16 @@ config SPMI_MSM_PMIC_ARB_DEBUG Inc. (QTI) MSM family processors. This feature is available on chips with PMIC arbiter version 5 and above. +config VIOSPMI_MSM_PMIC_ARB + tristate "QTI Virtio SPMI Controller (Virtio PMIC Arbiter)" + select IRQ_DOMAIN + depends on ARCH_QCOM || COMPILE_TEST + depends on HAS_IOMEM + depends on VIRTIO + default ARCH_QCOM + help + This is virtio SPMI frontend driver for QTI MSM virtual platform. + source "drivers/spmi/simulator/Kconfig" endif diff --git a/drivers/spmi/Makefile b/drivers/spmi/Makefile index cd050b7cc643..d2e979dcfb7f 100644 --- a/drivers/spmi/Makefile +++ b/drivers/spmi/Makefile @@ -5,4 +5,5 @@ obj-$(CONFIG_SPMI) += spmi.o obj-$(CONFIG_SPMI_MSM_PMIC_ARB) += spmi-pmic-arb.o obj-$(CONFIG_SPMI_MSM_PMIC_ARB_DEBUG) += spmi-pmic-arb-debug.o +obj-$(CONFIG_VIOSPMI_MSM_PMIC_ARB) += viospmi-pmic-arb.o obj-y += simulator/ diff --git a/drivers/spmi/viospmi-pmic-arb.c b/drivers/spmi/viospmi-pmic-arb.c new file mode 100644 index 000000000000..de5230728f30 --- /dev/null +++ b/drivers/spmi/viospmi-pmic-arb.c @@ -0,0 +1,976 @@ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* Mapping Table */ +#define PMIC_ARB_MAX_PPID BIT(12) /* PPID is 12bit */ +#define PMIC_ARB_APID_VALID BIT(15) +#define PMIC_ARB_CHAN_IS_IRQ_OWNER(reg) ((reg) & BIT(24)) +#define INVALID_EE 0xFF + +/* Command Opcodes */ +enum pmic_arb_cmd_op_code { + PMIC_ARB_OP_EXT_WRITEL = 0, + PMIC_ARB_OP_EXT_READL = 1, + PMIC_ARB_OP_EXT_WRITE = 2, + PMIC_ARB_OP_RESET = 3, + PMIC_ARB_OP_SLEEP = 4, + PMIC_ARB_OP_SHUTDOWN = 5, + PMIC_ARB_OP_WAKEUP = 6, + PMIC_ARB_OP_AUTHENTICATE = 7, + PMIC_ARB_OP_MSTR_READ = 8, + PMIC_ARB_OP_MSTR_WRITE = 9, + PMIC_ARB_OP_EXT_READ = 13, + PMIC_ARB_OP_WRITE = 14, + PMIC_ARB_OP_READ = 15, + PMIC_ARB_OP_ZERO_WRITE = 16, +}; + +/* Maximum number of support PMIC peripherals */ +#define PMIC_ARB_MAX_PERIPHS 512 +#define PMIC_ARB_MAX_TRANS_BYTES (8) + +#define PMIC_ARB_APID_MASK 0xFF +#define PMIC_ARB_PPID_MASK 0xFFF + +/* interrupt enable bit */ +#define SPMI_PIC_ACC_ENABLE_BIT BIT(0) + +#define spec_to_hwirq(slave_id, periph_id, irq_id, apid) \ + ((((slave_id) & 0xF) << 28) | \ + (((periph_id) & 0xFF) << 20) | \ + (((irq_id) & 0x7) << 16) | \ + (((apid) & 0x1FF) << 0)) + +#define hwirq_to_sid(hwirq) (((hwirq) >> 28) & 0xF) +#define hwirq_to_per(hwirq) (((hwirq) >> 20) & 0xFF) +#define hwirq_to_irq(hwirq) (((hwirq) >> 16) & 0x7) +#define hwirq_to_apid(hwirq) (((hwirq) >> 0) & 0x1FF) + +struct pmic_arb_ver_ops; + +struct apid_data { + u16 ppid; + u8 write_ee; + u8 irq_ee; +}; + +struct virtio_spmi { + struct virtio_device *vdev; + struct virtqueue *vq; + spinlock_t lock; + struct virtio_spmi_config config; + struct spmi_pmic_arb *pa; +}; +static struct virtio_spmi *g_vspmi; + +/** + * spmi_pmic_arb - SPMI PMIC Arbiter object + * + * @irq: PMIC ARB interrupt. + * @ee: the current Execution Environment + * @min_apid: minimum APID (used for bounding IRQ search) + * @max_apid: maximum APID + * @domain: irq domain object for PMIC IRQ domain + * @spmic: SPMI controller object + * @ver_ops: version dependent operations. + * @ppid_to_apid in-memory copy of PPID -> APID mapping table. + */ +struct spmi_pmic_arb { + int irq; + u8 ee; + u16 min_apid; + u16 max_apid; + struct irq_domain *domain; + struct spmi_controller *spmic; + const struct pmic_arb_ver_ops *ver_ops; + u16 *ppid_to_apid; + struct apid_data apid_data[PMIC_ARB_MAX_PERIPHS]; +}; + +/** + * pmic_arb_ver: version dependent functionality. + * + * @ver_str: version string. + * @ppid_to_apid: finds the apid for a given ppid. + * @fmt_cmd: formats a GENI/SPMI command. + */ +struct pmic_arb_ver_ops { + const char *ver_str; + int (*ppid_to_apid)(struct spmi_pmic_arb *pa, u16 ppid); + u32 (*fmt_cmd)(u8 opc, u8 sid, u16 addr, u8 bc); +}; + +static int +vspmi_pmic_arb_xfer(struct spmi_pmic_arb *pa, struct virtio_spmi_msg *req) +{ + struct scatterlist sg[1]; + struct virtio_spmi_msg *rsp; + unsigned int vqlen; + int rc = 0; + unsigned long flags; + + sg_init_one(sg, req, virtio32_to_cpu(g_vspmi->vdev, req->len)); + + spin_lock_irqsave(&g_vspmi->lock, flags); + rc = virtqueue_add_outbuf(g_vspmi->vq, sg, 1, req, GFP_ATOMIC); + if (rc) { + dev_err(&g_vspmi->vdev->dev, "fail to add output buffer\n"); + goto out; + } + + virtqueue_kick(g_vspmi->vq); + + do { + rsp = virtqueue_get_buf(g_vspmi->vq, &vqlen); + } while (!rsp); + rc = virtio32_to_cpu(g_vspmi->vdev, rsp->res); + +out: + spin_unlock_irqrestore(&g_vspmi->lock, flags); + return rc; +} + +static struct virtio_spmi_msg *vspmi_init_msg(u32 len, u32 type, u32 u) +{ + struct virtio_spmi_msg *req = NULL; + + req = kzalloc(len, GFP_ATOMIC); + if (req) { + req->len = cpu_to_virtio32(g_vspmi->vdev, len); + req->type = cpu_to_virtio32(g_vspmi->vdev, type); + req->u.cnt = req->u.cmd = cpu_to_virtio32(g_vspmi->vdev, u); + } else { + dev_err(&g_vspmi->vdev->dev, "no atomic mem\n"); + } + + dev_dbg(&g_vspmi->vdev->dev, "len:%u type:%u u:%x\n", len, type, u); + return req; +} + +static void +vspmi_fill_one(struct virtio_spmi_msg *req, u32 ppid, u32 val) +{ + u32 idx = virtio32_to_cpu(g_vspmi->vdev, req->u.cnt); + u32 type = virtio32_to_cpu(g_vspmi->vdev, req->type); + + req->payload[idx].irqd.ppid = + cpu_to_virtio32(g_vspmi->vdev, ppid); + if ((type == VIO_IRQ_CLEAR) || (type == VIO_ACC_ENABLE_WR)) + req->payload[idx].irqd.val = + cpu_to_virtio32(g_vspmi->vdev, val); + + dev_dbg(&g_vspmi->vdev->dev, "spmi: cnt:%u ppid:%u val:%u\n", idx, + virtio32_to_cpu(g_vspmi->vdev, req->payload[idx].irqd.ppid), + virtio32_to_cpu(g_vspmi->vdev, req->payload[idx].irqd.val)); + + req->u.cnt = cpu_to_virtio32(g_vspmi->vdev, (idx + 1)); +} + +static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, + u16 addr, u8 *buf, size_t len) +{ + struct spmi_pmic_arb *pa = spmi_controller_get_drvdata(ctrl); + struct virtio_spmi_msg *req; + u8 bc = len - 1; + u32 data, cmd; + int rc; + + if (bc >= PMIC_ARB_MAX_TRANS_BYTES) { + dev_err(&ctrl->dev, + "pmic-arb supports 1..%d bytes per trans, but:%zu requested", + PMIC_ARB_MAX_TRANS_BYTES, len); + return -EINVAL; + } + + /* Check the opcode */ + if (opc >= 0x60 && opc <= 0x7F) + opc = PMIC_ARB_OP_READ; + else if (opc >= 0x20 && opc <= 0x2F) + opc = PMIC_ARB_OP_EXT_READ; + else if (opc >= 0x38 && opc <= 0x3F) + opc = PMIC_ARB_OP_EXT_READL; + else + return -EINVAL; + + cmd = pa->ver_ops->fmt_cmd(opc, sid, addr, bc); + + req = vspmi_init_msg(MSG_SZ(1), VIO_SPMI_BUS_READ, cmd); + if (!req) + return -ENOMEM; + + rc = vspmi_pmic_arb_xfer(pa, req); + if (rc) + goto out; + + data = virtio32_to_cpu(g_vspmi->vdev, + req->payload[0].cmdd.data[0]); + memcpy(buf, &data, (bc & 3) + 1); + + if (bc > 3) { + data = virtio32_to_cpu(g_vspmi->vdev, + req->payload[0].cmdd.data[1]); + memcpy((buf + 4), &data, ((bc - 4) & 3) + 1); + } + +out: + kfree(req); + return rc; +} + +static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, + u8 sid, u16 addr, const u8 *buf, size_t len) +{ + struct spmi_pmic_arb *pa = spmi_controller_get_drvdata(ctrl); + struct virtio_spmi_msg *req; + u8 bc = len - 1; + u32 data, cmd; + int rc; + + if (bc >= PMIC_ARB_MAX_TRANS_BYTES) { + dev_err(&ctrl->dev, + "pmic-arb supports 1..%d bytes per trans, but:%zu requested", + PMIC_ARB_MAX_TRANS_BYTES, len); + return -EINVAL; + } + + /* Check the opcode */ + if (opc >= 0x40 && opc <= 0x5F) + opc = PMIC_ARB_OP_WRITE; + else if (opc <= 0x0F) + opc = PMIC_ARB_OP_EXT_WRITE; + else if (opc >= 0x30 && opc <= 0x37) + opc = PMIC_ARB_OP_EXT_WRITEL; + else if (opc >= 0x80) + opc = PMIC_ARB_OP_ZERO_WRITE; + else + return -EINVAL; + + cmd = pa->ver_ops->fmt_cmd(opc, sid, addr, bc); + + req = vspmi_init_msg(MSG_SZ(1), VIO_SPMI_BUS_WRITE, cmd); + if (!req) + return -ENOMEM; + + memcpy(&data, buf, (bc & 3) + 1); + req->payload[0].cmdd.data[0] = cpu_to_virtio32(g_vspmi->vdev, data); + if (bc > 3) { + memcpy(&data, (buf + 4), ((bc - 4) & 3) + 1); + req->payload[0].cmdd.data[1] = + cpu_to_virtio32(g_vspmi->vdev, data); + } + + rc = vspmi_pmic_arb_xfer(pa, req); + + kfree(req); + return rc; +} + +enum qpnpint_regs { + QPNPINT_REG_RT_STS = 0x10, + QPNPINT_REG_SET_TYPE = 0x11, + QPNPINT_REG_POLARITY_HIGH = 0x12, + QPNPINT_REG_POLARITY_LOW = 0x13, + QPNPINT_REG_LATCHED_CLR = 0x14, + QPNPINT_REG_EN_SET = 0x15, + QPNPINT_REG_EN_CLR = 0x16, + QPNPINT_REG_LATCHED_STS = 0x18, +}; + +struct spmi_pmic_arb_qpnpint_type { + u8 type; /* 1 -> edge */ + u8 polarity_high; + u8 polarity_low; +} __packed; + +/* Simplified accessor functions for irqchip callbacks */ +static void qpnpint_spmi_write(struct irq_data *d, u8 reg, void *buf, + size_t len) +{ + struct spmi_pmic_arb *pa = irq_data_get_irq_chip_data(d); + u8 sid = hwirq_to_sid(d->hwirq); + u8 per = hwirq_to_per(d->hwirq); + + if (pmic_arb_write_cmd(pa->spmic, SPMI_CMD_EXT_WRITEL, sid, + (per << 8) + reg, buf, len)) + dev_err_ratelimited(&pa->spmic->dev, + "failed irqchip transaction on %x\n", d->irq); +} + +static void qpnpint_spmi_read(struct irq_data *d, u8 reg, void *buf, size_t len) +{ + struct spmi_pmic_arb *pa = irq_data_get_irq_chip_data(d); + u8 sid = hwirq_to_sid(d->hwirq); + u8 per = hwirq_to_per(d->hwirq); + + if (pmic_arb_read_cmd(pa->spmic, SPMI_CMD_EXT_READL, sid, + (per << 8) + reg, buf, len)) + dev_err_ratelimited(&pa->spmic->dev, + "failed irqchip transaction on %x\n", d->irq); +} + +static void cleanup_irq(struct spmi_pmic_arb *pa, u16 apid, int id) +{ + u16 ppid = pa->apid_data[apid].ppid; + u8 sid = ppid >> 8; + u8 per = ppid & 0xFF; + u8 irq_mask = BIT(id); + + struct virtio_spmi_msg *req; + + req = vspmi_init_msg(MSG_SZ(1), VIO_IRQ_CLEAR, 0); + if (req) { + dev_err_ratelimited(&pa->spmic->dev, + "%s apid=%d sid=0x%x per=0x%x irq=%d\n", + __func__, apid, sid, per, id); + + vspmi_fill_one(req, ppid, irq_mask); + vspmi_pmic_arb_xfer(pa, req); + kfree(req); + } +} + +static void periph_interrupt(struct spmi_pmic_arb *pa, u16 apid) +{ + unsigned int irq; + u32 status, id; + u8 sid = (pa->apid_data[apid].ppid >> 8) & 0xF; + u8 per = pa->apid_data[apid].ppid & 0xFF; + + struct virtio_spmi_msg *req; + + req = vspmi_init_msg(MSG_SZ(1), VIO_IRQ_STATUS, 0); + if (!req) + return; + + vspmi_fill_one(req, pa->apid_data[apid].ppid, 0); + if (vspmi_pmic_arb_xfer(pa, req)) { + kfree(req); + return; + } + + status = virtio32_to_cpu(g_vspmi->vdev, + req->payload[0].irqd.val); + kfree(req); + + while (status) { + id = ffs(status) - 1; + status &= ~BIT(id); + irq = irq_find_mapping(pa->domain, + spec_to_hwirq(sid, per, id, apid)); + if (irq == 0) { + cleanup_irq(pa, apid, id); + continue; + } + generic_handle_irq(irq); + } +} + +static void pmic_arb_chained_irq(struct irq_desc *desc) +{ + struct spmi_pmic_arb *pa = irq_desc_get_handler_data(desc); + struct irq_chip *chip = irq_desc_get_chip(desc); + + u32 enable; + int i; + u16 ppid; + + struct virtio_spmi_msg *req; + u32 *irq_status; + + irq_status = kzalloc((pa->max_apid + 1) * sizeof(u32), GFP_ATOMIC); + if (!irq_status) + return; + + chained_irq_enter(chip, desc); + + /* get all irq_status */ + req = vspmi_init_msg(MSG_SZ(pa->max_apid + 1), VIO_IRQ_STATUS, 0); + if (req) { + for (i = pa->min_apid; i <= pa->max_apid; i++) { + ppid = pa->apid_data[i].ppid; + vspmi_fill_one(req, ppid, 0); + } + } else + goto out; + + if (vspmi_pmic_arb_xfer(pa, req)) { + kfree(req); + goto out; + } + + for (i = pa->min_apid; i <= pa->max_apid; i++) + irq_status[i] = virtio32_to_cpu(g_vspmi->vdev, + req->payload[i].irqd.val); + kfree(req); + + /* ACC_STATUS is empty but IRQ fired check IRQ_STATUS */ + for (i = pa->min_apid; i <= pa->max_apid; i++) { + ppid = pa->apid_data[i].ppid; + + if (irq_status[i]) { + req = vspmi_init_msg(MSG_SZ(1), VIO_ACC_ENABLE_RD, 0); + if (!req) + goto out; + + vspmi_fill_one(req, ppid, 0); + if (vspmi_pmic_arb_xfer(pa, req)) + goto out; + + enable = virtio32_to_cpu(g_vspmi->vdev, + req->payload[0].irqd.val); + kfree(req); + + if (enable & SPMI_PIC_ACC_ENABLE_BIT) { + dev_dbg(&pa->spmic->dev, + "Dispatching IRQ for apid=%d status=%x\n", + i, irq_status[i]); + periph_interrupt(pa, i); + } + } + } + +out: + chained_irq_exit(chip, desc); + kfree(irq_status); +} + +static void qpnpint_irq_ack(struct irq_data *d) +{ + struct spmi_pmic_arb *pa = irq_data_get_irq_chip_data(d); + u8 irq = hwirq_to_irq(d->hwirq); + u16 apid = hwirq_to_apid(d->hwirq); + u16 ppid = pa->apid_data[apid].ppid; + u8 data; + + struct virtio_spmi_msg *req; + + req = vspmi_init_msg(MSG_SZ(1), VIO_IRQ_CLEAR, 0); + if (req) { + vspmi_fill_one(req, ppid, BIT(irq)); + vspmi_pmic_arb_xfer(pa, req); + kfree(req); + } else + return; + + data = BIT(irq); + qpnpint_spmi_write(d, QPNPINT_REG_LATCHED_CLR, &data, 1); +} + +static void qpnpint_irq_mask(struct irq_data *d) +{ + u8 irq = hwirq_to_irq(d->hwirq); + u8 data = BIT(irq); + + qpnpint_spmi_write(d, QPNPINT_REG_EN_CLR, &data, 1); +} + +static void qpnpint_irq_unmask(struct irq_data *d) +{ + struct spmi_pmic_arb *pa = irq_data_get_irq_chip_data(d); + u8 irq = hwirq_to_irq(d->hwirq); + u16 apid = hwirq_to_apid(d->hwirq); + u16 ppid = pa->apid_data[apid].ppid; + u8 buf[2]; + + struct virtio_spmi_msg *req; + + req = vspmi_init_msg(MSG_SZ(1), VIO_ACC_ENABLE_WR, 0); + if (req) { + vspmi_fill_one(req, ppid, SPMI_PIC_ACC_ENABLE_BIT); + vspmi_pmic_arb_xfer(pa, req); + kfree(req); + } else + return; + + qpnpint_spmi_read(d, QPNPINT_REG_EN_SET, &buf[0], 1); + if (!(buf[0] & BIT(irq))) { + /* + * Since the interrupt is currently disabled, write to both the + * LATCHED_CLR and EN_SET registers so that a spurious interrupt + * cannot be triggered when the interrupt is enabled + */ + buf[0] = BIT(irq); + buf[1] = BIT(irq); + qpnpint_spmi_write(d, QPNPINT_REG_LATCHED_CLR, &buf, 2); + } +} + +static int qpnpint_irq_set_type(struct irq_data *d, unsigned int flow_type) +{ + struct spmi_pmic_arb_qpnpint_type type; + irq_flow_handler_t flow_handler; + u8 irq = hwirq_to_irq(d->hwirq); + + qpnpint_spmi_read(d, QPNPINT_REG_SET_TYPE, &type, sizeof(type)); + + if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) { + type.type |= BIT(irq); + if (flow_type & IRQF_TRIGGER_RISING) + type.polarity_high |= BIT(irq); + else + type.polarity_high &= ~BIT(irq); + if (flow_type & IRQF_TRIGGER_FALLING) + type.polarity_low |= BIT(irq); + else + type.polarity_low &= ~BIT(irq); + + flow_handler = handle_edge_irq; + } else { + if ((flow_type & (IRQF_TRIGGER_HIGH)) && + (flow_type & (IRQF_TRIGGER_LOW))) + return -EINVAL; + + type.type &= ~BIT(irq); /* level trig */ + if (flow_type & IRQF_TRIGGER_HIGH) { + type.polarity_high |= BIT(irq); + type.polarity_low &= ~BIT(irq); + } else { + type.polarity_low |= BIT(irq); + type.polarity_high &= ~BIT(irq); + } + + flow_handler = handle_level_irq; + } + + qpnpint_spmi_write(d, QPNPINT_REG_SET_TYPE, &type, sizeof(type)); + irq_set_handler_locked(d, flow_handler); + + return 0; +} + +static int qpnpint_irq_set_wake(struct irq_data *d, unsigned int on) +{ + struct spmi_pmic_arb *pa = irq_data_get_irq_chip_data(d); + + return irq_set_irq_wake(pa->irq, on); +} + +static int qpnpint_get_irqchip_state(struct irq_data *d, + enum irqchip_irq_state which, + bool *state) +{ + u8 irq = hwirq_to_irq(d->hwirq); + u8 status = 0; + + if (which != IRQCHIP_STATE_LINE_LEVEL) + return -EINVAL; + + qpnpint_spmi_read(d, QPNPINT_REG_RT_STS, &status, 1); + *state = !!(status & BIT(irq)); + + return 0; +} + +static int qpnpint_irq_request_resources(struct irq_data *d) +{ + struct spmi_pmic_arb *pa = irq_data_get_irq_chip_data(d); + u16 periph = hwirq_to_per(d->hwirq); + u16 apid = hwirq_to_apid(d->hwirq); + u16 sid = hwirq_to_sid(d->hwirq); + u16 irq = hwirq_to_irq(d->hwirq); + + if (pa->apid_data[apid].irq_ee != pa->ee) { + dev_err(&pa->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u: ee=%u but owner=%u\n", + sid, periph, irq, pa->ee, + pa->apid_data[apid].irq_ee); + return -ENODEV; + } + + return 0; +} + +static struct irq_chip pmic_arb_irqchip = { + .name = "pmic_arb", + .irq_ack = qpnpint_irq_ack, + .irq_mask = qpnpint_irq_mask, + .irq_unmask = qpnpint_irq_unmask, + .irq_set_type = qpnpint_irq_set_type, + .irq_set_wake = qpnpint_irq_set_wake, + .irq_get_irqchip_state = qpnpint_get_irqchip_state, + .irq_request_resources = qpnpint_irq_request_resources, + .flags = IRQCHIP_MASK_ON_SUSPEND, +}; + +static void qpnpint_irq_domain_activate(struct irq_domain *domain, + struct irq_data *d) +{ + u8 irq = hwirq_to_irq(d->hwirq); + u8 buf; + + buf = BIT(irq); + qpnpint_spmi_write(d, QPNPINT_REG_EN_CLR, &buf, 1); + qpnpint_spmi_write(d, QPNPINT_REG_LATCHED_CLR, &buf, 1); +} + +static int qpnpint_irq_domain_dt_translate(struct irq_domain *d, + struct device_node *controller, + const u32 *intspec, + unsigned int intsize, + unsigned long *out_hwirq, + unsigned int *out_type) +{ + struct spmi_pmic_arb *pa = d->host_data; + u16 apid, ppid; + int rc; + + dev_dbg(&pa->spmic->dev, "intspec[0] 0x%1x intspec[1] 0x%02x intspec[2] 0x%02x\n", + intspec[0], intspec[1], intspec[2]); + + if (irq_domain_get_of_node(d) != controller) + return -EINVAL; + if (intsize != 4) + return -EINVAL; + if (intspec[0] > 0xF || intspec[1] > 0xFF || intspec[2] > 0x7) + return -EINVAL; + + ppid = intspec[0] << 8 | intspec[1]; + rc = pa->ver_ops->ppid_to_apid(pa, ppid); + if (rc < 0) { + dev_err(&pa->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u rc = %d\n", + intspec[0], intspec[1], intspec[2], rc); + return rc; + } + + apid = rc; + /* Keep track of {max,min}_apid for bounding search during interrupt */ + if (apid > pa->max_apid) + pa->max_apid = apid; + if (apid < pa->min_apid) + pa->min_apid = apid; + + *out_hwirq = spec_to_hwirq(intspec[0], intspec[1], intspec[2], apid); + *out_type = intspec[3] & IRQ_TYPE_SENSE_MASK; + + dev_dbg(&pa->spmic->dev, "out_hwirq = %lu\n", *out_hwirq); + + return 0; +} + +static int qpnpint_irq_domain_map(struct irq_domain *d, + unsigned int virq, + irq_hw_number_t hwirq) +{ + struct spmi_pmic_arb *pa = d->host_data; + + dev_dbg(&pa->spmic->dev, "virq = %u, hwirq = %lu\n", virq, hwirq); + + irq_set_chip_and_handler(virq, &pmic_arb_irqchip, handle_level_irq); + irq_set_chip_data(virq, d->host_data); + irq_set_noprobe(virq); + return 0; +} + +static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pa) +{ + struct apid_data *apidd = pa->apid_data; + u16 apid, ppid; + u16 i; + + for (i = 0; i < VM_MAX_PERIPHS; i++) { + ppid = g_vspmi->config.ppid_allowed[i]; + if (!ppid) + break; + + apid = i; + pa->ppid_to_apid[ppid] = apid | PMIC_ARB_APID_VALID; + pa->apid_data[apid].ppid = ppid; + pa->apid_data[apid].irq_ee = 0; + pa->apid_data[apid].write_ee = 0; + } + + /* Dump the mapping table for debug purposes. */ + dev_dbg(&pa->spmic->dev, "PPID APID Write-EE IRQ-EE\n"); + for (ppid = 0; ppid < PMIC_ARB_MAX_PPID; ppid++) { + apid = pa->ppid_to_apid[ppid]; + if (apid & PMIC_ARB_APID_VALID) { + apid &= ~PMIC_ARB_APID_VALID; + apidd = &pa->apid_data[apid]; + dev_dbg(&pa->spmic->dev, "%#03X %3u %2u %2u\n", + ppid, apid, apidd->write_ee, apidd->irq_ee); + } + } + + return 0; +} + +static int pmic_arb_ppid_to_apid_v5(struct spmi_pmic_arb *pa, u16 ppid) +{ + if (!(pa->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID)) + return -ENODEV; + + return pa->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID; +} + +static u32 pmic_arb_fmt_cmd_v1(u8 opc, u8 sid, u16 addr, u8 bc) +{ + return (opc << 27) | ((sid & 0xf) << 20) | (addr << 4) | (bc & 0x7); +} + +static const struct pmic_arb_ver_ops pmic_arb_v5 = { + .ver_str = "v5", + .ppid_to_apid = pmic_arb_ppid_to_apid_v5, + .fmt_cmd = pmic_arb_fmt_cmd_v1, +}; + +static const struct irq_domain_ops pmic_arb_irq_domain_ops = { + .map = qpnpint_irq_domain_map, + .xlate = qpnpint_irq_domain_dt_translate, + .activate = qpnpint_irq_domain_activate, +}; + +static int spmi_pmic_arb_probe(struct platform_device *pdev) +{ + struct spmi_pmic_arb *pa; + struct spmi_controller *ctrl; + int err; + u32 ee; + + if (!g_vspmi) + return -EINVAL; + + ctrl = spmi_controller_alloc(&pdev->dev, sizeof(*pa)); + if (!ctrl) + return -ENOMEM; + + pa = spmi_controller_get_drvdata(ctrl); + pa->spmic = ctrl; + g_vspmi->pa = pa; + + pa->ver_ops = &pmic_arb_v5; + dev_info(&ctrl->dev, "Virtio PMIC arbiter\n"); + + pa->irq = platform_get_irq_byname(pdev, "periph_irq"); + if (pa->irq < 0) { + err = pa->irq; + goto err_put_ctrl; + } + + err = of_property_read_u32(pdev->dev.of_node, "qcom,ee", &ee); + if (err) { + dev_err(&pdev->dev, "EE unspecified.\n"); + goto err_put_ctrl; + } + pa->ee = ee; + + pa->ppid_to_apid = devm_kcalloc(&ctrl->dev, PMIC_ARB_MAX_PPID, + sizeof(*pa->ppid_to_apid), + GFP_KERNEL); + if (!pa->ppid_to_apid) { + err = -ENOMEM; + goto err_put_ctrl; + } + + /* Initialize max_apid/min_apid to the opposite bounds, during + * the irq domain translation, we are sure to update these + */ + pa->max_apid = 0; + pa->min_apid = PMIC_ARB_MAX_PERIPHS - 1; + + platform_set_drvdata(pdev, ctrl); + + ctrl->read_cmd = pmic_arb_read_cmd; + ctrl->write_cmd = pmic_arb_write_cmd; + + err = pmic_arb_read_apid_map_v5(pa); + if (err) { + dev_err(&pdev->dev, "could not read APID->PPID mapping table, rc= %d\n", + err); + goto err_put_ctrl; + } + + dev_dbg(&pdev->dev, "adding irq domain\n"); + pa->domain = irq_domain_add_tree(pdev->dev.of_node, + &pmic_arb_irq_domain_ops, pa); + if (!pa->domain) { + dev_err(&pdev->dev, "unable to create irq_domain\n"); + err = -ENOMEM; + goto err_put_ctrl; + } + + irq_set_chained_handler_and_data(pa->irq, pmic_arb_chained_irq, pa); + err = spmi_controller_add(ctrl); + if (err) + goto err_domain_remove; + + return 0; + +err_domain_remove: + irq_set_chained_handler_and_data(pa->irq, NULL, NULL); + irq_domain_remove(pa->domain); +err_put_ctrl: + spmi_controller_put(ctrl); + return err; +} + +static int spmi_pmic_arb_remove(struct platform_device *pdev) +{ + struct spmi_controller *ctrl = platform_get_drvdata(pdev); + struct spmi_pmic_arb *pa = spmi_controller_get_drvdata(ctrl); + + spmi_controller_remove(ctrl); + irq_set_chained_handler_and_data(pa->irq, NULL, NULL); + irq_domain_remove(pa->domain); + spmi_controller_put(ctrl); + return 0; +} + +static const struct of_device_id spmi_pmic_arb_match_table[] = { + { .compatible = "qcom,viospmi-pmic-arb", }, + {}, +}; +MODULE_DEVICE_TABLE(of, spmi_pmic_arb_match_table); + +static struct platform_driver spmi_pmic_arb_driver = { + .probe = spmi_pmic_arb_probe, + .remove = spmi_pmic_arb_remove, + .driver = { + .name = "viospmi_pmic_arb", + .of_match_table = spmi_pmic_arb_match_table, + .probe_type = PROBE_PREFER_ASYNCHRONOUS, + }, +}; + +static void virtio_spmi_isr(struct virtqueue *vq) { } + +static int virtio_spmi_init_vqs(struct virtio_spmi *vspmi) +{ + struct virtqueue *vqs[1]; + vq_callback_t *cbs[] = { virtio_spmi_isr }; + static const char * const names[] = { "virtio_spmi_isr" }; + int rc; + + rc = virtio_find_vqs(vspmi->vdev, 1, vqs, cbs, names, NULL); + if (rc) + return rc; + + vspmi->vq = vqs[0]; + + return 0; +} + +static void virtio_spmi_del_vqs(struct virtio_spmi *vspmi) +{ + vspmi->vdev->config->del_vqs(vspmi->vdev); +} + +static int virtio_spmi_probe(struct virtio_device *vdev) +{ + struct virtio_spmi *vspmi; + int i; + int ret = 0; + u32 val; + + if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) + return -ENODEV; + + vspmi = devm_kzalloc(&vdev->dev, sizeof(*vspmi), GFP_KERNEL); + if (!vspmi) + return -ENOMEM; + + vdev->priv = vspmi; + vspmi->vdev = vdev; + spin_lock_init(&vspmi->lock); + + ret = virtio_spmi_init_vqs(vspmi); + if (ret) + goto err_init_vq; + + virtio_device_ready(vdev); + + memset(&vspmi->config, 0x0, sizeof(vspmi->config)); + + for (i = 0; i < VM_MAX_PERIPHS; i += 2) { + val = virtio_cread32(vdev, + offsetof(struct virtio_spmi_config, ppid_allowed[i])); + vspmi->config.ppid_allowed[i] = val & PMIC_ARB_PPID_MASK; + vspmi->config.ppid_allowed[i + 1] = + (val >> 16) & PMIC_ARB_PPID_MASK; + if ((!vspmi->config.ppid_allowed[i]) || + !(vspmi->config.ppid_allowed[i + 1])) + break; + } + + g_vspmi = vspmi; + + return platform_driver_register(&spmi_pmic_arb_driver); + +err_init_vq: + virtio_spmi_del_vqs(vspmi); + devm_kfree(&vdev->dev, vspmi); + return ret; +} + +static void virtio_spmi_remove(struct virtio_device *vdev) +{ + struct virtio_spmi *vspmi = vdev->priv; + + vdev->config->reset(vdev); + vdev->config->del_vqs(vdev); + devm_kfree(&vdev->dev, vspmi); + g_vspmi = NULL; +} + +static unsigned int features[] = { + VIRTIO_SPMI_F_INT, +}; + +static struct virtio_device_id id_table[] = { + { VIRTIO_ID_SPMI, VIRTIO_DEV_ANY_ID }, + { 0 }, +}; + +static struct virtio_driver virtio_spmi_driver = { + .feature_table = features, + .feature_table_size = ARRAY_SIZE(features), + .driver.name = KBUILD_MODNAME, + .driver.owner = THIS_MODULE, + .id_table = id_table, + .probe = virtio_spmi_probe, + .remove = virtio_spmi_remove, +}; + +static int __init virtio_spmi_init(void) +{ + return register_virtio_driver(&virtio_spmi_driver); +} + +static void __exit virtio_spmi_exit(void) +{ + unregister_virtio_driver(&virtio_spmi_driver); +} + +subsys_initcall(virtio_spmi_init); +module_exit(virtio_spmi_exit); + +MODULE_DEVICE_TABLE(virtio, id_table); +MODULE_DESCRIPTION("virtio spmi_pmic_arb frontend driver"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/virtio_spmi.h b/include/linux/virtio_spmi.h new file mode 100644 index 000000000000..d3224983fa93 --- /dev/null +++ b/include/linux/virtio_spmi.h @@ -0,0 +1,77 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _LINUX_VIRTIO_SPMI_H +#define _LINUX_VIRTIO_SPMI_H + +#include +#include +#include +#include + +/* Feature bits */ +#define VIRTIO_SPMI_F_INT 1 /* Support interrupt */ + +#define VM_MAX_PERIPHS 512 + +/* Configuration layout */ +struct virtio_spmi_config { + __u16 ppid_allowed[VM_MAX_PERIPHS]; +} __packed; + +struct payload_cmd { + __virtio32 data[2]; +}; + +struct payload_irq { + __virtio32 ppid; + __virtio32 val; +}; + +union payload_data { + struct payload_cmd cmdd; + struct payload_irq irqd; +}; + +struct virtio_spmi_msg { + __virtio32 type; + __virtio32 len; + __virtio32 res; + union { + __virtio32 cmd; + __virtio32 cnt; + } u; + union payload_data payload[]; +}; + +/* Virtio SPMI message type */ +enum vio_spmi_msg_type { + VIO_SPMI_BUS_WRITE = 0, + VIO_SPMI_BUS_READ = 1, + VIO_ACC_ENABLE_WR = 2, + VIO_ACC_ENABLE_RD = 3, + VIO_IRQ_CLEAR = 4, + VIO_IRQ_STATUS = 5, +}; + +/* Virtio SPMI message type */ +enum vio_spmi_msg_res { + VIO_SPMI_DONE = 0, + VIO_SPMI_ERR = 1, +}; + +/* payload fix size and one payload_data size */ +#define MSG_FIX_SZ (sizeof(struct virtio_spmi_msg)) +#define PER_PLD_SZ (sizeof(union payload_data)) +#define MSG_SZ(x) (MSG_FIX_SZ + ((PER_PLD_SZ) * (x))) + +#endif /* _LINUX_VIRTIO_SPMI_H */ diff --git a/include/uapi/linux/virtio_ids.h b/include/uapi/linux/virtio_ids.h index af8f368f3425..c9c11445593b 100644 --- a/include/uapi/linux/virtio_ids.h +++ b/include/uapi/linux/virtio_ids.h @@ -47,5 +47,6 @@ #define VIRTIO_ID_REGULATOR 31 /* virtio regulator */ #define VIRTIO_ID_I2C 32 /* virtio i2c */ +#define VIRTIO_ID_SPMI 33 /* virtio spmi */ #endif /* _LINUX_VIRTIO_IDS_H */ -- GitLab From ff4d0c76e4c8b179e82ed7ed049e657326a603a6 Mon Sep 17 00:00:00 2001 From: Yimin Peng Date: Tue, 30 Jul 2019 17:49:42 +0800 Subject: [PATCH 1104/1121] ARM: dts: msm: Add virtio spmi and pmic gpios on sa6155p and sa8155 VMs Add spmi pmic gpios some of which are must for peripherals' functionality on virtual platforms. But disable virtio spmi for SA8195 first for no requirement now. Change-Id: I66beb779cb0761dba008202fdf9d90db0ec2cdc9 Signed-off-by: Yimin Peng --- arch/arm64/boot/dts/qcom/pm6155-vm.dtsi | 49 +++++++++++++ arch/arm64/boot/dts/qcom/pm8150-vm.dtsi | 77 ++++++++++++++++++++ arch/arm64/boot/dts/qcom/quin-vm-common.dtsi | 22 ++++++ arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi | 1 + arch/arm64/boot/dts/qcom/sa8155-vm.dtsi | 1 + arch/arm64/boot/dts/qcom/sa8195-vm.dts | 8 ++ 6 files changed, 158 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/pm6155-vm.dtsi create mode 100644 arch/arm64/boot/dts/qcom/pm8150-vm.dtsi diff --git a/arch/arm64/boot/dts/qcom/pm6155-vm.dtsi b/arch/arm64/boot/dts/qcom/pm6155-vm.dtsi new file mode 100644 index 000000000000..d7a5b9672d14 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/pm6155-vm.dtsi @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include + +&spmi_bus { + qcom,pm6155@0 { + compatible = "qcom,spmi-pmic"; + reg = <0x0 SPMI_USID>; + #address-cells = <2>; + #size-cells = <0>; + + pm6155_1_gpios: pinctrl@c000 { + compatible = "qcom,spmi-gpio"; + reg = <0xc000 0xa00>; + interrupts = <0x0 0xc0 0 IRQ_TYPE_NONE>, + <0x0 0xc1 0 IRQ_TYPE_NONE>, + <0x0 0xc2 0 IRQ_TYPE_NONE>, + <0x0 0xc3 0 IRQ_TYPE_NONE>, + <0x0 0xc4 0 IRQ_TYPE_NONE>, + <0x0 0xc5 0 IRQ_TYPE_NONE>, + <0x0 0xc6 0 IRQ_TYPE_NONE>, + <0x0 0xc7 0 IRQ_TYPE_NONE>, + <0x0 0xc8 0 IRQ_TYPE_NONE>, + <0x0 0xc9 0 IRQ_TYPE_NONE>; + interrupt-names = "pm6155_1_gpio1", "pm6155_1_gpio2", + "pm6155_1_gpio3", "pm6155_1_gpio4", + "pm6155_1_gpio5", "pm6155_1_gpio6", + "pm6155_1_gpio7", "pm6155_1_gpio8", + "pm6155_1_gpio9", "pm6155_1_gpio10"; + gpio-controller; + #gpio-cells = <2>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/pm8150-vm.dtsi b/arch/arm64/boot/dts/qcom/pm8150-vm.dtsi new file mode 100644 index 000000000000..6c5a21a6e7f3 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/pm8150-vm.dtsi @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include + +&spmi_bus { + qcom,pm8150@0 { + compatible = "qcom,spmi-pmic"; + reg = <0x0 SPMI_USID>; + #address-cells = <2>; + #size-cells = <0>; + + pm8150_gpios: pinctrl@c000 { + compatible = "qcom,spmi-gpio"; + reg = <0xc000 0xa00>; + interrupts = <0x0 0xc0 0 IRQ_TYPE_NONE>, + <0x0 0xc2 0 IRQ_TYPE_NONE>, + <0x0 0xc3 0 IRQ_TYPE_NONE>, + <0x0 0xc5 0 IRQ_TYPE_NONE>, + <0x0 0xc8 0 IRQ_TYPE_NONE>, + <0x0 0xc9 0 IRQ_TYPE_NONE>; + interrupt-names = "pm8150_gpio1", "pm8150_gpio3", + "pm8150_gpio4", "pm8150_gpio6", + "pm8150_gpio9", "pm8150_gpio10"; + gpio-controller; + #gpio-cells = <2>; + qcom,gpios-disallowed = <2 5 7 8>; + }; + }; +}; + +&pm8150_gpios { + key_home { + key_home_default: key_home_default { + pins = "gpio1"; + function = "normal"; + input-enable; + bias-pull-up; + power-source = <0>; + }; + }; + + storage_sd_detect { + storage_cd_default: storage_cd_default { + pins = "gpio4"; + function = "normal"; + input-enable; + bias-pull-up; + power-source = <0>; + }; + }; + + key_vol_up { + key_vol_up_default: key_vol_up_default { + pins = "gpio6"; + function = "normal"; + input-enable; + bias-pull-up; + power-source = <1>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/quin-vm-common.dtsi b/arch/arm64/boot/dts/qcom/quin-vm-common.dtsi index 3d353aa5dfca..bbe8e8e6f225 100644 --- a/arch/arm64/boot/dts/qcom/quin-vm-common.dtsi +++ b/arch/arm64/boot/dts/qcom/quin-vm-common.dtsi @@ -248,4 +248,26 @@ compatible = "qcom,vm-restart"; status = "ok"; }; + + spmi_bus: qcom,spmi { + compatible = "qcom,viospmi-pmic-arb"; + interrupt-names = "periph_irq"; + interrupts = ; + qcom,ee = <0>; + qcom,channel = <0>; + #address-cells = <2>; + #size-cells = <0>; + interrupt-controller; + #interrupt-cells = <4>; + cell-index = <0>; + }; + + viospmi: virtio-spmi@1c800000 { + compatible = "virtio,mmio"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x1c800000 0x1100>; + interrupts = ; + status = "okay"; + }; }; diff --git a/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi b/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi index aff7ecb2fe01..60291e58a6b9 100644 --- a/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155p-vm.dtsi @@ -320,6 +320,7 @@ #include "sa6155p-vm-usb.dtsi" #include "sa8155-vm-audio.dtsi" #include "sa6155p-vm-pcie.dtsi" +#include "pm6155-vm.dtsi" &tlmm { dirconn-list = <100 216 1>, diff --git a/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi b/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi index ff028a04be6f..fca2335ca1b8 100644 --- a/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi @@ -474,6 +474,7 @@ #include "sa8155-vm-audio.dtsi" #include "sa8155-vm-pcie.dtsi" #include "sa8155-vm-mhi.dtsi" +#include "pm8150-vm.dtsi" &tlmm { dirconn-list = <37 216 1>; diff --git a/arch/arm64/boot/dts/qcom/sa8195-vm.dts b/arch/arm64/boot/dts/qcom/sa8195-vm.dts index 12807e33cf4e..5c7ef0257b31 100644 --- a/arch/arm64/boot/dts/qcom/sa8195-vm.dts +++ b/arch/arm64/boot/dts/qcom/sa8195-vm.dts @@ -36,3 +36,11 @@ &usb2_phy0 { status = "ok"; }; + +&spmi_bus { + status = "disabled"; +}; + +&viospmi { + status = "disabled"; +}; -- GitLab From 300bb6dd44a3ff7a2a5ac1da908f4e3687b5df3d Mon Sep 17 00:00:00 2001 From: Pratham Pratap Date: Tue, 30 Jul 2019 11:28:16 +0530 Subject: [PATCH 1105/1121] ARM: dts: msm: Add SMMU entry and disable io-coherency on sdmmagpie This change adds SMMU entry for USB and disables io-coherency when allocating buffers for GSI in USB driver for sdmmagpie. Change-Id: Icd792124db70141358cf0dec7b20a37830527ecc Signed-off-by: Pratham Pratap --- arch/arm64/boot/dts/qcom/sdmmagpie-usb.dtsi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdmmagpie-usb.dtsi b/arch/arm64/boot/dts/qcom/sdmmagpie-usb.dtsi index 367be23a8c81..28103989d07d 100644 --- a/arch/arm64/boot/dts/qcom/sdmmagpie-usb.dtsi +++ b/arch/arm64/boot/dts/qcom/sdmmagpie-usb.dtsi @@ -19,6 +19,8 @@ reg = <0x0a600000 0x100000>; reg-names = "core_base"; + iommus = <&apps_smmu 0x540 0x0>; + qcom,smmu-s1-bypass; #address-cells = <1>; #size-cells = <1>; ranges; @@ -52,6 +54,7 @@ 0x130 /* GSI_RING_BASE_ADDR_L */ 0x144 /* GSI_RING_BASE_ADDR_H */ 0x1a4>; /* GSI_IF_STS */ + qcom,gsi-disable-io-coherency; qcom,dwc-usb3-msm-tx-fifo-size = <21288>; qcom,pm-qos-latency = <62>; -- GitLab From 79f74c15fabd53a7168334cd68f37c9be11a754e Mon Sep 17 00:00:00 2001 From: Pratham Pratap Date: Wed, 31 Jul 2019 14:23:05 +0530 Subject: [PATCH 1106/1121] ARM: dts: msm: Disable io-coherency for GSI on SM6150 Disable io-coherency when allocating buffers for GSI in usb driver to avoid SMMU faults. Change-Id: I12858a36dfa51886078f3c60b719ab34b9435f70 Signed-off-by: Pratham Pratap --- arch/arm64/boot/dts/qcom/sm6150-usb.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/qcom/sm6150-usb.dtsi b/arch/arm64/boot/dts/qcom/sm6150-usb.dtsi index 29f885820156..f8a5554f5bee 100644 --- a/arch/arm64/boot/dts/qcom/sm6150-usb.dtsi +++ b/arch/arm64/boot/dts/qcom/sm6150-usb.dtsi @@ -55,6 +55,7 @@ 0x130 /* GSI_RING_BASE_ADDR_L */ 0x144 /* GSI_RING_BASE_ADDR_H */ 0x1a4>; /* GSI_IF_STS */ + qcom,gsi-disable-io-coherency; qcom,dwc-usb3-msm-tx-fifo-size = <21288>; qcom,pm-qos-latency = <61>; -- GitLab From b56d80c49359e193cec9fb8dcdf61c096496b2ba Mon Sep 17 00:00:00 2001 From: Zhenhua Huang Date: Thu, 1 Aug 2019 13:49:18 +0800 Subject: [PATCH 1107/1121] ARM: dts: qcom: Add GFX iommu HSR setting for atoll Update GFX iommu HSR settings. Change-Id: I44c734c1d6d28558847479f286bbf693942ab913 Signed-off-by: Zhenhua Huang --- arch/arm64/boot/dts/qcom/msm-arm-smmu-atoll.dtsi | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm-arm-smmu-atoll.dtsi b/arch/arm64/boot/dts/qcom/msm-arm-smmu-atoll.dtsi index d96746cce5cd..e90b0bfa4468 100644 --- a/arch/arm64/boot/dts/qcom/msm-arm-smmu-atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/msm-arm-smmu-atoll.dtsi @@ -36,6 +36,20 @@ ; clock-names = "gcc_gpu_memnoc_gfx_clk"; clocks = <&clock_gcc GCC_GPU_MEMNOC_GFX_CLK>; + + attach-impl-defs = + <0x6000 0x2378>, + <0x6060 0x1055>, + <0x678c 0x8>, + <0x6794 0x28>, + <0x6800 0x6>, + <0x6900 0x3ff>, + <0x6924 0x204>, + <0x6928 0x11000>, + <0x6930 0x800>, + <0x6960 0xffffffff>, + <0x6b64 0x1a5551>, + <0x6b68 0x9a82a382>; }; apps_smmu: apps-smmu@0x15000000 { -- GitLab From e3ee6c36590ed4b28e041b8e85bdc0a37244e693 Mon Sep 17 00:00:00 2001 From: Mayank Grover Date: Thu, 1 Aug 2019 13:54:46 +0530 Subject: [PATCH 1108/1121] defconfig: msm: cleanup sdmmagpie configs from atoll Change to cleanup sdmmagpie configs from atoll def configs. Change-Id: I572f542f1e531835335be99b02b86e2063dd56bf Signed-off-by: Mayank Grover --- arch/arm64/configs/vendor/atoll-perf_defconfig | 3 --- arch/arm64/configs/vendor/atoll_defconfig | 3 --- 2 files changed, 6 deletions(-) diff --git a/arch/arm64/configs/vendor/atoll-perf_defconfig b/arch/arm64/configs/vendor/atoll-perf_defconfig index 60d5ced35b1b..99cc314d2b48 100644 --- a/arch/arm64/configs/vendor/atoll-perf_defconfig +++ b/arch/arm64/configs/vendor/atoll-perf_defconfig @@ -347,7 +347,6 @@ CONFIG_SLIMBUS_MSM_NGD=y CONFIG_PTP_1588_CLOCK=y CONFIG_PINCTRL_SX150X=y CONFIG_PINCTRL_QCOM_SPMI_PMIC=y -CONFIG_PINCTRL_SDMMAGPIE=y CONFIG_PINCTRL_ATOLL=y CONFIG_PINCTRL_SLPI=y CONFIG_GPIO_SYSFS=y @@ -555,8 +554,6 @@ CONFIG_RPMSG_QCOM_GLINK_SPI=y CONFIG_QCOM_CPUSS_DUMP=y CONFIG_QCOM_RUN_QUEUE_STATS=y CONFIG_QCOM_LLCC=y -CONFIG_QCOM_SM6150_LLCC=y -CONFIG_QCOM_SDMMAGPIE_LLCC=y CONFIG_QCOM_ATOLL_LLCC=y CONFIG_QCOM_LLCC_PERFMON=m CONFIG_QCOM_QMI_HELPERS=y diff --git a/arch/arm64/configs/vendor/atoll_defconfig b/arch/arm64/configs/vendor/atoll_defconfig index fb51877064cd..5aad1bca8889 100644 --- a/arch/arm64/configs/vendor/atoll_defconfig +++ b/arch/arm64/configs/vendor/atoll_defconfig @@ -368,7 +368,6 @@ CONFIG_SLIMBUS_MSM_NGD=y CONFIG_PTP_1588_CLOCK=y CONFIG_PINCTRL_SX150X=y CONFIG_PINCTRL_QCOM_SPMI_PMIC=y -CONFIG_PINCTRL_SDMMAGPIE=y CONFIG_PINCTRL_ATOLL=y CONFIG_PINCTRL_SLPI=y CONFIG_GPIO_SYSFS=y @@ -585,8 +584,6 @@ CONFIG_RPMSG_QCOM_GLINK_SPI=y CONFIG_QCOM_CPUSS_DUMP=y CONFIG_QCOM_RUN_QUEUE_STATS=y CONFIG_QCOM_LLCC=y -CONFIG_QCOM_SM6150_LLCC=y -CONFIG_QCOM_SDMMAGPIE_LLCC=y CONFIG_QCOM_ATOLL_LLCC=y CONFIG_QCOM_LLCC_PERFMON=m CONFIG_QCOM_QMI_HELPERS=y -- GitLab From d2c029bdeec13c82c4bd7bd9d2d0bae9aa212994 Mon Sep 17 00:00:00 2001 From: Zhenhua Huang Date: Tue, 30 Jul 2019 18:22:04 +0800 Subject: [PATCH 1109/1121] ARM: dts: msm: Add ion secure carveout for atoll Describe the memory region reserved for the ion secure carveout allocator. Change-Id: Ic8cc69681b84f860dd64ba097c407f00cbef7482 Signed-off-by: Zhenhua Huang --- arch/arm64/boot/dts/qcom/atoll-ion.dtsi | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/atoll-ion.dtsi b/arch/arm64/boot/dts/qcom/atoll-ion.dtsi index fa7262d64552..326c882d9918 100644 --- a/arch/arm64/boot/dts/qcom/atoll-ion.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll-ion.dtsi @@ -37,5 +37,14 @@ memory-region = <&secure_display_memory>; qcom,ion-heap-type = "HYP_CMA"; }; + + qcom,ion-heap@14 { /* SECURE CARVEOUT HEAP */ + reg = <14>; + qcom,ion-heap-type = "SECURE_CARVEOUT"; + cdsp { + memory-region = <&cdsp_sec_mem>; + token = <0x20000000>; + }; + }; }; }; -- GitLab From 893fe7e36e9069fcd4948a6c6b30f87ed12a8425 Mon Sep 17 00:00:00 2001 From: Tao Jiang Date: Thu, 25 Jul 2019 10:29:49 +0800 Subject: [PATCH 1110/1121] ARM: dts: msm: add hostless QUIN TDM configuration Add hostless quinary TDM to sa8155-vm group TDM configuration with tdm-quin-tx-7 and tdm-quin-rx-7. Change-Id: I978378a87436157783b402a35a6a1a336c2b5779 Signed-off-by: Han Lu --- arch/arm64/boot/dts/qcom/sa8155-vm-audio.dtsi | 36 +++++++++++++------ 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sa8155-vm-audio.dtsi b/arch/arm64/boot/dts/qcom/sa8155-vm-audio.dtsi index e101ced50d9d..a9480a4a430f 100644 --- a/arch/arm64/boot/dts/qcom/sa8155-vm-audio.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8155-vm-audio.dtsi @@ -351,8 +351,9 @@ qcom,msm-dai-tdm-quin-rx { compatible = "qcom,msm-dai-tdm"; qcom,msm-cpudai-tdm-group-id = <37184>; - qcom,msm-cpudai-tdm-group-num-ports = <4>; - qcom,msm-cpudai-tdm-group-port-id = <36928 36930 36932 36934>; + qcom,msm-cpudai-tdm-group-num-ports = <5>; + qcom,msm-cpudai-tdm-group-port-id = <36928 36930 36932 + 36934 36942>; qcom,msm-cpudai-tdm-clk-rate = <24576000>; qcom,msm-cpudai-tdm-clk-internal = <1>; qcom,msm-cpudai-tdm-sync-mode = <1>; @@ -383,13 +384,20 @@ qcom,msm-cpudai-tdm-dev-id = <36934>; qcom,msm-cpudai-tdm-data-align = <0>; }; + + dai_quin_tdm_rx_7: qcom,msm-dai-q6-tdm-quin-rx-7 { + compatible = "qcom,msm-dai-q6-tdm"; + qcom,msm-cpudai-tdm-dev-id = <36942>; + qcom,msm-cpudai-tdm-data-align = <0>; + }; }; qcom,msm-dai-tdm-quin-tx { compatible = "qcom,msm-dai-tdm"; qcom,msm-cpudai-tdm-group-id = <37185>; - qcom,msm-cpudai-tdm-group-num-ports = <4>; - qcom,msm-cpudai-tdm-group-port-id = <36929 36931 36933 36935>; + qcom,msm-cpudai-tdm-group-num-ports = <5>; + qcom,msm-cpudai-tdm-group-port-id = <36929 36931 36933 + 36935 36943>; qcom,msm-cpudai-tdm-clk-rate = <24576000>; qcom,msm-cpudai-tdm-clk-internal = <1>; qcom,msm-cpudai-tdm-sync-mode = <1>; @@ -420,6 +428,12 @@ qcom,msm-cpudai-tdm-dev-id = <36935>; qcom,msm-cpudai-tdm-data-align = <0>; }; + + dai_quin_tdm_tx_7: qcom,msm-dai-q6-tdm-quin-tx-7 { + compatible = "qcom,msm-dai-q6-tdm"; + qcom,msm-cpudai-tdm-dev-id = <36943>; + qcom,msm-cpudai-tdm-data-align = <0>; + }; }; qcom,avtimer@170f7000 { @@ -489,9 +503,10 @@ <&dai_quat_tdm_tx_2>, <&dai_quat_tdm_tx_3>, <&dai_quat_tdm_tx_7>, <&dai_quin_tdm_rx_0>, <&dai_quin_tdm_rx_1>, <&dai_quin_tdm_rx_2>, - <&dai_quin_tdm_rx_3>, <&dai_quin_tdm_tx_0>, - <&dai_quin_tdm_tx_1>, <&dai_quin_tdm_tx_2>, - <&dai_quin_tdm_tx_3>; + <&dai_quin_tdm_rx_3>, <&dai_quin_tdm_rx_7>, + <&dai_quin_tdm_tx_0>, <&dai_quin_tdm_tx_1>, + <&dai_quin_tdm_tx_2>, <&dai_quin_tdm_tx_3>, + <&dai_quin_tdm_tx_7>; asoc-cpu-names = "msm-dai-q6-hdmi.8", "msm-dai-q6-dp.24608", "msm-dai-q6-mi2s.0", "msm-dai-q6-mi2s.1", "msm-dai-q6-mi2s.2", "msm-dai-q6-mi2s.3", @@ -523,9 +538,10 @@ "msm-dai-q6-tdm.36917", "msm-dai-q6-tdm.36919", "msm-dai-q6-tdm.36927", "msm-dai-q6-tdm.36928", "msm-dai-q6-tdm.36930", "msm-dai-q6-tdm.36932", - "msm-dai-q6-tdm.36934", "msm-dai-q6-tdm.36929", - "msm-dai-q6-tdm.36931", "msm-dai-q6-tdm.36933", - "msm-dai-q6-tdm.36935"; + "msm-dai-q6-tdm.36934", "msm-dai-q6-tdm.36942", + "msm-dai-q6-tdm.36929", "msm-dai-q6-tdm.36931", + "msm-dai-q6-tdm.36933", "msm-dai-q6-tdm.36935", + "msm-dai-q6-tdm.36943"; asoc-codec = <&stub_codec>; asoc-codec-names = "msm-stub-codec.1"; qcom,msm_audio_ssr_devs = <&audio_apr>, <&q6core>; -- GitLab From 8bb6cf9cd7d76de1a3c3a9e3ac298ef64c95be11 Mon Sep 17 00:00:00 2001 From: Gustavo Solaira Date: Thu, 1 Aug 2019 14:50:46 -0700 Subject: [PATCH 1111/1121] defconfig: msm: Enable QRTR_MHI_DEV for SA515M Enable QRTR over MHI_DEV PCIe transport for SA515M devices. Change-Id: I7204c7adbe80cd0e3881c6605bf96b14753ece30 Signed-off-by: Gustavo Solaira --- arch/arm/configs/vendor/sa515m-perf_defconfig | 2 ++ arch/arm/configs/vendor/sa515m_defconfig | 2 ++ 2 files changed, 4 insertions(+) diff --git a/arch/arm/configs/vendor/sa515m-perf_defconfig b/arch/arm/configs/vendor/sa515m-perf_defconfig index d6bd6d572c45..c726917d76cb 100644 --- a/arch/arm/configs/vendor/sa515m-perf_defconfig +++ b/arch/arm/configs/vendor/sa515m-perf_defconfig @@ -156,8 +156,10 @@ CONFIG_VLAN_8021Q=y CONFIG_NET_SCHED=y CONFIG_NET_SCH_PRIO=y CONFIG_QRTR=y +CONFIG_QRTR_NODE_ID=2 CONFIG_QRTR_SMD=y CONFIG_QRTR_MHI=y +CONFIG_QRTR_MHI_DEV=y CONFIG_CAN=y CONFIG_QTI_CAN=y CONFIG_BT=y diff --git a/arch/arm/configs/vendor/sa515m_defconfig b/arch/arm/configs/vendor/sa515m_defconfig index 614cc62dec95..5041ddd15f9f 100644 --- a/arch/arm/configs/vendor/sa515m_defconfig +++ b/arch/arm/configs/vendor/sa515m_defconfig @@ -156,8 +156,10 @@ CONFIG_VLAN_8021Q=y CONFIG_NET_SCHED=y CONFIG_NET_SCH_PRIO=y CONFIG_QRTR=y +CONFIG_QRTR_NODE_ID=2 CONFIG_QRTR_SMD=y CONFIG_QRTR_MHI=y +CONFIG_QRTR_MHI_DEV=y CONFIG_CAN=y CONFIG_QTI_CAN=y CONFIG_BT=y -- GitLab From 74319062a32fd9cb927eb808f1de0993b02b14d1 Mon Sep 17 00:00:00 2001 From: Rama Krishna Phani A Date: Thu, 20 Jun 2019 21:11:50 +0530 Subject: [PATCH 1112/1121] msm: mhi_dev: add random mac generation and ethernet parse support Host can generate Ethernet packets over the network stack. Add support to assign proper protocol for ethernet packets. Also, add support for mhi net device for random mac address generation. Change-Id: Icd29e7df9aff0529ebaf4897560d9a9acec76fd7 Signed-off-by: Rama Krishna Phani A --- .../devicetree/bindings/mhi/msm_mhi_dev.txt | 17 ++++ drivers/platform/msm/mhi_dev/mhi_dev_net.c | 88 +++++++++++++++++-- 2 files changed, 100 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/mhi/msm_mhi_dev.txt b/Documentation/devicetree/bindings/mhi/msm_mhi_dev.txt index 30174680a91d..ece30e43d308 100644 --- a/Documentation/devicetree/bindings/mhi/msm_mhi_dev.txt +++ b/Documentation/devicetree/bindings/mhi/msm_mhi_dev.txt @@ -31,6 +31,18 @@ Optional property: MHI driver on the host. This property is required if iatu property qcom,mhi-config-iatu is present. +MSM MHI DEV NET + +MSM MHI DEV enables communication with the host over a PCIe link using the +Network Interface. + +Required properties: + - compatible: should be "qcom,msm-mhi-dev-net" for MHI net device driver. + +Optional property: + - qcom,mhi-ethernet-interface;: If property is present use ethernet packet + parsing support. + Example: mhi: qcom,msm-mhi-dev { @@ -44,3 +56,8 @@ Example: qcom,mhi-ep-msi = <1>; qcom,mhi-version = <0x1000000>; }; + + qcom,mhi_net_dev { + compatible = "qcom,msm-mhi-dev-net"; + qcom,mhi-ethernet-interface; + }; diff --git a/drivers/platform/msm/mhi_dev/mhi_dev_net.c b/drivers/platform/msm/mhi_dev/mhi_dev_net.c index d76c65aba883..ec1b67976b3d 100644 --- a/drivers/platform/msm/mhi_dev/mhi_dev_net.c +++ b/drivers/platform/msm/mhi_dev/mhi_dev_net.c @@ -27,11 +27,14 @@ #include #include #include +#include +#include +#include #include "mhi.h" #define MHI_NET_DRIVER_NAME "mhi_dev_net_drv" -#define MHI_NET_DEV_NAME "mhi_dev_net%d" +#define MHI_NET_DEV_NAME "mhi_swip%d" #define MHI_NET_DEFAULT_MTU 8192 #define MHI_NET_IPC_PAGES (100) #define MHI_MAX_RX_REQ (128) @@ -90,6 +93,7 @@ struct mhi_dev_net_client { u32 out_chan; /* read channel - always odd */ u32 in_chan; + bool eth_iface; struct mhi_dev_client *out_handle; struct mhi_dev_client *in_handle; /*process pendig packets */ @@ -113,6 +117,7 @@ struct mhi_dev_net_client { struct mhi_dev_net_ctxt { struct mhi_dev_net_chan_attr chan_attr[MHI_MAX_SOFTWARE_CHANNELS]; struct mhi_dev_net_client *client_handle; + struct platform_device *pdev; void (*net_event_notifier)(struct mhi_dev_client_cb_reason *cb); }; @@ -247,8 +252,12 @@ static void mhi_dev_net_read_completion_cb(void *req) unsigned long flags; skb->len = mreq->transfer_len; - skb->protocol = - mhi_dev_net_eth_type_trans(skb); + + if (net_handle->eth_iface) + skb->protocol = eth_type_trans(skb, net_handle->dev); + else + skb->protocol = mhi_dev_net_eth_type_trans(skb); + skb_put(skb, mreq->transfer_len); net_handle->dev->stats.rx_packets++; skb->dev = net_handle->dev; @@ -433,12 +442,15 @@ static const struct net_device_ops mhi_dev_net_ops_ip = { .ndo_change_mtu = mhi_dev_net_change_mtu, }; -static void mhi_dev_net_setup(struct net_device *dev) +static void mhi_dev_net_rawip_setup(struct net_device *dev) { dev->netdev_ops = &mhi_dev_net_ops_ip; ether_setup(dev); + mhi_dev_net_log(MHI_INFO, + "mhi_dev_net Raw IP setup\n"); /* set this after calling ether_setup */ + dev->header_ops = NULL; dev->type = ARPHRD_RAWIP; dev->hard_header_len = 0; dev->mtu = MHI_NET_DEFAULT_MTU; @@ -446,6 +458,14 @@ static void mhi_dev_net_setup(struct net_device *dev) dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST); } +static void mhi_dev_net_ether_setup(struct net_device *dev) +{ + dev->netdev_ops = &mhi_dev_net_ops_ip; + ether_setup(dev); + mhi_dev_net_log(MHI_INFO, + "mhi_dev_net Ethernet setup\n"); +} + static int mhi_dev_net_enable_iface(struct mhi_dev_net_client *mhi_dev_net_ptr) { int ret = 0; @@ -462,12 +482,20 @@ static int mhi_dev_net_enable_iface(struct mhi_dev_net_client *mhi_dev_net_ptr) "mhi_dev_net interface registration\n"); netdev = alloc_netdev(sizeof(struct mhi_dev_net_client), MHI_NET_DEV_NAME, NET_NAME_PREDICTABLE, - mhi_dev_net_setup); + mhi_net_ctxt.client_handle->eth_iface ? + mhi_dev_net_ether_setup : + mhi_dev_net_rawip_setup); if (!netdev) { pr_err("Failed to allocate netdev for mhi_dev_net\n"); goto net_dev_alloc_fail; } + if (mhi_net_ctxt.client_handle->eth_iface) { + eth_random_addr(netdev->dev_addr); + if (!is_valid_ether_addr(netdev->dev_addr)) + return -EADDRNOTAVAIL; + } + mhi_dev_net_ctxt = netdev_priv(netdev); mhi_dev_net_ptr->dev = netdev; *mhi_dev_net_ctxt = mhi_dev_net_ptr; @@ -621,6 +649,12 @@ int mhi_dev_net_interface_init(void) "Failed to create IPC logging for mhi_dev_net\n"); mhi_net_ctxt.client_handle = mhi_net_client; + if (mhi_net_ctxt.pdev) + mhi_net_ctxt.client_handle->eth_iface = + of_property_read_bool + ((&mhi_net_ctxt.pdev->dev)->of_node, + "qcom,mhi-ethernet-interface"); + /*Process pending packet work queue*/ mhi_net_client->pending_pckt_wq = create_singlethread_workqueue("pending_xmit_pckt_wq"); @@ -665,3 +699,47 @@ void __exit mhi_dev_net_exit(void) mhi_dev_net_close(); } EXPORT_SYMBOL(mhi_dev_net_exit); + +static int mhi_dev_net_probe(struct platform_device *pdev) +{ + if (pdev->dev.of_node) { + mhi_net_ctxt.pdev = pdev; + mhi_dev_net_log(MHI_INFO, + "MHI Network probe success"); + } + + return 0; +} + +static int mhi_dev_net_remove(struct platform_device *pdev) +{ + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static const struct of_device_id mhi_dev_net_match_table[] = { + { .compatible = "qcom,msm-mhi-dev-net" }, + {} +}; + +static struct platform_driver mhi_dev_net_driver = { + .driver = { + .name = "qcom,msm-mhi-dev-net", + .of_match_table = mhi_dev_net_match_table, + }, + .probe = mhi_dev_net_probe, + .remove = mhi_dev_net_remove, +}; + +static int __init mhi_dev_net_init(void) +{ + return platform_driver_register(&mhi_dev_net_driver); +} +subsys_initcall(mhi_dev_net_init); + +static void __exit mhi_dev_exit(void) +{ + platform_driver_unregister(&mhi_dev_net_driver); +} +module_exit(mhi_dev_net_exit); -- GitLab From 09dabd87c15ce6456cdcd2a6b6a8fd20bd84cf96 Mon Sep 17 00:00:00 2001 From: Gustavo Solaira Date: Thu, 1 Aug 2019 14:59:12 -0700 Subject: [PATCH 1113/1121] ARM: dts: msm: add MHI NET devicetree node for sdxprairie Add initial devicetree node to support MHI NET based devices over PCIe on sdxprairie. Change-Id: Iec2fdb20b0d18c7ca709a97cf99517a287459c12 Signed-off-by: Gustavo Solaira --- arch/arm64/boot/dts/qcom/sa515m-ccard-pcie-ep.dts | 4 ++++ arch/arm64/boot/dts/qcom/sdxprairie-pcie-ep-mtp.dtsi | 4 ++++ arch/arm64/boot/dts/qcom/sdxprairie.dtsi | 6 ++++++ 3 files changed, 14 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sa515m-ccard-pcie-ep.dts b/arch/arm64/boot/dts/qcom/sa515m-ccard-pcie-ep.dts index 7bd092eebb5c..0d95e1540cf4 100644 --- a/arch/arm64/boot/dts/qcom/sa515m-ccard-pcie-ep.dts +++ b/arch/arm64/boot/dts/qcom/sa515m-ccard-pcie-ep.dts @@ -44,3 +44,7 @@ &mhi_device { status = "ok"; }; + +&mhi_net_device { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/qcom/sdxprairie-pcie-ep-mtp.dtsi b/arch/arm64/boot/dts/qcom/sdxprairie-pcie-ep-mtp.dtsi index f0dfb1eb9a01..8fbf342620c1 100644 --- a/arch/arm64/boot/dts/qcom/sdxprairie-pcie-ep-mtp.dtsi +++ b/arch/arm64/boot/dts/qcom/sdxprairie-pcie-ep-mtp.dtsi @@ -40,3 +40,7 @@ &mhi_device { status = "ok"; }; + +&mhi_net_device { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/qcom/sdxprairie.dtsi b/arch/arm64/boot/dts/qcom/sdxprairie.dtsi index 548ca524bb4f..fdb7bca4eee6 100644 --- a/arch/arm64/boot/dts/qcom/sdxprairie.dtsi +++ b/arch/arm64/boot/dts/qcom/sdxprairie.dtsi @@ -1361,6 +1361,12 @@ status = "disabled"; }; + mhi_net_device: qcom,mhi_net_dev { + compatible = "qcom,msm-mhi-dev-net"; + qcom,mhi-ethernet-interface; + status = "disabled"; + }; + sdhc_1: sdhci@8804000 { compatible = "qcom,sdhci-msm-v5"; reg = <0x8804000 0x1000>; -- GitLab From 56fa0caa8bd40d65fd5075bb77b49d6a901634f9 Mon Sep 17 00:00:00 2001 From: Praveen Kurapati Date: Fri, 2 Aug 2019 07:46:30 +0530 Subject: [PATCH 1114/1121] ARM: dts: msm: Enable IPA SMMU S1 stage for atoll Enable IPA SMMU stage 1 translations for atoll target. Change-Id: Iebb86222b37c303a293b3d43c68114ede410e281 Signed-off-by: Praveen Kurapati --- arch/arm64/boot/dts/qcom/atoll.dtsi | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index bf9082faf01a..6a7fcbdbc380 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -2066,7 +2066,6 @@ ipa_smmu_ap: ipa_smmu_ap { compatible = "qcom,ipa-smmu-ap-cb"; - qcom,smmu-s1-bypass; iommus = <&apps_smmu 0x0440 0x0>; qcom,iova-mapping = <0x20000000 0x40000000>; /* modem tables in IMEM */ @@ -2075,7 +2074,6 @@ ipa_smmu_wlan: ipa_smmu_wlan { compatible = "qcom,ipa-smmu-wlan-cb"; - qcom,smmu-s1-bypass; iommus = <&apps_smmu 0x0441 0x0>; /* ipa-uc ram */ qcom,additional-mapping = <0x1e60000 0x1e60000 0x80000>; @@ -2083,7 +2081,6 @@ ipa_smmu_uc: ipa_smmu_uc { compatible = "qcom,ipa-smmu-uc-cb"; - qcom,smmu-s1-bypass; iommus = <&apps_smmu 0x0442 0x0>; qcom,iova-mapping = <0x40400000 0x1fc00000>; }; -- GitLab From 35d9f1a804b0fa5cd884289210152d984702197b Mon Sep 17 00:00:00 2001 From: Sumeet Sahu Date: Fri, 2 Aug 2019 11:22:34 +0530 Subject: [PATCH 1115/1121] defconfig: Enable lightnvm driver Enable lightnvm for NVMe performance improvement Change-Id: I5d3df72b1216ed5bc945a93b6d9f893df602765b Signed-off-by: Sumeet Sahu --- arch/arm64/configs/vendor/sa8155-perf_defconfig | 3 +++ arch/arm64/configs/vendor/sa8155_defconfig | 3 +++ 2 files changed, 6 insertions(+) diff --git a/arch/arm64/configs/vendor/sa8155-perf_defconfig b/arch/arm64/configs/vendor/sa8155-perf_defconfig index dde0c1b81692..ca9ff962ff29 100644 --- a/arch/arm64/configs/vendor/sa8155-perf_defconfig +++ b/arch/arm64/configs/vendor/sa8155-perf_defconfig @@ -309,6 +309,9 @@ CONFIG_CNSS2_DEBUG=y CONFIG_CNSS2_QMI=y CONFIG_CNSS_ASYNC=y CONFIG_CNSS_GENL=y +CONFIG_NVM=y +CONFIG_NVM_RRPC=y +CONFIG_NVM_PBLK=y CONFIG_INPUT_EVDEV=y CONFIG_KEYBOARD_GPIO=y # CONFIG_INPUT_MOUSE is not set diff --git a/arch/arm64/configs/vendor/sa8155_defconfig b/arch/arm64/configs/vendor/sa8155_defconfig index 98af752b29b7..940dbf4ca592 100644 --- a/arch/arm64/configs/vendor/sa8155_defconfig +++ b/arch/arm64/configs/vendor/sa8155_defconfig @@ -322,6 +322,9 @@ CONFIG_CNSS2_DEBUG=y CONFIG_CNSS2_QMI=y CONFIG_CNSS_ASYNC=y CONFIG_CNSS_GENL=y +CONFIG_NVM=y +CONFIG_NVM_RRPC=y +CONFIG_NVM_PBLK=y CONFIG_INPUT_EVDEV=y CONFIG_KEYBOARD_GPIO=y # CONFIG_INPUT_MOUSE is not set -- GitLab From ee0d82e6d278a499f101e9907315349a383d24ad Mon Sep 17 00:00:00 2001 From: Tengfei Fan Date: Wed, 17 Jul 2019 09:17:53 +0800 Subject: [PATCH 1116/1121] AndroidKernel: add TARGET_PREBUILT_INT_KERNEL_IMAGE Add TARGET_PREBUILT_INT_KERNEL_IMAGE to support compile modules to dependence on Image. Change-Id: If8f5825c3028fc8cd304cf745bcf68a6b2d28ec4 Signed-off-by: Tengfei Fan --- AndroidKernel.mk | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/AndroidKernel.mk b/AndroidKernel.mk index e19c5eb406a5..270dc28d357a 100644 --- a/AndroidKernel.mk +++ b/AndroidKernel.mk @@ -165,14 +165,31 @@ $(KERNEL_CONFIG): $(KERNEL_OUT) echo $(KERNEL_CONFIG_OVERRIDE) >> $(KERNEL_OUT)/.config; \ $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) oldconfig; fi -$(TARGET_PREBUILT_INT_KERNEL): $(KERNEL_OUT) $(KERNEL_HEADERS_INSTALL) +ifeq ($(TARGET_KERNEL_APPEND_DTB), true) +TARGET_PREBUILT_INT_KERNEL_IMAGE := $(KERNEL_OUT)/arch/$(KERNEL_ARCH)/boot/Image +$(TARGET_PREBUILT_INT_KERNEL_IMAGE): $(KERNEL_USR) +$(TARGET_PREBUILT_INT_KERNEL_IMAGE): $(KERNEL_OUT) $(KERNEL_HEADERS_INSTALL) + $(hide) echo "Building kernel modules..." + $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) $(KERNEL_CFLAGS) Image + $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) $(KERNEL_CFLAGS) modules + $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) INSTALL_MOD_PATH=$(BUILD_ROOT_LOC)../$(KERNEL_MODULES_INSTALL) INSTALL_MOD_STRIP=1 $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) modules_install + $(mv-modules) + $(clean-module-folder) + +$(TARGET_PREBUILT_INT_KERNEL): $(TARGET_PREBUILT_INT_KERNEL_IMAGE) $(hide) echo "Building kernel..." $(hide) rm -rf $(KERNEL_OUT)/arch/$(KERNEL_ARCH)/boot/dts $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) $(KERNEL_CFLAGS) +else +TARGET_PREBUILT_INT_KERNEL_IMAGE := $(TARGET_PREBUILT_INT_KERNEL) +$(TARGET_PREBUILT_INT_KERNEL): $(KERNEL_OUT) $(KERNEL_HEADERS_INSTALL) + $(hide) echo "Building kernel..." + $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) $(KERNEL_CFLAGS) $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) $(KERNEL_CFLAGS) modules $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) INSTALL_MOD_PATH=$(BUILD_ROOT_LOC)../$(KERNEL_MODULES_INSTALL) INSTALL_MOD_STRIP=1 $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) modules_install $(mv-modules) $(clean-module-folder) +endif $(KERNEL_HEADERS_INSTALL): $(KERNEL_OUT) $(hide) if [ ! -z "$(KERNEL_HEADER_DEFCONFIG)" ]; then \ -- GitLab From 88f7de35444c8699bfa4913c8acd8b112bc0e94b Mon Sep 17 00:00:00 2001 From: Manaf Meethalavalappu Pallikunhi Date: Fri, 19 Jul 2019 12:28:02 +0530 Subject: [PATCH 1117/1121] ARM: dts: msm: Add LMH-DCVSh configuration for ATOLL Add LMH-DCVSh hardware configuration like debug interrupt and cluster affinity value for SDMMAGPIE. It enables CPU cooling devices for this target. Add the CPU to LMH-DCVSh hardware mapping. Change-Id: I4c14c995345bb1315594a7a919cb90febb1a131e Signed-off-by: Manaf Meethalavalappu Pallikunhi --- arch/arm64/boot/dts/qcom/atoll-thermal.dtsi | 22 +++++++++++++++++++++ arch/arm64/boot/dts/qcom/atoll.dtsi | 8 ++++++++ 2 files changed, 30 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/atoll-thermal.dtsi b/arch/arm64/boot/dts/qcom/atoll-thermal.dtsi index 12a619563603..a6110a349889 100644 --- a/arch/arm64/boot/dts/qcom/atoll-thermal.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll-thermal.dtsi @@ -13,6 +13,28 @@ #include +&clock_cpucc { + #address-cells = <1>; + #size-cells = <1>; + lmh_dcvs0: qcom,limits-dcvs@18358800 { + compatible = "qcom,msm-hw-limits"; + interrupts = ; + qcom,affinity = <0>; + reg = <0x18358800 0x1000>, + <0x18323000 0x1000>; + #thermal-sensor-cells = <0>; + }; + + lmh_dcvs1: qcom,limits-dcvs@18350800 { + compatible = "qcom,msm-hw-limits"; + interrupts = ; + qcom,affinity = <1>; + reg = <0x18350800 0x1000>, + <0x18325800 0x1000>; + #thermal-sensor-cells = <0>; + }; +}; + &soc { qmi-tmd-devices { compatible = "qcom,qmi-cooling-devices"; diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index e3fd7db33baf..ddfd1cfd1778 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -52,6 +52,7 @@ d-cache-size = <0x8000>; i-cache-size = <0x8000>; next-level-cache = <&L2_0>; + qcom,lmh-dcvs = <&lmh_dcvs0>; L2_0: l2-cache { compatible = "arm,arch-cache"; cache-size = <0x10000>; @@ -90,6 +91,7 @@ d-cache-size = <0x8000>; i-cache-size = <0x8000>; next-level-cache = <&L2_100>; + qcom,lmh-dcvs = <&lmh_dcvs0>; L2_100: l2-cache { compatible = "arm,arch-cache"; cache-size = <0x10000>; @@ -123,6 +125,7 @@ d-cache-size = <0x8000>; i-cache-size = <0x8000>; next-level-cache = <&L2_200>; + qcom,lmh-dcvs = <&lmh_dcvs0>; L2_200: l2-cache { compatible = "arm,arch-cache"; cache-size = <0x10000>; @@ -155,6 +158,7 @@ d-cache-size = <0x8000>; i-cache-size = <0x8000>; next-level-cache = <&L2_300>; + qcom,lmh-dcvs = <&lmh_dcvs0>; L2_300: l2-cache { compatible = "arm,arch-cache"; cache-size = <0x10000>; @@ -187,6 +191,7 @@ d-cache-size = <0x8000>; i-cache-size = <0x8000>; next-level-cache = <&L2_400>; + qcom,lmh-dcvs = <&lmh_dcvs0>; L2_400: l2-cache { compatible = "arm,arch-cache"; cache-size = <0x10000>; @@ -219,6 +224,7 @@ d-cache-size = <0x8000>; i-cache-size = <0x8000>; next-level-cache = <&L2_500>; + qcom,lmh-dcvs = <&lmh_dcvs0>; L2_500: l2-cache { compatible = "arm,arch-cache"; cache-size = <0x10000>; @@ -251,6 +257,7 @@ d-cache-size = <0x10000>; i-cache-size = <0x10000>; next-level-cache = <&L2_600>; + qcom,lmh-dcvs = <&lmh_dcvs1>; L2_600: l2-cache { compatible = "arm,arch-cache"; cache-size = <0x40000>; @@ -292,6 +299,7 @@ d-cache-size = <0x10000>; i-cache-size = <0x10000>; next-level-cache = <&L2_700>; + qcom,lmh-dcvs = <&lmh_dcvs1>; L2_700: l2-cache { compatible = "arm,arch-cache"; cache-size = <0x40000>; -- GitLab From a80d7828b84d47979993c63de6ff5071205a2c69 Mon Sep 17 00:00:00 2001 From: Manaf Meethalavalappu Pallikunhi Date: Fri, 19 Jul 2019 12:14:11 +0530 Subject: [PATCH 1118/1121] ARM: dts: msm: Add regulator cooling device for ATOLL Add regulator cooling device for ATOLL. These cooling devices will be used to place minimum voltage restriction at low temperature for CX and MX rails. Change-Id: I4438fb7bf56569364abc383a52bf3081e3cdb36c Signed-off-by: Manaf Meethalavalappu Pallikunhi --- arch/arm64/boot/dts/qcom/atoll-regulator.dtsi | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/atoll-regulator.dtsi b/arch/arm64/boot/dts/qcom/atoll-regulator.dtsi index 133af309bfcf..3106ced89fc1 100644 --- a/arch/arm64/boot/dts/qcom/atoll-regulator.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll-regulator.dtsi @@ -47,6 +47,13 @@ ; qcom,min-dropout-voltage-level = <(-1)>; }; + + cx_cdev: regulator-cdev { + compatible = "qcom,rpmh-reg-cdev"; + mboxes = <&qmp_aop 0>; + qcom,reg-resource-name = "cx"; + #cooling-cells = <2>; + }; }; rpmh-regulator-gfxlvl { @@ -96,6 +103,14 @@ qcom,init-voltage-level = ; }; + + mx_cdev: mx-cdev-lvl { + compatible = "qcom,regulator-cooling-device"; + regulator-cdev-supply = <&VDD_MX_LEVEL>; + regulator-levels = ; + #cooling-cells = <2>; + }; }; rpmh-regulator-smpa1 { -- GitLab From c8b2c22f327b9e2875e65336d42f3695ba16d274 Mon Sep 17 00:00:00 2001 From: Manaf Meethalavalappu Pallikunhi Date: Fri, 19 Jul 2019 12:36:56 +0530 Subject: [PATCH 1119/1121] ARM: dts: msm: Add thermal zone definition for ATOLL Add thermal zone configuration for GPU, CPU virtual sensor, CPU emergency mitigation and low temperature voltage restriction for ATOLL. Change-Id: I2a0c302eb717f18534378a58bf40d57cd0213e6d Signed-off-by: Manaf Meethalavalappu Pallikunhi --- arch/arm64/boot/dts/qcom/atoll-rumi.dtsi | 4 + arch/arm64/boot/dts/qcom/atoll-thermal.dtsi | 331 ++++++++++++++++++++ arch/arm64/boot/dts/qcom/atoll.dtsi | 8 + 3 files changed, 343 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/atoll-rumi.dtsi b/arch/arm64/boot/dts/qcom/atoll-rumi.dtsi index bd99744a8040..f7a4f391b4a6 100644 --- a/arch/arm64/boot/dts/qcom/atoll-rumi.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll-rumi.dtsi @@ -134,6 +134,10 @@ status = "ok"; }; +&thermal_zones { + /delete-node/ aoss-0-lowf; +}; + &usb0 { dwc3@a600000 { usb-phy = <&usb_emu_phy>, <&usb_nop_phy>; diff --git a/arch/arm64/boot/dts/qcom/atoll-thermal.dtsi b/arch/arm64/boot/dts/qcom/atoll-thermal.dtsi index a6110a349889..fdd8d09839fb 100644 --- a/arch/arm64/boot/dts/qcom/atoll-thermal.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll-thermal.dtsi @@ -693,4 +693,335 @@ }; }; }; + + gpuss-max-step { + polling-delay-passive = <10>; + polling-delay = <100>; + thermal-governor = "step_wise"; + wake-capable-sensor; + trips { + gpu_trip: gpu-trip { + temperature = <95000>; + hysteresis = <0>; + type = "passive"; + }; + }; + + cooling-maps { + gpu_cdev { + trip = <&gpu_trip>; + cooling-device = <&msm_gpu THERMAL_NO_LIMIT + THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu-0-max-step { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "step_wise"; + wake-capable-sensor; + trips { + silver-trip { + temperature = <120000>; + hysteresis = <0>; + type = "passive"; + }; + }; + }; + + cpu-1-max-step { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "step_wise"; + wake-capable-sensor; + trips { + gold-trip { + temperature = <120000>; + hysteresis = <0>; + type = "passive"; + }; + }; + }; + + cpu-0-0-step { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "step_wise"; + thermal-sensors = <&tsens0 1>; + wake-capable-sensor; + trips { + cpu0_config: cpu0-config { + temperature = <110000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + cooling-maps { + cpu0_cdev { + trip = <&cpu0_config>; + cooling-device = + <&CPU0 THERMAL_MAX_LIMIT + THERMAL_MAX_LIMIT>; + }; + }; + }; + + cpu-0-1-step { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "step_wise"; + thermal-sensors = <&tsens0 2>; + wake-capable-sensor; + trips { + cpu1_config: cpu1-config { + temperature = <110000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + cooling-maps { + cpu1_cdev { + trip = <&cpu1_config>; + cooling-device = + <&CPU1 THERMAL_MAX_LIMIT + THERMAL_MAX_LIMIT>; + }; + }; + }; + + cpu-0-2-step { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "step_wise"; + thermal-sensors = <&tsens0 3>; + wake-capable-sensor; + trips { + cpu2_config: cpu2-config { + temperature = <110000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + cooling-maps { + cpu2_cdev { + trip = <&cpu2_config>; + cooling-device = + <&CPU2 THERMAL_MAX_LIMIT + THERMAL_MAX_LIMIT>; + }; + }; + }; + + cpu-0-3-step { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "step_wise"; + thermal-sensors = <&tsens0 4>; + wake-capable-sensor; + trips { + cpu3_config: cpu3-config { + temperature = <110000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + cooling-maps { + cpu3_cdev { + trip = <&cpu3_config>; + cooling-device = + <&CPU3 THERMAL_MAX_LIMIT + THERMAL_MAX_LIMIT>; + }; + }; + }; + + cpu-0-4-step { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "step_wise"; + thermal-sensors = <&tsens0 5>; + wake-capable-sensor; + trips { + cpu4_config: cpu4-config { + temperature = <110000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + cooling-maps { + cpu4_cdev { + trip = <&cpu4_config>; + cooling-device = + <&CPU4 THERMAL_MAX_LIMIT + THERMAL_MAX_LIMIT>; + }; + }; + }; + + cpu-0-5-step { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "step_wise"; + thermal-sensors = <&tsens0 6>; + wake-capable-sensor; + trips { + cpu5_config: cpu5-config { + temperature = <110000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + cooling-maps { + cpu5_cdev { + trip = <&cpu5_config>; + cooling-device = + <&CPU5 THERMAL_MAX_LIMIT + THERMAL_MAX_LIMIT>; + }; + }; + }; + + cpu-1-0-step { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "step_wise"; + thermal-sensors = <&tsens0 9>; + wake-capable-sensor; + trips { + cpu6_0_config: cpu6-0-config { + temperature = <110000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + cooling-maps { + cpu6_cdev { + trip = <&cpu6_0_config>; + cooling-device = + <&CPU6 THERMAL_MAX_LIMIT + THERMAL_MAX_LIMIT>; + }; + }; + }; + + cpu-1-1-step { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "step_wise"; + thermal-sensors = <&tsens0 10>; + wake-capable-sensor; + trips { + cpu6_1_config: cpu6-1-config { + temperature = <110000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + cooling-maps { + cpu6_cdev { + trip = <&cpu6_1_config>; + cooling-device = + <&CPU6 THERMAL_MAX_LIMIT + THERMAL_MAX_LIMIT>; + }; + }; + }; + + cpu-1-2-step { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "step_wise"; + thermal-sensors = <&tsens0 11>; + wake-capable-sensor; + trips { + cpu7_0_config: cpu7-0-config { + temperature = <110000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + cooling-maps { + cpu7_cdev { + trip = <&cpu7_0_config>; + cooling-device = + <&CPU7 THERMAL_MAX_LIMIT + THERMAL_MAX_LIMIT>; + }; + }; + }; + + cpu-1-3-step { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "step_wise"; + thermal-sensors = <&tsens0 12>; + wake-capable-sensor; + trips { + cpu7_1_config: cpu7-1-config { + temperature = <110000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + cooling-maps { + cpu7_cdev { + trip = <&cpu7_1_config>; + cooling-device = + <&CPU7 THERMAL_MAX_LIMIT + THERMAL_MAX_LIMIT>; + }; + }; + }; + + aoss-0-lowf { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "low_limits_floor"; + thermal-sensors = <&tsens0 0>; + wake-capable-sensor; + tracks-low; + trips { + aoss0_trip: aoss0-trip { + temperature = <5000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + cooling-maps { + cpu0_cdev { + trip = <&aoss0_trip>; + cooling-device = <&CPU0 2 2>; + }; + cpu1_cdev { + trip = <&aoss0_trip>; + cooling-device = <&CPU6 4 4>; + }; + gpu_vdd_cdev { + trip = <&aoss0_trip>; + cooling-device = <&msm_gpu (THERMAL_MAX_LIMIT-3) + (THERMAL_MAX_LIMIT-3)>; + }; + cx_vdd_cdev { + trip = <&aoss0_trip>; + cooling-device = <&cx_cdev 0 0>; + }; + mx_vdd_cdev { + trip = <&aoss0_trip>; + cooling-device = <&mx_cdev 0 0>; + }; + modem_vdd_cdev { + trip = <&aoss0_trip>; + cooling-device = <&modem_vdd 0 0>; + }; + adsp_vdd_cdev { + trip = <&aoss0_trip>; + cooling-device = <&adsp_vdd 0 0>; + }; + cdsp_vdd_cdev { + trip = <&aoss0_trip>; + cooling-device = <&cdsp_vdd 0 0>; + }; + }; + }; }; diff --git a/arch/arm64/boot/dts/qcom/atoll.dtsi b/arch/arm64/boot/dts/qcom/atoll.dtsi index ddfd1cfd1778..8a2a117ab194 100644 --- a/arch/arm64/boot/dts/qcom/atoll.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll.dtsi @@ -53,6 +53,7 @@ i-cache-size = <0x8000>; next-level-cache = <&L2_0>; qcom,lmh-dcvs = <&lmh_dcvs0>; + #cooling-cells = <2>; L2_0: l2-cache { compatible = "arm,arch-cache"; cache-size = <0x10000>; @@ -92,6 +93,7 @@ i-cache-size = <0x8000>; next-level-cache = <&L2_100>; qcom,lmh-dcvs = <&lmh_dcvs0>; + #cooling-cells = <2>; L2_100: l2-cache { compatible = "arm,arch-cache"; cache-size = <0x10000>; @@ -126,6 +128,7 @@ i-cache-size = <0x8000>; next-level-cache = <&L2_200>; qcom,lmh-dcvs = <&lmh_dcvs0>; + #cooling-cells = <2>; L2_200: l2-cache { compatible = "arm,arch-cache"; cache-size = <0x10000>; @@ -159,6 +162,7 @@ i-cache-size = <0x8000>; next-level-cache = <&L2_300>; qcom,lmh-dcvs = <&lmh_dcvs0>; + #cooling-cells = <2>; L2_300: l2-cache { compatible = "arm,arch-cache"; cache-size = <0x10000>; @@ -192,6 +196,7 @@ i-cache-size = <0x8000>; next-level-cache = <&L2_400>; qcom,lmh-dcvs = <&lmh_dcvs0>; + #cooling-cells = <2>; L2_400: l2-cache { compatible = "arm,arch-cache"; cache-size = <0x10000>; @@ -225,6 +230,7 @@ i-cache-size = <0x8000>; next-level-cache = <&L2_500>; qcom,lmh-dcvs = <&lmh_dcvs0>; + #cooling-cells = <2>; L2_500: l2-cache { compatible = "arm,arch-cache"; cache-size = <0x10000>; @@ -258,6 +264,7 @@ i-cache-size = <0x10000>; next-level-cache = <&L2_600>; qcom,lmh-dcvs = <&lmh_dcvs1>; + #cooling-cells = <2>; L2_600: l2-cache { compatible = "arm,arch-cache"; cache-size = <0x40000>; @@ -300,6 +307,7 @@ i-cache-size = <0x10000>; next-level-cache = <&L2_700>; qcom,lmh-dcvs = <&lmh_dcvs1>; + #cooling-cells = <2>; L2_700: l2-cache { compatible = "arm,arch-cache"; cache-size = <0x40000>; -- GitLab From 889d85140e067b77c879eb67fe4bbcaaf1f4db26 Mon Sep 17 00:00:00 2001 From: Chandana Kishori Chiluveru Date: Fri, 2 Aug 2019 16:15:54 +0530 Subject: [PATCH 1120/1121] ARM: dts: msm: Disable io-coherency for GSI on atoll This change will disable io-coherency when allocating buffers for GSI in usb driver. Change-Id: Id413e6b625eac2dc71a55801160d943d63065cba Signed-off-by: Chandana Kishori Chiluveru --- arch/arm64/boot/dts/qcom/atoll-usb.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/qcom/atoll-usb.dtsi b/arch/arm64/boot/dts/qcom/atoll-usb.dtsi index 90b79a03bf55..83e4a9ea0512 100644 --- a/arch/arm64/boot/dts/qcom/atoll-usb.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll-usb.dtsi @@ -54,6 +54,7 @@ 0x130 /* GSI_RING_BASE_ADDR_L */ 0x144 /* GSI_RING_BASE_ADDR_H */ 0x1a4>; /* GSI_IF_STS */ + qcom,gsi-disable-io-coherency; qcom,dwc-usb3-msm-tx-fifo-size = <21288>; qcom,pm-qos-latency = <62>; -- GitLab From f66217b11603c2bf9a08246005d85b4343945341 Mon Sep 17 00:00:00 2001 From: Zhen Kong Date: Thu, 1 Aug 2019 16:10:20 -0700 Subject: [PATCH 1121/1121] qseecom: correct range check in __qseecom_update_cmd_buf_64 Make change to validate if there exists enough space to write a uint64 instead of a unit32 value, in __qseecom_update_cmd_buf_64. Change-Id: I861cbada8f472123b5058511764b487281ae1343 Signed-off-by: Zhen Kong --- drivers/misc/qseecom.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c index 02422cdbb5a8..48e9d4c25c2c 100644 --- a/drivers/misc/qseecom.c +++ b/drivers/misc/qseecom.c @@ -3579,6 +3579,33 @@ int __boundary_checks_offset(struct qseecom_send_modfd_cmd_req *req, return 0; } +static int __boundary_checks_offset_64(struct qseecom_send_modfd_cmd_req *req, + struct qseecom_send_modfd_listener_resp *lstnr_resp, + struct qseecom_dev_handle *data, int i) +{ + + if ((data->type != QSEECOM_LISTENER_SERVICE) && + (req->ifd_data[i].fd > 0)) { + if ((req->cmd_req_len < sizeof(uint64_t)) || + (req->ifd_data[i].cmd_buf_offset > + req->cmd_req_len - sizeof(uint64_t))) { + pr_err("Invalid offset (req len) 0x%x\n", + req->ifd_data[i].cmd_buf_offset); + return -EINVAL; + } + } else if ((data->type == QSEECOM_LISTENER_SERVICE) && + (lstnr_resp->ifd_data[i].fd > 0)) { + if ((lstnr_resp->resp_len < sizeof(uint64_t)) || + (lstnr_resp->ifd_data[i].cmd_buf_offset > + lstnr_resp->resp_len - sizeof(uint64_t))) { + pr_err("Invalid offset (lstnr resp len) 0x%x\n", + lstnr_resp->ifd_data[i].cmd_buf_offset); + return -EINVAL; + } + } + return 0; +} + static int __qseecom_update_cmd_buf(void *msg, bool cleanup, struct qseecom_dev_handle *data) { @@ -3922,7 +3949,8 @@ static int __qseecom_update_cmd_buf_64(void *msg, bool cleanup, if (sg_ptr->nents == 1) { uint64_t *update_64bit; - if (__boundary_checks_offset(req, lstnr_resp, data, i)) + if (__boundary_checks_offset_64(req, lstnr_resp, + data, i)) goto err; /* 64bit app uses 64bit address */ update_64bit = (uint64_t *) field; -- GitLab