Kernel 5.10 -> 5.15

This commit is contained in:
survolog (Andrey Grigorev) 2022-03-17 10:23:10 +03:00
parent ac08a6c618
commit 3136620039
46 changed files with 25030 additions and 12176 deletions

View file

@ -1,6 +1,6 @@
sources: sources:
linux-5.10.tar.xz: be0b909f1fbb760cc2d5cf146e1da3b2af0cf899 linux-5.15.tar.xz: ac61f2459040c09af1d5abd4ed100c3d316b443e
patch-5.10.105.xz: 417d3ebae4907d7308468e900430412c25a80aa6 patch-5.15.28.xz: 20337719e70d8bd465f2ffbccd84cd8c3b2b274b
public_key_GOST_1.pem: b4fb6bf1cf73824944931a8f0c2cb7bf427e0774 public_key_GOST_1.pem: b4fb6bf1cf73824944931a8f0c2cb7bf427e0774
public_key_GOST_2.pem: cba209bd331f29031c5d945949b230a8d7a4dc12 public_key_GOST_2.pem: cba209bd331f29031c5d945949b230a8d7a4dc12
public_key_GOST_3.pem: e5a223dd7c556d4d0cac326f5ed9fc12dd769afb public_key_GOST_3.pem: e5a223dd7c556d4d0cac326f5ed9fc12dd769afb

View file

@ -1,431 +0,0 @@
From e9343095462964e78faadde92bab44a6a13cd4da Mon Sep 17 00:00:00 2001
From: Kernel Bot <kernelbot@altlinux.org>
Date: Wed, 21 Aug 2019 16:11:26 +0300
Subject: [PATCH 1/2] AltHa LSM module
* ignore SUID on binaries (with exceptions possible);
* prevent running selected script interprers in interactive move;
* disable open file unlinking in selected dirs;
Changelog:
* ported to 5.2 as ordered LSM
* introduced OLock
* no more WxorX
* error handling, path_puts and locking added
* lists handling rewritten
* indentation fixed
Rediffed for vanilla kernel 5.10.1
Signed-off-by: Mikhail Novosyolov <m.novosyolov@rosalinux.ru>
---
security/Kconfig | 3 +-
security/Makefile | 2 +
security/altha/Kconfig | 11 ++
security/altha/Makefile | 3 +
security/altha/altha_lsm.c | 325 +++++++++++++++++++++++++++++++++++++
5 files changed, 343 insertions(+), 1 deletion(-)
create mode 100644 security/altha/Kconfig
create mode 100644 security/altha/Makefile
create mode 100644 security/altha/altha_lsm.c
diff --git a/security/Kconfig b/security/Kconfig
index 7561f6f99f1d..b7551d9001e6 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -238,6 +238,7 @@ source "security/loadpin/Kconfig"
source "security/yama/Kconfig"
source "security/safesetid/Kconfig"
source "security/lockdown/Kconfig"
+source "security/altha/Kconfig"
source "security/integrity/Kconfig"
@@ -281,7 +282,7 @@ config LSM
default "lockdown,yama,loadpin,safesetid,integrity,apparmor,selinux,smack,tomoyo,bpf" if DEFAULT_SECURITY_APPARMOR
default "lockdown,yama,loadpin,safesetid,integrity,tomoyo,bpf" if DEFAULT_SECURITY_TOMOYO
default "lockdown,yama,loadpin,safesetid,integrity,bpf" if DEFAULT_SECURITY_DAC
- default "lockdown,yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor,bpf"
+ default "lockdown,yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor,bpf,altha"
help
A comma-separated list of LSMs, in initialization order.
Any LSMs left off this list will be ignored. This can be
diff --git a/security/Makefile b/security/Makefile
index 3baf435de541..9cc6f5b1b099 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -13,6 +13,7 @@ subdir-$(CONFIG_SECURITY_LOADPIN) += loadpin
subdir-$(CONFIG_SECURITY_SAFESETID) += safesetid
subdir-$(CONFIG_SECURITY_LOCKDOWN_LSM) += lockdown
subdir-$(CONFIG_BPF_LSM) += bpf
+subdir-$(CONFIG_SECURITY_ALTHA) += altha
# always enable default capabilities
obj-y += commoncap.o
@@ -32,6 +33,7 @@ obj-$(CONFIG_SECURITY_SAFESETID) += safesetid/
obj-$(CONFIG_SECURITY_LOCKDOWN_LSM) += lockdown/
obj-$(CONFIG_CGROUPS) += device_cgroup.o
obj-$(CONFIG_BPF_LSM) += bpf/
+obj-$(CONFIG_SECURITY_ALTHA) += altha/
# Object integrity file lists
subdir-$(CONFIG_INTEGRITY) += integrity
diff --git a/security/altha/Kconfig b/security/altha/Kconfig
new file mode 100644
index 000000000000..4bafdef4e58e
--- /dev/null
+++ b/security/altha/Kconfig
@@ -0,0 +1,11 @@
+config SECURITY_ALTHA
+ bool "AltHa security module"
+ depends on SECURITY
+ default n
+ help
+ Some hardening options:
+ * ignore SUID on binaries (with exceptions possible);
+ * prevent running selected script interprers in interactive move;
+ * WxorX for filesystems (with exceptions possible);
+
+ If you are unsure how to answer this question, answer N.
diff --git a/security/altha/Makefile b/security/altha/Makefile
new file mode 100644
index 000000000000..56735b157567
--- /dev/null
+++ b/security/altha/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_SECURITY_ALTHA) := altha.o
+
+altha-y := altha_lsm.o
diff --git a/security/altha/altha_lsm.c b/security/altha/altha_lsm.c
new file mode 100644
index 000000000000..7d1cc8f8a1a7
--- /dev/null
+++ b/security/altha/altha_lsm.c
@@ -0,0 +1,325 @@
+/*
+ * AltHa Linux Security Module
+ *
+ * Author: Anton Boyarshinov <boyarsh@altlinux.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/lsm_hooks.h>
+#include <linux/cred.h>
+#include <linux/sysctl.h>
+#include <linux/binfmts.h>
+#include <linux/file.h>
+#include <linux/ratelimit.h>
+#include <linux/moduleparam.h>
+#include <linux/list.h>
+#include <linux/namei.h>
+#include <linux/namei.h>
+#include <linux/printk.h>
+#include <linux/rwsem.h>
+#include <asm/uaccess.h>
+
+#define ALTHA_PARAMS_SIZE 4096
+char proc_nosuid_exceptions[ALTHA_PARAMS_SIZE];
+char proc_interpreters[ALTHA_PARAMS_SIZE];
+char proc_olock_dirs[ALTHA_PARAMS_SIZE];
+
+/* Boot time disable flag */
+static bool altha_enabled = 0;
+
+/* sysctl flags */
+static int nosuid_enabled;
+static int rstrscript_enabled;
+static int olock_enabled;
+
+/* Boot parameter handing */
+module_param_named(enabled, altha_enabled, bool, S_IRUGO);
+
+static int __init altha_enabled_setup(char *str)
+{
+ unsigned long enabled;
+ int error = kstrtoul(str, 0, &enabled);
+ if (!error)
+ altha_enabled = enabled ? 1 : 0;
+ return 1;
+}
+
+__setup("altha=", altha_enabled_setup);
+
+struct altha_list_struct {
+ struct path path;
+ struct list_head list;
+};
+
+/* Lists handling */
+DECLARE_RWSEM(nosuid_exceptions_sem);
+DECLARE_RWSEM(interpreters_sem);
+DECLARE_RWSEM(olock_dirs_sem);
+LIST_HEAD(nosuid_exceptions_list);
+LIST_HEAD(interpreters_list);
+LIST_HEAD(olock_dirs_list);
+
+static int altha_list_handler(struct ctl_table *table, int write,
+ void __user * buffer, size_t * lenp,
+ loff_t * ppos)
+{
+ struct altha_list_struct *item, *tmp;
+ struct list_head *list_struct;
+ char *p, *fluid;
+ char *copy_buffer;
+ struct rw_semaphore *sem = table->extra2;
+ unsigned long error = proc_dostring(table, write, buffer, lenp, ppos);
+ down_write(sem);
+ if (error)
+ goto out;
+
+ if (write && !error) {
+ copy_buffer = kmalloc(ALTHA_PARAMS_SIZE, GFP_KERNEL);
+ if (!copy_buffer) {
+ pr_err
+ ("AltHa: can't get memory for copy_buffer processing sysctl\n");
+ error = -1;
+ goto out;
+ }
+
+ list_struct = (struct list_head *)(table->extra1);
+ /*empty list and that fill with new info */
+ list_for_each_entry_safe(item, tmp, list_struct, list) {
+ list_del(&item->list);
+ path_put(&item->path);
+ kfree(item);
+ }
+
+ strlcpy(copy_buffer, table->data, ALTHA_PARAMS_SIZE);
+
+ /* buffer can have a garbage after \n */
+ p = strchrnul(copy_buffer, '\n');
+ *p = 0;
+
+ /* for strsep usage */
+ fluid = copy_buffer;
+
+ while ((p = strsep(&fluid, ":\n")) != NULL) {
+ if (strlen(p)) {
+ item = kmalloc(sizeof(*item), GFP_KERNEL);
+ if (!item) {
+ pr_err
+ ("AltHa: can't get memory processing sysctl\n");
+ kfree(copy_buffer);
+ error = -1;
+ goto out;
+ }
+ if (kern_path(p, LOOKUP_FOLLOW, &item->path)) {
+ pr_info
+ ("AltHa: error lookup '%s'\n", p);
+ kfree(item);
+ } else {
+ list_add_tail(&item->list, list_struct);
+ }
+ }
+ }
+ kfree(copy_buffer);
+ }
+out:
+ up_write(sem);
+ return error;
+}
+
+struct ctl_path nosuid_sysctl_path[] = {
+ {.procname = "kernel",},
+ {.procname = "altha",},
+ {.procname = "nosuid",},
+ {}
+};
+
+static struct ctl_table nosuid_sysctl_table[] = {
+ {
+ .procname = "enabled",
+ .data = &nosuid_enabled,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec_minmax,
+ },
+ {
+ .procname = "exceptions",
+ .data = proc_nosuid_exceptions,
+ .maxlen = ALTHA_PARAMS_SIZE,
+ .mode = 0644,
+ .proc_handler = altha_list_handler,
+ .extra1 = &nosuid_exceptions_list,
+ .extra2 = &nosuid_exceptions_sem,
+ },
+ {}
+};
+
+struct ctl_path rstrscript_sysctl_path[] = {
+ {.procname = "kernel",},
+ {.procname = "altha",},
+ {.procname = "rstrscript",},
+ {}
+};
+
+static struct ctl_table rstrscript_sysctl_table[] = {
+ {
+ .procname = "enabled",
+ .data = &rstrscript_enabled,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_minmax,
+ },
+ {
+ .procname = "interpreters",
+ .data = proc_interpreters,
+ .maxlen = ALTHA_PARAMS_SIZE,
+ .mode = 0644,
+ .proc_handler = altha_list_handler,
+ .extra1 = &interpreters_list,
+ .extra2 = &interpreters_sem,
+ },
+ {}
+};
+
+struct ctl_path olock_sysctl_path[] = {
+ {.procname = "kernel",},
+ {.procname = "altha",},
+ {.procname = "olock",},
+ {}
+};
+
+static struct ctl_table olock_sysctl_table[] = {
+ {
+ .procname = "enabled",
+ .data = &olock_enabled,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_minmax,
+ },
+ {
+ .procname = "dirs",
+ .data = proc_olock_dirs,
+ .maxlen = ALTHA_PARAMS_SIZE,
+ .mode = 0644,
+ .proc_handler = altha_list_handler,
+ .extra1 = &olock_dirs_list,
+ .extra2 = &olock_dirs_sem,
+ },
+ {}
+};
+
+struct altha_readdir_callback {
+ struct dir_context ctx;
+ u64 inode;
+ int found;
+};
+
+
+int is_olock_dir(struct inode *inode)
+{
+ struct altha_list_struct *node;
+ down_read(&olock_dirs_sem);
+ list_for_each_entry(node, &olock_dirs_list, list) {
+ struct inode *exc_inode = node->path.dentry->d_inode;
+ if (exc_inode == inode) {
+ up_read(&olock_dirs_sem);
+ return 1;
+ }
+ }
+ up_read(&olock_dirs_sem);
+ return 0;
+}
+
+/* Hooks */
+static int altha_bprm_set_creds(struct linux_binprm *bprm)
+{
+ struct altha_list_struct *node;
+ /* when it's not a shebang issued script interpreter */
+ if (rstrscript_enabled && !bprm->called_set_creds) {
+ down_read(&interpreters_sem);
+ list_for_each_entry(node, &interpreters_list, list) {
+ if (path_equal(&bprm->file->f_path, &node->path)) {
+ uid_t cur_uid = from_kuid(bprm->cred->user_ns,
+ bprm->cred->uid);
+ pr_notice_ratelimited
+ ("AltHa/RestrScript: %s is blocked to run directly by %d\n",
+ bprm->filename, cur_uid);
+ up_read(&interpreters_sem);
+ return -EPERM;
+ }
+ }
+ up_read(&interpreters_sem);
+ }
+ if (unlikely(nosuid_enabled &&
+ !uid_eq(bprm->cred->uid, bprm->cred->euid))) {
+ uid_t cur_uid = from_kuid(bprm->cred->user_ns, bprm->cred->uid);
+ down_read(&nosuid_exceptions_sem);
+ list_for_each_entry(node, &nosuid_exceptions_list, list) {
+ if (path_equal(&bprm->file->f_path, &node->path)) {
+ pr_notice_ratelimited
+ ("AltHa/NoSUID: %s permitted to setuid from %d\n",
+ bprm->filename, cur_uid);
+ up_read(&nosuid_exceptions_sem);
+ return 0;
+ }
+ }
+ up_read(&nosuid_exceptions_sem);
+ pr_notice_ratelimited
+ ("AltHa/NoSUID: %s prevented to setuid from %d\n",
+ bprm->filename, cur_uid);
+ bprm->cred->euid = bprm->cred->uid;
+ }
+ return 0;
+}
+
+/* For OLock */
+static int altha_inode_unlink(struct inode *inode, struct dentry *dentry)
+{
+ if (olock_enabled && (atomic_read(&dentry->d_inode->i_writecount)
+#ifdef CONFIG_IMA
+ || atomic_read(&dentry->d_inode->i_readcount)
+#endif
+ )) {
+ if (is_olock_dir(inode))
+ return -EPERM;
+ }
+ return 0;
+}
+
+/* Initialization */
+
+static struct security_hook_list altha_hooks[] = {
+ LSM_HOOK_INIT(bprm_set_creds, altha_bprm_set_creds),
+ LSM_HOOK_INIT(inode_unlink, altha_inode_unlink),
+};
+
+static int __init altha_init(void)
+{
+ if (altha_enabled) {
+ pr_info("AltHa enabled.\n");
+ security_add_hooks(altha_hooks, ARRAY_SIZE(altha_hooks),"altha");
+
+ if (!register_sysctl_paths
+ (nosuid_sysctl_path, nosuid_sysctl_table))
+ panic("AltHa: NoSUID sysctl registration failed.\n");
+
+ if (!register_sysctl_paths
+ (rstrscript_sysctl_path, rstrscript_sysctl_table))
+ panic
+ ("AltHa: RestrScript sysctl registration failed.\n");
+
+ if (!register_sysctl_paths
+ (olock_sysctl_path, olock_sysctl_table))
+ panic("AltHa: OLock sysctl registration failed.\n");
+ } else
+ pr_info("AltHa disabled.\n");
+ return 0;
+}
+
+DEFINE_LSM(altha) = {
+ .name = "altha",
+ .init = altha_init,
+};
+
--
2.25.1

File diff suppressed because it is too large Load diff

View file

@ -1,15 +0,0 @@
https://github.com/sfjro/aufs5-linux/commit/a4e1cd668aeb906061bb8cd44554ad3f89759a2d
fs/inode.c only
diff -Naur linux-5.10/fs/inode.c aufs5-linux-aufs5.10/fs/inode.c
--- linux-5.10/fs/inode.c 2020-12-14 01:41:30.000000000 +0300
+++ aufs5-linux-aufs5.10/fs/inode.c 2022-03-07 10:18:47.000000000 +0300
@@ -1770,7 +1770,7 @@
* This does the actual work of updating an inodes time or version. Must have
* had called mnt_want_write() before calling this.
*/
-static int update_time(struct inode *inode, struct timespec64 *time, int flags)
+int update_time(struct inode *inode, struct timespec64 *time, int flags)
{
if (inode->i_op->update_time)
return inode->i_op->update_time(inode, time, flags);

View file

@ -1,6 +1,3 @@
From 48d6235433c8cffaeb3ede8a0173babf737addaa Mon Sep 17 00:00:00 2001
From: Mikhail Novosyolov <m.novosyolov@rosalinux.ru>
Date: Fri, 1 Jan 2021 19:03:29 +0300
Subject: [PATCH] Revert "kallsyms: unexport kallsyms_lookup_name() and Subject: [PATCH] Revert "kallsyms: unexport kallsyms_lookup_name() and
kallsyms_on_each_symbol()" kallsyms_on_each_symbol()"
@ -9,31 +6,25 @@ https://lwn.net/Articles/813350/
anbox kernel modules require kallsyms_lookup_name(), they are not propietary stuff like e.g. Nvidia, I want it to work more than trying to fight with violations of GPL where I do not have enough power. anbox kernel modules require kallsyms_lookup_name(), they are not propietary stuff like e.g. Nvidia, I want it to work more than trying to fight with violations of GPL where I do not have enough power.
Signed-off-by: Mikhail Novosyolov <m.novosyolov@rosalinux.ru> Update for 5.15.28
---
kernel/kallsyms.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index fe9de067771c..04b58bccbb0d 100644
--- a/kernel/kallsyms.c --- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c +++ b/kernel/kallsyms.c
@@ -176,6 +176,7 @@ unsigned long kallsyms_lookup_name(const char *name) @@ -203,6 +203,7 @@
} }
return module_kallsyms_lookup_name(name); return module_kallsyms_lookup_name(name);
} }
+EXPORT_SYMBOL_GPL(kallsyms_lookup_name); +EXPORT_SYMBOL_GPL(kallsyms_lookup_name);
int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *, #ifdef CONFIG_LIVEPATCH
unsigned long), /*
@@ -194,6 +195,7 @@ int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *, @@ -226,6 +227,7 @@
} }
return module_kallsyms_on_each_symbol(fn, data); return 0;
} }
+EXPORT_SYMBOL_GPL(kallsyms_on_each_symbol); +EXPORT_SYMBOL_GPL(kallsyms_on_each_symbol);
#endif /* CONFIG_LIVEPATCH */
static unsigned long get_symbol_pos(unsigned long addr, static unsigned long get_symbol_pos(unsigned long addr,
unsigned long *symbolsize,
--
2.30.0

1172
0001-altha.patch Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,22 +1,15 @@
From 59bf6ed4709ea82d63be300814af2c4c94503e14 Mon Sep 17 00:00:00 2001
From: Mikhail Novosyolov <m.novosyolov@rosalinux.ru>
Date: Thu, 6 Aug 2020 14:17:31 +0300
Subject: [PATCH] crypto: support loading GOST-signed kernel modules Subject: [PATCH] crypto: support loading GOST-signed kernel modules
Support loading kernel modules signed with: Support loading kernel modules signed with:
* 1.2.643.7.1.1.1.1 id-tc26-gost3410-12-256 * 1.2.643.7.1.1.1.1 id-tc26-gost3410-12-256
* 1.2.643.7.1.1.1.2 id-tc26-gost3410-12-512 * 1.2.643.7.1.1.1.2 id-tc26-gost3410-12-512
Signed-off-by: Mikhail Novosyolov <m.novosyolov@rosalinux.ru> Update for 5.15.28
---
crypto/asymmetric_keys/pkcs7_parser.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/crypto/asymmetric_keys/pkcs7_parser.c b/crypto/asymmetric_keys/pkcs7_parser.c diff --git a/crypto/asymmetric_keys/pkcs7_parser.c b/crypto/asymmetric_keys/pkcs7_parser.c
index 967329e0a07b..39c260a04167 100644
--- a/crypto/asymmetric_keys/pkcs7_parser.c --- a/crypto/asymmetric_keys/pkcs7_parser.c
+++ b/crypto/asymmetric_keys/pkcs7_parser.c +++ b/crypto/asymmetric_keys/pkcs7_parser.c
@@ -248,6 +248,12 @@ int pkcs7_sig_note_digest_algo(void *context, size_t hdrlen, @@ -248,6 +248,12 @@
case OID_sha224: case OID_sha224:
ctx->sinfo->sig->hash_algo = "sha224"; ctx->sinfo->sig->hash_algo = "sha224";
break; break;
@ -29,9 +22,9 @@ index 967329e0a07b..39c260a04167 100644
default: default:
printk("Unsupported digest algo: %u\n", ctx->last_oid); printk("Unsupported digest algo: %u\n", ctx->last_oid);
return -ENOPKG; return -ENOPKG;
@@ -269,6 +275,11 @@ int pkcs7_sig_note_pkey_algo(void *context, size_t hdrlen, @@ -277,6 +283,11 @@
ctx->sinfo->sig->pkey_algo = "rsa"; ctx->sinfo->sig->pkey_algo = "ecdsa";
ctx->sinfo->sig->encoding = "pkcs1"; ctx->sinfo->sig->encoding = "x962";
break; break;
+ case OID_gost2012PKey256: + case OID_gost2012PKey256:
+ case OID_gost2012PKey512: + case OID_gost2012PKey512:

View file

@ -1,22 +1,14 @@
From 1a821310ed4c0519e7fe534ea0a4ba46e604ee4f Mon Sep 17 00:00:00 2001
From: Evgenii Shatokhin <eshatokhin@virtuozzo.com>
Date: Wed, 11 Dec 2019 21:15:36 +0300
Subject: [PATCH] disable mrproper prepare scripts configs in devel rpms Subject: [PATCH] disable mrproper prepare scripts configs in devel rpms
This is for disabling *config, mrproper, prepare, scripts on -devel rpms This is for disabling *config, mrproper, prepare, scripts on -devel rpms
Needed, because otherwise the -devel won't build correctly. Needed, because otherwise the -devel won't build correctly.
Signed-off-by: Mikhail Novosyolov <m.novosyolov@rosalinux.ru> Update for 5.15.28
---
Makefile | 22 +++++-----------------
scripts/kconfig/Makefile | 17 -----------------
2 files changed, 5 insertions(+), 34 deletions(-)
diff --git a/Makefile b/Makefile diff --git a/Makefile b/Makefile
index 076d4e6b9ccc..75bf27049d60 100644
--- a/Makefile --- a/Makefile
+++ b/Makefile +++ b/Makefile
@@ -1186,8 +1186,7 @@ include/config/kernel.release: FORCE @@ -1199,8 +1199,7 @@
# Carefully list dependencies so we do not try to build scripts twice # Carefully list dependencies so we do not try to build scripts twice
# in parallel # in parallel
PHONY += scripts PHONY += scripts
@ -26,17 +18,17 @@ index 076d4e6b9ccc..75bf27049d60 100644
# Things we need to do before we recursively start building the kernel # Things we need to do before we recursively start building the kernel
# or the modules are listed in "prepare". # or the modules are listed in "prepare".
@@ -1206,7 +1205,7 @@ prepare0: archprepare @@ -1219,7 +1218,7 @@
$(Q)$(MAKE) $(build)=. $(Q)$(MAKE) $(build)=.
# All the preparing.. # All the preparing..
-prepare: prepare0 prepare-objtool prepare-resolve_btfids -prepare: prepare0
+prepare: +prepare:
# Support for using generic headers in asm-generic PHONY += remove-stale-files
asm-generic := -f $(srctree)/scripts/Makefile.asm-generic obj remove-stale-files:
@@ -1472,15 +1471,7 @@ CLEAN_FILES += include/ksym vmlinux.symvers \ @@ -1520,15 +1519,7 @@
compile_commands.json compile_commands.json .thinlto-cache
# Directories & files removed with 'make mrproper' # Directories & files removed with 'make mrproper'
-MRPROPER_FILES += include/config include/generated \ -MRPROPER_FILES += include/config include/generated \
@ -44,15 +36,15 @@ index 076d4e6b9ccc..75bf27049d60 100644
- debian snap tar-install \ - debian snap tar-install \
- .config .config.old .version \ - .config .config.old .version \
- Module.symvers \ - Module.symvers \
- signing_key.pem signing_key.priv signing_key.x509 \ - certs/signing_key.pem certs/signing_key.x509 \
- x509.genkey extra_certificates signing_key.x509.keyid \ - certs/x509.genkey \
- signing_key.x509.signer vmlinux-gdb.py \ - vmlinux-gdb.py \
- *.spec - *.spec
+MRPROPER_FILES += "" +MRPROPER_FILES += ""
# Directories & files removed with 'make distclean' # clean - Delete most, but leave enough to build external modules
DISTCLEAN_FILES += tags TAGS cscope* GPATH GTAGS GRTAGS GSYMS #
@@ -1500,13 +1491,10 @@ clean: archclean vmlinuxclean @@ -1545,13 +1536,10 @@
# mrproper - Delete all generated files, including .config # mrproper - Delete all generated files, including .config
# #
mrproper: rm-files := $(wildcard $(MRPROPER_FILES)) mrproper: rm-files := $(wildcard $(MRPROPER_FILES))
@ -69,30 +61,9 @@ index 076d4e6b9ccc..75bf27049d60 100644
# distclean # distclean
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index e46df0a2d4f9..edceb8d1d213 100644
--- a/scripts/kconfig/Makefile --- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile
@@ -20,19 +20,14 @@ endif @@ -54,11 +54,9 @@
unexport CONFIG_
xconfig: $(obj)/qconf
- $(Q)$< $(silent) $(Kconfig)
gconfig: $(obj)/gconf
- $(Q)$< $(silent) $(Kconfig)
menuconfig: $(obj)/mconf
- $(Q)$< $(silent) $(Kconfig)
config: $(obj)/conf
- $(Q)$< $(silent) --oldaskconfig $(Kconfig)
nconfig: $(obj)/nconf
- $(Q)$< $(silent) $(Kconfig)
build_menuconfig: $(obj)/mconf
@@ -48,11 +43,9 @@ localyesconfig localmodconfig: $(obj)/conf
cmp -s .tmp.config .config || \ cmp -s .tmp.config .config || \
(mv -f .config .config.old.1; \ (mv -f .config .config.old.1; \
mv -f .tmp.config .config; \ mv -f .tmp.config .config; \
@ -104,7 +75,7 @@ index e46df0a2d4f9..edceb8d1d213 100644
fi fi
$(Q)rm -f .tmp.config $(Q)rm -f .tmp.config
@@ -68,24 +61,14 @@ simple-targets := oldconfig allnoconfig allyesconfig allmodconfig \ @@ -74,24 +72,14 @@
PHONY += $(simple-targets) PHONY += $(simple-targets)
$(simple-targets): $(obj)/conf $(simple-targets): $(obj)/conf
@ -129,6 +100,3 @@ index e46df0a2d4f9..edceb8d1d213 100644
configfiles=$(wildcard $(srctree)/kernel/configs/$@ $(srctree)/arch/$(SRCARCH)/configs/$@) configfiles=$(wildcard $(srctree)/kernel/configs/$@ $(srctree)/arch/$(SRCARCH)/configs/$@)
--
2.25.1

View file

@ -1,73 +0,0 @@
From fe0e9e1b7fc6bc4a8ca0e0473bf88297ca7020a7 Mon Sep 17 00:00:00 2001
From: "Anton V. Boyarshinov" <boyarsh@altlinux.org>
Date: Thu, 17 May 2018 08:30:25 +0000
Subject: [PATCH 2/2] Documentation for AltHa LSM
Signed-off-by: Mikhail Novosyolov <m.novosyolov@rosalinux.ru>
---
Documentation/admin-guide/LSM/AltHa.rst | 43 +++++++++++++++++++++++++
Documentation/admin-guide/LSM/index.rst | 1 +
2 files changed, 44 insertions(+)
create mode 100644 Documentation/admin-guide/LSM/AltHa.rst
diff --git a/Documentation/admin-guide/LSM/AltHa.rst b/Documentation/admin-guide/LSM/AltHa.rst
new file mode 100644
index 000000000000..0b2ad0c8dd17
--- /dev/null
+++ b/Documentation/admin-guide/LSM/AltHa.rst
@@ -0,0 +1,43 @@
+====
+AltHa
+====
+
+AltHa is a Linux Security Module currently has three userspace hardening options:
+ * ignore SUID on binaries (with exceptions possible);
+ * prevent running selected script interprers in interactive move;
+ * disable open file unlinking in selected dirs.
+
+
+It is selectable at build-time with ``CONFIG_SECURITY_ALTHA``, and should be
+enabled in runtime by command line option ``altha=1`` and configuded
+through sysctls in ``/proc/sys/kernel/altha``.
+
+NoSUID
+============
+Modern Linux systems can be used with minimal (or even zero at least for OWL and ALT) usage of SUID programms, but in many cases in full-featured desktop or server systems there ara plenty of them: uncounted and sometimes unnessesary. Privileged programms are always a attack surface, but mounting filesystems with ``nosuid`` flag doesn't provide enouth granularity in SUID binaries manageent. This LSM module provides a single control point for all SUID binaries. When this submodule is enabled, SUID bits on all binaries except explicitally listed are system-wide ignored.
+
+Sysctl parameters and defaults:
+
+* ``kernel.altha.nosuid.enabled = 0``, set to 1 to enable
+* ``kernel.altha.nosuid.exceptions =``, colon-separated list of enabled SUID binaries, for example: ``/bin/su:/usr/libexec/hasher-priv/hasher-priv``
+
+RestrScript
+============
+There is a one way to hardening: prevent users from executing ther own arbitrary code. Thraditionally it can be done setting on user-writable filesystems ``noexec`` flag. But modern script languages such as Python also can be used to write exploits or even load arbitary machine code via ``dlopen`` and users can start scripts from ``noexec`` filesystem starting interpreter directly.
+Restrscript LSM submodule provides a way to restrict some programms to be executed directly, but allows to execute them as shebang handler.
+
+Sysctl parameters and defaults:
+
+* ``kernel.altha.rstrscript.enabled = 0``, set to 1 to enable
+* ``kernel.altha.rstrscript.interpreters =``, colon-separated list of restricted interpreters for example: ``/usr/bin/python:/usr/bin/python3:/usr/bin/perl:/usr/bin/tclsh``. Simlinks are suporrted in both ways: you can set symlink to interpreter as exception and interpreter and all symlinks on it will be restricted.
+
+Note: in this configuration all scripts starting with ``#!/usr/bin/env python`` will be blocked.
+
+OLock
+============
+Unlink disabling for open files needed for Russian sertification, but this is a nasty feature leading to DOS.
+
+Sysctl parameters and defaults:
+
+* ``kernel.altha.olock.enabled = 0``, set to 1 to enable
+* ``kernel.altha.olock.dirs =``, colon-separated list of dirs, for example: ``/var/lib/something:/tmp/something``.
diff --git a/Documentation/admin-guide/LSM/index.rst b/Documentation/admin-guide/LSM/index.rst
index a6ba95fbaa9f..20b57e7adadd 100644
--- a/Documentation/admin-guide/LSM/index.rst
+++ b/Documentation/admin-guide/LSM/index.rst
@@ -47,3 +47,4 @@ subdirectories.
tomoyo
Yama
SafeSetID
+ AltHa
--
2.25.1

View file

@ -1,68 +0,0 @@
From d89442861500242809d99c9e178b0ed1dd741b28 Mon Sep 17 00:00:00 2001
From: Kernel Bot <kernelbot@altlinux.org>
Date: Mon, 24 Aug 2020 17:16:53 +0300
Subject: [PATCH 3/4] security/altha/altha_lsm.c: build fixed with kernel 5.8
---
security/altha/altha_lsm.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/security/altha/altha_lsm.c b/security/altha/altha_lsm.c
index 7d1cc8f8a1a7..41f0fc7ac8e5 100644
--- a/security/altha/altha_lsm.c
+++ b/security/altha/altha_lsm.c
@@ -216,6 +216,15 @@ struct altha_readdir_callback {
int found;
};
+int compare_paths(const struct path *path1, const struct path *path2)
+{
+ char a1[PATH_MAX];
+ char a2[PATH_MAX];
+ char* p1, *p2;
+ p1=d_path(path1,a1,PATH_MAX);
+ p2=d_path(path2,a2,PATH_MAX);
+ return strcmp(p1,p2);
+}
int is_olock_dir(struct inode *inode)
{
@@ -233,14 +242,14 @@ int is_olock_dir(struct inode *inode)
}
/* Hooks */
-static int altha_bprm_set_creds(struct linux_binprm *bprm)
+static int altha_bprm_creds_from_file(struct linux_binprm *bprm, struct file * fi)
{
struct altha_list_struct *node;
/* when it's not a shebang issued script interpreter */
- if (rstrscript_enabled && !bprm->called_set_creds) {
+ if (rstrscript_enabled && bprm->filename == bprm->interp) {
down_read(&interpreters_sem);
list_for_each_entry(node, &interpreters_list, list) {
- if (path_equal(&bprm->file->f_path, &node->path)) {
+ if (compare_paths(&bprm->file->f_path, &node->path) == 0) {
uid_t cur_uid = from_kuid(bprm->cred->user_ns,
bprm->cred->uid);
pr_notice_ratelimited
@@ -257,7 +266,7 @@ static int altha_bprm_set_creds(struct linux_binprm *bprm)
uid_t cur_uid = from_kuid(bprm->cred->user_ns, bprm->cred->uid);
down_read(&nosuid_exceptions_sem);
list_for_each_entry(node, &nosuid_exceptions_list, list) {
- if (path_equal(&bprm->file->f_path, &node->path)) {
+ if (compare_paths(&bprm->file->f_path, &node->path) == 0) {
pr_notice_ratelimited
("AltHa/NoSUID: %s permitted to setuid from %d\n",
bprm->filename, cur_uid);
@@ -291,7 +300,7 @@ static int altha_inode_unlink(struct inode *inode, struct dentry *dentry)
/* Initialization */
static struct security_hook_list altha_hooks[] = {
- LSM_HOOK_INIT(bprm_set_creds, altha_bprm_set_creds),
+ LSM_HOOK_INIT(bprm_creds_from_file, altha_bprm_creds_from_file),
LSM_HOOK_INIT(inode_unlink, altha_inode_unlink),
};
--
2.25.1

View file

@ -1,101 +0,0 @@
From 5765b709411696cd58db43e6e006a36e5a207ee0 Mon Sep 17 00:00:00 2001
From: Kernel Bot <kernelbot@altlinux.org>
Date: Wed, 2 Sep 2020 15:19:59 +0300
Subject: [PATCH 4/4] altha: use path strings instead of path structs
Path strings continueto work even when target file was replaced.
---
security/altha/altha_lsm.c | 30 ++++++++++++++++--------------
1 file changed, 16 insertions(+), 14 deletions(-)
diff --git a/security/altha/altha_lsm.c b/security/altha/altha_lsm.c
index 41f0fc7ac8e5..ccde83ebb26c 100644
--- a/security/altha/altha_lsm.c
+++ b/security/altha/altha_lsm.c
@@ -52,6 +52,8 @@ __setup("altha=", altha_enabled_setup);
struct altha_list_struct {
struct path path;
+ char * spath;
+ char * spath_p;
struct list_head list;
};
@@ -91,6 +93,7 @@ static int altha_list_handler(struct ctl_table *table, int write,
list_for_each_entry_safe(item, tmp, list_struct, list) {
list_del(&item->list);
path_put(&item->path);
+ kfree(item->spath_p);
kfree(item);
}
@@ -106,7 +109,9 @@ static int altha_list_handler(struct ctl_table *table, int write,
while ((p = strsep(&fluid, ":\n")) != NULL) {
if (strlen(p)) {
item = kmalloc(sizeof(*item), GFP_KERNEL);
- if (!item) {
+ if (item)
+ item->spath_p = kmalloc(PATH_MAX, GFP_KERNEL);
+ if (!item || !item->spath_p) {
pr_err
("AltHa: can't get memory processing sysctl\n");
kfree(copy_buffer);
@@ -118,6 +123,7 @@ static int altha_list_handler(struct ctl_table *table, int write,
("AltHa: error lookup '%s'\n", p);
kfree(item);
} else {
+ item->spath=d_path(&item->path,item->spath_p,PATH_MAX);
list_add_tail(&item->list, list_struct);
}
}
@@ -216,16 +222,6 @@ struct altha_readdir_callback {
int found;
};
-int compare_paths(const struct path *path1, const struct path *path2)
-{
- char a1[PATH_MAX];
- char a2[PATH_MAX];
- char* p1, *p2;
- p1=d_path(path1,a1,PATH_MAX);
- p2=d_path(path2,a2,PATH_MAX);
- return strcmp(p1,p2);
-}
-
int is_olock_dir(struct inode *inode)
{
struct altha_list_struct *node;
@@ -246,10 +242,13 @@ static int altha_bprm_creds_from_file(struct linux_binprm *bprm, struct file * f
{
struct altha_list_struct *node;
/* when it's not a shebang issued script interpreter */
- if (rstrscript_enabled && bprm->filename == bprm->interp) {
+ if (rstrscript_enabled && bprm->executable == bprm->interpreter) {
+ char path_buffer[PATH_MAX];
+ char *path_p;
+ path_p = d_path(&bprm->file->f_path,path_buffer,PATH_MAX);
down_read(&interpreters_sem);
list_for_each_entry(node, &interpreters_list, list) {
- if (compare_paths(&bprm->file->f_path, &node->path) == 0) {
+ if (strcmp(path_p, node->spath) == 0) {
uid_t cur_uid = from_kuid(bprm->cred->user_ns,
bprm->cred->uid);
pr_notice_ratelimited
@@ -263,10 +262,13 @@ static int altha_bprm_creds_from_file(struct linux_binprm *bprm, struct file * f
}
if (unlikely(nosuid_enabled &&
!uid_eq(bprm->cred->uid, bprm->cred->euid))) {
+ char path_buffer[PATH_MAX];
+ char *path_p;
uid_t cur_uid = from_kuid(bprm->cred->user_ns, bprm->cred->uid);
+ path_p = d_path(&bprm->file->f_path,path_buffer,PATH_MAX);
down_read(&nosuid_exceptions_sem);
list_for_each_entry(node, &nosuid_exceptions_list, list) {
- if (compare_paths(&bprm->file->f_path, &node->path) == 0) {
+ if (strcmp(path_p, node->spath) == 0) {
pr_notice_ratelimited
("AltHa/NoSUID: %s permitted to setuid from %d\n",
bprm->filename, cur_uid);
--
2.25.1

File diff suppressed because it is too large Load diff

23032
0601-baikalm.patch Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,502 +0,0 @@
From 2e8241aba5add6f768a0876bc11c989681e28817 Mon Sep 17 00:00:00 2001
From: Alexey Sheplyakov <asheplyakov@altlinux.org>
Date: Fri, 20 Mar 2020 13:55:42 +0400
Subject: [PATCH 602/625] Baikal-M: clock driver
(cherry picked from commit acf15020f93d3be658922bb46ee9b4eb84497494)
---
drivers/clk/Makefile | 1 +
drivers/clk/baikal/Makefile | 1 +
drivers/clk/baikal/clk-baikal.c | 459 ++++++++++++++++++++++++++++++++
3 files changed, 461 insertions(+)
create mode 100644 drivers/clk/baikal/Makefile
create mode 100644 drivers/clk/baikal/clk-baikal.c
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index da8fcf147eb1..ab785aca5c8e 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -77,6 +77,7 @@ obj-$(CONFIG_COMMON_CLK_AT91) += at91/
obj-$(CONFIG_ARCH_ARTPEC) += axis/
obj-$(CONFIG_ARC_PLAT_AXS10X) += axs10x/
obj-$(CONFIG_CLK_BAIKAL_T1) += baikal-t1/
+obj-$(CONFIG_ARCH_BAIKAL) += baikal/
obj-y += bcm/
obj-$(CONFIG_ARCH_BERLIN) += berlin/
obj-$(CONFIG_ARCH_DAVINCI) += davinci/
diff --git a/drivers/clk/baikal/Makefile b/drivers/clk/baikal/Makefile
new file mode 100644
index 000000000000..56aa4de4081c
--- /dev/null
+++ b/drivers/clk/baikal/Makefile
@@ -0,0 +1 @@
+obj-y += clk-baikal.o
\ No newline at end of file
diff --git a/drivers/clk/baikal/clk-baikal.c b/drivers/clk/baikal/clk-baikal.c
new file mode 100644
index 000000000000..ddf1d328eeaf
--- /dev/null
+++ b/drivers/clk/baikal/clk-baikal.c
@@ -0,0 +1,459 @@
+/*
+ * clk-baikal.c - Baikal Electronics clock driver.
+ *
+ * Copyright (C) 2015,2016 Baikal Electronics JSC
+ *
+ * Author:
+ * Ekaterina Skachko <Ekaterina.Skachko@baikalelectronics.ru>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <asm/setup.h>
+#include <linux/arm-smccc.h>
+
+#define CMU_PLL_SET_RATE 0
+#define CMU_PLL_GET_RATE 1
+#define CMU_PLL_ENABLE 2
+#define CMU_PLL_DISABLE 3
+#define CMU_PLL_ROUND_RATE 4
+#define CMU_PLL_IS_ENABLED 5
+#define CMU_CLK_CH_SET_RATE 6
+#define CMU_CLK_CH_GET_RATE 7
+#define CMU_CLK_CH_ENABLE 8
+#define CMU_CLK_CH_DISABLE 9
+#define CMU_CLK_CH_ROUND_RATE 10
+#define CMU_CLK_CH_IS_ENABLED 11
+
+
+struct baikal_clk_cmu {
+ struct clk_hw hw;
+ uint32_t cmu_id;
+ unsigned int parent;
+ const char *name;
+ spinlock_t *lock;
+ void __iomem *reg;
+ unsigned int latency; /* ns */
+ unsigned int min, max, step;
+ unsigned int clk_ch_num;
+ uint32_t is_clk_ch;
+};
+
+#define to_baikal_cmu(_hw) container_of(_hw, struct baikal_clk_cmu, hw)
+
+/* Pointer to the place on handling SMC CMU calls in monitor */
+#define BAIKAL_SMC_LCRU_ID 0x82000000
+
+static int baikal_clk_enable(struct clk_hw *hw)
+{
+ struct arm_smccc_res res;
+ struct baikal_clk_cmu *pclk = to_baikal_cmu(hw);
+ uint32_t cmd;
+
+ if (pclk->is_clk_ch){
+ cmd = CMU_CLK_CH_ENABLE;
+ }
+ else {
+ cmd = CMU_PLL_ENABLE;
+ }
+
+ pr_debug("[%s, %x:%d:%s] %s\n",
+ pclk->name,
+ pclk->parent,
+ pclk->cmu_id,
+ pclk->is_clk_ch?"ch":"pll",
+ "enable");
+
+ /* If clock valid */
+ arm_smccc_smc(BAIKAL_SMC_LCRU_ID, pclk->cmu_id, cmd, 0,
+ pclk->parent, 0, 0, 0, &res);
+
+ return res.a0;
+}
+
+static void baikal_clk_disable(struct clk_hw *hw)
+{
+
+ struct arm_smccc_res res;
+ struct baikal_clk_cmu *pclk = to_baikal_cmu(hw);
+ uint32_t cmd;
+
+ if (pclk->is_clk_ch)
+ cmd = CMU_CLK_CH_DISABLE;
+ else
+ cmd = CMU_PLL_DISABLE;
+
+ pr_debug("[%s, %x:%d:%s] %s\n",
+ pclk->name,
+ pclk->parent,
+ pclk->cmu_id,
+ pclk->is_clk_ch?"ch":"pll",
+ "disable");
+
+ /* If clock valid */
+ arm_smccc_smc(BAIKAL_SMC_LCRU_ID, pclk->cmu_id, cmd, 0,
+ pclk->parent, 0, 0, 0, &res);
+}
+
+static int baikal_clk_is_enabled(struct clk_hw *hw)
+{
+ struct arm_smccc_res res;
+ struct baikal_clk_cmu *pclk = to_baikal_cmu(hw);
+ uint32_t cmd;
+
+ if (pclk->is_clk_ch)
+ cmd = CMU_CLK_CH_IS_ENABLED;
+ else
+ cmd = CMU_PLL_IS_ENABLED;
+
+ /* If clock valid */
+ arm_smccc_smc(BAIKAL_SMC_LCRU_ID, pclk->cmu_id, cmd, 0,
+ pclk->parent, 0, 0, 0, &res);
+
+ pr_debug("[%s, %x:%d:%s] %s, %ld\n",
+ pclk->name,
+ pclk->parent,
+ pclk->cmu_id,
+ pclk->is_clk_ch?"ch":"pll",
+ "is enable",
+ res.a0);
+
+ return res.a0;
+}
+
+static unsigned long baikal_clk_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct arm_smccc_res res;
+ struct baikal_clk_cmu *pclk = to_baikal_cmu(hw);
+ uint32_t cmd;
+ unsigned long parent;
+
+ if (pclk->is_clk_ch) {
+ cmd = CMU_CLK_CH_GET_RATE;
+ parent = pclk->parent;
+ } else {
+ cmd = CMU_PLL_GET_RATE;
+ parent= parent_rate;
+ }
+
+ /* If clock valid */
+ arm_smccc_smc(BAIKAL_SMC_LCRU_ID, pclk->cmu_id, cmd, 0,
+ parent, 0, 0, 0, &res);
+
+ pr_debug("[%s, %x:%d:%s] %s, %ld\n",
+ pclk->name,
+ parent,
+ pclk->cmu_id,
+ pclk->is_clk_ch?"ch":"pll",
+ "get rate",
+ res.a0);
+
+ /* Return actual freq */
+ return res.a0;
+
+}
+
+static int baikal_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct arm_smccc_res res;
+ struct baikal_clk_cmu *pclk = to_baikal_cmu(hw);
+ uint32_t cmd;
+
+ if (pclk->is_clk_ch)
+ cmd = CMU_CLK_CH_SET_RATE;
+ else
+ cmd = CMU_PLL_SET_RATE;
+
+ pr_debug("[%s, %x:%d:%s] %s, %ld\n",
+ pclk->name,
+ pclk->parent,
+ pclk->cmu_id,
+ pclk->is_clk_ch?"ch":"pll",
+ "set rate",
+ rate);
+
+ arm_smccc_smc(BAIKAL_SMC_LCRU_ID, pclk->cmu_id, cmd, rate,
+ pclk->parent, 0, 0, 0, &res);
+
+ return res.a0;
+}
+
+static long baikal_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ struct arm_smccc_res res;
+ struct baikal_clk_cmu *pclk = to_baikal_cmu(hw);
+ unsigned long parent;
+ uint32_t cmd;
+
+ if (pclk->is_clk_ch) {
+ cmd = CMU_CLK_CH_ROUND_RATE;
+ parent = pclk->parent;
+ } else {
+ cmd = CMU_PLL_ROUND_RATE;
+ parent = *prate;
+ }
+
+
+ /* If clock valid */
+ arm_smccc_smc(BAIKAL_SMC_LCRU_ID, pclk->cmu_id, cmd, rate,
+ parent, 0, 0, 0, &res);
+
+ pr_debug("[%s, %x:%d:%s] %s, %ld\n",
+ pclk->name,
+ pclk->parent,
+ pclk->cmu_id,
+ pclk->is_clk_ch?"ch":"pll",
+ "round rate",
+ res.a0);
+
+ /* Return actual freq */
+ return res.a0;
+}
+
+const struct clk_ops be_clk_pll_ops = {
+ .enable = baikal_clk_enable,
+ .disable = baikal_clk_disable,
+ .is_enabled = baikal_clk_is_enabled,
+ .recalc_rate = baikal_clk_recalc_rate,
+ .set_rate = baikal_clk_set_rate,
+ .round_rate = baikal_clk_round_rate,
+};
+
+
+
+static int baikal_clk_probe(struct platform_device *pdev)
+{
+ struct clk_init_data init;
+ struct clk_init_data *init_ch;
+ struct baikal_clk_cmu *cmu;
+ struct baikal_clk_cmu **cmu_ch;
+ struct device_node *node = pdev->dev.of_node;
+
+ struct clk *clk;
+ struct clk_onecell_data *clk_ch;
+
+ int number, i = 0;
+ u32 rc, index;
+ struct property *prop;
+ const __be32 *p;
+ const char *clk_ch_name;
+ const char *parent_name;
+
+ cmu = kmalloc(sizeof(struct baikal_clk_cmu *), GFP_KERNEL);
+ if (!cmu) {
+ /* Error */
+ pr_err("%s: could not allocate CMU clk\n", __func__);
+ kfree(cmu);
+ return -ENOMEM;
+ }
+
+ of_property_read_string(node, "clock-output-names", &cmu->name);
+ parent_name = of_clk_get_parent_name(node, 0);
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+ of_property_read_u32(node, "clock-frequency", &cmu->parent);
+ of_property_read_u32(node, "cmu-id", &cmu->cmu_id);
+
+ /* Setup clock init structure */
+ init.name = cmu->name;
+ init.ops = &be_clk_pll_ops;
+ init.flags = CLK_IGNORE_UNUSED;
+
+ cmu->hw.init = &init;
+ cmu->is_clk_ch = 0;
+
+ /* Register the clock */
+ pr_debug("Add %s clock\n", cmu->name);
+ clk = clk_register(NULL, &cmu->hw);
+
+ if (IS_ERR(clk)) {
+ /* Error */
+ pr_err("%s: could not register clk %s\n", __func__, cmu->name);
+ return -ENOMEM;
+ }
+
+ /* Register the clock for lookup */
+ rc = clk_register_clkdev(clk, cmu->name, NULL);
+ if (rc != 0) {
+ /* Error */
+ pr_err("%s: could not register lookup clk %s\n",
+ __func__, cmu->name);
+ }
+
+ /* FIXME We probably SHOULDN'T enable it here */
+ clk_prepare_enable(clk);
+
+ number = of_property_count_u32_elems(node, "clock-indices");
+
+ if (number > 0) {
+ clk_ch = kmalloc(sizeof(struct clk_onecell_data), GFP_KERNEL);
+ if (!clk_ch) {
+ /* Error */
+ pr_err("%s: could not allocate CMU clk channel\n", __func__);
+ kfree(clk_ch);
+ return -ENOMEM;
+ }
+ /* Get the last index to find out max number of children*/
+ of_property_for_each_u32(node, "clock-indices", prop, p, index) {
+ ;
+ }
+ clk_ch->clks = kcalloc(index + 1, sizeof(struct clk *), GFP_KERNEL);
+ clk_ch->clk_num = index + 1;
+ cmu_ch = kcalloc((index + 1 ), sizeof(struct baikal_clk_cmu *), GFP_KERNEL);
+ if (!cmu_ch) {
+ kfree(cmu_ch);
+ kfree(clk_ch);
+ return -ENOMEM;
+ }
+ init_ch = kcalloc((number + 1 ), sizeof(struct clk_init_data), GFP_KERNEL);
+ if (!init_ch){
+ /* Error */
+ pr_err("%s: could not allocate CMU init structure \n", __func__);
+ kfree(init_ch);
+ kfree(cmu_ch);
+ kfree(clk_ch);
+ return -ENOMEM;
+ }
+
+ of_property_for_each_u32(node, "clock-indices", prop, p, index) {
+ of_property_read_string_index(node, "clock-names",
+ i, &clk_ch_name);
+ pr_err("%s index %x name <%s> i %x \n", __func__,index, clk_ch_name, i);
+ cmu_ch[index] = kmalloc(sizeof(struct baikal_clk_cmu), GFP_KERNEL);
+
+ cmu_ch[index]->name = clk_ch_name;
+ cmu_ch[index]->cmu_id = index;
+ cmu_ch[index]->parent = cmu->cmu_id;
+ cmu_ch[index]->is_clk_ch = 1;
+ init_ch[i].parent_names = &cmu->name;
+ init_ch[i].num_parents = 1;
+
+ init_ch[i].name = clk_ch_name;
+ init_ch[i].ops = &be_clk_pll_ops;
+ init_ch[i].flags = CLK_IGNORE_UNUSED;
+
+ cmu_ch[index]->hw.init = &init_ch[i];
+ clk_ch->clks[index] = clk_register(NULL, &cmu_ch[index]->hw);
+
+ if (IS_ERR(clk_ch->clks[index])) {
+ /* Error */
+ pr_err("%s: could not register clk %s\n", __func__, clk_ch_name);
+ }
+ /* Register the clock for lookup */
+ rc = clk_register_clkdev(clk_ch->clks[index], clk_ch_name, NULL);
+ if (rc != 0) {
+ /* Error */
+ pr_err("%s: could not register lookup clk %s\n",
+ __func__, clk_ch_name);
+ }
+ /* FIXME We probably SHOULDN'T enable it here */
+ clk_prepare_enable(clk_ch->clks[index]);
+ i++;
+ }
+ return of_clk_add_provider(pdev->dev.of_node, of_clk_src_onecell_get, clk_ch);
+ } else
+
+ return of_clk_add_provider(pdev->dev.of_node, of_clk_src_simple_get, clk);
+}
+
+static int baikal_clk_remove(struct platform_device *pdev)
+{
+ of_clk_del_provider(pdev->dev.of_node);
+
+ return 0;
+}
+
+static const struct of_device_id baikal_clk_of_match[] = {
+ {.compatible = "baikal,cmu"},
+ { /* sentinel value */ }
+};
+
+static struct platform_driver clk_avlsp_cmu0_driver = {
+ .probe = baikal_clk_probe,
+ .remove = baikal_clk_remove,
+ .driver = {
+ .name = "baikal-avlsp-cmu0",
+ .of_match_table = baikal_clk_of_match,
+ },
+};
+
+static struct platform_driver clk_avlsp_cmu1_driver = {
+ .probe = baikal_clk_probe,
+ .remove = baikal_clk_remove,
+ .driver = {
+ .name = "baikal-avlsp-cmu1",
+ .of_match_table = baikal_clk_of_match,
+ },
+};
+
+static struct platform_driver clk_xgbe_cmu0_driver = {
+ .probe = baikal_clk_probe,
+ .remove = baikal_clk_remove,
+ .driver = {
+ .name = "baikal-xgbe-cmu0",
+ .of_match_table = baikal_clk_of_match,
+ },
+};
+
+static struct platform_driver clk_xgbe_cmu1_driver = {
+ .probe = baikal_clk_probe,
+ .remove = baikal_clk_remove,
+ .driver = {
+ .name = "baikal-xgbe-cmu1",
+ .of_match_table = baikal_clk_of_match,
+ },
+};
+
+static struct platform_driver clk_ca57_cmu_driver = {
+ .probe = baikal_clk_probe,
+ .remove = baikal_clk_remove,
+ .driver = {
+ .name = "baikal-ca57_cmu",
+ .of_match_table = baikal_clk_of_match,
+ },
+};
+
+static struct platform_driver clk_mali_cmu_driver = {
+ .probe = baikal_clk_probe,
+ .remove = baikal_clk_remove,
+ .driver = {
+ .name = "baikal-mali-cmu",
+ .of_match_table = baikal_clk_of_match,
+ },
+};
+
+module_platform_driver(clk_avlsp_cmu0_driver);
+module_platform_driver(clk_avlsp_cmu1_driver);
+module_platform_driver(clk_xgbe_cmu0_driver);
+module_platform_driver(clk_xgbe_cmu1_driver);
+module_platform_driver(clk_mali_cmu_driver);
+module_platform_driver(clk_ca57_cmu_driver);
+
+MODULE_DESCRIPTION("Clkout driver for the Baikal-M");
+MODULE_AUTHOR("Ekaterina Skachko <Ekaterina.Skachko@baikalelectronics.ru>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:baikal-cmu");
--
2.31.1

View file

@ -1,44 +0,0 @@
From 7b165ef3f844bd6a7f6edb195ba03e33291f0f8d Mon Sep 17 00:00:00 2001
From: Alexey Sheplyakov <asheplyakov@altlinux.org>
Date: Thu, 8 Oct 2020 18:31:28 +0400
Subject: [PATCH 603/625] efi-rtc: avoid calling efi.get_time on Baikal-M
boards
UEFI does NOT provide get_time at the runtime, hence calling it results
in an Oops.
(cherry picked from commit 57a5898a6f7e7c80999cb844ed2f0394b38afcbe)
---
drivers/rtc/rtc-efi.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/rtc/rtc-efi.c b/drivers/rtc/rtc-efi.c
index edb64debd173..895bb07a7006 100644
--- a/drivers/rtc/rtc-efi.c
+++ b/drivers/rtc/rtc-efi.c
@@ -17,6 +17,7 @@
#include <linux/platform_device.h>
#include <linux/rtc.h>
#include <linux/efi.h>
+#include <linux/of.h>
#define EFI_ISDST (EFI_TIME_ADJUST_DAYLIGHT|EFI_TIME_IN_DAYLIGHT)
@@ -257,6 +258,14 @@ static int __init efi_rtc_probe(struct platform_device *dev)
efi_time_t eft;
efi_time_cap_t cap;
+#ifdef CONFIG_OF
+ /* efi.get_time is not always safe to call since some UEFI
+ * implementations do not privde get_time at runtime. */
+ if (of_device_is_compatible(of_root, "baikal,baikal-m")) {
+ dev_err(&dev->dev, "Baikal-M UEFI has no get_time\n");
+ return -ENODEV;
+ }
+#endif
/* First check if the RTC is usable */
if (efi.get_time(&eft, &cap) != EFI_SUCCESS)
return -ENODEV;
--
2.31.1

View file

@ -1,253 +0,0 @@
From ddbb6264ac1a4216a1b965b4ddc0d7cb31fe3d99 Mon Sep 17 00:00:00 2001
From: Alexey Sheplyakov <asheplyakov@altlinux.org>
Date: Wed, 3 Jun 2020 20:22:29 +0400
Subject: [PATCH 605/625] ethernet: stmmac: made dwmac1000_* DMA functions
available for reuse
Some variants of dwmac hardware (in particular the one in the BE-M1000
SoC) need custom DMA reset, and can reuse other dwmac1000 DMA functions.
(cherry picked from commit f8e6ec3642eb28e7b74c0a7875310d7354895c8a)
---
.../ethernet/stmicro/stmmac/dwmac1000_core.c | 1 +
.../ethernet/stmicro/stmmac/dwmac1000_dma.c | 45 +++++++++++--------
.../ethernet/stmicro/stmmac/dwmac1000_dma.h | 26 +++++++++++
.../net/ethernet/stmicro/stmmac/dwmac_lib.c | 8 ++++
4 files changed, 62 insertions(+), 18 deletions(-)
create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.h
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
index fc8759f146c7..bf4f79ef3b22 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
@@ -563,3 +563,4 @@ int dwmac1000_setup(struct stmmac_priv *priv)
return 0;
}
+EXPORT_SYMBOL_GPL(dwmac1000_setup);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
index 2bac49b49f73..d27d5292550a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
@@ -16,7 +16,7 @@
#include "dwmac1000.h"
#include "dwmac_dma.h"
-static void dwmac1000_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi)
+void dwmac1000_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi)
{
u32 value = readl(ioaddr + DMA_AXI_BUS_MODE);
int i;
@@ -69,9 +69,10 @@ static void dwmac1000_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi)
writel(value, ioaddr + DMA_AXI_BUS_MODE);
}
+EXPORT_SYMBOL_GPL(dwmac1000_dma_axi);
-static void dwmac1000_dma_init(void __iomem *ioaddr,
- struct stmmac_dma_cfg *dma_cfg, int atds)
+void dwmac1000_dma_init(void __iomem *ioaddr,
+ struct stmmac_dma_cfg *dma_cfg, int atds)
{
u32 value = readl(ioaddr + DMA_BUS_MODE);
int txpbl = dma_cfg->txpbl ?: dma_cfg->pbl;
@@ -109,22 +110,25 @@ static void dwmac1000_dma_init(void __iomem *ioaddr,
/* Mask interrupts by writing to CSR7 */
writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
}
+EXPORT_SYMBOL_GPL(dwmac1000_dma_init);
-static void dwmac1000_dma_init_rx(void __iomem *ioaddr,
- struct stmmac_dma_cfg *dma_cfg,
- dma_addr_t dma_rx_phy, u32 chan)
+void dwmac1000_dma_init_rx(void __iomem *ioaddr,
+ struct stmmac_dma_cfg *dma_cfg,
+ dma_addr_t dma_rx_phy, u32 chan)
{
/* RX descriptor base address list must be written into DMA CSR3 */
writel(lower_32_bits(dma_rx_phy), ioaddr + DMA_RCV_BASE_ADDR);
}
+EXPORT_SYMBOL_GPL(dwmac1000_dma_init_rx);
-static void dwmac1000_dma_init_tx(void __iomem *ioaddr,
- struct stmmac_dma_cfg *dma_cfg,
- dma_addr_t dma_tx_phy, u32 chan)
+void dwmac1000_dma_init_tx(void __iomem *ioaddr,
+ struct stmmac_dma_cfg *dma_cfg,
+ dma_addr_t dma_tx_phy, u32 chan)
{
/* TX descriptor base address list must be written into DMA CSR4 */
writel(lower_32_bits(dma_tx_phy), ioaddr + DMA_TX_BASE_ADDR);
}
+EXPORT_SYMBOL_GPL(dwmac1000_dma_init_tx);
static u32 dwmac1000_configure_fc(u32 csr6, int rxfifosz)
{
@@ -147,8 +151,8 @@ static u32 dwmac1000_configure_fc(u32 csr6, int rxfifosz)
return csr6;
}
-static void dwmac1000_dma_operation_mode_rx(void __iomem *ioaddr, int mode,
- u32 channel, int fifosz, u8 qmode)
+void dwmac1000_dma_operation_mode_rx(void __iomem *ioaddr, int mode,
+ u32 channel, int fifosz, u8 qmode)
{
u32 csr6 = readl(ioaddr + DMA_CONTROL);
@@ -174,9 +178,10 @@ static void dwmac1000_dma_operation_mode_rx(void __iomem *ioaddr, int mode,
writel(csr6, ioaddr + DMA_CONTROL);
}
+EXPORT_SYMBOL_GPL(dwmac1000_dma_operation_mode_rx);
-static void dwmac1000_dma_operation_mode_tx(void __iomem *ioaddr, int mode,
- u32 channel, int fifosz, u8 qmode)
+void dwmac1000_dma_operation_mode_tx(void __iomem *ioaddr, int mode,
+ u32 channel, int fifosz, u8 qmode)
{
u32 csr6 = readl(ioaddr + DMA_CONTROL);
@@ -207,8 +212,9 @@ static void dwmac1000_dma_operation_mode_tx(void __iomem *ioaddr, int mode,
writel(csr6, ioaddr + DMA_CONTROL);
}
+EXPORT_SYMBOL_GPL(dwmac1000_dma_operation_mode_tx);
-static void dwmac1000_dump_dma_regs(void __iomem *ioaddr, u32 *reg_space)
+void dwmac1000_dump_dma_regs(void __iomem *ioaddr, u32 *reg_space)
{
int i;
@@ -217,9 +223,10 @@ static void dwmac1000_dump_dma_regs(void __iomem *ioaddr, u32 *reg_space)
reg_space[DMA_BUS_MODE / 4 + i] =
readl(ioaddr + DMA_BUS_MODE + i * 4);
}
+EXPORT_SYMBOL_GPL(dwmac1000_dump_dma_regs);
-static void dwmac1000_get_hw_feature(void __iomem *ioaddr,
- struct dma_features *dma_cap)
+void dwmac1000_get_hw_feature(void __iomem *ioaddr,
+ struct dma_features *dma_cap)
{
u32 hw_cap = readl(ioaddr + DMA_HW_FEATURE);
@@ -253,12 +260,14 @@ static void dwmac1000_get_hw_feature(void __iomem *ioaddr,
/* Alternate (enhanced) DESC mode */
dma_cap->enh_desc = (hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24;
}
+EXPORT_SYMBOL_GPL(dwmac1000_get_hw_feature);
-static void dwmac1000_rx_watchdog(void __iomem *ioaddr, u32 riwt,
- u32 number_chan)
+void dwmac1000_rx_watchdog(void __iomem *ioaddr, u32 riwt,
+ u32 number_chan)
{
writel(riwt, ioaddr + DMA_RX_WATCHDOG);
}
+EXPORT_SYMBOL_GPL(dwmac1000_rx_watchdog);
const struct stmmac_dma_ops dwmac1000_dma_ops = {
.reset = dwmac_dma_reset,
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.h
new file mode 100644
index 000000000000..b1e39a109f31
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __DWMAC1000_DMA_H__
+#define __DWMAC1000_DMA_H__
+#include "dwmac1000.h"
+
+void dwmac1000_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi);
+void dwmac1000_dma_init(void __iomem *ioaddr,
+ struct stmmac_dma_cfg *dma_cfg, int atds);
+void dwmac1000_dma_init_rx(void __iomem *ioaddr,
+ struct stmmac_dma_cfg *dma_cfg,
+ dma_addr_t dma_rx_phy, u32 chan);
+void dwmac1000_dma_init_tx(void __iomem *ioaddr,
+ struct stmmac_dma_cfg *dma_cfg,
+ dma_addr_t dma_tx_phy, u32 chan);
+void dwmac1000_dma_operation_mode_rx(void __iomem *ioaddr, int mode,
+ u32 channel, int fifosz, u8 qmode);
+void dwmac1000_dma_operation_mode_tx(void __iomem *ioaddr, int mode,
+ u32 channel, int fifosz, u8 qmode);
+void dwmac1000_dump_dma_regs(void __iomem *ioaddr, u32 *reg_space);
+
+void dwmac1000_get_hw_feature(void __iomem *ioaddr,
+ struct dma_features *dma_cap);
+
+void dwmac1000_rx_watchdog(void __iomem *ioaddr, u32 riwt, u32 number_chan);
+#endif /* __DWMAC1000_DMA_H__ */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
index 57a53a600aa5..e391285a2158 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
@@ -31,6 +31,7 @@ void dwmac_enable_dma_transmission(void __iomem *ioaddr)
{
writel(1, ioaddr + DMA_XMT_POLL_DEMAND);
}
+EXPORT_SYMBOL_GPL(dwmac_enable_dma_transmission);
void dwmac_enable_dma_irq(void __iomem *ioaddr, u32 chan, bool rx, bool tx)
{
@@ -43,6 +44,7 @@ void dwmac_enable_dma_irq(void __iomem *ioaddr, u32 chan, bool rx, bool tx)
writel(value, ioaddr + DMA_INTR_ENA);
}
+EXPORT_SYMBOL_GPL(dwmac_enable_dma_irq);
void dwmac_disable_dma_irq(void __iomem *ioaddr, u32 chan, bool rx, bool tx)
{
@@ -55,6 +57,7 @@ void dwmac_disable_dma_irq(void __iomem *ioaddr, u32 chan, bool rx, bool tx)
writel(value, ioaddr + DMA_INTR_ENA);
}
+EXPORT_SYMBOL_GPL(dwmac_disable_dma_irq);
void dwmac_dma_start_tx(void __iomem *ioaddr, u32 chan)
{
@@ -62,6 +65,7 @@ void dwmac_dma_start_tx(void __iomem *ioaddr, u32 chan)
value |= DMA_CONTROL_ST;
writel(value, ioaddr + DMA_CONTROL);
}
+EXPORT_SYMBOL_GPL(dwmac_dma_start_tx);
void dwmac_dma_stop_tx(void __iomem *ioaddr, u32 chan)
{
@@ -69,6 +73,7 @@ void dwmac_dma_stop_tx(void __iomem *ioaddr, u32 chan)
value &= ~DMA_CONTROL_ST;
writel(value, ioaddr + DMA_CONTROL);
}
+EXPORT_SYMBOL_GPL(dwmac_dma_stop_tx);
void dwmac_dma_start_rx(void __iomem *ioaddr, u32 chan)
{
@@ -76,6 +81,7 @@ void dwmac_dma_start_rx(void __iomem *ioaddr, u32 chan)
value |= DMA_CONTROL_SR;
writel(value, ioaddr + DMA_CONTROL);
}
+EXPORT_SYMBOL_GPL(dwmac_dma_start_rx);
void dwmac_dma_stop_rx(void __iomem *ioaddr, u32 chan)
{
@@ -83,6 +89,7 @@ void dwmac_dma_stop_rx(void __iomem *ioaddr, u32 chan)
value &= ~DMA_CONTROL_SR;
writel(value, ioaddr + DMA_CONTROL);
}
+EXPORT_SYMBOL_GPL(dwmac_dma_stop_rx);
#ifdef DWMAC_DMA_DEBUG
static void show_tx_process_state(unsigned int status)
@@ -224,6 +231,7 @@ int dwmac_dma_interrupt(void __iomem *ioaddr,
return ret;
}
+EXPORT_SYMBOL_GPL(dwmac_dma_interrupt);
void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr)
{
--
2.31.1

View file

@ -1,508 +0,0 @@
From: Alexey Sheplyakov <asheplyakov@basealt.ru>
To: netdev@vger.kernel.org
Cc: Giuseppe Cavallaro <peppe.cavallaro@st.com>,
Alexandre Torgue <alexandre.torgue@foss.st.com>,
Jose Abreu <joabreu@synopsys.com>,
Alexey Sheplyakov <asheplyakov@basealt.ru>,
Dmitry Dunaev <dmitry.dunaev@baikalelectronics.ru>
Subject: [PATCH 1/2] net: stmmac: added Baikal-T1/M SoCs glue layer
Date: Wed, 26 Jan 2022 12:44:55 +0400 [thread overview]
Message-ID: <20220126084456.1122873-1-asheplyakov@basealt.ru> (raw)
The gigabit Ethernet controller available in Baikal-T1 and Baikal-M
SoCs is a Synopsys DesignWare MAC IP core, already supported by
the stmmac driver.
This patch implements some SoC specific operations (DMA reset and
speed fixup) necessary for Baikal-T1/M variants.
Signed-off-by: Alexey Sheplyakov <asheplyakov@basealt.ru>
Signed-off-by: Dmitry Dunaev <dmitry.dunaev@baikalelectronics.ru>
---
drivers/net/ethernet/stmicro/stmmac/Kconfig | 11 +
drivers/net/ethernet/stmicro/stmmac/Makefile | 1 +
.../ethernet/stmicro/stmmac/dwmac-baikal.c | 199 ++++++++++++++++++
.../ethernet/stmicro/stmmac/dwmac1000_core.c | 1 +
.../ethernet/stmicro/stmmac/dwmac1000_dma.c | 46 ++--
.../ethernet/stmicro/stmmac/dwmac1000_dma.h | 26 +++
.../net/ethernet/stmicro/stmmac/dwmac_lib.c | 8 +
7 files changed, 274 insertions(+), 18 deletions(-)
create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-baikal.c
create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.h
Update fo 5.10.105
diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
index 929cfc22cd0c..d8e6dcb98e6c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
@@ -65,6 +65,16 @@
Support for Adaptrum Anarion GMAC Ethernet controller.
This selects the Anarion SoC glue layer support for the stmmac driver.
+config DWMAC_BAIKAL
+ tristate "Baikal Electronics GMAC support"
+ default MIPS_BAIKAL_T1
+ depends on OF && (MIPS || ARM64 || COMPILE_TEST)
+ help
+ Support for gigabit ethernet controller on Baikal Electronics SoCs.
+
+ This selects the Baikal Electronics SoCs glue layer support for
+ the stmmac driver. This driver is used for Baikal-T1 and Baikal-M
+ SoCs gigabit ethernet controller.
config DWMAC_IPQ806X
tristate "QCA IPQ806x DWMAC support"
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
index d4e12e9ace4f..ad138062e199 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -13,6 +13,7 @@
# Ordering matters. Generic driver must be last.
obj-$(CONFIG_STMMAC_PLATFORM) += stmmac-platform.o
obj-$(CONFIG_DWMAC_ANARION) += dwmac-anarion.o
+obj-$(CONFIG_DWMAC_BAIKAL) += dwmac-baikal.o
obj-$(CONFIG_DWMAC_IPQ806X) += dwmac-ipq806x.o
obj-$(CONFIG_DWMAC_LPC18XX) += dwmac-lpc18xx.o
obj-$(CONFIG_DWMAC_MEDIATEK) += dwmac-mediatek.o
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-baikal.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-baikal.c
new file mode 100644
index 000000000000..9133188a5d1b
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-baikal.c
@@ -0,0 +1,199 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Baikal-T1/M SoCs DWMAC glue layer
+ *
+ * Copyright (C) 2015,2016,2021 Baikal Electronics JSC
+ * Copyright (C) 2020-2022 BaseALT Ltd
+ * Authors: Dmitry Dunaev <dmitry.dunaev@baikalelectronics.ru>
+ * Alexey Sheplyakov <asheplyakov@basealt.ru>
+ */
+
+#include <linux/clk.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#include "stmmac.h"
+#include "stmmac_platform.h"
+#include "common.h"
+#include "dwmac_dma.h"
+#include "dwmac1000_dma.h"
+
+#define MAC_GPIO 0x00e0 /* GPIO register */
+#define MAC_GPIO_GPO BIT(8) /* Output port */
+
+struct baikal_dwmac {
+ struct device *dev;
+ struct clk *tx2_clk;
+};
+
+static int baikal_dwmac_dma_reset(void __iomem *ioaddr)
+{
+ int err;
+ u32 value;
+
+ /* DMA SW reset */
+ value = readl(ioaddr + DMA_BUS_MODE);
+ value |= DMA_BUS_MODE_SFT_RESET;
+ writel(value, ioaddr + DMA_BUS_MODE);
+
+ usleep_range(100, 120);
+
+ /* Clear PHY reset */
+ value = readl(ioaddr + MAC_GPIO);
+ value |= MAC_GPIO_GPO;
+ writel(value, ioaddr + MAC_GPIO);
+
+ return readl_poll_timeout(ioaddr + DMA_BUS_MODE, value,
+ !(value & DMA_BUS_MODE_SFT_RESET),
+ 10000, 1000000);
+}
+
+static const struct stmmac_dma_ops baikal_dwmac_dma_ops = {
+ .reset = baikal_dwmac_dma_reset,
+ .init = dwmac1000_dma_init,
+ .init_rx_chan = dwmac1000_dma_init_rx,
+ .init_tx_chan = dwmac1000_dma_init_tx,
+ .axi = dwmac1000_dma_axi,
+ .dump_regs = dwmac1000_dump_dma_regs,
+ .dma_rx_mode = dwmac1000_dma_operation_mode_rx,
+ .dma_tx_mode = dwmac1000_dma_operation_mode_tx,
+ .enable_dma_transmission = dwmac_enable_dma_transmission,
+ .enable_dma_irq = dwmac_enable_dma_irq,
+ .disable_dma_irq = dwmac_disable_dma_irq,
+ .start_tx = dwmac_dma_start_tx,
+ .stop_tx = dwmac_dma_stop_tx,
+ .start_rx = dwmac_dma_start_rx,
+ .stop_rx = dwmac_dma_stop_rx,
+ .dma_interrupt = dwmac_dma_interrupt,
+ .get_hw_feature = dwmac1000_get_hw_feature,
+ .rx_watchdog = dwmac1000_rx_watchdog
+};
+
+static struct mac_device_info *baikal_dwmac_setup(void *ppriv)
+{
+ struct mac_device_info *mac;
+ struct stmmac_priv *priv = ppriv;
+ int ret;
+ u32 value;
+
+ mac = devm_kzalloc(priv->device, sizeof(*mac), GFP_KERNEL);
+ if (!mac)
+ return NULL;
+
+ /* Clear PHY reset */
+ value = readl(priv->ioaddr + MAC_GPIO);
+ value |= MAC_GPIO_GPO;
+ writel(value, priv->ioaddr + MAC_GPIO);
+
+ mac->dma = &baikal_dwmac_dma_ops;
+ priv->hw = mac;
+ ret = dwmac1000_setup(priv);
+ if (ret) {
+ dev_err(priv->device, "dwmac1000_setup: error %d", ret);
+ return NULL;
+ }
+
+ return mac;
+}
+
+static void baikal_dwmac_fix_mac_speed(void *priv, unsigned int speed)
+{
+ struct baikal_dwmac *dwmac = priv;
+ unsigned long tx2_clk_freq;
+
+ switch (speed) {
+ case SPEED_1000:
+ tx2_clk_freq = 250000000;
+ break;
+ case SPEED_100:
+ tx2_clk_freq = 50000000;
+ break;
+ case SPEED_10:
+ tx2_clk_freq = 5000000;
+ break;
+ default:
+ dev_warn(dwmac->dev, "invalid speed: %u\n", speed);
+ return;
+ }
+ dev_dbg(dwmac->dev, "speed %u, setting TX2 clock frequency to %lu\n",
+ speed, tx2_clk_freq);
+ clk_set_rate(dwmac->tx2_clk, tx2_clk_freq);
+}
+
+static int dwmac_baikal_probe(struct platform_device *pdev)
+{
+ struct plat_stmmacenet_data *plat_dat;
+ struct stmmac_resources stmmac_res;
+ struct baikal_dwmac *dwmac;
+ int ret;
+
+ dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
+ if (!dwmac)
+ return -ENOMEM;
+
+ ret = stmmac_get_platform_resources(pdev, &stmmac_res);
+ if (ret)
+ return ret;
+
+ ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+ if (ret) {
+ dev_err(&pdev->dev, "no suitable DMA available\n");
+ return ret;
+ }
+
+ plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
+ if (IS_ERR(plat_dat)) {
+ dev_err(&pdev->dev, "dt configuration failed\n");
+ return PTR_ERR(plat_dat);
+ }
+
+ dwmac->dev = &pdev->dev;
+ dwmac->tx2_clk = devm_clk_get_optional(dwmac->dev, "tx2_clk");
+ if (IS_ERR(dwmac->tx2_clk)) {
+ ret = PTR_ERR(dwmac->tx2_clk);
+ dev_err(&pdev->dev, "couldn't get TX2 clock: %d\n", ret);
+ goto err_remove_config_dt;
+ }
+
+ if (dwmac->tx2_clk)
+ plat_dat->fix_mac_speed = baikal_dwmac_fix_mac_speed;
+ plat_dat->bsp_priv = dwmac;
+ plat_dat->has_gmac = 1;
+ plat_dat->enh_desc = 1;
+ plat_dat->tx_coe = 1;
+ plat_dat->rx_coe = 1;
+ plat_dat->clk_csr = 3;
+ plat_dat->setup = baikal_dwmac_setup;
+
+ ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+ if (ret)
+ goto err_remove_config_dt;
+
+ return 0;
+
+err_remove_config_dt:
+ stmmac_remove_config_dt(pdev, plat_dat);
+ return ret;
+}
+
+static const struct of_device_id dwmac_baikal_match[] = {
+ { .compatible = "baikal,dwmac" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, dwmac_baikal_match);
+
+static struct platform_driver dwmac_baikal_driver = {
+ .probe = dwmac_baikal_probe,
+ .remove = stmmac_pltfr_remove,
+ .driver = {
+ .name = "baikal-dwmac",
+ .pm = &stmmac_pltfr_pm_ops,
+ .of_match_table = of_match_ptr(dwmac_baikal_match)
+ }
+};
+module_platform_driver(dwmac_baikal_driver);
+
+MODULE_DESCRIPTION("Baikal-T1/M DWMAC driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
index 76edb9b72675..7b8a955d98a9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
@@ -563,3 +563,4 @@
return 0;
}
+EXPORT_SYMBOL_GPL(dwmac1000_setup);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
index f5581db0ba9b..1782a65cc9af 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
@@ -15,8 +15,9 @@
#include <asm/io.h>
#include "dwmac1000.h"
#include "dwmac_dma.h"
+#include "dwmac1000_dma.h"
-static void dwmac1000_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi)
+void dwmac1000_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi)
{
u32 value = readl(ioaddr + DMA_AXI_BUS_MODE);
int i;
@@ -69,9 +70,10 @@
writel(value, ioaddr + DMA_AXI_BUS_MODE);
}
+EXPORT_SYMBOL_GPL(dwmac1000_dma_axi);
-static void dwmac1000_dma_init(void __iomem *ioaddr,
- struct stmmac_dma_cfg *dma_cfg, int atds)
+void dwmac1000_dma_init(void __iomem *ioaddr,
+ struct stmmac_dma_cfg *dma_cfg, int atds)
{
u32 value = readl(ioaddr + DMA_BUS_MODE);
int txpbl = dma_cfg->txpbl ?: dma_cfg->pbl;
@@ -109,22 +111,25 @@
/* Mask interrupts by writing to CSR7 */
writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
}
+EXPORT_SYMBOL_GPL(dwmac1000_dma_init);
-static void dwmac1000_dma_init_rx(void __iomem *ioaddr,
- struct stmmac_dma_cfg *dma_cfg,
- dma_addr_t dma_rx_phy, u32 chan)
+void dwmac1000_dma_init_rx(void __iomem *ioaddr,
+ struct stmmac_dma_cfg *dma_cfg,
+ dma_addr_t dma_rx_phy, u32 chan)
{
/* RX descriptor base address list must be written into DMA CSR3 */
writel(lower_32_bits(dma_rx_phy), ioaddr + DMA_RCV_BASE_ADDR);
}
+EXPORT_SYMBOL_GPL(dwmac1000_dma_init_rx);
-static void dwmac1000_dma_init_tx(void __iomem *ioaddr,
- struct stmmac_dma_cfg *dma_cfg,
- dma_addr_t dma_tx_phy, u32 chan)
+void dwmac1000_dma_init_tx(void __iomem *ioaddr,
+ struct stmmac_dma_cfg *dma_cfg,
+ dma_addr_t dma_tx_phy, u32 chan)
{
/* TX descriptor base address list must be written into DMA CSR4 */
writel(lower_32_bits(dma_tx_phy), ioaddr + DMA_TX_BASE_ADDR);
}
+EXPORT_SYMBOL_GPL(dwmac1000_dma_init_tx);
static u32 dwmac1000_configure_fc(u32 csr6, int rxfifosz)
{
@@ -147,8 +152,8 @@
return csr6;
}
-static void dwmac1000_dma_operation_mode_rx(void __iomem *ioaddr, int mode,
- u32 channel, int fifosz, u8 qmode)
+void dwmac1000_dma_operation_mode_rx(void __iomem *ioaddr, int mode,
+ u32 channel, int fifosz, u8 qmode)
{
u32 csr6 = readl(ioaddr + DMA_CONTROL);
@@ -174,9 +179,10 @@
writel(csr6, ioaddr + DMA_CONTROL);
}
+EXPORT_SYMBOL_GPL(dwmac1000_dma_operation_mode_rx);
-static void dwmac1000_dma_operation_mode_tx(void __iomem *ioaddr, int mode,
- u32 channel, int fifosz, u8 qmode)
+void dwmac1000_dma_operation_mode_tx(void __iomem *ioaddr, int mode,
+ u32 channel, int fifosz, u8 qmode)
{
u32 csr6 = readl(ioaddr + DMA_CONTROL);
@@ -207,8 +213,9 @@
writel(csr6, ioaddr + DMA_CONTROL);
}
+EXPORT_SYMBOL_GPL(dwmac1000_dma_operation_mode_tx);
-static void dwmac1000_dump_dma_regs(void __iomem *ioaddr, u32 *reg_space)
+void dwmac1000_dump_dma_regs(void __iomem *ioaddr, u32 *reg_space)
{
int i;
@@ -224,9 +224,10 @@
reg_space[DMA_BUS_MODE / 4 + i] =
readl(ioaddr + DMA_BUS_MODE + i * 4);
}
+EXPORT_SYMBOL_GPL(dwmac1000_dump_dma_regs);
-static int dwmac1000_get_hw_feature(void __iomem *ioaddr,
- struct dma_features *dma_cap)
+int dwmac1000_get_hw_feature(void __iomem *ioaddr,
+ struct dma_features *dma_cap)
{
u32 hw_cap = readl(ioaddr + DMA_HW_FEATURE);
@@ -269,12 +270,14 @@
return 0;
}
+EXPORT_SYMBOL_GPL(dwmac1000_get_hw_feature);
-static void dwmac1000_rx_watchdog(void __iomem *ioaddr, u32 riwt,
- u32 number_chan)
+void dwmac1000_rx_watchdog(void __iomem *ioaddr, u32 riwt,
+ u32 queue)
{
writel(riwt, ioaddr + DMA_RX_WATCHDOG);
}
+EXPORT_SYMBOL_GPL(dwmac1000_rx_watchdog);
const struct stmmac_dma_ops dwmac1000_dma_ops = {
.reset = dwmac_dma_reset,
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.h
new file mode 100644
index 000000000000..b254a0734447
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __DWMAC1000_DMA_H__
+#define __DWMAC1000_DMA_H__
+#include "dwmac1000.h"
+
+void dwmac1000_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi);
+void dwmac1000_dma_init(void __iomem *ioaddr,
+ struct stmmac_dma_cfg *dma_cfg, int atds);
+void dwmac1000_dma_init_rx(void __iomem *ioaddr,
+ struct stmmac_dma_cfg *dma_cfg,
+ dma_addr_t dma_rx_phy, u32 chan);
+void dwmac1000_dma_init_tx(void __iomem *ioaddr,
+ struct stmmac_dma_cfg *dma_cfg,
+ dma_addr_t dma_tx_phy, u32 chan);
+void dwmac1000_dma_operation_mode_rx(void __iomem *ioaddr, int mode,
+ u32 channel, int fifosz, u8 qmode);
+void dwmac1000_dma_operation_mode_tx(void __iomem *ioaddr, int mode,
+ u32 channel, int fifosz, u8 qmode);
+void dwmac1000_dump_dma_regs(void __iomem *ioaddr, u32 *reg_space);
+
+int dwmac1000_get_hw_feature(void __iomem *ioaddr,
+ struct dma_features *dma_cap);
+
+void dwmac1000_rx_watchdog(void __iomem *ioaddr, u32 riwt, u32 number_chan);
+#endif /* __DWMAC1000_DMA_H__ */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
index caa4bfc4c1d6..2d8d1b0e2b98 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
@@ -31,6 +31,7 @@
{
writel(1, ioaddr + DMA_XMT_POLL_DEMAND);
}
+EXPORT_SYMBOL_GPL(dwmac_enable_dma_transmission);
void dwmac_enable_dma_irq(void __iomem *ioaddr, u32 chan, bool rx, bool tx)
{
@@ -43,6 +44,7 @@
writel(value, ioaddr + DMA_INTR_ENA);
}
+EXPORT_SYMBOL_GPL(dwmac_enable_dma_irq);
void dwmac_disable_dma_irq(void __iomem *ioaddr, u32 chan, bool rx, bool tx)
{
@@ -55,6 +57,7 @@
writel(value, ioaddr + DMA_INTR_ENA);
}
+EXPORT_SYMBOL_GPL(dwmac_disable_dma_irq);
void dwmac_dma_start_tx(void __iomem *ioaddr, u32 chan)
{
@@ -62,6 +65,7 @@
value |= DMA_CONTROL_ST;
writel(value, ioaddr + DMA_CONTROL);
}
+EXPORT_SYMBOL_GPL(dwmac_dma_start_tx);
void dwmac_dma_stop_tx(void __iomem *ioaddr, u32 chan)
{
@@ -69,6 +73,7 @@
value &= ~DMA_CONTROL_ST;
writel(value, ioaddr + DMA_CONTROL);
}
+EXPORT_SYMBOL_GPL(dwmac_dma_stop_tx);
void dwmac_dma_start_rx(void __iomem *ioaddr, u32 chan)
{
@@ -76,6 +81,7 @@
value |= DMA_CONTROL_SR;
writel(value, ioaddr + DMA_CONTROL);
}
+EXPORT_SYMBOL_GPL(dwmac_dma_start_rx);
void dwmac_dma_stop_rx(void __iomem *ioaddr, u32 chan)
{
@@ -83,6 +89,7 @@
value &= ~DMA_CONTROL_SR;
writel(value, ioaddr + DMA_CONTROL);
}
+EXPORT_SYMBOL_GPL(dwmac_dma_stop_rx);
#ifdef DWMAC_DMA_DEBUG
static void show_tx_process_state(unsigned int status)
@@ -224,6 +231,7 @@
return ret;
}
+EXPORT_SYMBOL_GPL(dwmac_dma_interrupt);
void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr)
{
--
2.32.0

View file

@ -1,137 +0,0 @@
From f2c459c92298deb7054414bd857fe26723be5dab Mon Sep 17 00:00:00 2001
From: Alexey Sheplyakov <asheplyakov@altlinux.org>
Date: Tue, 10 Nov 2020 19:05:39 +0400
Subject: [PATCH 607/631] Fixed secondary CPUs boot on BE-M1000 SoC
The secure world on BE-M1000 SoC denies execution attempts outside of
the ranges [0x80000000, 0x8FFFFFFF] [0xA0000000, 0xBFFFFFFF]. Thus
PSCI calls to boot secondary CPUs fail unless the kernel image resides
in one of these (physical) address ranges. However BE-M1000's UEFI
PE/COFF loader puts the kernel into the forbidden range. Since the alignment
is good enough EFI stub does not try to relocate the kernel. As a result
secondary CPUs fail to boot.
Relocation to a random address is not going to work either. Therefore
automatically disable kaslr on "known bad" systems (for now only BE-M1000
ones) and forcibly relocate the kernel to a low(er) address.
---
drivers/firmware/efi/libstub/arm64-stub.c | 61 ++++++++++++++++++++++-
1 file changed, 60 insertions(+), 1 deletion(-)
diff --git a/drivers/firmware/efi/libstub/arm64-stub.c b/drivers/firmware/efi/libstub/arm64-stub.c
index c1b57dfb1277..411f1546d171 100644
--- a/drivers/firmware/efi/libstub/arm64-stub.c
+++ b/drivers/firmware/efi/libstub/arm64-stub.c
@@ -11,6 +11,7 @@
#include <asm/efi.h>
#include <asm/memory.h>
#include <asm/sections.h>
+#include <linux/libfdt.h>
#include <asm/sysreg.h>
#include "efistub.h"
@@ -34,6 +35,31 @@ efi_status_t check_platform_features(void)
return EFI_SUCCESS;
}
+static const char* machines_need_low_alloc[] = {
+ "baikal,baikal-m",
+};
+
+static bool need_low_alloc(void) {
+ size_t i;
+ const void *fdt;
+ const char *match;
+
+ fdt = get_efi_config_table(DEVICE_TREE_GUID);
+ if (!fdt) {
+ efi_info("failed to retrive FDT from EFI\n");
+ return false;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(machines_need_low_alloc); i++) {
+ match = machines_need_low_alloc[i];
+ if (fdt_node_check_compatible(fdt, 0, match) == 0) {
+ efi_info("machine %s: forcing kernel relocation to low address\n", match);
+ return true;
+ }
+ }
+ return false;
+}
+
/*
* Distro versions of GRUB may ignore the BSS allocation entirely (i.e., fail
* to provide space, and fail to zero it). Check for this condition by double
@@ -79,6 +105,19 @@ static bool check_image_region(u64 base, u64 size)
return ret;
}
+static inline efi_status_t efi_low_alloc(unsigned long size, unsigned long align,
+ unsigned long *addr)
+{
+ /*
+ * Don't allocate at 0x0. It will confuse code that
+ * checks pointers against NULL. Skip the first 8
+ * bytes so we start at a nice even number.
+ */
+ return efi_low_alloc_above(size, align, addr, 0x8);
+}
+
+
+
efi_status_t handle_kernel_image(unsigned long *image_addr,
unsigned long *image_size,
unsigned long *reserve_addr,
@@ -88,6 +127,13 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
efi_status_t status;
unsigned long kernel_size, kernel_memsize = 0;
u32 phys_seed = 0;
+ bool force_low_reloc = need_low_alloc();
+ if (force_low_reloc) {
+ if (!efi_nokaslr) {
+ efi_info("booting on a broken firmware, KASLR will be disabled\n");
+ efi_nokaslr = true;
+ }
+ }
/*
* Although relocatable kernels can fix up the misalignment with
@@ -112,7 +158,8 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
efi_nokaslr = true;
}
} else {
- efi_info("KASLR disabled on kernel command line\n");
+ if (!force_low_reloc)
+ efi_info("KASLR disabled on kernel command line\n");
}
}
@@ -138,6 +185,15 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
status = EFI_OUT_OF_RESOURCES;
}
+ if (force_low_reloc) {
+ status = efi_low_alloc(*reserve_size,
+ min_kimg_align(),
+ reserve_addr);
+ if (status != EFI_SUCCESS) {
+ efi_err("Failed to relocate kernel, expect secondary CPUs boot failure\n");
+ }
+ }
+
if (status != EFI_SUCCESS) {
if (!check_image_region((u64)_text, kernel_memsize)) {
efi_err("FIRMWARE BUG: Image BSS overlaps adjacent EFI memory region\n");
@@ -162,6 +218,9 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
}
*image_addr = *reserve_addr;
+ if (efi_nokaslr) {
+ efi_info("relocating kernel to 0x%lx\n", *image_addr);
+ }
memcpy((void *)*image_addr, _text, kernel_size);
return EFI_SUCCESS;
--
2.31.1

View file

@ -1,22 +1,12 @@
From 91e33969c0864de65db59308b298d321a5280daa Mon Sep 17 00:00:00 2001
From: Alexey Sheplyakov <asheplyakov@altlinux.org>
Date: Fri, 20 Mar 2020 14:02:43 +0400
Subject: [PATCH 608/625] Baikal-M: USB driver Subject: [PATCH 608/625] Baikal-M: USB driver
(cherry picked from commit 136cab54114b2b0b61cf503065d6d547f3d3d5a2) Update for 5.15.105
---
drivers/usb/dwc3/Kconfig | 9 +++
drivers/usb/dwc3/Makefile | 1 +
drivers/usb/dwc3/dwc3-baikal.c | 126 +++++++++++++++++++++++++++++++++
3 files changed, 136 insertions(+)
create mode 100644 drivers/usb/dwc3/dwc3-baikal.c
diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
index 7a2304565a73..121f8e708d51 100644
--- a/drivers/usb/dwc3/Kconfig --- a/drivers/usb/dwc3/Kconfig
+++ b/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig
@@ -139,4 +139,13 @@ config USB_DWC3_QCOM @@ -158,4 +158,13 @@
for peripheral mode support. This driver handles both ZynqMP and Versal SoC operations.
Say 'Y' or 'M' if you have one such device. Say 'Y' or 'M' if you have one such device.
+config USB_DWC3_BAIKAL +config USB_DWC3_BAIKAL
@ -30,13 +20,12 @@ index 7a2304565a73..121f8e708d51 100644
+ +
endif endif
diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
index ae86da0dc5bd..0dcaf92a43ec 100644
--- a/drivers/usb/dwc3/Makefile --- a/drivers/usb/dwc3/Makefile
+++ b/drivers/usb/dwc3/Makefile +++ b/drivers/usb/dwc3/Makefile
@@ -51,3 +51,4 @@ obj-$(CONFIG_USB_DWC3_MESON_G12A) += dwc3-meson-g12a.o @@ -53,3 +53,4 @@
obj-$(CONFIG_USB_DWC3_OF_SIMPLE) += dwc3-of-simple.o
obj-$(CONFIG_USB_DWC3_ST) += dwc3-st.o
obj-$(CONFIG_USB_DWC3_QCOM) += dwc3-qcom.o obj-$(CONFIG_USB_DWC3_QCOM) += dwc3-qcom.o
obj-$(CONFIG_USB_DWC3_IMX8MP) += dwc3-imx8mp.o
obj-$(CONFIG_USB_DWC3_XILINX) += dwc3-xilinx.o
+obj-$(CONFIG_USB_DWC3_BAIKAL) += dwc3-baikal.o +obj-$(CONFIG_USB_DWC3_BAIKAL) += dwc3-baikal.o
diff --git a/drivers/usb/dwc3/dwc3-baikal.c b/drivers/usb/dwc3/dwc3-baikal.c diff --git a/drivers/usb/dwc3/dwc3-baikal.c b/drivers/usb/dwc3/dwc3-baikal.c
new file mode 100644 new file mode 100644
@ -170,6 +159,3 @@ index 000000000000..2426dc49bd79
+MODULE_AUTHOR("Dmitry Dunaev <dmitry.dunaev@baikalelectronics.ru>"); +MODULE_AUTHOR("Dmitry Dunaev <dmitry.dunaev@baikalelectronics.ru>");
+MODULE_LICENSE("GPL v2"); +MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("DesignWare USB3 Baikal SoCs Glue Layer"); +MODULE_DESCRIPTION("DesignWare USB3 Baikal SoCs Glue Layer");
--
2.31.1

File diff suppressed because it is too large Load diff

View file

@ -1,810 +0,0 @@
From 11c1cbda8ed87683a6a058e1991e1bb5f8379d04 Mon Sep 17 00:00:00 2001
From: Alexey Sheplyakov <asheplyakov@altlinux.org>
Date: Tue, 9 Jun 2020 10:37:23 +0400
Subject: [PATCH 610/625] Added Baikal-T1/M BMC driver
The BMC device is responsible for CPU kick-starting, controlling
power button, and a full board poweroff.
(cherry picked from commit 53d167c426d92ca9df319924a107e8cd62cd96b1)
---
drivers/misc/Kconfig | 18 +
drivers/misc/Makefile | 1 +
drivers/misc/tp_bmc.c | 747 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 766 insertions(+)
create mode 100644 drivers/misc/tp_bmc.c
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index fafa8b0d8099..00368637ede0 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -466,6 +466,24 @@ config HISI_HIKEY_USB
switching between the dual-role USB-C port and the USB-A host ports
using only one USB controller.
+config TP_BMC
+ tristate "T-platforms Baikal-T(1)/M BMC"
+ depends on I2C && SYSFS
+ depends on OF
+ select PINCTRL
+ select GENERIC_PINCONF
+ select SERIO
+ default y if ARCH_BAIKAL
+ help
+ Say Y here if you want to build a driver for T-platforms BMC devices
+ embedded into the boards with Baikal-T(1)/M processors. The device main
+ purpose is the CPU kick-starting as well as some additional side-way
+ functionality like power on/off buttons state tracing and full device
+ powering off.
+
+ If you choose to build module, its name will be tp-bmc. If unsure,
+ say N here.
+
source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index d23231e73330..f60e5079a6fb 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -57,3 +57,4 @@ obj-$(CONFIG_HABANA_AI) += habanalabs/
obj-$(CONFIG_UACCE) += uacce/
obj-$(CONFIG_XILINX_SDFEC) += xilinx_sdfec.o
obj-$(CONFIG_HISI_HIKEY_USB) += hisi_hikey_usb.o
+obj-$(CONFIG_TP_BMC) += tp_bmc.o
diff --git a/drivers/misc/tp_bmc.c b/drivers/misc/tp_bmc.c
new file mode 100644
index 000000000000..0b320d3ffae4
--- /dev/null
+++ b/drivers/misc/tp_bmc.c
@@ -0,0 +1,747 @@
+#include <linux/i2c.h>
+#include <linux/bcd.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/input.h>
+#include <linux/regmap.h>
+#include <linux/delay.h>
+#include <linux/kthread.h>
+#include <linux/pm.h>
+#include <linux/rtc.h>
+#include <linux/serio.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+
+enum I2C_REGS {
+ R_ID1 = 0,
+ R_ID2,
+ R_ID3,
+ R_ID4,
+ R_SOFTOFF_RQ,
+ R_PWROFF_RQ,
+ R_PWRBTN_STATE,
+ R_VERSION1,
+ R_VERSION2,
+ R_BOOTREASON,
+ R_BOOTREASON_ARG,
+ R_SCRATCH1,
+ R_SCRATCH2,
+ R_SCRATCH3,
+ R_SCRATCH4,
+ R_CAP,
+ R_GPIODIR0,
+ R_GPIODIR1,
+ R_GPIODIR2,
+ R_COUNT
+};
+
+#define BMC_ID1_VAL 0x49
+#define BMC_ID2_VAL 0x54
+#define BMC_ID3_VAL 0x58
+#define BMC_ID4_VAL0 0x32
+#define BMC_ID4_VAL1 0x2
+
+#define BMC_VERSION1 0
+#define BMC_VERSION2 2
+#define BMC_VERSION2_3 3
+
+#define BMC_CAP_PWRBTN 0x1
+#define BMC_CAP_TOUCHPAD 0x2
+#define BMC_CAP_RTC 0x4
+#define BMC_CAP_FRU 0x8
+#define BMC_CAP_GPIODIR 0x10
+
+#define BMC_SERIO_BUFSIZE 7
+
+#define POLL_JIFFIES 100
+
+struct bmc_poll_data {
+ struct i2c_client *c;
+};
+
+static struct i2c_client *bmc_i2c;
+static struct i2c_client *rtc_i2c;
+static struct i2c_driver mitx2_bmc_i2c_driver;
+static struct input_dev *button_dev;
+static struct bmc_poll_data poll_data;
+static struct task_struct *polling_task;
+#ifdef CONFIG_SERIO
+static struct i2c_client *serio_i2c;
+static struct task_struct *touchpad_task;
+#endif
+static u8 bmc_proto_version[3];
+static u8 bmc_bootreason[2];
+static u8 bmc_scratch[4];
+static int bmc_cap;
+static const char input_name[] = "BMC input dev";
+static u8 prev_ret;
+
+/* BMC RTC */
+static int
+bmc_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ uint8_t rtc_buf[8];
+ struct i2c_msg msg;
+ int t;
+ int rc;
+
+ msg.addr = client->addr;
+ msg.flags = I2C_M_RD;
+ msg.len = 8;
+ msg.buf = rtc_buf;
+ rc = i2c_transfer(client->adapter, &msg, 1);
+ if (rc != 1) {
+ dev_err(dev, "rtc_read_time: i2c_transfer error %d\n", rc);
+ return rc;
+ }
+
+ tm->tm_sec = bcd2bin(rtc_buf[0] & 0x7f);
+ tm->tm_min = bcd2bin(rtc_buf[1] & 0x7f);
+ tm->tm_hour = bcd2bin(rtc_buf[2] & 0x3f);
+ if (rtc_buf[3] & (1 << 6)) /* PM */
+ tm->tm_hour += 12;
+ tm->tm_mday = bcd2bin(rtc_buf[4] & 0x3f);
+ tm->tm_mon = bcd2bin(rtc_buf[5] & 0x1f);
+ t = rtc_buf[5] >> 5;
+ tm->tm_wday = (t == 7) ? 0 : t;
+ tm->tm_year = bcd2bin(rtc_buf[6]) + 100; /* year since 1900 */
+ tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year);
+ tm->tm_isdst = 0;
+
+ return rtc_valid_tm(tm);
+}
+
+static int
+bmc_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ uint8_t rtc_buf[8];
+ struct i2c_msg msg;
+ int rc;
+ uint8_t seconds, minutes, hours, wday, mday, month, years;
+
+ seconds = bin2bcd(tm->tm_sec);
+ minutes = bin2bcd(tm->tm_min);
+ hours = bin2bcd(tm->tm_hour);
+ wday = tm->tm_wday ? tm->tm_wday : 0x7;
+ mday = bin2bcd(tm->tm_mday);
+ month = bin2bcd(tm->tm_mon);
+ years = bin2bcd(tm->tm_year % 100);
+
+ /* Need sanity check??? */
+ rtc_buf[0] = seconds;
+ rtc_buf[1] = minutes;
+ rtc_buf[2] = hours;
+ rtc_buf[3] = 0;
+ rtc_buf[4] = mday;
+ rtc_buf[5] = month | (wday << 5);
+ rtc_buf[6] = years;
+ rtc_buf[7] = 0;
+
+ msg.addr = client->addr;
+ msg.flags = 0;
+ msg.len = 8;
+ msg.buf = rtc_buf;
+ dev_dbg(dev, "rtc_set_time: %08x-%08x\n", *(uint32_t *)&rtc_buf[0],
+ *(uint32_t *)&rtc_buf[4]);
+ rc = i2c_transfer(client->adapter, &msg, 1);
+ if (rc != 1)
+ dev_err(dev, "i2c write: %d\n", rc);
+
+ return (rc == 1) ? 0 : -EIO;
+}
+
+static const struct rtc_class_ops
+bmc_rtc_ops = {
+ .read_time = bmc_rtc_read_time,
+ .set_time = bmc_rtc_set_time,
+};
+
+#ifdef CONFIG_SERIO
+/* BMC serio (PS/2 touchpad) interface */
+
+static int bmc_serio_write(struct serio *id, unsigned char val)
+{
+ struct i2c_client *client = id->port_data;
+ uint8_t buf[4];
+ struct i2c_msg msg;
+ int rc;
+
+ buf[0] = val;
+ msg.addr = client->addr;
+ msg.flags = 0;
+ msg.len = 1;
+ msg.buf = buf;
+ dev_dbg(&client->dev, "bmc_serio_write: %02x\n", val);
+ rc = i2c_transfer(client->adapter, &msg, 1);
+ if (rc != 1)
+ dev_err(&client->dev, "i2c write: %d\n", rc);
+
+ return (rc == 1) ? 0 : -EIO;
+}
+
+/* returns: -1 on error, +1 if more data available, 0 otherwise */
+static int bmc_serio_read(struct i2c_client *client)
+{
+ struct serio *serio = dev_get_drvdata(&client->dev);
+ int i, rc, cnt;
+ uint8_t buf[BMC_SERIO_BUFSIZE];
+ struct i2c_msg msg;
+
+ msg.addr = client->addr;
+ msg.flags = I2C_M_RD;
+ msg.len = BMC_SERIO_BUFSIZE;
+ msg.buf = buf;
+ rc = i2c_transfer(client->adapter, &msg, 1);
+ if (rc != 1) {
+ dev_err(&client->dev, "bmc_serio_read: i2c_transfer error %d\n", rc);
+ return -1;
+ }
+
+ cnt = buf[0];
+ rc = 0;
+ if (cnt > BMC_SERIO_BUFSIZE - 1) {
+ cnt = BMC_SERIO_BUFSIZE - 1;
+ rc = 1;
+ }
+
+ for (i = 0; i < cnt; i++) {
+ serio_interrupt(serio, buf[i + 1], 0);
+ }
+
+ return 0;
+}
+
+int
+touchpad_poll_fn(void *data) {
+ int ret;
+
+ while (1) {
+ if (kthread_should_stop())
+ break;
+ while ((ret = bmc_serio_read(serio_i2c)) > 0)
+ ;
+ if (ret < 0) {
+ msleep_interruptible(10000);
+ }
+ msleep_interruptible(10);
+ }
+ return 0;
+}
+#endif /* CONFIG_SERIO */
+
+#ifdef CONFIG_PINCTRL
+static uint8_t bmc_pincf_state [3];
+#define BMC_NPINS (sizeof(bmc_pincf_state) * 8)
+
+static struct pinctrl_pin_desc bmc_pin_desc[BMC_NPINS] = {
+ PINCTRL_PIN(0, "P0"),
+ PINCTRL_PIN(1, "P1"),
+ PINCTRL_PIN(2, "P2"),
+ PINCTRL_PIN(3, "P3"),
+ PINCTRL_PIN(4, "P4"),
+ PINCTRL_PIN(5, "P5"),
+ PINCTRL_PIN(6, "P6"),
+ PINCTRL_PIN(7, "P7"),
+ PINCTRL_PIN(8, "P8"),
+ PINCTRL_PIN(9, "P9"),
+ PINCTRL_PIN(10, "P10"),
+ PINCTRL_PIN(11, "P11"),
+ PINCTRL_PIN(12, "P12"),
+ PINCTRL_PIN(13, "P13"),
+ PINCTRL_PIN(14, "P14"),
+ PINCTRL_PIN(15, "P15"),
+ PINCTRL_PIN(16, "P16"),
+ PINCTRL_PIN(17, "P17"),
+ PINCTRL_PIN(18, "P18"),
+ PINCTRL_PIN(19, "P19"),
+ PINCTRL_PIN(20, "P20"),
+ PINCTRL_PIN(21, "P21"),
+ PINCTRL_PIN(22, "P22"),
+ PINCTRL_PIN(23, "P23"),
+};
+
+#define PCTRL_DEV "bmc_pinctrl"
+
+static int bmc_pin_config_get(struct pinctrl_dev *pctldev,
+ unsigned pin,
+ unsigned long *config)
+{
+ int idx, bit;
+
+ if (pin > BMC_NPINS)
+ return -EINVAL;
+
+ idx = pin >> 3;
+ bit = pin & 7;
+
+ *config = !!(bmc_pincf_state[idx] & (1 << bit));
+ return 0;
+}
+
+static int bmc_pin_config_set(struct pinctrl_dev *pctldev,
+ unsigned pin,
+ unsigned long *config,
+ unsigned nc)
+{
+ int idx, bit;
+ enum pin_config_param param;
+ int arg;
+
+ if (pin > BMC_NPINS)
+ return -EINVAL;
+
+ idx = pin >> 3;
+ bit = pin & 7;
+
+ param = pinconf_to_config_param (*config);
+ arg = pinconf_to_config_argument (*config);
+ if (param != PIN_CONFIG_OUTPUT)
+ return -EINVAL;
+
+ if (arg)
+ bmc_pincf_state[idx] |= (1 << bit);
+ else
+ bmc_pincf_state[idx] &= ~(1 << bit);
+dev_dbg(&bmc_i2c->dev, "bmc_pin_config_set: pin %u, dir %lu\n", pin, *config);
+
+ return i2c_smbus_write_byte_data(bmc_i2c, R_GPIODIR0 + idx, bmc_pincf_state[idx]);
+}
+
+void pinconf_generic_dump_config(struct pinctrl_dev *pctldev,
+ struct seq_file *s, unsigned long config);
+
+void pinctrl_utils_free_map(struct pinctrl_dev *pctldev,
+ struct pinctrl_map *map, unsigned num_maps);
+
+static const struct pinconf_ops bmc_confops = {
+ .pin_config_get = bmc_pin_config_get,
+ .pin_config_set = bmc_pin_config_set,
+ .pin_config_config_dbg_show = pinconf_generic_dump_config,
+};
+
+static int bmc_groups_count(struct pinctrl_dev *pctldev)
+{
+ return 0;
+}
+
+static const char *bmc_group_name(struct pinctrl_dev *pctldev,
+ unsigned selector)
+{
+ return NULL;
+}
+
+static const struct pinctrl_ops bmc_ctrl_ops = {
+ .get_groups_count = bmc_groups_count,
+ .get_group_name = bmc_group_name,
+ .dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
+ .dt_free_map = pinctrl_utils_free_map,
+};
+
+static struct pinctrl_desc bmc_pincrtl_desc = {
+ .name = PCTRL_DEV,
+ .pins = bmc_pin_desc,
+ .pctlops = &bmc_ctrl_ops,
+ .npins = BMC_NPINS,
+ .confops = &bmc_confops,
+};
+
+static struct pinctrl_dev *bmc_pinctrl_dev;
+
+static int bmc_pinctrl_register(struct device *dev)
+{
+ struct pinctrl_dev *pctrl_dev;
+ struct platform_device *pbdev;
+
+ pbdev = platform_device_alloc(PCTRL_DEV, -1);
+ pbdev->dev.parent = dev;
+ pbdev->dev.of_node = of_find_node_by_name(dev->of_node, "bmc_pinctrl");
+ platform_device_add(pbdev);
+ pctrl_dev = devm_pinctrl_register(&pbdev->dev, &bmc_pincrtl_desc, NULL);
+ if (IS_ERR(pctrl_dev)) {
+ dev_err(&pbdev->dev, "Can't register pinctrl (%ld)\n", PTR_ERR(pctrl_dev));
+ return PTR_ERR(pctrl_dev);
+ } else {
+ dev_info(&pbdev->dev, "BMC pinctrl registered\n");
+ bmc_pinctrl_dev = pctrl_dev;
+ }
+ /* reset all pins to default state */
+ i2c_smbus_write_byte_data(to_i2c_client(dev), R_GPIODIR0, 0);
+ i2c_smbus_write_byte_data(to_i2c_client(dev), R_GPIODIR1, 0);
+ i2c_smbus_write_byte_data(to_i2c_client(dev), R_GPIODIR2, 0);
+ return 0;
+}
+
+static void bmc_pinctrl_unregister(void)
+{
+ if (bmc_pinctrl_dev)
+ devm_pinctrl_unregister(&bmc_i2c->dev, bmc_pinctrl_dev);
+}
+
+#endif
+
+void
+bmc_pwroff_rq(void) {
+ int ret = 0;
+
+ dev_info(&bmc_i2c->dev, "Write reg R_PWROFF_RQ\n");
+ ret = i2c_smbus_write_byte_data(bmc_i2c, R_PWROFF_RQ, 0x01);
+ dev_info(&bmc_i2c->dev, "ret: %i\n", ret);
+}
+
+int
+pwroff_rq_poll_fn(void *data) {
+ int ret;
+
+ while (1) {
+ if (kthread_should_stop())
+ break;
+ dev_dbg(&poll_data.c->dev, "Polling\n");
+ ret = i2c_smbus_read_byte_data(poll_data.c, R_SOFTOFF_RQ);
+ dev_dbg(&poll_data.c->dev, "Polling returned: %i\n", ret);
+ if (prev_ret != ret) {
+ dev_info(&poll_data.c->dev, "key change [%i]\n", ret);
+ if (ret < 0) {
+ dev_err(&poll_data.c->dev,
+ "Could not read register %x\n",
+ R_SOFTOFF_RQ);
+ return -EIO;
+ } else if (ret != 0) {
+ dev_info(&poll_data.c->dev,
+ "PWROFF \"irq\" detected [%i]\n", ret);
+ input_event(button_dev, EV_KEY, KEY_POWER, 1);
+ } else {
+ input_event(button_dev, EV_KEY, KEY_POWER, 0);
+ }
+ input_sync(button_dev);
+ }
+ prev_ret = ret;
+
+ msleep_interruptible(100);
+ }
+ do_exit(1);
+ return 0;
+}
+
+static int
+mitx2_bmc_validate(struct i2c_client *client) {
+ int ret = 0;
+ int i = 0;
+ static const u8 regs[] = {R_ID1, R_ID2, R_ID3};
+ static const u8 vals[] = {BMC_ID1_VAL, BMC_ID2_VAL, BMC_ID3_VAL};
+
+ bmc_proto_version[0] = 0;
+ bmc_proto_version[1] = 0;
+ bmc_proto_version[2] = 0;
+
+ for (i = 0; i < ARRAY_SIZE(regs); i++) {
+ ret = i2c_smbus_read_byte_data(client, regs[i]);
+ if (ret < 0) {
+ dev_err(&client->dev, "Could not read register %x\n",
+ regs[i]);
+ return -EIO;
+ }
+ if (ret != vals[i]) {
+ dev_err(&client->dev,
+ "Bad value [0x%02x] in register 0x%02x, should be [0x%02x]\n",
+ ret, regs[i], vals[i]);
+
+ return -ENODEV;
+ }
+ }
+ ret = i2c_smbus_read_byte_data(client, R_ID4);
+ if (ret < 0) {
+ dev_err(&client->dev, "Could not read register %x\n", R_ID4);
+ return -EIO;
+ }
+ if (ret == BMC_ID4_VAL0) {
+ bmc_proto_version[0] = 0;
+ } else if (ret == BMC_ID4_VAL1) {
+ bmc_proto_version[0] = 2;
+ ret = i2c_smbus_read_byte_data(client, R_VERSION1);
+ if (ret < 0) {
+ dev_err(&client->dev, "Could not read register %x\n",
+ R_VERSION1);
+ return -EIO;
+ }
+ bmc_proto_version[1] = ret;
+ ret = i2c_smbus_read_byte_data(client, R_VERSION2);
+ if (ret < 0) {
+ dev_err(&client->dev, "Could not read register %x\n",
+ R_VERSION2);
+ return -EIO;
+ }
+ bmc_proto_version[2] = ret;
+ ret = i2c_smbus_read_byte_data(client, R_BOOTREASON);
+ if (ret < 0) {
+ dev_err(&client->dev, "Could not read register %x\n",
+ R_BOOTREASON);
+ return -EIO;
+ }
+ bmc_bootreason[0] = ret;
+ dev_info(&client->dev, "BMC bootreason[0]->%i\n", ret);
+ ret = i2c_smbus_read_byte_data(client, R_BOOTREASON_ARG);
+ if (ret < 0) {
+ dev_err(&client->dev, "Could not read register %x\n",
+ R_BOOTREASON_ARG);
+ return -EIO;
+ }
+ bmc_bootreason[1] = ret;
+ dev_info(&client->dev, "BMC bootreason[1]->%i\n", ret);
+ for (i = R_SCRATCH1; i <= R_SCRATCH4; i++) {
+ ret = i2c_smbus_read_byte_data(client, i);
+ if (ret < 0) {
+ dev_err(&client->dev,
+ "Could not read register %x\n", i);
+ return -EIO;
+ }
+ bmc_scratch[i - R_SCRATCH1] = ret;
+ }
+ if (bmc_proto_version[2] >= BMC_VERSION2_3) {
+ ret = i2c_smbus_read_byte_data(client, R_CAP);
+ if (ret >= 0)
+ bmc_cap = ret;
+ dev_info(&client->dev,
+ "BMC extended capabilities %x\n", bmc_cap);
+ } else {
+ bmc_cap = BMC_CAP_PWRBTN;
+ }
+ } else {
+ dev_err(&client->dev, "Bad value [0x%02x] in register 0x%02x\n",
+ ret, R_ID4);
+ return -ENODEV;
+ }
+ dev_info(&client->dev, "BMC seems to be valid\n");
+ return 0;
+}
+
+static int
+bmc_create_client_devices(struct device *bmc_dev)
+{
+ int ret = 0;
+ struct rtc_device *rtc_dev;
+ struct i2c_client *client = to_i2c_client(bmc_dev);
+ int client_addr = client->addr + 1;
+
+ if (bmc_cap & BMC_CAP_TOUCHPAD) {
+#ifdef CONFIG_SERIO
+ struct serio *serio;
+ serio_i2c = i2c_new_ancillary_device(client,
+ "bmc_serio", client_addr);
+ if (IS_ERR(serio_i2c)) {
+ dev_err(&client->dev, "Can't get serio secondary\n");
+ serio_i2c = NULL;
+ ret = -ENOMEM;
+ goto fail;
+ }
+ serio = devm_kzalloc(&serio_i2c->dev, sizeof(struct serio), GFP_KERNEL);
+ if (!serio) {
+ dev_err(&serio_i2c->dev, "Can't allocate serio\n");
+ ret = -ENOMEM;
+ i2c_unregister_device(serio_i2c);
+ serio_i2c = NULL;
+ goto skip_tp;
+ }
+ serio->write = bmc_serio_write;
+ serio->port_data = serio_i2c;
+ serio->id.type = SERIO_PS_PSTHRU;
+ serio_register_port(serio);
+ dev_set_drvdata(&serio_i2c->dev, serio);
+ touchpad_task = kthread_run(touchpad_poll_fn, NULL, "BMC serio poll task");
+
+skip_tp:
+#endif
+ client_addr++;
+ }
+
+ if (bmc_cap & BMC_CAP_RTC) {
+ rtc_i2c = i2c_new_ancillary_device(client,
+ "bmc_rtc", client_addr);
+ if (IS_ERR(rtc_i2c)) {
+ dev_err(&client->dev, "Can't get RTC secondary\n");
+ rtc_i2c = NULL;
+ ret = -ENOMEM;
+ goto fail;
+ }
+
+ rtc_dev = devm_rtc_device_register(&rtc_i2c->dev, "bmc_rtc",
+ &bmc_rtc_ops, THIS_MODULE);
+ if (IS_ERR(rtc_dev)) {
+ ret = PTR_ERR(rtc_dev);
+ dev_err(&client->dev, "Failed to register RTC device: %d\n",
+ ret);
+ i2c_unregister_device(rtc_i2c);
+ rtc_i2c = NULL;
+ }
+fail:
+ client_addr++;
+ }
+
+#ifdef CONFIG_PINCTRL
+ if (bmc_cap & BMC_CAP_GPIODIR || 1 /*vvv*/)
+ bmc_pinctrl_register(bmc_dev);
+#endif
+
+ return ret;
+}
+
+static int
+mitx2_bmc_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int err = 0;
+ int i = 0;
+
+ dev_info(&client->dev, "mitx2 bmc probe\n");
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
+ return -ENODEV;
+
+ for (i = 0; i < 10; i++) {
+ err = mitx2_bmc_validate(client);
+ if (!err)
+ break;
+ msleep_interruptible(20);
+ }
+ if (err)
+ return err;
+
+ if (bmc_cap & BMC_CAP_PWRBTN) {
+ button_dev = input_allocate_device();
+ if (!button_dev) {
+ dev_err(&client->dev, "Not enough memory\n");
+ return -ENOMEM;
+ }
+
+ button_dev->id.bustype = BUS_I2C;
+ button_dev->dev.parent = &client->dev;
+ button_dev->name = input_name;
+ button_dev->phys = "bmc-input0";
+ button_dev->evbit[0] = BIT_MASK(EV_KEY);
+ button_dev->keybit[BIT_WORD(KEY_POWER)] = BIT_MASK(KEY_POWER);
+
+ err = input_register_device(button_dev);
+ if (err) {
+ dev_err(&client->dev, "Failed to register device\n");
+ input_free_device(button_dev);
+ return err;
+ }
+
+ dev_info(&client->dev, "Starting polling thread\n");
+ poll_data.c = client;
+ polling_task = kthread_run(pwroff_rq_poll_fn, NULL, "BMC poll task");
+ }
+
+ if (bmc_cap || 1 /*vvv*/)
+ err = bmc_create_client_devices(&client->dev);
+
+ bmc_i2c = client;
+ /* register as poweroff handler */
+ pm_power_off = bmc_pwroff_rq;
+
+ return 0;
+}
+
+static int
+mitx2_bmc_i2c_remove(struct i2c_client *client)
+{
+#ifdef CONFIG_SERIO
+ struct serio *serio;
+#endif
+
+ if (button_dev) {
+ kthread_stop(polling_task);
+ input_unregister_device(button_dev);
+ }
+#ifdef CONFIG_SERIO
+ if (serio_i2c) {
+ kthread_stop(touchpad_task);
+ serio = dev_get_drvdata(&serio_i2c->dev);
+ serio_unregister_port(serio);
+ i2c_unregister_device(serio_i2c);
+ }
+#endif
+ if (rtc_i2c)
+ i2c_unregister_device(rtc_i2c);
+#ifdef CONFIG_PINCTRL
+ bmc_pinctrl_unregister();
+#endif
+
+ return 0;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id mitx2_bmc_of_match[] = {
+ { .compatible = "tp,mitx2-bmc" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, mitx2_bmc_of_match);
+#endif
+
+static const struct i2c_device_id mitx2_bmc_i2c_id[] = {
+ { "mitx2_bmc", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, mitx2_bmc_i2c_id);
+
+static ssize_t
+version_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%i.%i.%i\n", bmc_proto_version[0],
+ bmc_proto_version[1], bmc_proto_version[2]);
+}
+
+static struct kobj_attribute version_attribute =
+ __ATTR(version, 0664, version_show, NULL);
+
+static ssize_t
+bootreason_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%i\n", (bmc_bootreason[0] |
+ (bmc_bootreason[1] << 8)));
+}
+
+static struct kobj_attribute bootreason_attribute =
+ __ATTR(bootreason, 0664, bootreason_show, NULL);
+
+static ssize_t
+scratch_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%i\n", (bmc_scratch[0] | (bmc_scratch[1] << 8) |
+ (bmc_scratch[2] << 16) | (bmc_scratch[3] << 24)));
+}
+
+static struct kobj_attribute scratch_attribute =
+ __ATTR(scratch, 0664, scratch_show, NULL);
+
+static struct attribute *bmc_attrs[] = {
+ &version_attribute.attr,
+ &bootreason_attribute.attr,
+ &scratch_attribute.attr,
+ NULL,
+};
+
+ATTRIBUTE_GROUPS(bmc);
+
+static struct i2c_driver mitx2_bmc_i2c_driver = {
+ .driver = {
+ .name = "mitx2-bmc",
+ .of_match_table = of_match_ptr(mitx2_bmc_of_match),
+ .groups = bmc_groups,
+ },
+ .probe = mitx2_bmc_i2c_probe,
+ .remove = mitx2_bmc_i2c_remove,
+ .id_table = mitx2_bmc_i2c_id,
+};
+module_i2c_driver(mitx2_bmc_i2c_driver);
+
+MODULE_AUTHOR("Konstantin Kirik");
+MODULE_DESCRIPTION("mITX2 BMC driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("serial:bmc");
--
2.31.1

View file

@ -1,251 +0,0 @@
From 750bd359f6fff79a3131f89c3bd9ad8a83a6356a Mon Sep 17 00:00:00 2001
From: Alexey Sheplyakov <asheplyakov@altlinux.org>
Date: Wed, 3 Feb 2021 16:58:16 +0400
Subject: [PATCH 611/625] dw-hdmi-ahb-audio: support BE-M1000 SoC
---
.../drm/bridge/synopsys/dw-hdmi-ahb-audio.c | 106 ++++++++++++------
.../gpu/drm/bridge/synopsys/dw-hdmi-audio.h | 1 +
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 6 +
3 files changed, 78 insertions(+), 35 deletions(-)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c
index d0db1acf11d7..3bb652e42718 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c
@@ -132,12 +132,45 @@ struct snd_dw_hdmi {
u8 cs[192][8];
};
-static void dw_hdmi_writel(u32 val, void __iomem *ptr)
+static inline void dw_hdmi_writeb_relaxed(u8 value, const struct dw_hdmi_audio_data *data, int offset)
{
- writeb_relaxed(val, ptr);
- writeb_relaxed(val >> 8, ptr + 1);
- writeb_relaxed(val >> 16, ptr + 2);
- writeb_relaxed(val >> 24, ptr + 3);
+ void __iomem *base = data->base;
+ if (data->reg_offset != 0)
+ offset <<= data->reg_offset;
+ writeb_relaxed(value, base + offset);
+}
+
+static inline void dw_hdmi_writeb(u8 value, const struct dw_hdmi_audio_data *data, int offset)
+{
+ void __iomem *base = data->base;
+ if (data->reg_offset != 0)
+ offset <<= data->reg_offset;
+ writeb(value, base + offset);
+}
+
+static inline u8 dw_hdmi_readb(const struct dw_hdmi_audio_data *data, int offset)
+{
+ void __iomem *base = data->base;
+ if (data->reg_offset != 0)
+ offset <<= data->reg_offset;
+ return readb(base + offset);
+
+}
+
+static inline u8 dw_hdmi_readb_relaxed(const struct dw_hdmi_audio_data *data, int offset)
+{
+ void __iomem *base = data->base;
+ if (data->reg_offset != 0)
+ offset <<= data->reg_offset;
+ return readb_relaxed(base + offset);
+}
+
+static void dw_hdmi_writel(u32 val, const struct dw_hdmi_audio_data *data, int offset)
+{
+ dw_hdmi_writeb_relaxed(val, data, offset);
+ dw_hdmi_writeb_relaxed(val >> 8, data, offset + 1);
+ dw_hdmi_writeb_relaxed(val >> 16, data, offset + 2);
+ dw_hdmi_writeb_relaxed(val >> 24, data, offset + 3);
}
/*
@@ -232,7 +265,6 @@ static void dw_hdmi_create_cs(struct snd_dw_hdmi *dw,
static void dw_hdmi_start_dma(struct snd_dw_hdmi *dw)
{
- void __iomem *base = dw->data.base;
unsigned offset = dw->buf_offset;
unsigned period = dw->buf_period;
u32 start, stop;
@@ -240,18 +272,18 @@ static void dw_hdmi_start_dma(struct snd_dw_hdmi *dw)
dw->reformat(dw, offset, period);
/* Clear all irqs before enabling irqs and starting DMA */
- writeb_relaxed(HDMI_IH_AHBDMAAUD_STAT0_ALL,
- base + HDMI_IH_AHBDMAAUD_STAT0);
+ dw_hdmi_writeb_relaxed(HDMI_IH_AHBDMAAUD_STAT0_ALL,
+ &dw->data, HDMI_IH_AHBDMAAUD_STAT0);
start = dw->buf_addr + offset;
stop = start + period - 1;
/* Setup the hardware start/stop addresses */
- dw_hdmi_writel(start, base + HDMI_AHB_DMA_STRADDR0);
- dw_hdmi_writel(stop, base + HDMI_AHB_DMA_STPADDR0);
+ dw_hdmi_writel(start, &dw->data, HDMI_AHB_DMA_STRADDR0);
+ dw_hdmi_writel(stop, &dw->data, HDMI_AHB_DMA_STPADDR0);
- writeb_relaxed((u8)~HDMI_AHB_DMA_MASK_DONE, base + HDMI_AHB_DMA_MASK);
- writeb(HDMI_AHB_DMA_START_START, base + HDMI_AHB_DMA_START);
+ dw_hdmi_writeb_relaxed((u8)~HDMI_AHB_DMA_MASK_DONE, &dw->data, HDMI_AHB_DMA_MASK);
+ dw_hdmi_writeb(HDMI_AHB_DMA_START_START, &dw->data, HDMI_AHB_DMA_START);
offset += period;
if (offset >= dw->buf_size)
@@ -262,8 +294,8 @@ static void dw_hdmi_start_dma(struct snd_dw_hdmi *dw)
static void dw_hdmi_stop_dma(struct snd_dw_hdmi *dw)
{
/* Disable interrupts before disabling DMA */
- writeb_relaxed(~0, dw->data.base + HDMI_AHB_DMA_MASK);
- writeb_relaxed(HDMI_AHB_DMA_STOP_STOP, dw->data.base + HDMI_AHB_DMA_STOP);
+ dw_hdmi_writeb_relaxed(~0, &dw->data, HDMI_AHB_DMA_MASK);
+ dw_hdmi_writeb_relaxed(HDMI_AHB_DMA_STOP_STOP, &dw->data, HDMI_AHB_DMA_STOP);
}
static irqreturn_t snd_dw_hdmi_irq(int irq, void *data)
@@ -272,11 +304,11 @@ static irqreturn_t snd_dw_hdmi_irq(int irq, void *data)
struct snd_pcm_substream *substream;
unsigned stat;
- stat = readb_relaxed(dw->data.base + HDMI_IH_AHBDMAAUD_STAT0);
+ stat = dw_hdmi_readb_relaxed(&dw->data, HDMI_IH_AHBDMAAUD_STAT0);
if (!stat)
return IRQ_NONE;
- writeb_relaxed(stat, dw->data.base + HDMI_IH_AHBDMAAUD_STAT0);
+ dw_hdmi_writeb_relaxed(stat, &dw->data, HDMI_IH_AHBDMAAUD_STAT0);
substream = dw->substream;
if (stat & HDMI_IH_AHBDMAAUD_STAT0_DONE && substream) {
@@ -319,7 +351,6 @@ static int dw_hdmi_open(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_dw_hdmi *dw = substream->private_data;
- void __iomem *base = dw->data.base;
int ret;
runtime->hw = dw_hdmi_hw;
@@ -345,16 +376,16 @@ static int dw_hdmi_open(struct snd_pcm_substream *substream)
return ret;
/* Clear FIFO */
- writeb_relaxed(HDMI_AHB_DMA_CONF0_SW_FIFO_RST,
- base + HDMI_AHB_DMA_CONF0);
+ dw_hdmi_writeb_relaxed(HDMI_AHB_DMA_CONF0_SW_FIFO_RST,
+ &dw->data, HDMI_AHB_DMA_CONF0);
/* Configure interrupt polarities */
- writeb_relaxed(~0, base + HDMI_AHB_DMA_POL);
- writeb_relaxed(~0, base + HDMI_AHB_DMA_BUFFPOL);
+ dw_hdmi_writeb_relaxed(~0, &dw->data, HDMI_AHB_DMA_POL);
+ dw_hdmi_writeb_relaxed(~0, &dw->data, HDMI_AHB_DMA_BUFFPOL);
/* Keep interrupts masked, and clear any pending */
- writeb_relaxed(~0, base + HDMI_AHB_DMA_MASK);
- writeb_relaxed(~0, base + HDMI_IH_AHBDMAAUD_STAT0);
+ dw_hdmi_writeb_relaxed(~0, &dw->data, HDMI_AHB_DMA_MASK);
+ dw_hdmi_writeb_relaxed(~0, &dw->data, HDMI_IH_AHBDMAAUD_STAT0);
ret = request_irq(dw->data.irq, snd_dw_hdmi_irq, IRQF_SHARED,
"dw-hdmi-audio", dw);
@@ -362,9 +393,9 @@ static int dw_hdmi_open(struct snd_pcm_substream *substream)
return ret;
/* Un-mute done interrupt */
- writeb_relaxed(HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL &
- ~HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE,
- base + HDMI_IH_MUTE_AHBDMAAUD_STAT0);
+ dw_hdmi_writeb_relaxed(HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL &
+ ~HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE,
+ &dw->data, HDMI_IH_MUTE_AHBDMAAUD_STAT0);
return 0;
}
@@ -374,8 +405,8 @@ static int dw_hdmi_close(struct snd_pcm_substream *substream)
struct snd_dw_hdmi *dw = substream->private_data;
/* Mute all interrupts */
- writeb_relaxed(HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL,
- dw->data.base + HDMI_IH_MUTE_AHBDMAAUD_STAT0);
+ dw_hdmi_writeb_relaxed(HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL,
+ &dw->data, HDMI_IH_MUTE_AHBDMAAUD_STAT0);
free_irq(dw->data.irq, dw);
@@ -416,6 +447,11 @@ static int dw_hdmi_prepare(struct snd_pcm_substream *substream)
HDMI_AHB_DMA_CONF0_INCR8;
threshold = 128;
break;
+ case 0x2a: /* this revision is used in Baikal-M SoC */
+ conf0 = HDMI_AHB_DMA_CONF0_BURST_MODE |
+ HDMI_AHB_DMA_CONF0_INCR16;
+ threshold = 128;
+ break;
default:
/* NOTREACHED */
return -EINVAL;
@@ -430,9 +466,9 @@ static int dw_hdmi_prepare(struct snd_pcm_substream *substream)
conf1 = default_hdmi_channel_config[runtime->channels - 2].conf1;
ca = default_hdmi_channel_config[runtime->channels - 2].ca;
- writeb_relaxed(threshold, dw->data.base + HDMI_AHB_DMA_THRSLD);
- writeb_relaxed(conf0, dw->data.base + HDMI_AHB_DMA_CONF0);
- writeb_relaxed(conf1, dw->data.base + HDMI_AHB_DMA_CONF1);
+ dw_hdmi_writeb_relaxed(threshold, &dw->data, HDMI_AHB_DMA_THRSLD);
+ dw_hdmi_writeb_relaxed(conf0, &dw->data, HDMI_AHB_DMA_CONF0);
+ dw_hdmi_writeb_relaxed(conf1, &dw->data, HDMI_AHB_DMA_CONF1);
dw_hdmi_set_channel_count(dw->data.hdmi, runtime->channels);
dw_hdmi_set_channel_allocation(dw->data.hdmi, ca);
@@ -524,10 +560,10 @@ static int snd_dw_hdmi_probe(struct platform_device *pdev)
unsigned revision;
int ret;
- writeb_relaxed(HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL,
- data->base + HDMI_IH_MUTE_AHBDMAAUD_STAT0);
- revision = readb_relaxed(data->base + HDMI_REVISION_ID);
- if (revision != 0x0a && revision != 0x1a) {
+ dw_hdmi_writeb_relaxed(HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL,
+ data, HDMI_IH_MUTE_AHBDMAAUD_STAT0);
+ revision = dw_hdmi_readb_relaxed(data, HDMI_REVISION_ID);
+ if (revision != 0x0a && revision != 0x1a && revision != 0x2a) {
dev_err(dev, "dw-hdmi-audio: unknown revision 0x%02x\n",
revision);
return -ENXIO;
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h
index cb07dc0da5a7..8fb5ebd5a169 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h
@@ -10,6 +10,7 @@ struct dw_hdmi_audio_data {
int irq;
struct dw_hdmi *hdmi;
u8 *eld;
+ unsigned reg_offset;
};
struct dw_hdmi_i2s_audio_data {
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 0c79a9ba48bb..d0580b7d7430 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -3396,6 +3396,12 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
audio.irq = irq;
audio.hdmi = hdmi;
audio.eld = hdmi->connector.eld;
+ audio.reg_offset = 0;
+ if (of_device_is_compatible(np, "baikal,hdmi")) {
+ audio.reg_offset = 2;
+ dev_info(dev, "setting audio.reg_offset=%d for BE-M1000 SoC\n",
+ audio.reg_offset);
+ }
hdmi->enable_audio = dw_hdmi_ahb_audio_enable;
hdmi->disable_audio = dw_hdmi_ahb_audio_disable;
--
2.31.1

View file

@ -1,252 +0,0 @@
From 5b71a758ddc825759d287b5077c0f36a25c30da6 Mon Sep 17 00:00:00 2001
From: Alexey Sheplyakov <asheplyakov@altlinux.org>
Date: Thu, 3 Dec 2020 19:02:15 +0400
Subject: [PATCH 612/625] bt1-pvt.c: access registers via pvt_{readl,writel}
helper functions
BE-M1000 SoC is equipped with PVT sensors too. However PVT registers are
not directly accessible to kernel. Instead the registers (and clocks)
are managed by the "secure world", so Linux has to call into firmware.
This patch replaces readl/writel with pvt_readl/pvt_writel functions.
No functional changes is intended. Subsequent patch will define pvt_readl
and pvt_writel functions for BE-M1000 SoC.
---
drivers/hwmon/bt1-pvt.c | 85 +++++++++++++++++++++++------------------
1 file changed, 48 insertions(+), 37 deletions(-)
diff --git a/drivers/hwmon/bt1-pvt.c b/drivers/hwmon/bt1-pvt.c
index 3e1d56585b91..c6749585d604 100644
--- a/drivers/hwmon/bt1-pvt.c
+++ b/drivers/hwmon/bt1-pvt.c
@@ -138,12 +138,23 @@ static long pvt_calc_poly(const struct pvt_poly *poly, long data)
return ret / poly->total_divider;
}
-static inline u32 pvt_update(void __iomem *reg, u32 mask, u32 data)
+static inline u32 pvt_readl(struct pvt_hwmon const *pvt, int reg) {
+ return readl(pvt->regs + reg);
+}
+
+static inline u32 pvt_readl_relaxed(struct pvt_hwmon const *pvt, int reg) {
+ return readl_relaxed(pvt->regs + reg);
+}
+
+static inline void pvt_writel(u32 data, struct pvt_hwmon const *pvt, int reg) {
+ writel(data, pvt->regs + reg);
+}
+static inline u32 pvt_update(struct pvt_hwmon *pvt, int reg, u32 mask, u32 data)
{
u32 old;
- old = readl_relaxed(reg);
- writel((old & ~mask) | (data & mask), reg);
+ old = pvt_readl_relaxed(pvt, reg);
+ pvt_writel((old & ~mask) | (data & mask), pvt, reg);
return old & mask;
}
@@ -161,8 +172,8 @@ static inline void pvt_set_mode(struct pvt_hwmon *pvt, u32 mode)
mode = FIELD_PREP(PVT_CTRL_MODE_MASK, mode);
- old = pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, 0);
- pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_MODE_MASK | PVT_CTRL_EN,
+ old = pvt_update(pvt, PVT_CTRL, PVT_CTRL_EN, 0);
+ pvt_update(pvt, PVT_CTRL, PVT_CTRL_MODE_MASK | PVT_CTRL_EN,
mode | old);
}
@@ -179,8 +190,8 @@ static inline void pvt_set_trim(struct pvt_hwmon *pvt, u32 trim)
trim = FIELD_PREP(PVT_CTRL_TRIM_MASK, trim);
- old = pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, 0);
- pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_TRIM_MASK | PVT_CTRL_EN,
+ old = pvt_update(pvt, PVT_CTRL, PVT_CTRL_EN, 0);
+ pvt_update(pvt, PVT_CTRL, PVT_CTRL_TRIM_MASK | PVT_CTRL_EN,
trim | old);
}
@@ -188,9 +199,9 @@ static inline void pvt_set_tout(struct pvt_hwmon *pvt, u32 tout)
{
u32 old;
- old = pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, 0);
- writel(tout, pvt->regs + PVT_TTIMEOUT);
- pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, old);
+ old = pvt_update(pvt, PVT_CTRL, PVT_CTRL_EN, 0);
+ pvt_writel(tout, pvt, PVT_TTIMEOUT);
+ pvt_update(pvt, PVT_CTRL, PVT_CTRL_EN, old);
}
/*
@@ -237,7 +248,7 @@ static irqreturn_t pvt_soft_isr(int irq, void *data)
* status before the next conversion happens. Threshold events will be
* handled a bit later.
*/
- thres_sts = readl(pvt->regs + PVT_RAW_INTR_STAT);
+ thres_sts = pvt_readl(pvt, PVT_RAW_INTR_STAT);
/*
* Then lets recharge the PVT interface with the next sampling mode.
@@ -260,14 +271,14 @@ static irqreturn_t pvt_soft_isr(int irq, void *data)
*/
mutex_lock(&pvt->iface_mtx);
- old = pvt_update(pvt->regs + PVT_INTR_MASK, PVT_INTR_DVALID,
+ old = pvt_update(pvt, PVT_INTR_MASK, PVT_INTR_DVALID,
PVT_INTR_DVALID);
- val = readl(pvt->regs + PVT_DATA);
+ val = pvt_readl(pvt, PVT_DATA);
pvt_set_mode(pvt, pvt_info[pvt->sensor].mode);
- pvt_update(pvt->regs + PVT_INTR_MASK, PVT_INTR_DVALID, old);
+ pvt_update(pvt, PVT_INTR_MASK, PVT_INTR_DVALID, old);
mutex_unlock(&pvt->iface_mtx);
@@ -337,7 +348,7 @@ static int pvt_read_limit(struct pvt_hwmon *pvt, enum pvt_sensor_type type,
u32 data;
/* No need in serialization, since it is just read from MMIO. */
- data = readl(pvt->regs + pvt_info[type].thres_base);
+ data = pvt_readl(pvt, pvt_info[type].thres_base);
if (is_low)
data = FIELD_GET(PVT_THRES_LO_MASK, data);
@@ -372,7 +383,7 @@ static int pvt_write_limit(struct pvt_hwmon *pvt, enum pvt_sensor_type type,
return ret;
/* Make sure the upper and lower ranges don't intersect. */
- limit = readl(pvt->regs + pvt_info[type].thres_base);
+ limit = pvt_readl(pvt, pvt_info[type].thres_base);
if (is_low) {
limit = FIELD_GET(PVT_THRES_HI_MASK, limit);
data = clamp_val(data, PVT_DATA_MIN, limit);
@@ -385,7 +396,7 @@ static int pvt_write_limit(struct pvt_hwmon *pvt, enum pvt_sensor_type type,
mask = PVT_THRES_HI_MASK;
}
- pvt_update(pvt->regs + pvt_info[type].thres_base, mask, data);
+ pvt_update(pvt, pvt_info[type].thres_base, mask, data);
mutex_unlock(&pvt->iface_mtx);
@@ -439,14 +450,14 @@ static irqreturn_t pvt_hard_isr(int irq, void *data)
* Mask the DVALID interrupt so after exiting from the handler a
* repeated conversion wouldn't happen.
*/
- pvt_update(pvt->regs + PVT_INTR_MASK, PVT_INTR_DVALID,
+ pvt_update(pvt, PVT_INTR_MASK, PVT_INTR_DVALID,
PVT_INTR_DVALID);
/*
* Nothing special for alarm-less driver. Just read the data, update
* the cache and notify a waiter of this event.
*/
- val = readl(pvt->regs + PVT_DATA);
+ val = pvt_readl(pvt, PVT_DATA);
if (!(val & PVT_DATA_VALID)) {
dev_err(pvt->dev, "Got IRQ when data isn't valid\n");
return IRQ_HANDLED;
@@ -498,8 +509,8 @@ static int pvt_read_data(struct pvt_hwmon *pvt, enum pvt_sensor_type type,
* Unmask the DVALID interrupt and enable the sensors conversions.
* Do the reverse procedure when conversion is done.
*/
- pvt_update(pvt->regs + PVT_INTR_MASK, PVT_INTR_DVALID, 0);
- pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, PVT_CTRL_EN);
+ pvt_update(pvt, PVT_INTR_MASK, PVT_INTR_DVALID, 0);
+ pvt_update(pvt, PVT_CTRL, PVT_CTRL_EN, PVT_CTRL_EN);
/*
* Wait with timeout since in case if the sensor is suddenly powered
@@ -510,8 +521,8 @@ static int pvt_read_data(struct pvt_hwmon *pvt, enum pvt_sensor_type type,
timeout = 2 * usecs_to_jiffies(ktime_to_us(pvt->timeout));
ret = wait_for_completion_timeout(&cache->conversion, timeout);
- pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, 0);
- pvt_update(pvt->regs + PVT_INTR_MASK, PVT_INTR_DVALID,
+ pvt_update(pvt, PVT_CTRL, PVT_CTRL_EN, 0);
+ pvt_update(pvt, PVT_INTR_MASK, PVT_INTR_DVALID,
PVT_INTR_DVALID);
data = READ_ONCE(cache->data);
@@ -637,7 +648,7 @@ static int pvt_read_trim(struct pvt_hwmon *pvt, long *val)
{
u32 data;
- data = readl(pvt->regs + PVT_CTRL);
+ data = pvt_readl(pvt, PVT_CTRL);
*val = FIELD_GET(PVT_CTRL_TRIM_MASK, data) * PVT_TRIM_STEP;
return 0;
@@ -983,21 +994,21 @@ static int pvt_check_pwr(struct pvt_hwmon *pvt)
* conversion. In the later case alas we won't be able to detect the
* problem.
*/
- pvt_update(pvt->regs + PVT_INTR_MASK, PVT_INTR_ALL, PVT_INTR_ALL);
- pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, PVT_CTRL_EN);
+ pvt_update(pvt, PVT_INTR_MASK, PVT_INTR_ALL, PVT_INTR_ALL);
+ pvt_update(pvt, PVT_CTRL, PVT_CTRL_EN, PVT_CTRL_EN);
pvt_set_tout(pvt, 0);
- readl(pvt->regs + PVT_DATA);
+ pvt_readl(pvt, PVT_DATA);
tout = PVT_TOUT_MIN / NSEC_PER_USEC;
usleep_range(tout, 2 * tout);
- data = readl(pvt->regs + PVT_DATA);
+ data = pvt_readl(pvt, PVT_DATA);
if (!(data & PVT_DATA_VALID)) {
ret = -ENODEV;
dev_err(pvt->dev, "Sensor is powered down\n");
}
- pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, 0);
+ pvt_update(pvt, PVT_CTRL, PVT_CTRL_EN, 0);
return ret;
}
@@ -1018,10 +1029,10 @@ static int pvt_init_iface(struct pvt_hwmon *pvt)
* accidentally have ISR executed before the driver data is fully
* initialized. Clear the IRQ status as well.
*/
- pvt_update(pvt->regs + PVT_INTR_MASK, PVT_INTR_ALL, PVT_INTR_ALL);
- pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, 0);
- readl(pvt->regs + PVT_CLR_INTR);
- readl(pvt->regs + PVT_DATA);
+ pvt_update(pvt, PVT_INTR_MASK, PVT_INTR_ALL, PVT_INTR_ALL);
+ pvt_update(pvt, PVT_CTRL, PVT_CTRL_EN, 0);
+ pvt_readl(pvt, PVT_CLR_INTR);
+ pvt_readl(pvt, PVT_DATA);
/* Setup default sensor mode, timeout and temperature trim. */
pvt_set_mode(pvt, pvt_info[pvt->sensor].mode);
@@ -1105,8 +1116,8 @@ static void pvt_disable_iface(void *data)
struct pvt_hwmon *pvt = data;
mutex_lock(&pvt->iface_mtx);
- pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, 0);
- pvt_update(pvt->regs + PVT_INTR_MASK, PVT_INTR_DVALID,
+ pvt_update(pvt, PVT_CTRL, PVT_CTRL_EN, 0);
+ pvt_update(pvt, PVT_INTR_MASK, PVT_INTR_DVALID,
PVT_INTR_DVALID);
mutex_unlock(&pvt->iface_mtx);
}
@@ -1128,8 +1139,8 @@ static int pvt_enable_iface(struct pvt_hwmon *pvt)
* which theoretically may cause races.
*/
mutex_lock(&pvt->iface_mtx);
- pvt_update(pvt->regs + PVT_INTR_MASK, PVT_INTR_DVALID, 0);
- pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, PVT_CTRL_EN);
+ pvt_update(pvt, PVT_INTR_MASK, PVT_INTR_DVALID, 0);
+ pvt_update(pvt, PVT_CTRL, PVT_CTRL_EN, PVT_CTRL_EN);
mutex_unlock(&pvt->iface_mtx);
return 0;
--
2.31.1

View file

@ -1,87 +0,0 @@
From bb4383c2491f602cb87e619418cbff9c32a0f0ac Mon Sep 17 00:00:00 2001
From: Alexey Sheplyakov <asheplyakov@altlinux.org>
Date: Thu, 3 Dec 2020 19:13:51 +0400
Subject: [PATCH 613/625] bt1-pvt: define pvt_readl/pvt_writel for BE-M1000 SoC
---
drivers/hwmon/bt1-pvt.c | 23 +++++++++++++++++++++++
drivers/hwmon/bt1-pvt.h | 8 ++++++++
2 files changed, 31 insertions(+)
diff --git a/drivers/hwmon/bt1-pvt.c b/drivers/hwmon/bt1-pvt.c
index c6749585d604..d1f66de6a2cd 100644
--- a/drivers/hwmon/bt1-pvt.c
+++ b/drivers/hwmon/bt1-pvt.c
@@ -29,6 +29,9 @@
#include <linux/seqlock.h>
#include <linux/sysfs.h>
#include <linux/types.h>
+#ifdef CONFIG_ARM64
+#include <linux/arm-smccc.h>
+#endif
#include "bt1-pvt.h"
@@ -138,6 +141,7 @@ static long pvt_calc_poly(const struct pvt_poly *poly, long data)
return ret / poly->total_divider;
}
+#ifdef BT1_PVT_DIRECT_REG_ACCESS
static inline u32 pvt_readl(struct pvt_hwmon const *pvt, int reg) {
return readl(pvt->regs + reg);
}
@@ -149,6 +153,25 @@ static inline u32 pvt_readl_relaxed(struct pvt_hwmon const *pvt, int reg) {
static inline void pvt_writel(u32 data, struct pvt_hwmon const *pvt, int reg) {
writel(data, pvt->regs + reg);
}
+#else
+static inline u32 pvt_readl(struct pvt_hwmon const *pvt, int reg) {
+ struct arm_smccc_res res;
+ arm_smccc_smc(BAIKAL_SMC_PVT_ID, PVT_READ, pvt->pvt_id, reg,
+ 0, 0, 0, 0, &res);
+ return res.a0;
+}
+
+static inline u32 pvt_readl_relaxed(struct pvt_hwmon const *pvt, int reg) {
+ return pvt_readl(pvt, reg);
+}
+
+static inline void pvt_writel(u32 data, struct pvt_hwmon const *pvt, int reg) {
+ struct arm_smccc_res res;
+ arm_smccc_smc(BAIKAL_SMC_PVT_ID, PVT_WRITE, pvt->pvt_id, reg,
+ data, 0, 0, 0, &res);
+}
+#endif
+
static inline u32 pvt_update(struct pvt_hwmon *pvt, int reg, u32 mask, u32 data)
{
u32 old;
diff --git a/drivers/hwmon/bt1-pvt.h b/drivers/hwmon/bt1-pvt.h
index 93b8dd5e7c94..0cea95b01c13 100644
--- a/drivers/hwmon/bt1-pvt.h
+++ b/drivers/hwmon/bt1-pvt.h
@@ -101,6 +101,13 @@
# define PVT_TOUT_DEF 0
#endif
+#define BAIKAL_SMC_PVT_ID 0x82000001
+#define PVT_READ 0
+#define PVT_WRITE 1
+#ifndef CONFIG_ARM64
+#define BT1_PVT_DIRECT_REG_ACCESS
+#endif
+
/*
* enum pvt_sensor_type - Baikal-T1 PVT sensor types (correspond to each PVT
* sampling mode)
@@ -217,6 +224,7 @@ struct pvt_hwmon {
enum pvt_sensor_type sensor;
struct pvt_cache cache[PVT_SENSORS_NUM];
ktime_t timeout;
+ int pvt_id;
};
/*
--
2.31.1

View file

@ -1,135 +0,0 @@
From 1048ea091c614a2514a0e851d6c614de572e1141 Mon Sep 17 00:00:00 2001
From: Alexey Sheplyakov <asheplyakov@altlinux.org>
Date: Thu, 3 Dec 2020 19:22:04 +0400
Subject: [PATCH 614/625] bt1-pvt: adjust probing for BE-M1000 SoC
The registers and clocks are managed by the secure world and can't be
accessed by Linux directly. Therefore skip enabling/disabling clocks
and ioremapping registers on BE-M1000.
Also a sensor is identified by special `pvt_id' instead of registers base
address. pvt_id is initialized from the device tree.
---
drivers/hwmon/Kconfig | 7 ++++---
drivers/hwmon/bt1-pvt.c | 28 ++++++++++++++++++++++++----
2 files changed, 28 insertions(+), 7 deletions(-)
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index a850e4f0e0bd..efaf8ba21e7b 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -415,10 +415,11 @@ config SENSORS_ATXP1
will be called atxp1.
config SENSORS_BT1_PVT
- tristate "Baikal-T1 Process, Voltage, Temperature sensor driver"
- depends on MIPS_BAIKAL_T1 || COMPILE_TEST
+ tristate "Baikal-T1/M Process, Voltage, Temperature sensor driver"
+ depends on MIPS_BAIKAL_T1 || ARCH_BAIKAL || COMPILE_TEST
+ default m if MIPS_BAIKAL_T1 || ARCH_BAIKAL
help
- If you say yes here you get support for Baikal-T1 PVT sensor
+ If you say yes here you get support for Baikal-M or Baikal-T1 PVT sensor
embedded into the SoC.
This driver can also be built as a module. If so, the module will be
diff --git a/drivers/hwmon/bt1-pvt.c b/drivers/hwmon/bt1-pvt.c
index d1f66de6a2cd..38774ec33ee1 100644
--- a/drivers/hwmon/bt1-pvt.c
+++ b/drivers/hwmon/bt1-pvt.c
@@ -950,6 +950,7 @@ static int pvt_request_regs(struct pvt_hwmon *pvt)
{
struct platform_device *pdev = to_platform_device(pvt->dev);
struct resource *res;
+ int err = 0;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
@@ -957,11 +958,19 @@ static int pvt_request_regs(struct pvt_hwmon *pvt)
return -EINVAL;
}
+#ifdef BT1_PVT_DIRECT_REG_ACCESS
pvt->regs = devm_ioremap_resource(pvt->dev, res);
if (IS_ERR(pvt->regs)) {
dev_err(pvt->dev, "Couldn't map PVT registers\n");
return PTR_ERR(pvt->regs);
}
+#else
+ err = of_property_read_u32(pvt->dev->of_node, "pvt_id", &(pvt->pvt_id));
+ if (err) {
+ dev_err(pvt->dev, "couldn't find pvt_id\n");
+ return err;
+ }
+#endif
return 0;
}
@@ -975,11 +984,12 @@ static void pvt_disable_clks(void *data)
static int pvt_request_clks(struct pvt_hwmon *pvt)
{
- int ret;
+ int ret = 0;
pvt->clks[PVT_CLOCK_APB].id = "pclk";
pvt->clks[PVT_CLOCK_REF].id = "ref";
+#ifdef BT1_PVT_DIRECT_REG_ACCESS
ret = devm_clk_bulk_get(pvt->dev, PVT_CLOCK_NUM, pvt->clks);
if (ret) {
dev_err(pvt->dev, "Couldn't get PVT clocks descriptors\n");
@@ -997,8 +1007,11 @@ static int pvt_request_clks(struct pvt_hwmon *pvt)
dev_err(pvt->dev, "Can't add PVT clocks disable action\n");
return ret;
}
-
- return 0;
+#else
+ pvt->clks[PVT_CLOCK_APB].clk = NULL;
+ pvt->clks[PVT_CLOCK_REF].clk = NULL;
+#endif
+ return ret;
}
static int pvt_check_pwr(struct pvt_hwmon *pvt)
@@ -1038,14 +1051,17 @@ static int pvt_check_pwr(struct pvt_hwmon *pvt)
static int pvt_init_iface(struct pvt_hwmon *pvt)
{
- unsigned long rate;
u32 trim, temp;
+#ifdef BT1_PVT_DIRECT_REG_ACCESS
+ unsigned long rate;
+
rate = clk_get_rate(pvt->clks[PVT_CLOCK_REF].clk);
if (!rate) {
dev_err(pvt->dev, "Invalid reference clock rate\n");
return -ENODEV;
}
+#endif
/*
* Make sure all interrupts and controller are disabled so not to
@@ -1074,6 +1090,7 @@ static int pvt_init_iface(struct pvt_hwmon *pvt)
* polled. In that case the formulae will look a bit different:
* Ttotal = 5 * (N / Fclk + Tmin)
*/
+#if defined(BT1_PVT_DIRECT_REG_ACCESS)
#if defined(CONFIG_SENSORS_BT1_PVT_ALARMS)
pvt->timeout = ktime_set(PVT_SENSORS_NUM * PVT_TOUT_DEF, 0);
pvt->timeout = ktime_divns(pvt->timeout, rate);
@@ -1083,6 +1100,9 @@ static int pvt_init_iface(struct pvt_hwmon *pvt)
pvt->timeout = ktime_divns(pvt->timeout, rate);
pvt->timeout = ktime_add_ns(pvt->timeout, PVT_TOUT_MIN);
#endif
+#else
+ pvt->timeout = ktime_set(0, PVT_TOUT_MIN * PVT_SENSORS_NUM);
+#endif
trim = PVT_TRIM_DEF;
if (!of_property_read_u32(pvt->dev->of_node,
--
2.31.1

View file

@ -1,27 +0,0 @@
From 7028d81bce581b1075c55b34f2596f16ae8686ce Mon Sep 17 00:00:00 2001
From: Alexey Sheplyakov <asheplyakov@altlinux.org>
Date: Thu, 3 Dec 2020 19:24:00 +0400
Subject: [PATCH 615/625] bt1-pvt: added compatible baikal,pvt
So the driver will be loaded on existing BE-M1000 based boards.
X-DONTUPSTREAM
---
drivers/hwmon/bt1-pvt.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/hwmon/bt1-pvt.c b/drivers/hwmon/bt1-pvt.c
index 38774ec33ee1..585614a384e1 100644
--- a/drivers/hwmon/bt1-pvt.c
+++ b/drivers/hwmon/bt1-pvt.c
@@ -1240,6 +1240,7 @@ static int pvt_probe(struct platform_device *pdev)
static const struct of_device_id pvt_of_match[] = {
{ .compatible = "baikal,bt1-pvt" },
+ { .compatible = "baikal,pvt" },
{ }
};
MODULE_DEVICE_TABLE(of, pvt_of_match);
--
2.31.1

View file

@ -1,6 +1,3 @@
From 72b2f9de7609df9b7e7a60e4a9bfca45463cfac5 Mon Sep 17 00:00:00 2001
From: Alexey Sheplyakov <asheplyakov@altlinux.org>
Date: Fri, 20 Mar 2020 13:57:57 +0400
Subject: [PATCH 616/625] Baikal-M: PCIe driver from SDK-M 4.3 Subject: [PATCH 616/625] Baikal-M: PCIe driver from SDK-M 4.3
Improvements: Improvements:
@ -80,19 +77,10 @@ Improvements:
[ 9.324041] Memory Limit: none [ 9.324041] Memory Limit: none
Note: detection of new firmware is not 100% reliable. Note: detection of new firmware is not 100% reliable.
---
drivers/pci/controller/Kconfig | 12 + Update for 5.15.28
drivers/pci/controller/dwc/Makefile | 1 +
drivers/pci/controller/dwc/pcie-baikal.c | 722 +++++++++++++++++++++++
drivers/pci/controller/dwc/pcie-baikal.h | 217 +++++++
include/linux/mfd/baikal/lcru-pcie.h | 140 +++++
5 files changed, 1092 insertions(+)
create mode 100644 drivers/pci/controller/dwc/pcie-baikal.c
create mode 100644 drivers/pci/controller/dwc/pcie-baikal.h
create mode 100644 include/linux/mfd/baikal/lcru-pcie.h
diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index 64e2f5e379aa..b8a5eb633259 100644
--- a/drivers/pci/controller/Kconfig --- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig +++ b/drivers/pci/controller/Kconfig
@@ -281,6 +281,18 @@ config PCIE_BRCMSTB @@ -281,6 +281,18 @@ config PCIE_BRCMSTB
@ -118,17 +106,16 @@ diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Ma
index a751553fa0db..85e6ad1954e5 100644 index a751553fa0db..85e6ad1954e5 100644
--- a/drivers/pci/controller/dwc/Makefile --- a/drivers/pci/controller/dwc/Makefile
+++ b/drivers/pci/controller/dwc/Makefile +++ b/drivers/pci/controller/dwc/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_PCI_MESON) += pci-meson.o @@ -24,6 +24,7 @@
obj-$(CONFIG_PCIE_TEGRA194) += pcie-tegra194.o
obj-$(CONFIG_PCIE_UNIPHIER) += pcie-uniphier.o obj-$(CONFIG_PCIE_UNIPHIER) += pcie-uniphier.o
obj-$(CONFIG_PCIE_UNIPHIER_EP) += pcie-uniphier-ep.o obj-$(CONFIG_PCIE_UNIPHIER_EP) += pcie-uniphier-ep.o
obj-$(CONFIG_PCIE_VISCONTI_HOST) += pcie-visconti.o
+obj-$(CONFIG_PCI_BAIKAL) += pcie-baikal.o +obj-$(CONFIG_PCI_BAIKAL) += pcie-baikal.o
# The following drivers are for devices that use the generic ACPI # The following drivers are for devices that use the generic ACPI
# pci_root.c driver but don't support standard ECAM config access. # pci_root.c driver but don't support standard ECAM config access.
diff --git a/drivers/pci/controller/dwc/pcie-baikal.c b/drivers/pci/controller/dwc/pcie-baikal.c diff --git a/drivers/pci/controller/dwc/pcie-baikal.c b/drivers/pci/controller/dwc/pcie-baikal.c
new file mode 100644 new file mode 100644
index 000000000000..1eb5f0e780c4
--- /dev/null --- /dev/null
+++ b/drivers/pci/controller/dwc/pcie-baikal.c +++ b/drivers/pci/controller/dwc/pcie-baikal.c
@@ -0,0 +1,722 @@ @@ -0,0 +1,722 @@
@ -856,7 +843,6 @@ index 000000000000..1eb5f0e780c4
+MODULE_LICENSE("GPL v2"); +MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/controller/dwc/pcie-baikal.h b/drivers/pci/controller/dwc/pcie-baikal.h diff --git a/drivers/pci/controller/dwc/pcie-baikal.h b/drivers/pci/controller/dwc/pcie-baikal.h
new file mode 100644 new file mode 100644
index 000000000000..f59100cf0c6d
--- /dev/null --- /dev/null
+++ b/drivers/pci/controller/dwc/pcie-baikal.h +++ b/drivers/pci/controller/dwc/pcie-baikal.h
@@ -0,0 +1,217 @@ @@ -0,0 +1,217 @@
@ -1079,7 +1065,6 @@ index 000000000000..f59100cf0c6d
+#define PCIE_PHY_DWC_PCS_MACIFC_MON_2 (0x38023) /* MAC to Raw PCS Interface Monitor Register #1 */ +#define PCIE_PHY_DWC_PCS_MACIFC_MON_2 (0x38023) /* MAC to Raw PCS Interface Monitor Register #1 */
diff --git a/include/linux/mfd/baikal/lcru-pcie.h b/include/linux/mfd/baikal/lcru-pcie.h diff --git a/include/linux/mfd/baikal/lcru-pcie.h b/include/linux/mfd/baikal/lcru-pcie.h
new file mode 100644 new file mode 100644
index 000000000000..40562d00ab85
--- /dev/null --- /dev/null
+++ b/include/linux/mfd/baikal/lcru-pcie.h +++ b/include/linux/mfd/baikal/lcru-pcie.h
@@ -0,0 +1,140 @@ @@ -0,0 +1,140 @@
@ -1223,6 +1208,3 @@ index 000000000000..40562d00ab85
+} +}
+ +
+#endif /* _LINUX_MFD_SYSCON_BAIKAL_LCRU_H_ */ +#endif /* _LINUX_MFD_SYSCON_BAIKAL_LCRU_H_ */
--
2.31.1

View file

@ -1,24 +1,17 @@
From 1865253e6f0bd9dd35495cf5c5cc0db1c5df071b Mon Sep 17 00:00:00 2001
From: Alexey Sheplyakov <asheplyakov@altlinux.org>
Date: Thu, 14 Jan 2021 12:25:44 +0400
Subject: [PATCH 617/625] Baikal-M: PCIe driver from SDK-M 4.4 Subject: [PATCH 617/625] Baikal-M: PCIe driver from SDK-M 4.4
Appears to successfully probe the hardware, lspci -vv output Appears to successfully probe the hardware, lspci -vv output
looks good. No other testing has been done yet. looks good. No other testing has been done yet.
---
drivers/pci/controller/dwc/Makefile | 2 +- Update for 5.15.28
drivers/pci/controller/dwc/pcie-baikal-v44.c | 826 +++++++++++++++++++
2 files changed, 827 insertions(+), 1 deletion(-)
create mode 100644 drivers/pci/controller/dwc/pcie-baikal-v44.c
diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile
index 85e6ad1954e5..dcd23d7d5430 100644
--- a/drivers/pci/controller/dwc/Makefile --- a/drivers/pci/controller/dwc/Makefile
+++ b/drivers/pci/controller/dwc/Makefile +++ b/drivers/pci/controller/dwc/Makefile
@@ -20,7 +20,7 @@ obj-$(CONFIG_PCI_MESON) += pci-meson.o @@ -24,7 +24,7 @@
obj-$(CONFIG_PCIE_TEGRA194) += pcie-tegra194.o
obj-$(CONFIG_PCIE_UNIPHIER) += pcie-uniphier.o obj-$(CONFIG_PCIE_UNIPHIER) += pcie-uniphier.o
obj-$(CONFIG_PCIE_UNIPHIER_EP) += pcie-uniphier-ep.o obj-$(CONFIG_PCIE_UNIPHIER_EP) += pcie-uniphier-ep.o
obj-$(CONFIG_PCIE_VISCONTI_HOST) += pcie-visconti.o
-obj-$(CONFIG_PCI_BAIKAL) += pcie-baikal.o -obj-$(CONFIG_PCI_BAIKAL) += pcie-baikal.o
+obj-$(CONFIG_PCI_BAIKAL) += pcie-baikal.o pcie-baikal-v44.o +obj-$(CONFIG_PCI_BAIKAL) += pcie-baikal.o pcie-baikal-v44.o
@ -26,7 +19,6 @@ index 85e6ad1954e5..dcd23d7d5430 100644
# pci_root.c driver but don't support standard ECAM config access. # pci_root.c driver but don't support standard ECAM config access.
diff --git a/drivers/pci/controller/dwc/pcie-baikal-v44.c b/drivers/pci/controller/dwc/pcie-baikal-v44.c diff --git a/drivers/pci/controller/dwc/pcie-baikal-v44.c b/drivers/pci/controller/dwc/pcie-baikal-v44.c
new file mode 100644 new file mode 100644
index 000000000000..5e5f0a9e59e2
--- /dev/null --- /dev/null
+++ b/drivers/pci/controller/dwc/pcie-baikal-v44.c +++ b/drivers/pci/controller/dwc/pcie-baikal-v44.c
@@ -0,0 +1,826 @@ @@ -0,0 +1,826 @@
@ -530,11 +522,11 @@ index 000000000000..5e5f0a9e59e2
+ } + }
+ +
+ /* Deinitialise all iATU regions */ + /* Deinitialise all iATU regions */
+ for (idx = 0; idx < pp->num_viewport; ++idx) { +// for (idx = 0; idx < pp->num_viewport; ++idx) {
+ dw_pcie_writel_dbi(pp, PCIE_IATU_VIEWPORT_REG, +// dw_pcie_writel_dbi(pp, PCIE_IATU_VIEWPORT_REG,
+ PCIE_IATU_REGION_OUTBOUND | idx); +// PCIE_IATU_REGION_OUTBOUND | idx);
+ dw_pcie_writel_dbi(pp, PCIE_IATU_REGION_CTRL_2_REG, 0); +// dw_pcie_writel_dbi(pp, PCIE_IATU_REGION_CTRL_2_REG, 0);
+ } +// }
+ +
+ /* + /*
+ * Enable writing to config regs. This is required as the DW driver + * Enable writing to config regs. This is required as the DW driver
@ -856,6 +848,3 @@ index 000000000000..5e5f0a9e59e2
+MODULE_DEVICE_TABLE(of, of_baikal_pcie_match); +MODULE_DEVICE_TABLE(of, of_baikal_pcie_match);
+module_platform_driver(baikal_pcie_driver); +module_platform_driver(baikal_pcie_driver);
+MODULE_LICENSE("GPL v2"); +MODULE_LICENSE("GPL v2");
--
2.31.1

View file

@ -1,223 +0,0 @@
From 74a27e95a02db904c452f4b06b0e976cbecf113e Mon Sep 17 00:00:00 2001
From: Alexey Sheplyakov <asheplyakov@altlinux.org>
Date: Thu, 28 Jan 2021 18:44:36 +0400
Subject: [PATCH 618/625] baikal_vdu: avoid using SMC calls for updating
framebuffer address
(from SDK-M 4.4)
---
drivers/gpu/drm/baikal/baikal_vdu_drm.h | 16 -----
drivers/gpu/drm/baikal/baikal_vdu_drv.c | 2 -
drivers/gpu/drm/baikal/baikal_vdu_plane.c | 88 ++++++++---------------
3 files changed, 28 insertions(+), 78 deletions(-)
diff --git a/drivers/gpu/drm/baikal/baikal_vdu_drm.h b/drivers/gpu/drm/baikal/baikal_vdu_drm.h
index d049335dab1d..2db3fb73c9e7 100644
--- a/drivers/gpu/drm/baikal/baikal_vdu_drm.h
+++ b/drivers/gpu/drm/baikal/baikal_vdu_drm.h
@@ -22,23 +22,12 @@
#include <drm/drm_gem.h>
#include <drm/drm_simple_kms_helper.h>
-#include <linux/workqueue.h>
struct clk;
struct drm_device;
struct drm_fbdev_cma;
struct drm_panel;
-/*struct baikal_vdu_framebuffer {
- u32 base;
- u32 size;
- u32 index;
- u32 reg_base;
- u32 reg_size;
- u32 reg_width;
- u32 reg_height;
-};*/
-
struct baikal_vdu_drm_connector {
struct drm_connector connector;
struct drm_panel *panel;
@@ -61,8 +50,6 @@ struct baikal_vdu_private {
u32 fb_addr;
u32 fb_end;
-
- struct delayed_work update_work;
};
#define to_baikal_vdu_drm_connector(x) \
@@ -89,7 +76,4 @@ int baikal_vdu_dumb_create(struct drm_file *file_priv,
void baikal_vdu_debugfs_init(struct drm_minor *minor);
-/* Worker functions */
-void baikal_vdu_update_work(struct work_struct *work);
-
#endif /* __BAIKAL_VDU_DRM_H__ */
diff --git a/drivers/gpu/drm/baikal/baikal_vdu_drv.c b/drivers/gpu/drm/baikal/baikal_vdu_drv.c
index 0caa97dcb2e9..5deab510ea57 100644
--- a/drivers/gpu/drm/baikal/baikal_vdu_drv.c
+++ b/drivers/gpu/drm/baikal/baikal_vdu_drv.c
@@ -152,8 +152,6 @@ static int vdu_modeset_init(struct drm_device *dev)
}
arm_smccc_smc(BAIKAL_SMC_SCP_LOG_DISABLE, 0, 0, 0, 0, 0, 0, 0, &res);
- INIT_DEFERRABLE_WORK(&priv->update_work,
- baikal_vdu_update_work);
drm_mode_config_reset(dev);
diff --git a/drivers/gpu/drm/baikal/baikal_vdu_plane.c b/drivers/gpu/drm/baikal/baikal_vdu_plane.c
index 9817af3c6de8..5a047835e154 100644
--- a/drivers/gpu/drm/baikal/baikal_vdu_plane.c
+++ b/drivers/gpu/drm/baikal/baikal_vdu_plane.c
@@ -17,7 +17,6 @@
*
*/
-#include <linux/arm-smccc.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/delay.h>
@@ -32,42 +31,6 @@
#include "baikal_vdu_drm.h"
#include "baikal_vdu_regs.h"
-#define BAIKAL_SMC_VDU_UPDATE_HDMI 0x82000100
-
-void baikal_vdu_update_work(struct work_struct *work)
-{
- struct arm_smccc_res res;
- unsigned long flags;
- struct baikal_vdu_private *priv = container_of(work, struct baikal_vdu_private,
- update_work.work);
- int count = 0;
- u64 t1, t2;
- t1 = read_sysreg(CNTVCT_EL0);
- spin_lock_irqsave(&priv->lock, flags);
- arm_smccc_smc(BAIKAL_SMC_VDU_UPDATE_HDMI, priv->fb_addr, priv->fb_end, 0, 0, 0, 0, 0, &res);
- spin_unlock_irqrestore(&priv->lock, flags);
- if (res.a0 == -EBUSY)
- priv->counters[15]++;
- else
- priv->counters[16]++;
- while (res.a0 == -EBUSY && count < 10) {
- count++;
- usleep_range(10000, 20000);
- res.a0 = 0;
- spin_lock_irqsave(&priv->lock, flags);
- arm_smccc_smc(BAIKAL_SMC_VDU_UPDATE_HDMI, priv->fb_addr, priv->fb_end, 0, 0, 0, 0, 0, &res);
- spin_unlock_irqrestore(&priv->lock, flags);
- if (res.a0 == -EBUSY)
- priv->counters[15]++;
- else
- priv->counters[16]++;
- }
- t2 = read_sysreg(CNTVCT_EL0);
- priv->counters[17] = t2 - t1;
- priv->counters[18] = count;
- priv->counters[19]++;
-}
-
static int baikal_vdu_primary_plane_atomic_check(struct drm_plane *plane,
struct drm_plane_state *state)
{
@@ -76,6 +39,7 @@ static int baikal_vdu_primary_plane_atomic_check(struct drm_plane *plane,
struct drm_crtc_state *crtc_state;
struct drm_display_mode *mode;
int rate, ret;
+ u32 cntl;
if (!state->crtc)
return 0;
@@ -86,6 +50,9 @@ static int baikal_vdu_primary_plane_atomic_check(struct drm_plane *plane,
if (rate == clk_get_rate(priv->clk))
return 0;
+ /* hold clock domain reset; disable clocking */
+ writel(0, priv->regs + PCTR);
+
if (__clk_is_enabled(priv->clk))
clk_disable_unprepare(priv->clk);
ret = clk_set_rate(priv->clk, rate);
@@ -94,15 +61,23 @@ static int baikal_vdu_primary_plane_atomic_check(struct drm_plane *plane,
if (ret < 0) {
DRM_ERROR("Cannot set desired pixel clock (%d Hz)\n",
rate);
- return -EINVAL;
- }
- clk_prepare_enable(priv->clk);
- if (!__clk_is_enabled(priv->clk)) {
- DRM_ERROR("PLL could not lock at desired frequency (%d Hz)\n",
+ ret = -EINVAL;
+ } else {
+ clk_prepare_enable(priv->clk);
+ if (__clk_is_enabled(priv->clk))
+ ret = 0;
+ else {
+ DRM_ERROR("PLL could not lock at desired frequency (%d Hz)\n",
rate);
- return -EINVAL;
+ ret = -EINVAL;
+ }
}
- return 0;
+
+ /* release clock domain reset; enable clocking */
+ cntl = readl(priv->regs + PCTR);
+ cntl |= PCTR_PCR + PCTR_PCI;
+
+ return ret;
}
static void baikal_vdu_primary_plane_atomic_update(struct drm_plane *plane,
@@ -112,28 +87,13 @@ static void baikal_vdu_primary_plane_atomic_update(struct drm_plane *plane,
struct baikal_vdu_private *priv = dev->dev_private;
struct drm_plane_state *state = plane->state;
struct drm_framebuffer *fb = state->fb;
- struct arm_smccc_res res;
u32 cntl, addr, end;
- unsigned long flags;
if (!fb)
return;
addr = drm_fb_cma_get_gem_addr(fb, state, 0);
- end = ((addr + fb->height * fb->pitches[0] - 1) & MRR_DEAR_MRR_MASK) | MRR_OUTSTND_RQ(4);
-
- spin_lock_irqsave(&priv->lock, flags);
- arm_smccc_smc(BAIKAL_SMC_VDU_UPDATE_HDMI, addr, end, 0, 0, 0, 0, 0, &res);
- spin_unlock_irqrestore(&priv->lock, flags);
-
- if (res.a0 == -EBUSY) {
- priv->counters[15]++;
- priv->fb_addr = addr;
- priv->fb_end = end;
- smp_wmb();
- schedule_delayed_work(&priv->update_work, usecs_to_jiffies(250));
- } else
- priv->counters[16]++;
+ priv->fb_addr = addr & 0xfffffff8;
cntl = readl(priv->regs + CR1);
cntl &= ~CR1_BPP_MASK;
@@ -178,6 +138,14 @@ static void baikal_vdu_primary_plane_atomic_update(struct drm_plane *plane,
break;
}
+ writel(priv->fb_addr, priv->regs + DBAR);
+ end = ((priv->fb_addr + fb->height * fb->pitches[0] - 1) & MRR_DEAR_MRR_MASK) | \
+ MRR_OUTSTND_RQ(4);
+
+ if (priv->fb_end < end) {
+ writel(end, priv->regs + MRR);
+ priv->fb_end = end;
+ }
writel(cntl, priv->regs + CR1);
}
--
2.31.1

View file

@ -1,6 +1,3 @@
From 190b6e5664f8a541f0f38da5dff65d39adf1b549 Mon Sep 17 00:00:00 2001
From: Alexey Sheplyakov <asheplyakov@altlinux.org>
Date: Tue, 16 Feb 2021 17:12:40 +0400
Subject: [PATCH 619/625] panfrost: compatibility with Baikal-M firmware from Subject: [PATCH 619/625] panfrost: compatibility with Baikal-M firmware from
SDK-M 4.3 SDK-M 4.3
@ -9,22 +6,17 @@ systems with firmware from SDK-M 4.3.
Note: the driver should be explicitly enabled with Note: the driver should be explicitly enabled with
enable_broken_machines=y module parameter enable_broken_machines=y module parameter
---
drivers/gpu/drm/panfrost/panfrost_drv.c | 1 + Update for 5.15.28
1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c
index 689be734ed20..7376b17bc44a 100644
--- a/drivers/gpu/drm/panfrost/panfrost_drv.c --- a/drivers/gpu/drm/panfrost/panfrost_drv.c
+++ b/drivers/gpu/drm/panfrost/panfrost_drv.c +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
@@ -681,6 +681,7 @@ static const struct of_device_id dt_match[] = { @@ -655,6 +655,7 @@
{ .compatible = "arm,mali-t860", .data = &default_data, },
{ .compatible = "arm,mali-t880", .data = &default_data, }, { .compatible = "arm,mali-t880", .data = &default_data, },
{ .compatible = "arm,mali-bifrost", .data = &default_data, }, { .compatible = "arm,mali-bifrost", .data = &default_data, },
{ .compatible = "mediatek,mt8183-mali", .data = &mediatek_mt8183_data },
+ { .compatible = "arm,mali-midgard", .data = &default_data, }, + { .compatible = "arm,mali-midgard", .data = &default_data, },
{} {}
}; };
MODULE_DEVICE_TABLE(of, dt_match); MODULE_DEVICE_TABLE(of, dt_match);
--
2.31.1

View file

@ -1,136 +0,0 @@
From 7c3c753e3d32b250467bcc172f5abeb08dead01e Mon Sep 17 00:00:00 2001
From: Alexey Sheplyakov <asheplyakov@altlinux.org>
Date: Fri, 19 Feb 2021 12:55:03 +0400
Subject: [PATCH 620/625] cpufreq-dt: don't load on BE-M1000 SoC
Apparently the driver deadlocks the kernel in a few minutes:
[ 454.690508] rcu: INFO: rcu_preempt detected stalls on CPUs/tasks:
[ 454.696839] (detected by 4, t=26002 jiffies, g=22561, q=15)
[ 454.703017] rcu: All QSes seen, last rcu_preempt kthread activity 25992 (4295121102-4295095110), jiffies_till_next_fqs=3, root ->qsmask 0x0
[ 454.715570] rcu: rcu_preempt kthread starved for 25992 jiffies! g22561 f0x2 RCU_GP_WAIT_FQS(5) ->state=0x200 ->cpu=1
[ 454.726117] rcu: Unless rcu_preempt kthread gets sufficient CPU time, OOM is now expected behavior.
[ 454.735273] rcu: RCU grace-period kthread stack dump:
[ 454.740344] task:rcu_preempt state:R stack: 0 pid: 13 ppid: 2 flags:0x00000028
[ 454.748731] Call trace:
[ 454.751204] __switch_to+0x114/0x170
[ 454.754803] __schedule+0x370/0xa3c
[ 454.758310] schedule+0x50/0x104
[ 454.761557] schedule_timeout+0x9c/0x114
[ 454.765503] rcu_gp_kthread+0x598/0xb50
[ 454.769360] kthread+0x150/0x160
[ 454.772607] ret_from_fork+0x10/0x38
[ 454.778130]
[ 454.779631] ================================
[ 454.783912] WARNING: inconsistent lock state
[ 454.788196] 5.10.17-00041-g454ed3004040-dirty #1 Not tainted
[ 454.793867] --------------------------------
[ 454.798147] inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage.
[ 454.804168] swapper/4/0 [HC0[0]:SC1[1]:HE0:SE0] takes:
[ 454.809319] ffff800011198498 (rcu_node_0){?.-.}-{2:2}, at: rcu_sched_clock_irq+0x480/0xce0
[ 454.817615] {IN-HARDIRQ-W} state was registered at:
[ 454.822508] __lock_acquire+0xad8/0x2094
[ 454.826530] lock_acquire.part.0+0xfc/0x360
[ 454.830813] lock_acquire+0x68/0x84
[ 454.834399] _raw_spin_lock_irqsave+0x84/0x158
[ 454.838941] rcu_exp_handler+0xcc/0x140
[ 454.842878] flush_smp_call_function_queue+0xec/0x304
[ 454.848029] generic_smp_call_function_single_interrupt+0x20/0x2c
[ 454.854225] ipi_handler+0x1d8/0x39c
[ 454.857899] handle_percpu_devid_fasteoi_ipi+0xb0/0xe0
[ 454.863137] __handle_domain_irq+0xbc/0x13c
[ 454.867419] gic_handle_irq+0xcc/0x14c
[ 454.871265] el1_irq+0xc4/0x180
[ 454.874504] lock_acquire.part.0+0x120/0x360
[ 454.878873] lock_acquire+0x68/0x84
[ 454.882461] lock_page_memcg+0x5c/0x150
[ 454.886399] page_add_file_rmap+0x28/0x27c
[ 454.890595] alloc_set_pte+0xb8/0x5c0
[ 454.894356] filemap_map_pages+0x4a4/0x4c0
[ 454.898551] handle_mm_fault+0xbcc/0xf50
[ 454.902572] do_page_fault+0x14c/0x404
[ 454.906418] do_translation_fault+0xbc/0xd8
[ 454.910701] do_mem_abort+0x4c/0xac
[ 454.914287] el0_ia+0x68/0xcc
[ 454.917351] el0_sync_handler+0x180/0x1b0
[ 454.921458] el0_sync+0x174/0x180
[ 454.924868] irq event stamp: 449729
[ 454.928368] hardirqs last enabled at (449725): [<ffff8000109fcf74>] default_idle_call+0x24/0xdc
[ 454.937171] hardirqs last disabled at (449726): [<ffff8000109f27a0>] enter_el1_irq_or_nmi+0x10/0x20
[ 454.946237] softirqs last enabled at (449728): [<ffff8000100532f0>] _local_bh_enable+0x30/0x54
[ 454.954952] softirqs last disabled at (449729): [<ffff8000100534c4>] __irq_exit_rcu+0x1b0/0x1bc
[ 454.963665]
[ 454.963665] other info that might help us debug this:
[ 454.970206] Possible unsafe locking scenario:
[ 454.970206]
[ 454.976136] CPU0
[ 454.978590] ----
[ 454.981043] lock(rcu_node_0);
[ 454.984198] <Interrupt>
[ 454.986825] lock(rcu_node_0);
[ 454.990155]
[ 454.990155] *** DEADLOCK ***
[ 454.990155]
[ 454.996087] 1 lock held by swapper/4/0:
[ 454.999932] #0: ffff800011198498 (rcu_node_0){?.-.}-{2:2}, at: rcu_sched_clock_irq+0x480/0xce0
[ 455.008662]
[ 455.008662] stack backtrace:
[ 455.013033] CPU: 4 PID: 0 Comm: swapper/4 Not tainted 5.10.17-00041-g454ed3004040-dirty #1
[ 455.021313] Hardware name: Baikal Electronics Baikal-M mitx board (DT)
[ 455.027854] Call trace:
[ 455.030311] dump_backtrace+0x0/0x1e4
[ 455.033985] show_stack+0x24/0x80
[ 455.037312] dump_stack+0xec/0x154
[ 455.040723] print_usage_bug.part.0+0x208/0x22c
[ 455.045265] mark_lock+0x88c/0x934
[ 455.048677] mark_held_locks+0x58/0x90
[ 455.052437] lockdep_hardirqs_on_prepare+0xe4/0x23c
[ 455.057330] trace_hardirqs_on+0x78/0x2e0
[ 455.061350] __do_softirq+0x114/0x6d0
[ 455.065022] __irq_exit_rcu+0x1b0/0x1bc
[ 455.068868] irq_exit+0x1c/0x54
[ 455.072020] __handle_domain_irq+0xc0/0x13c
[ 455.076214] gic_handle_irq+0xcc/0x14c
[ 455.079972] el1_irq+0xc4/0x180
[ 455.083124] arch_cpu_idle+0x18/0x30
[ 455.086710] default_idle_call+0x5c/0xdc
[ 455.090645] do_idle+0x260/0x2e0
[ 455.093883] cpu_startup_entry+0x30/0x8c
[ 455.097818] secondary_start_kernel+0x138/0x184
[ 455.102410] BUG: scheduling while atomic: swapper/4/0/0x00000002
[ 455.108449] INFO: lockdep is turned off.
[ 455.112399] Modules linked in: dm_mod designware_i2s sdhci_of_dwcmshc snd_soc_core sdhci_pltfm dw_hdmi_ahb_audio snd_pcm_dmaengine ac97_bus evdev sdhci snd_pcm at24 panfrost mmc_core snd_timer pcie_baikal_v44 snd pcie_baikal bt1_pvt gpu_sched soundcore cpufreq_dt fuse configfs efivarfs ipv6
[ 455.138295] Preemption disabled at:
[ 455.138305] [<ffff800010028c64>] secondary_start_kernel+0xb4/0x184
[ 455.148020] CPU: 4 PID: 0 Comm: swapper/4 Not tainted 5.10.17-00041-g454ed3004040-dirty #1
[ 455.156299] Hardware name: Baikal Electronics Baikal-M mitx board (DT)
[ 455.162840] Call trace:
[ 455.165296] dump_backtrace+0x0/0x1e4
[ 455.168969] show_stack+0x24/0x80
[ 455.172295] dump_stack+0xec/0x154
[ 455.175711] __schedule_bug+0xcc/0xe0
[ 455.179383] __schedule+0x928/0xa3c
[ 455.182881] schedule_idle+0x34/0x5c
[ 455.186467] do_idle+0x1dc/0x2e0
[ 455.189706] cpu_startup_entry+0x30/0x8c
[ 455.193640] secondary_start_kernel+0x138/0x184
---
drivers/cpufreq/cpufreq-dt-platdev.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
index 1c192a42f11e..2885ad3779bf 100644
--- a/drivers/cpufreq/cpufreq-dt-platdev.c
+++ b/drivers/cpufreq/cpufreq-dt-platdev.c
@@ -105,6 +105,8 @@ static const struct of_device_id blacklist[] __initconst = {
{ .compatible = "arm,vexpress", },
+ { .compatible = "baikal,baikal-m", },
+
{ .compatible = "calxeda,highbank", },
{ .compatible = "calxeda,ecx-2000", },
--
2.31.1

View file

@ -1,38 +0,0 @@
From 3a2d37d8f2aacdd8711f0f90a4c04d75eccd7a1f Mon Sep 17 00:00:00 2001
From: Alexey Sheplyakov <asheplyakov@altlinux.org>
Date: Fri, 19 Feb 2021 12:38:34 +0400
Subject: [PATCH 621/625] baikal_clk: compatibility with SDK-M 5.1 firmware
Without this patch the kernel seems to locks up within 10 -- 20 seconds
after the boot on a board with firmware from SDK-M 5.1
baikal_clk_set_rate: fixed parent rate calculation (from SDK-M 4.4)
---
drivers/clk/baikal/clk-baikal.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/baikal/clk-baikal.c b/drivers/clk/baikal/clk-baikal.c
index ddf1d328eeaf..d9709322b2ee 100644
--- a/drivers/clk/baikal/clk-baikal.c
+++ b/drivers/clk/baikal/clk-baikal.c
@@ -181,11 +181,15 @@ static int baikal_clk_set_rate(struct clk_hw *hw, unsigned long rate,
struct arm_smccc_res res;
struct baikal_clk_cmu *pclk = to_baikal_cmu(hw);
uint32_t cmd;
+ unsigned long parent;
- if (pclk->is_clk_ch)
+ if (pclk->is_clk_ch) {
cmd = CMU_CLK_CH_SET_RATE;
- else
+ parent = pclk->parent;
+ } else {
cmd = CMU_PLL_SET_RATE;
+ parent = parent_rate;
+ }
pr_debug("[%s, %x:%d:%s] %s, %ld\n",
pclk->name,
--
2.31.1

View file

@ -1,106 +0,0 @@
From ae07645b9fa53d7e863dc49998c266333d34906a Mon Sep 17 00:00:00 2001
From: Alexey Sheplyakov <asheplyakov@altlinux.org>
Date: Wed, 24 Feb 2021 13:46:49 +0400
Subject: [PATCH 622/625] stmmac_mdio: implemented reset via MAC GP out pin
BE-M1000 variant of stmmac mdio needs a special reset routine.
Related: #39714
---
.../net/ethernet/stmicro/stmmac/stmmac_mdio.c | 68 ++++++++++++++++++-
1 file changed, 66 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
index b2a707e2ef43..fa7b13e932e3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -287,6 +287,63 @@ static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
100, 10000);
}
+#define MAC_GPIO 0xe0 /* GPIO register */
+#define MAC_GPIO_GPO0 (1 << 8) /* 0-output port */
+
+/**
+ * Reset the MII bus via MAC GP out pin
+ */
+static int stmmac_mdio_reset_gp_out(struct stmmac_priv *priv) {
+#if IS_ENABLED(CONFIG_STMMAC_PLATFORM) && IS_ENABLED(CONFIG_OF)
+ u32 value, high, low;
+ u32 delays[3] = { 0, 0, 0 };
+ bool active_low = false;
+ struct device_node *np = priv->device->of_node;
+
+ if (!np)
+ return -ENODEV;
+
+ if (!of_property_read_bool(np, "snps,reset-gp-out")) {
+ dev_warn(priv->device, "snps,reset-gp-out is not set\n");
+ return -ENODEV;
+ }
+
+ active_low = of_property_read_bool(np, "snsps,reset-active-low");
+ of_property_read_u32_array(np, "snps,reset-delays-us", delays, 3);
+
+ value = readl(priv->ioaddr + MAC_GPIO);
+ if (active_low) {
+ high = value | MAC_GPIO_GPO0;
+ low = value & ~MAC_GPIO_GPO0;
+ } else {
+ high = value & ~MAC_GPIO_GPO0;
+ low = value | MAC_GPIO_GPO0;
+ }
+
+ writel(high, priv->ioaddr + MAC_GPIO);
+ if (delays[0])
+ msleep(DIV_ROUND_UP(delays[0], 1000));
+
+ writel(low, priv->ioaddr + MAC_GPIO);
+ if (delays[1])
+ msleep(DIV_ROUND_UP(delays[1], 1000));
+
+ writel(high, priv->ioaddr + MAC_GPIO);
+ if (delays[2])
+ msleep(DIV_ROUND_UP(delays[2], 1000));
+
+ /* Clear PHY reset */
+ udelay(10);
+ value = readl(priv->ioaddr + MAC_GPIO);
+ value |= MAC_GPIO_GPO0;
+ writel(value, priv->ioaddr + MAC_GPIO);
+ mdelay(1000);
+ dev_info(priv->device, "mdio reset completed\n");
+ return 0;
+#endif
+ return -ENODEV;
+}
+
/**
* stmmac_mdio_reset
* @bus: points to the mii_bus structure
@@ -302,13 +359,20 @@ int stmmac_mdio_reset(struct mii_bus *bus)
#ifdef CONFIG_OF
if (priv->device->of_node) {
struct gpio_desc *reset_gpio;
+ bool need_reset_gp_out;
u32 delays[3] = { 0, 0, 0 };
reset_gpio = devm_gpiod_get_optional(priv->device,
"snps,reset",
GPIOD_OUT_LOW);
- if (IS_ERR(reset_gpio))
- return PTR_ERR(reset_gpio);
+ if (IS_ERR(reset_gpio)) {
+ need_reset_gp_out = of_property_read_bool(priv->device->of_node,
+ "snps,reset-gp-out");
+ if (need_reset_gp_out)
+ return stmmac_mdio_reset_gp_out(priv);
+ else
+ return PTR_ERR(reset_gpio);
+ }
device_property_read_u32_array(priv->device,
"snps,reset-delays-us",
--
2.31.1

View file

@ -1,60 +0,0 @@
From b7110f36a3ea12867eabcd5caeb104d23e1a3f4a Mon Sep 17 00:00:00 2001
From: Alexey Sheplyakov <asheplyakov@altlinux.org>
Date: Wed, 24 Feb 2021 16:45:30 +0400
Subject: [PATCH 623/625] dwmac_baikal: clear PHY reset before calling generic
setup routine
Without this attaching to Micrel PHY fails with the following error:
[ 17.596114] Micrel KSZ9031 Gigabit PHY stmmac-2:03: phy_poll_reset failed: -110
[ 17.603602] baikal-dwmac 30250000.eth1 eth1: no phy at addr -1
[ 17.609468] baikal-dwmac 30250000.eth1 eth1: stmmac_open: Cannot attach to PHY (error: -19)
Closes: #39714
---
.../net/ethernet/stmicro/stmmac/dwmac-baikal.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-baikal.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-baikal.c
index 646051cd500d..e706ece9b4f5 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-baikal.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-baikal.c
@@ -34,6 +34,14 @@ struct baikal_dwmac {
struct clk *tx2_clk;
};
+static void clear_phy_reset(void __iomem *ioaddr)
+{
+ u32 value;
+ value = readl(ioaddr + MAC_GPIO);
+ value |= MAC_GPIO_GPO0;
+ writel(value, ioaddr + MAC_GPIO);
+}
+
static int baikal_dwmac_dma_reset(void __iomem *ioaddr)
{
int err;
@@ -44,10 +52,7 @@ static int baikal_dwmac_dma_reset(void __iomem *ioaddr)
writel(value, ioaddr + DMA_BUS_MODE);
udelay(10);
- /* Clear PHY reset */
- value = readl(ioaddr + MAC_GPIO);
- value |= MAC_GPIO_GPO0;
- writel(value, ioaddr + MAC_GPIO);
+ clear_phy_reset(ioaddr);
pr_info("PHY re-inited for Baikal DWMAC\n");
err = readl_poll_timeout(ioaddr + DMA_BUS_MODE, value,
@@ -90,6 +95,8 @@ static struct mac_device_info* baikal_dwmac_setup(void *ppriv)
if (!mac)
return NULL;
+ clear_phy_reset(priv->ioaddr);
+
mac->dma = &baikal_dwmac_dma_ops;
old_mac = priv->hw;
priv->hw = mac;
--
2.31.1

View file

@ -1,101 +0,0 @@
From c0b58206fc41cad2dcf7ae9193d69aafdce89173 Mon Sep 17 00:00:00 2001
From: Alexey Sheplyakov <asheplyakov@altlinux.org>
Date: Mon, 29 Mar 2021 12:22:11 +0400
Subject: [PATCH 624/625] (BROKEN) dwc-i2s: support BE-M1000 SoC
* dw_i2s_probe: request all IRQs specified in device tree
* dw_i2s_startup: set the correct DAI clock frequency
Note that the sound frequency is distorted (i.e. playing 440 Hz
sine wave results in 467 Hz), for more details see
https://github.com/edelweiss-tech/kernel/issues/2
---
sound/soc/dwc/dwc-i2s.c | 36 ++++++++++++++++++++++++++----------
sound/soc/dwc/local.h | 1 +
2 files changed, 27 insertions(+), 10 deletions(-)
diff --git a/sound/soc/dwc/dwc-i2s.c b/sound/soc/dwc/dwc-i2s.c
index fd4160289fac..e1efad33b522 100644
--- a/sound/soc/dwc/dwc-i2s.c
+++ b/sound/soc/dwc/dwc-i2s.c
@@ -100,6 +100,7 @@ static inline void i2s_enable_irqs(struct dw_i2s_dev *dev, u32 stream,
static irqreturn_t i2s_irq_handler(int irq, void *dev_id)
{
+ unsigned int rxor_count;
struct dw_i2s_dev *dev = dev_id;
bool irq_valid = false;
u32 isr[4];
@@ -136,9 +137,13 @@ static irqreturn_t i2s_irq_handler(int irq, void *dev_id)
irq_valid = true;
}
- /* Error Handling: TX */
+ /* Error Handling: RX */
if (isr[i] & ISR_RXFO) {
- dev_err(dev->dev, "RX overrun (ch_id=%d)\n", i);
+ rxor_count = READ_ONCE(dev->rx_overrun_count);
+ if (!(rxor_count & 0x3ff))
+ dev_dbg(dev->dev, "RX overrun (ch_id=%d)\n", i);
+ rxor_count++;
+ WRITE_ONCE(dev->rx_overrun_count, rxor_count);
irq_valid = true;
}
}
@@ -622,7 +627,8 @@ static int dw_i2s_probe(struct platform_device *pdev)
const struct i2s_platform_data *pdata = pdev->dev.platform_data;
struct dw_i2s_dev *dev;
struct resource *res;
- int ret, irq;
+ int ret, irq, irq_count;
+ unsigned idx;
struct snd_soc_dai_driver *dw_i2s_dai;
const char *clk_id;
@@ -643,13 +649,23 @@ static int dw_i2s_probe(struct platform_device *pdev)
dev->dev = &pdev->dev;
- irq = platform_get_irq(pdev, 0);
- if (irq >= 0) {
- ret = devm_request_irq(&pdev->dev, irq, i2s_irq_handler, 0,
- pdev->name, dev);
- if (ret < 0) {
- dev_err(&pdev->dev, "failed to request irq\n");
- return ret;
+ irq_count = platform_irq_count(pdev);
+ if (irq_count < 0) /* - EPROBE_DEFER */
+ return irq_count;
+ else if (!irq_count) {
+ dev_err(&pdev->dev, "no IRQs found for device\n");
+ return -ENODEV;
+ }
+
+ for (idx = 0; idx < (unsigned)irq_count; idx++) {
+ irq = platform_get_irq(pdev, idx);
+ if (irq >= 0) {
+ ret = devm_request_irq(&pdev->dev, irq, i2s_irq_handler, 0,
+ pdev->name, dev);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to request irq\n");
+ return ret;
+ }
}
}
diff --git a/sound/soc/dwc/local.h b/sound/soc/dwc/local.h
index 91dc70a826f8..49167d89daae 100644
--- a/sound/soc/dwc/local.h
+++ b/sound/soc/dwc/local.h
@@ -117,6 +117,7 @@ struct dw_i2s_dev {
bool *period_elapsed);
unsigned int tx_ptr;
unsigned int rx_ptr;
+ unsigned int rx_overrun_count;
};
#if IS_ENABLED(CONFIG_SND_DESIGNWARE_PCM)
--
2.31.1

View file

@ -1,548 +0,0 @@
From d38a793e0efeb27e49b1ac0bad855f49f840684b Mon Sep 17 00:00:00 2001
From: Alexey Sheplyakov <asheplyakov@altlinux.org>
Date: Tue, 16 Mar 2021 12:45:43 +0400
Subject: [PATCH 625/625] baikal_vdu_drm: (LVDS) panel support
---
drivers/gpu/drm/baikal/Makefile | 2 -
drivers/gpu/drm/baikal/baikal_vdu_connector.c | 54 ++++++++++++------
drivers/gpu/drm/baikal/baikal_vdu_crtc.c | 55 ++++++++++++++-----
drivers/gpu/drm/baikal/baikal_vdu_drm.h | 32 +++--------
drivers/gpu/drm/baikal/baikal_vdu_drv.c | 42 ++++++++------
drivers/gpu/drm/baikal/baikal_vdu_encoder.c | 51 -----------------
drivers/gpu/drm/baikal/baikal_vdu_gem.c | 37 -------------
drivers/gpu/drm/baikal/baikal_vdu_regs.h | 13 +----
8 files changed, 113 insertions(+), 173 deletions(-)
delete mode 100644 drivers/gpu/drm/baikal/baikal_vdu_encoder.c
delete mode 100644 drivers/gpu/drm/baikal/baikal_vdu_gem.c
diff --git a/drivers/gpu/drm/baikal/Makefile b/drivers/gpu/drm/baikal/Makefile
index 4c3e9e67befb..eb029494e823 100644
--- a/drivers/gpu/drm/baikal/Makefile
+++ b/drivers/gpu/drm/baikal/Makefile
@@ -2,8 +2,6 @@
baikal_vdu_drm-y += baikal_vdu_connector.o \
baikal_vdu_crtc.o \
baikal_vdu_drv.o \
- baikal_vdu_encoder.o \
- baikal_vdu_gem.o \
baikal_vdu_plane.o
baikal_vdu_drm-$(CONFIG_DEBUG_FS) += baikal_vdu_debugfs.o
diff --git a/drivers/gpu/drm/baikal/baikal_vdu_connector.c b/drivers/gpu/drm/baikal/baikal_vdu_connector.c
index ca48e230f174..2f20cf3da627 100644
--- a/drivers/gpu/drm/baikal/baikal_vdu_connector.c
+++ b/drivers/gpu/drm/baikal/baikal_vdu_connector.c
@@ -34,6 +34,9 @@
#include "baikal_vdu_drm.h"
#include "baikal_vdu_regs.h"
+#define to_baikal_vdu_private(x) \
+ container_of(x, struct baikal_vdu_private, connector)
+
static void baikal_vdu_drm_connector_destroy(struct drm_connector *connector)
{
drm_connector_unregister(connector);
@@ -43,10 +46,9 @@ static void baikal_vdu_drm_connector_destroy(struct drm_connector *connector)
static enum drm_connector_status baikal_vdu_drm_connector_detect(
struct drm_connector *connector, bool force)
{
- struct baikal_vdu_drm_connector *vdu_connector =
- to_baikal_vdu_drm_connector(connector);
+ struct baikal_vdu_private *priv = to_baikal_vdu_private(connector);
- return (vdu_connector->panel ?
+ return (priv->panel ?
connector_status_connected :
connector_status_disconnected);
}
@@ -54,24 +56,18 @@ static enum drm_connector_status baikal_vdu_drm_connector_detect(
static int baikal_vdu_drm_connector_helper_get_modes(
struct drm_connector *connector)
{
- struct baikal_vdu_drm_connector *vdu_connector =
- to_baikal_vdu_drm_connector(connector);
+ struct baikal_vdu_private *priv = to_baikal_vdu_private(connector);
- if (!vdu_connector) {
- pr_err("%s: vdu_connector == NULL\n", __func__);
- return 0;
- }
- if (!vdu_connector->panel)
+ if (!priv->panel)
return 0;
- return drm_panel_get_modes(vdu_connector->panel, connector);
+ return drm_panel_get_modes(priv->panel, connector);
}
const struct drm_connector_funcs connector_funcs = {
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = baikal_vdu_drm_connector_destroy,
.detect = baikal_vdu_drm_connector_detect,
- //.dpms = drm_atomic_helper_connector_dpms, // TODO enable it?
.reset = drm_atomic_helper_connector_reset,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
@@ -85,14 +81,38 @@ static const struct drm_encoder_funcs encoder_funcs = {
.destroy = drm_encoder_cleanup,
};
-int baikal_vdu_connector_create(struct drm_device *dev)
+int baikal_vdu_lvds_connector_create(struct drm_device *dev)
{
struct baikal_vdu_private *priv = dev->dev_private;
- struct baikal_vdu_drm_connector *vdu_connector = &priv->connector;
- struct drm_connector *connector = &vdu_connector->connector;
+ struct drm_connector *connector = &priv->connector;
+ struct drm_encoder *encoder = &priv->encoder;
+ int ret = 0;
- drm_connector_init(dev, connector, &connector_funcs,
+ ret = drm_connector_init(dev, connector, &connector_funcs,
DRM_MODE_CONNECTOR_LVDS);
+ if (ret) {
+ dev_err(dev->dev, "drm_connector_init failed: %d\n", ret);
+ goto out;
+ }
drm_connector_helper_add(connector, &connector_helper_funcs);
- return 0;
+ ret = drm_encoder_init(dev, encoder, &encoder_funcs,
+ DRM_MODE_ENCODER_LVDS, NULL);
+ if (ret) {
+ dev_err(dev->dev, "drm_encoder_init failed: %d\n", ret);
+ goto out;
+ }
+ encoder->crtc = &priv->crtc;
+ encoder->possible_crtcs = drm_crtc_mask(encoder->crtc);
+ ret = drm_connector_attach_encoder(connector, encoder);
+ if (ret) {
+ dev_err(dev->dev, "drm_connector_attach_encoder failed: %d\n", ret);
+ goto out;
+ }
+ ret = drm_connector_register(connector);
+ if (ret) {
+ dev_err(dev->dev, "drm_connector_register failed: %d\n", ret);
+ goto out;
+ }
+out:
+ return ret;
}
diff --git a/drivers/gpu/drm/baikal/baikal_vdu_crtc.c b/drivers/gpu/drm/baikal/baikal_vdu_crtc.c
index 6ef61791e299..d8bc1182bb77 100644
--- a/drivers/gpu/drm/baikal/baikal_vdu_crtc.c
+++ b/drivers/gpu/drm/baikal/baikal_vdu_crtc.c
@@ -134,8 +134,13 @@ static void baikal_vdu_crtc_helper_mode_set_nofb(struct drm_crtc *crtc)
drm_mode_debug_printmodeline(mode);
ppl = mode->hdisplay / 16;
- hsw = mode->hsync_end - mode->hsync_start - 1;
- hfp = mode->hsync_start - mode->hdisplay;
+ if (priv->panel) {
+ hsw = mode->hsync_end - mode->hsync_start;
+ hfp = mode->hsync_start - mode->hdisplay - 1;
+ } else {
+ hsw = mode->hsync_end - mode->hsync_start - 1;
+ hfp = mode->hsync_start - mode->hdisplay;
+ }
hbp = mode->htotal - mode->hsync_end;
lpp = mode->vdisplay;
@@ -188,12 +193,15 @@ static void baikal_vdu_crtc_helper_enable(struct drm_crtc *crtc,
struct drm_crtc_state *old_state)
{
struct baikal_vdu_private *priv = crtc->dev->dev_private;
- u32 cntl;
+ struct drm_panel *panel = priv->panel;
+ struct device_node *panel_node;
+ const char *data_mapping;
+ u32 cntl, gpio;
DRM_DEV_DEBUG_DRIVER(crtc->dev->dev, "enabling pixel clock\n");
clk_prepare_enable(priv->clk);
- drm_panel_prepare(priv->connector.panel);
+ drm_panel_prepare(panel);
writel(ISCR_VSC_VFP, priv->regs + ISCR);
@@ -202,13 +210,37 @@ static void baikal_vdu_crtc_helper_enable(struct drm_crtc *crtc,
cntl |= PCTR_PCR + PCTR_PCI;
writel(cntl, priv->regs + PCTR);
- /* Set 16-word input FIFO watermark and 24-bit LCD interface mode */
+ /* Set 16-word input FIFO watermark */
/* Enable and Power Up */
cntl = readl(priv->regs + CR1);
- cntl |= CR1_LCE + CR1_FDW_16_WORDS + CR1_OPS_LCD24;
+ cntl &= ~CR1_FDW_MASK;
+ cntl |= CR1_LCE + CR1_FDW_16_WORDS;
+
+ if (priv->type == VDU_TYPE_LVDS) {
+ panel_node = panel->dev->of_node;
+ if (of_property_read_string(panel_node, "data-mapping", &data_mapping)) {
+ cntl |= CR1_OPS_LCD18;
+ } else if (strncmp(data_mapping, "vesa-24", 7))
+ cntl |= CR1_OPS_LCD24;
+ else if (strncmp(data_mapping, "jeida-18", 8))
+ cntl |= CR1_OPS_LCD18;
+ else {
+ dev_warn(crtc->dev->dev, "%s data mapping is not supported, vesa-24 is set\n", data_mapping);
+ cntl |= CR1_OPS_LCD24;
+ }
+ gpio = GPIOR_UHD_ENB;
+ if (priv->ep_count == 4)
+ gpio |= GPIOR_UHD_QUAD_PORT;
+ else if (priv->ep_count == 2)
+ gpio |= GPIOR_UHD_DUAL_PORT;
+ else
+ gpio |= GPIOR_UHD_SNGL_PORT;
+ writel(gpio, priv->regs + GPIOR);
+ } else
+ cntl |= CR1_OPS_LCD24;
writel(cntl, priv->regs + CR1);
- drm_panel_enable(priv->connector.panel);
+ drm_panel_enable(priv->panel);
drm_crtc_vblank_on(crtc);
}
@@ -217,12 +249,9 @@ void baikal_vdu_crtc_helper_disable(struct drm_crtc *crtc)
struct baikal_vdu_private *priv = crtc->dev->dev_private;
drm_crtc_vblank_off(crtc);
- drm_panel_disable(priv->connector.panel);
+ drm_panel_disable(priv->panel);
- /* Disable and Power Down */
- //writel(0, priv->regs + CR1);
-
- drm_panel_unprepare(priv->connector.panel);
+ drm_panel_unprepare(priv->panel);
/* Disable clock */
DRM_DEV_DEBUG_DRIVER(crtc->dev->dev, "disabling pixel clock\n");
@@ -250,8 +279,6 @@ static int baikal_vdu_enable_vblank(struct drm_crtc *crtc)
{
struct baikal_vdu_private *priv = crtc->dev->dev_private;
- //clk_prepare_enable(priv->clk);
-
/* clear interrupt status */
writel(0x3ffff, priv->regs + ISR);
diff --git a/drivers/gpu/drm/baikal/baikal_vdu_drm.h b/drivers/gpu/drm/baikal/baikal_vdu_drm.h
index 2db3fb73c9e7..9ab6303a4195 100644
--- a/drivers/gpu/drm/baikal/baikal_vdu_drm.h
+++ b/drivers/gpu/drm/baikal/baikal_vdu_drm.h
@@ -23,22 +23,16 @@
#include <drm/drm_gem.h>
#include <drm/drm_simple_kms_helper.h>
-struct clk;
-struct drm_device;
-struct drm_fbdev_cma;
-struct drm_panel;
-
-struct baikal_vdu_drm_connector {
- struct drm_connector connector;
- struct drm_panel *panel;
-};
+#define VDU_TYPE_HDMI 0
+#define VDU_TYPE_LVDS 1
struct baikal_vdu_private {
struct drm_device *drm;
- struct baikal_vdu_drm_connector connector;
+ struct drm_connector connector;
struct drm_crtc crtc;
struct drm_encoder encoder;
+ struct drm_panel *panel;
struct drm_bridge *bridge;
struct drm_plane primary;
@@ -47,16 +41,12 @@ struct baikal_vdu_private {
spinlock_t lock;
u32 counters[20];
int mode_fixup;
-
+ int type;
+ u32 ep_count;
u32 fb_addr;
u32 fb_end;
};
-#define to_baikal_vdu_drm_connector(x) \
- container_of(x, struct baikal_vdu_drm_connector, connector)
-
-extern const struct drm_encoder_funcs baikal_vdu_encoder_funcs;
-
/* CRTC Functions */
int baikal_vdu_crtc_create(struct drm_device *dev);
irqreturn_t baikal_vdu_irq(int irq, void *data);
@@ -64,15 +54,7 @@ irqreturn_t baikal_vdu_irq(int irq, void *data);
int baikal_vdu_primary_plane_init(struct drm_device *dev);
/* Connector Functions */
-int baikal_vdu_connector_create(struct drm_device *dev);
-
-/* Encoder Functions */
-int baikal_vdu_encoder_init(struct drm_device *dev);
-
-/* GEM Functions */
-int baikal_vdu_dumb_create(struct drm_file *file_priv,
- struct drm_device *dev,
- struct drm_mode_create_dumb *args);
+int baikal_vdu_lvds_connector_create(struct drm_device *dev);
void baikal_vdu_debugfs_init(struct drm_minor *minor);
diff --git a/drivers/gpu/drm/baikal/baikal_vdu_drv.c b/drivers/gpu/drm/baikal/baikal_vdu_drv.c
index 5deab510ea57..8eb9dda7fa01 100644
--- a/drivers/gpu/drm/baikal/baikal_vdu_drv.c
+++ b/drivers/gpu/drm/baikal/baikal_vdu_drv.c
@@ -23,7 +23,6 @@
#include <linux/arm-smccc.h>
#include <linux/irq.h>
#include <linux/clk.h>
-#include <linux/version.h>
#include <linux/shmem_fs.h>
#include <linux/dma-buf.h>
#include <linux/module.h>
@@ -63,6 +62,10 @@ static struct drm_mode_config_funcs mode_config_funcs = {
.atomic_commit = drm_atomic_helper_commit,
};
+static const struct drm_encoder_funcs baikal_vdu_encoder_funcs = {
+ .destroy = drm_encoder_cleanup,
+};
+
static int vdu_modeset_init(struct drm_device *dev)
{
struct drm_mode_config *mode_config;
@@ -94,38 +97,35 @@ static int vdu_modeset_init(struct drm_device *dev)
}
ret = drm_of_find_panel_or_bridge(dev->dev->of_node, -1, -1,
- &priv->connector.panel,
+ &priv->panel,
&priv->bridge);
if (ret == -EPROBE_DEFER) {
dev_info(dev->dev, "Bridge probe deferred\n");
goto out_config;
}
- ret = baikal_vdu_encoder_init(dev);
- if (ret) {
- dev_err(dev->dev, "Failed to create DRM encoder\n");
- goto out_config;
- }
-
if (priv->bridge) {
+ struct drm_encoder *encoder = &priv->encoder;
+ ret = drm_encoder_init(dev, encoder, &baikal_vdu_encoder_funcs,
+ DRM_MODE_ENCODER_NONE, NULL);
+ if (ret) {
+ dev_err(dev->dev, "failed to create DRM encoder\n");
+ goto out_config;
+ }
+ encoder->crtc = &priv->crtc;
+ encoder->possible_crtcs = drm_crtc_mask(encoder->crtc);
priv->bridge->encoder = &priv->encoder;
ret = drm_bridge_attach(&priv->encoder, priv->bridge, NULL, 0);
if (ret) {
dev_err(dev->dev, "Failed to attach DRM bridge %d\n", ret);
goto out_config;
}
- } else if (priv->connector.panel) {
- ret = baikal_vdu_connector_create(dev);
+ } else if (priv->panel) {
+ ret = baikal_vdu_lvds_connector_create(dev);
if (ret) {
dev_err(dev->dev, "Failed to create DRM connector\n");
goto out_config;
}
- ret = drm_connector_attach_encoder(&priv->connector.connector,
- &priv->encoder);
- if (ret != 0) {
- dev_err(dev->dev, "Failed to attach encoder\n");
- goto out_config;
- }
} else
ret = -EINVAL;
@@ -194,7 +194,7 @@ static struct drm_driver vdu_drm_driver = {
.major = 1,
.minor = 0,
.patchlevel = 0,
- .dumb_create = baikal_vdu_dumb_create,
+ .dumb_create = drm_gem_cma_dumb_create,
.gem_create_object = drm_gem_cma_create_object_default_funcs,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
@@ -254,6 +254,14 @@ static int baikal_vdu_drm_probe(struct platform_device *pdev)
return ret;
}
+ if (pdev->dev.of_node && of_property_read_bool(pdev->dev.of_node, "lvds-out")) {
+ priv->type = VDU_TYPE_LVDS;
+ if (of_property_read_u32(pdev->dev.of_node, "num-lanes", &priv->ep_count))
+ priv->ep_count = 1;
+ }
+ else
+ priv->type = VDU_TYPE_HDMI;
+
ret = vdu_modeset_init(drm);
if (ret != 0) {
dev_err(dev, "Failed to init modeset\n");
diff --git a/drivers/gpu/drm/baikal/baikal_vdu_encoder.c b/drivers/gpu/drm/baikal/baikal_vdu_encoder.c
deleted file mode 100644
index 9081d196dac3..000000000000
--- a/drivers/gpu/drm/baikal/baikal_vdu_encoder.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2019-2020 Baikal Electronics JSC
- *
- * Author: Pavel Parkhomenko <Pavel.Parkhomenko@baikalelectronics.ru>
- *
- * Parts of this file were based on sources as follows:
- *
- * Copyright (c) 2006-2008 Intel Corporation
- * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
- * Copyright (C) 2011 Texas Instruments
- * (C) COPYRIGHT 2012-2013 ARM Limited. All rights reserved.
- *
- * This program is free software and is provided to you under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation, and any use by you of this program is subject to the terms of
- * such GNU licence.
- *
- */
-
-/**
- * baikal_vdu_encoder.c
- * Implementation of the encoder functions for Baikal Electronics BE-M1000 VDU driver
- */
-#include <linux/version.h>
-#include <linux/shmem_fs.h>
-#include <linux/dma-buf.h>
-
-#include <drm/drm_crtc_helper.h>
-
-#include "baikal_vdu_drm.h"
-
-const struct drm_encoder_funcs baikal_vdu_encoder_funcs = {
- .destroy = drm_encoder_cleanup,
-};
-
-int baikal_vdu_encoder_init(struct drm_device *dev)
-{
- struct baikal_vdu_private *priv = dev->dev_private;
- struct drm_encoder *encoder = &priv->encoder;
- int ret;
-
- ret = drm_encoder_init(dev, encoder, &baikal_vdu_encoder_funcs,
- DRM_MODE_ENCODER_NONE, NULL);
- if (ret)
- return ret;
-
- encoder->crtc = &priv->crtc;
- encoder->possible_crtcs = BIT(drm_crtc_index(encoder->crtc));
-
- return 0;
-}
diff --git a/drivers/gpu/drm/baikal/baikal_vdu_gem.c b/drivers/gpu/drm/baikal/baikal_vdu_gem.c
deleted file mode 100644
index b07566caf12c..000000000000
--- a/drivers/gpu/drm/baikal/baikal_vdu_gem.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2019-2020 Baikal Electronics JSC
- *
- * Author: Pavel Parkhomenko <Pavel.Parkhomenko@baikalelectronics.ru>
- *
- * Parts of this file were based on sources as follows:
- *
- * Copyright (c) 2006-2008 Intel Corporation
- * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
- * Copyright (C) 2011 Texas Instruments
- * (C) COPYRIGHT 2012-2013 ARM Limited. All rights reserved.
- *
- * This program is free software and is provided to you under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation, and any use by you of this program is subject to the terms of
- * such GNU licence.
- *
- */
-
-/**
- * baikal_vdu_gem.c
- * Implementation of the GEM functions for Baikal Electronics BE-M1000 VDU driver
- */
-#include <linux/version.h>
-#include <linux/shmem_fs.h>
-#include <linux/dma-buf.h>
-#include <drm/drm_crtc_helper.h>
-#include <drm/drm_gem_cma_helper.h>
-#include "baikal_vdu_drm.h"
-
-int baikal_vdu_dumb_create(struct drm_file *file_priv,
- struct drm_device *dev, struct drm_mode_create_dumb *args)
-{
- args->pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
-
- return drm_gem_cma_dumb_create_internal(file_priv, dev, args);
-}
diff --git a/drivers/gpu/drm/baikal/baikal_vdu_regs.h b/drivers/gpu/drm/baikal/baikal_vdu_regs.h
index a0d8e69eb5e6..5553fcac5fec 100644
--- a/drivers/gpu/drm/baikal/baikal_vdu_regs.h
+++ b/drivers/gpu/drm/baikal/baikal_vdu_regs.h
@@ -1,5 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C) 2019-2020 Baikal Electronics JSC
+ * Copyright (C) 2019-2021 Baikal Electronics JSC
*
* Author: Pavel Parkhomenko <Pavel.Parkhomenko@baikalelectronics.ru>
*
@@ -7,10 +8,6 @@
*
* David A Rusling
* Copyright (C) 2001 ARM Limited
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive
- * for more details.
*/
#ifndef __BAIKAL_VDU_REGS_H__
@@ -50,6 +47,7 @@
#define INTR_FER BIT(4)
#define CR1_FBP BIT(19)
+#define CR1_FDW_MASK GENMASK(17, 16)
#define CR1_FDW_4_WORDS (0 << 16)
#define CR1_FDW_8_WORDS (1 << 16)
#define CR1_FDW_16_WORDS (2 << 16)
@@ -129,15 +127,10 @@
#define HPPLOR_HPPLO(x) ((x) << 0)
#define GPIOR_UHD_MASK GENMASK(23, 16)
-#define GPIOR_UHD_FMT_LDI (0 << 20)
-#define GPIOR_UHD_FMT_VESA (1 << 20)
-#define GPIOR_UHD_FMT_JEIDA (2 << 20)
#define GPIOR_UHD_SNGL_PORT (0 << 18)
#define GPIOR_UHD_DUAL_PORT (1 << 18)
#define GPIOR_UHD_QUAD_PORT (2 << 18)
#define GPIOR_UHD_ENB BIT(17)
-#define GPIOR_UHD_PIX_INTLV (0 << 16)
-#define GPIOR_UHD_PIX_SQNTL (1 << 16)
#define MRR_DEAR_MRR_MASK GENMASK(31, 3)
#define MRR_OUTSTND_RQ_MASK GENMASK(2, 0)
--
2.31.1

View file

@ -1,45 +0,0 @@
From 7349284a3d505346b1e2913e5b04efbe9b9b32c8 Mon Sep 17 00:00:00 2001
From: "Vadim V. Vlasov" <vvv19xx@gmail.com>
Date: Fri, 16 Oct 2020 17:14:00 +0300
Subject: [PATCH] Serial: 82550_dw: Fix clock rate setting in
dw8250_set_termios()
If clk_round_rate() returns rate out of 1/16 precision range from
the desired rate, then do not change clock rate.
This usually happens if the desired rate is below the minimum
supported by the clk.
Fixes UART console on BE-M1000 SoC (without this patch the console
gets garbled after loading the driver)
---
drivers/tty/serial/8250/8250_dw.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
index 9e204f9b799a..0c29137a6583 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -329,14 +329,17 @@ dw8250_do_pm(struct uart_port *port, unsigned int state, unsigned int old)
static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios,
struct ktermios *old)
{
- unsigned long newrate = tty_termios_baud_rate(termios) * 16;
+ unsigned long baud = tty_termios_baud_rate(termios);
+ unsigned long newrate = baud * 16;
struct dw8250_data *d = to_dw8250_data(p->private_data);
long rate;
int ret;
clk_disable_unprepare(d->clk);
rate = clk_round_rate(d->clk, newrate);
- if (rate > 0) {
+ if (rate > baud * 17 || rate < baud * 15) {
+ ret = -EINVAL; /* cannot set rate with acceptable accuracy */
+ } else if (rate > 0) {
/*
* Premilinary set the uartclk to the new clock rate so the
* clock update event handler caused by the clk_set_rate()
--
2.31.1

View file

@ -1,46 +0,0 @@
From 6d1046bd245b1167b263f76b400c9426fca02113 Mon Sep 17 00:00:00 2001
From: "Vadim V. Vlasov" <vvv19xx@gmail.com>
Date: Thu, 26 Nov 2020 18:45:58 +0300
Subject: [PATCH] drm/panfrost: Fix memory attributes for Mali T620
Fix #19
---
drivers/gpu/drm/panfrost/panfrost_mmu.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c
index be8d68fb0e11..9762f3639aff 100644
--- a/drivers/gpu/drm/panfrost/panfrost_mmu.c
+++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c
@@ -123,6 +123,10 @@ static void panfrost_mmu_enable(struct panfrost_device *pfdev, struct panfrost_m
/* Need to revisit mem attrs.
* NC is the default, Mali driver is inner WT.
*/
+ if (panfrost_model_eq(pfdev, 0x620)) {
+ memattr &= ~0xf0f0f0ULL;
+ memattr |= 0x404040;
+ }
mmu_write(pfdev, AS_MEMATTR_LO(as_nr), memattr & 0xffffffffUL);
mmu_write(pfdev, AS_MEMATTR_HI(as_nr), memattr >> 32);
@@ -186,7 +190,7 @@ u32 panfrost_mmu_as_get(struct panfrost_device *pfdev, struct panfrost_mmu *mmu)
atomic_set(&mmu->as_count, 1);
list_add(&mmu->list, &pfdev->as_lru_list);
- dev_dbg(pfdev->dev, "Assigned AS%d to mmu %p, alloc_mask=%lx", as, mmu, pfdev->as_alloc_mask);
+ dev_dbg(pfdev->dev, "Assigned AS%d to mmu %px, alloc_mask=%lx", as, mmu, pfdev->as_alloc_mask);
panfrost_mmu_enable(pfdev, mmu);
@@ -287,6 +291,8 @@ int panfrost_mmu_map(struct panfrost_gem_mapping *mapping)
if (bo->noexec)
prot |= IOMMU_NOEXEC;
+ if (bo->is_heap)
+ prot |= IOMMU_CACHE;
sgt = drm_gem_shmem_get_pages_sgt(obj);
if (WARN_ON(IS_ERR(sgt)))
--
2.31.1

View file

@ -1,27 +0,0 @@
From 5192df6d13aa5ad12c5ade843a598b428760d9c0 Mon Sep 17 00:00:00 2001
From: "Vadim V. Vlasov" <vvv19xx@gmail.com>
Date: Fri, 11 Dec 2020 16:55:06 +0300
Subject: [PATCH] drm/panfrost: Trim affinity for Mali T620
libmali uses 0xf affinity instead of 0xff for jobs in slot 1.
Looks like this resolves problem with cache incoherency.
---
drivers/gpu/drm/panfrost/panfrost_job.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c b/drivers/gpu/drm/panfrost/panfrost_job.c
index 04e6f6f9b742..28a1a8f50fad 100644
--- a/drivers/gpu/drm/panfrost/panfrost_job.c
+++ b/drivers/gpu/drm/panfrost/panfrost_job.c
@@ -143,6 +143,8 @@ static void panfrost_job_write_affinity(struct panfrost_device *pfdev,
* multiple (2) coherent core groups
*/
affinity = pfdev->features.shader_present;
+ if (panfrost_model_eq(pfdev, 0x620) && js == 1)
+ affinity &= 0xf;
job_write(pfdev, JS_AFFINITY_NEXT_LO(js), affinity & 0xFFFFFFFF);
job_write(pfdev, JS_AFFINITY_NEXT_HI(js), affinity >> 32);
--
2.31.1

View file

@ -1,25 +0,0 @@
From ed685cdc61fe5da518b096a848bf9846df44fa9a Mon Sep 17 00:00:00 2001
From: Alexey Sheplyakov <asheplyakov@altlinux.org>
Date: Thu, 22 Apr 2021 15:03:04 +0400
Subject: [PATCH] baikal_vdu_drm: _plane_atomic_check: actually re-enable
clocking
---
drivers/gpu/drm/baikal/baikal_vdu_plane.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/baikal/baikal_vdu_plane.c b/drivers/gpu/drm/baikal/baikal_vdu_plane.c
index 5a047835e154..3cf04f5b97cf 100644
--- a/drivers/gpu/drm/baikal/baikal_vdu_plane.c
+++ b/drivers/gpu/drm/baikal/baikal_vdu_plane.c
@@ -76,6 +76,7 @@ static int baikal_vdu_primary_plane_atomic_check(struct drm_plane *plane,
/* release clock domain reset; enable clocking */
cntl = readl(priv->regs + PCTR);
cntl |= PCTR_PCR + PCTR_PCI;
+ writel(cntl, priv->regs + PCTR);
return ret;
}
--
2.31.1

View file

@ -1,48 +0,0 @@
From 92c85bac95a139c996ef1c9a8047c717e4455d3f Mon Sep 17 00:00:00 2001
From: Alexey Sheplyakov <asheplyakov@altlinux.org>
Date: Wed, 26 May 2021 15:23:52 +0400
Subject: [PATCH] baikal_vdu: figure out (LVDS) endpoint count
So the driver works correctly even when 'num-lanes' property is missing
in the device tree.
---
drivers/gpu/drm/baikal/baikal_vdu_drv.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/baikal/baikal_vdu_drv.c b/drivers/gpu/drm/baikal/baikal_vdu_drv.c
index 8eb9dda7fa01..f7fb3b81a9f1 100644
--- a/drivers/gpu/drm/baikal/baikal_vdu_drv.c
+++ b/drivers/gpu/drm/baikal/baikal_vdu_drv.c
@@ -71,7 +71,7 @@ static int vdu_modeset_init(struct drm_device *dev)
struct drm_mode_config *mode_config;
struct baikal_vdu_private *priv = dev->dev_private;
struct arm_smccc_res res;
- int ret = 0;
+ int ret = 0, ep_count = 0;
if (priv == NULL)
return -EINVAL;
@@ -103,6 +103,12 @@ static int vdu_modeset_init(struct drm_device *dev)
dev_info(dev->dev, "Bridge probe deferred\n");
goto out_config;
}
+ ep_count = of_graph_get_endpoint_count(dev->dev->of_node);
+ if (ep_count <= 0) {
+ dev_err(dev->dev, "no endpoints connected to panel/bridge\n");
+ goto out_config;
+ }
+ priv->ep_count = ep_count;
if (priv->bridge) {
struct drm_encoder *encoder = &priv->encoder;
@@ -121,6 +127,7 @@ static int vdu_modeset_init(struct drm_device *dev)
goto out_config;
}
} else if (priv->panel) {
+ dev_dbg(dev->dev, "panel has %d endpoints\n", priv->ep_count);
ret = baikal_vdu_lvds_connector_create(dev);
if (ret) {
dev_err(dev->dev, "Failed to create DRM connector\n");
--
2.31.1

View file

@ -1,35 +0,0 @@
From 5f6a25cbd373aa72738189356a0f606daa7bba59 Mon Sep 17 00:00:00 2001
From: Alexey Sheplyakov <asheplyakov@altlinux.org>
Date: Mon, 21 Jun 2021 15:42:47 +0400
Subject: [PATCH] panfrost: disable devfreq on BE-M1000 SoC
Enabling GPU frequency scaling on BE-M1000 cases GPU MMU lockup:
[ 38.108633] panfrost 2a200000.gpu: AS_ACTIVE bit stuck
Since GPU and CPU share the memory this locks up the whole system.
Therefore disable devfreq on BE-M1000.
---
drivers/gpu/drm/panfrost/panfrost_devfreq.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
index 8ab025d0035f..c2f46665cf33 100644
--- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c
+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
@@ -97,6 +97,12 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
struct thermal_cooling_device *cooling;
struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq;
+ if (of_device_is_compatible(of_root, "baikal,baikal-m")) {
+ dev_info(pfdev->dev, "disabling GPU devfreq on BE-M1000\n");
+ ret = 0;
+ goto err_fini;
+ }
+
opp_table = dev_pm_opp_set_regulators(dev, pfdev->comp->supply_names,
pfdev->comp->num_supplies);
if (IS_ERR(opp_table)) {
--
2.31.1

View file

@ -1,59 +0,0 @@
From a73eeb303cb72ab88dcc9c6182484300c235ca00 Mon Sep 17 00:00:00 2001
From: Alexey Sheplyakov <asheplyakov@altlinux.org>
Date: Fri, 3 Sep 2021 19:41:08 +0400
Subject: [PATCH] pm: disable all sleep states on BE-M1000 based boards
These days desktop environments try to put computer into a sleep
state after a certain period of inactivity. TF307 board is able
to enter a sleep state, however it does *NOT* wakeup via power
button or keyboard/mouse.
Apparently the only wakeup sources on TF307 board are
- Real time clock (RTC)
- Ethernet
Surprisingly BMC (board management controller) is NOT a wakeup
source. Also tp_bmc driver does not use interrupts, and polls
the device instead. Perhaps BMC is unable to generate interrupts
at all?
To avoid the problem disable all sleep states (including s2idle)
on Baikal-M systems
---
kernel/power/suspend.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index 32391acc806b..182947b94a37 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -30,6 +30,7 @@
#include <trace/events/power.h>
#include <linux/compiler.h>
#include <linux/moduleparam.h>
+#include <linux/of.h>
#include "power.h"
@@ -237,6 +238,17 @@ EXPORT_SYMBOL_GPL(suspend_valid_only_mem);
static bool sleep_state_supported(suspend_state_t state)
{
+#ifdef CONFIG_OF
+ if (of_device_is_compatible(of_root, "baikal,baikal-m")) {
+ /* XXX: there are no wakeup sources except RTC and Ethernet
+ * on BE-M1000 based boards. In other words, no way to wakeup
+ * system via the keyboard or power button.
+ * Thus even s2idle is unusable on BE-M1000 systems.
+ */
+ pr_info("%s: no useful wakeup sources on Baikal-M", __func__);
+ return false;
+ }
+#endif
return state == PM_SUSPEND_TO_IDLE || (suspend_ops && suspend_ops->enter);
}
--
2.31.1

View file

@ -1,55 +0,0 @@
From 92b5312314e5eb9f4d153c4f54ad6876c3bafc86 Mon Sep 17 00:00:00 2001
From: Alexey Sheplyakov <asheplyakov@altlinux.org>
Date: Wed, 25 Aug 2021 20:48:10 +0400
Subject: [PATCH] BE-M1000 secondary CPUs boot fix
(adaptation for changes in newer minor release of kernel 5.10.x)
---
drivers/firmware/efi/libstub/arm64-stub.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/drivers/firmware/efi/libstub/arm64-stub.c b/drivers/firmware/efi/libstub/arm64-stub.c
index 411f1546d171..d21f21b105d7 100644
--- a/drivers/firmware/efi/libstub/arm64-stub.c
+++ b/drivers/firmware/efi/libstub/arm64-stub.c
@@ -127,13 +127,6 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
efi_status_t status;
unsigned long kernel_size, kernel_memsize = 0;
u32 phys_seed = 0;
- bool force_low_reloc = need_low_alloc();
- if (force_low_reloc) {
- if (!efi_nokaslr) {
- efi_info("booting on a broken firmware, KASLR will be disabled\n");
- efi_nokaslr = true;
- }
- }
/*
* Although relocatable kernels can fix up the misalignment with
@@ -145,6 +138,14 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
*/
u64 min_kimg_align = efi_nokaslr ? MIN_KIMG_ALIGN : EFI_KIMG_ALIGN;
+ bool force_low_reloc = need_low_alloc();
+ if (force_low_reloc) {
+ if (!efi_nokaslr) {
+ efi_info("booting on a broken firmware, KASLR will be disabled\n");
+ efi_nokaslr = true;
+ }
+ }
+
if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) {
if (!efi_nokaslr) {
status = efi_get_random_bytes(sizeof(phys_seed),
@@ -187,7 +188,7 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
if (force_low_reloc) {
status = efi_low_alloc(*reserve_size,
- min_kimg_align(),
+ min_kimg_align,
reserve_addr);
if (status != EFI_SUCCESS) {
efi_err("Failed to relocate kernel, expect secondary CPUs boot failure\n");
--
2.31.1

View file

@ -28,8 +28,8 @@
%global _build_pkgcheck_srpm %(echo "%{_build_pkgcheck_srpm}" | sed -e 's,/%{name}.rpmlintrc,/kernel.rpmlintrc,') %global _build_pkgcheck_srpm %(echo "%{_build_pkgcheck_srpm}" | sed -e 's,/%{name}.rpmlintrc,/kernel.rpmlintrc,')
%define kernelversion 5 %define kernelversion 5
%define patchlevel 10 %define patchlevel 15
%define sublevel 105 %define sublevel 28
# Release number. Increase this before a rebuild. # Release number. Increase this before a rebuild.
%define rpmrel 1 %define rpmrel 1
@ -73,7 +73,7 @@
%endif %endif
# "Nickel" is a special brand for certified distros # "Nickel" is a special brand for certified distros
%if %{mdvver} == 201900 || %{mdvver} == 201905 %if %{mdvver} == 201905
%bcond_without nickel %bcond_without nickel
# Require kernel modules to be signed # Require kernel modules to be signed
%bcond_without oblig_signed_modules %bcond_without oblig_signed_modules
@ -329,10 +329,7 @@ Patch111: 0001-Remove-RPM-illegal-chars-from-module-version.patch
# https://www.altlinux.org/AltHa # https://www.altlinux.org/AltHa
# http://git.altlinux.org/gears/k/kernel-image-un-def.git # http://git.altlinux.org/gears/k/kernel-image-un-def.git
# TODO: known problem: https://bugzilla.altlinux.org/show_bug.cgi?id=38225 # TODO: known problem: https://bugzilla.altlinux.org/show_bug.cgi?id=38225
Patch201: 0001-AltHa-LSM-module.patch Patch201: 0001-altha.patch
Patch202: 0002-Documentation-for-AltHa-LSM.patch
Patch203: 0003-security-altha-altha_lsm.c-build-fixed-with-kernel-5.patch
Patch204: 0004-altha-use-path-strings-instead-of-path-structs.patch
# sent to upstream, https://patchwork.kernel.org/patch/11446123/ # sent to upstream, https://patchwork.kernel.org/patch/11446123/
Patch302: 0001-sign-file-full-functionality-with-modern-LibreSSL.patch Patch302: 0001-sign-file-full-functionality-with-modern-LibreSSL.patch
@ -357,40 +354,14 @@ Patch308: 0001-Revert-kallsyms-unexport-kallsyms_lookup_name-and-ka.patch
# Support SoC with Baikal-M (ARMv8) CPU # Support SoC with Baikal-M (ARMv8) CPU
# From http://git.altlinux.org/gears/k/kernel-image-std-def.git (many thanks!) # From http://git.altlinux.org/gears/k/kernel-image-std-def.git (many thanks!)
# They are based on sources from official SDK with patched kernel from Baikal Electronics # They are based on sources from official SDK with patched kernel from Baikal Electronics
Patch0601: 0601-Baikal-M-Kconfig-defconfig.patch Patch0601: 0601-baikalm.patch
Patch0602: 0602-Baikal-M-clock-driver.patch
Patch0603: 0603-efi-rtc-avoid-calling-efi.get_time-on-Baikal-M-board.patch
Patch0604: 0604-efi-arm-runtime-print-EFI-mapping.patch Patch0604: 0604-efi-arm-runtime-print-EFI-mapping.patch
#Patch0605: 0605-ethernet-stmmac-made-dwmac1000_-DMA-functions-availa.patch
Patch0606: 0606-stmmac-Baikal-M-dwmac-driver.patch
Patch0607: 0607-Fixed-secondary-CPUs-boot-on-BE-M1000-SoC.patch
Patch0608: 0608-Baikal-M-USB-driver.patch Patch0608: 0608-Baikal-M-USB-driver.patch
# https://bugzilla.altlinux.org/show_bug.cgi?id=40269 # https://bugzilla.altlinux.org/show_bug.cgi?id=40269
Patch0609: 0609-Baikal-M-video-unit-driver.patch Patch0609: 0609-Baikal-M-video-unit-driver.patch
Patch0610: 0610-Added-Baikal-T1-M-BMC-driver.patch
#Patch0611: 0611-dw-hdmi-ahb-audio-support-BE-M1000-SoC.patch
Patch0612: 0612-bt1-pvt.c-access-registers-via-pvt_-readl-writel-hel.patch
Patch0613: 0613-bt1-pvt-define-pvt_readl-pvt_writel-for-BE-M1000-SoC.patch
Patch0614: 0614-bt1-pvt-adjust-probing-for-BE-M1000-SoC.patch
Patch0615: 0615-bt1-pvt-added-compatible-baikal-pvt.patch
Patch0616: 0616-Baikal-M-PCIe-driver-from-SDK-M-4.3.patch Patch0616: 0616-Baikal-M-PCIe-driver-from-SDK-M-4.3.patch
Patch0617: 0617-Baikal-M-PCIe-driver-from-SDK-M-4.4.patch Patch0617: 0617-Baikal-M-PCIe-driver-from-SDK-M-4.4.patch
Patch0618: 0618-baikal_vdu-avoid-using-SMC-calls-for-updating-frameb.patch
Patch0619: 0619-panfrost-compatibility-with-Baikal-M-firmware-from-S.patch Patch0619: 0619-panfrost-compatibility-with-Baikal-M-firmware-from-S.patch
Patch0620: 0620-cpufreq-dt-don-t-load-on-BE-M1000-SoC.patch
Patch0621: 0621-baikal_clk-compatibility-with-SDK-M-5.1-firmware.patch
#Patch0622: 0622-stmmac_mdio-implemented-reset-via-MAC-GP-out-pin.patch
#Patch0623: 0623-dwmac_baikal-clear-PHY-reset-before-calling-generic-.patch
Patch0624: 0624-BROKEN-dwc-i2s-support-BE-M1000-SoC.patch
Patch0625: 0625-baikal_vdu_drm-LVDS-panel-support.patch
Patch0626: 0626-Serial-82550_dw-Fix-clock-rate-setting-in-dw8250_set.patch
Patch0627: 0627-drm-panfrost-Fix-memory-attributes-for-Mali-T620.patch
Patch0628: 0628-drm-panfrost-Trim-affinity-for-Mali-T620.patch
Patch0629: 0629-baikal_vdu_drm-_plane_atomic_check-actually-re-enabl.patch
Patch0630: 0630-baikal_vdu-figure-out-LVDS-endpoint-count.patch
Patch0631: 0631-panfrost-disable-devfreq-on-BE-M1000-SoC.patch
Patch0632: 0632-pm-disable-all-sleep-states-on-BE-M1000-based-boards.patch
Patch0633: 0633-BE-M1000-secondary-CPUs-boot-fix.patch
# Disable AutoReq # Disable AutoReq
AutoReq: 0 AutoReq: 0
@ -418,6 +389,9 @@ BuildRequires: xz
BuildRequires: zstd BuildRequires: zstd
%endif %endif
%endif %endif
%ifarch aarch64
BuildRequires: uboot-tools
%endif
BuildRequires: kmod-devel BuildRequires: kmod-devel
%ifarch x86_64 aarch64 %ifarch x86_64 aarch64
BuildRequires: numa-devel BuildRequires: numa-devel
@ -1125,74 +1099,72 @@ find . -name '*~' -o -name '*.orig' -o -name '*.append' | %kxargs rm -f
find . -name '.get_maintainer.ignore' | %kxargs rm -f find . -name '.get_maintainer.ignore' | %kxargs rm -f
# Versionize python shebang (#!/usr/bin/env python -> #!/usr/bin/python3) in scripts # Versionize python shebang (#!/usr/bin/env python -> #!/usr/bin/python3) in scripts
sed -i -e '1 s,^.*$,#!%{__python3},' scripts/bloat-o-meter sed -i '1 s,^#!/usr/bin/env python$,#!%{__python3},' \
sed -i -e '1 s,^.*$,#!%{__python3},' scripts/bpf_helpers_doc.py scripts/bloat-o-meter \
sed -i -e '1 s,^.*$,#!%{__python3},' scripts/checkkconfigsymbols.py scripts/checkkconfigsymbols.py \
sed -i -e '1 s,^.*$,#!%{__python3},' scripts/diffconfig scripts/diffconfig \
sed -i -e '1 s,^.*$,#!%{__python3},' scripts/jobserver-exec scripts/jobserver-exec \
sed -i -e '1 s,^.*$,#!%{__python3},' scripts/show_delta scripts/show_delta \
sed -i -e '1 s,^.*$,#!%{__python3},' scripts/spdxcheck.py scripts/spdxcheck.py \
sed -i -e '1 s,^.*$,#!%{__python3},' scripts/clang-tools/gen_compile_commands.py scripts/clang-tools/gen_compile_commands.py \
sed -i -e '1 s,^.*$,#!%{__python3},' scripts/clang-tools/run-clang-tools.py scripts/clang-tools/run-clang-tools.py \
sed -i -e '1 s,^.*$,#!%{__python3},' scripts/tracing/draw_functrace.py scripts/tracing/draw_functrace.py \
sed -i -e '1 s,^.*$,#!%{__python3},' tools/hv/vmbus_testing tools/hv/vmbus_testing \
sed -i -e '1 s,^.*$,#!%{__python3},' tools/kvm/kvm_stat/kvm_stat tools/kvm/kvm_stat/kvm_stat \
sed -i -e '1 s,^.*$,#!%{__python3},' tools/perf/python/tracepoint.py tools/perf/python/tracepoint.py \
sed -i -e '1 s,^.*$,#!%{__python3},' tools/perf/python/twatch.py tools/perf/python/twatch.py \
#tools/perf/scripts/python/exported-sql-viewer.py tools/power/pm-graph/bootgraph.py \
sed -i -e '1 s,^.*$,#!%{__python3},' tools/power/pm-graph/bootgraph.py tools/power/pm-graph/sleepgraph.py \
sed -i -e '1 s,^.*$,#!%{__python3},' tools/power/pm-graph/sleepgraph.py tools/power/x86/intel_pstate_tracer/intel_pstate_tracer.py \
sed -i -e '1 s,^.*$,#!%{__python3},' tools/power/x86/intel_pstate_tracer/intel_pstate_tracer.py tools/testing/kunit/kunit.py \
sed -i -e '1 s,^.*$,#!%{__python3},' tools/testing/kunit/kunit.py tools/testing/kunit/kunit_tool_test.py \
sed -i -e '1 s,^.*$,#!%{__python3},' tools/testing/kunit/kunit_tool_test.py tools/testing/selftests/bpf/test_offload.py \
sed -i -e '1 s,^.*$,#!%{__python3},' tools/testing/selftests/bpf/tcp_client.py tools/testing/selftests/drivers/net/mlxsw/sharedbuffer_configuration.py \
sed -i -e '1 s,^.*$,#!%{__python3},' tools/testing/selftests/bpf/tcp_server.py tools/testing/selftests/exec/binfmt_script \
sed -i -e '1 s,^.*$,#!%{__python3},' tools/testing/selftests/bpf/test_offload.py tools/testing/selftests/net/devlink_port_split.py \
sed -i -e '1 s,^.*$,#!%{__python3},' tools/testing/selftests/drivers/net/mlxsw/sharedbuffer_configuration.py tools/testing/selftests/tc-testing/tdc.py \
sed -i -e '1 s,^.*$,#!%{__python3},' tools/testing/selftests/exec/binfmt_script tools/testing/selftests/tc-testing/tdc_batch.py \
sed -i -e '1 s,^.*$,#!%{__python3},' tools/testing/selftests/net/devlink_port_split.py tools/testing/selftests/tc-testing/tdc_multibatch.py \
sed -i -e '1 s,^.*$,#!%{__python3},' tools/testing/selftests/tc-testing/tdc.py Documentation/sphinx/kernel_include.py \
sed -i -e '1 s,^.*$,#!%{__python3},' tools/testing/selftests/tc-testing/tdc_batch.py Documentation/sphinx/maintainers_include.py \
sed -i -e '1 s,^.*$,#!%{__python3},' tools/testing/selftests/tc-testing/tdc_multibatch.py Documentation/sphinx/rstFlatTable.py \
sed -i -e '1 s,^.*$,#!%{__python3},' Documentation/sphinx/kernel_include.py Documentation/target/tcm_mod_builder.py
sed -i -e '1 s,^.*$,#!%{__python3},' Documentation/sphinx/maintainers_include.py
sed -i -e '1 s,^.*$,#!%{__python3},' Documentation/sphinx/rstFlatTable.py
sed -i -e '1 s,^.*$,#!%{__python3},' Documentation/target/tcm_mod_builder.py
# Drop env from bash scripts # Drop env from bash scripts
sed -i -e '1 s,^.*$,#!%{_bindir}/bash,' scripts/config sed -i '1 s,^#!.*env .*,#!%{_bindir}/bash,' scripts/config
# Drop env from perl scripts # Drop env from perl scripts
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/bootgraph.pl sed -i '1 s,^#!.*env .*,#!%{_bindir}/perl,' \
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/checkincludes.pl scripts/bootgraph.pl \
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/checkkconfigsymbols.py scripts/checkincludes.pl \
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/checkpatch.pl scripts/checkkconfigsymbols.py \
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/checkstack.pl scripts/checkpatch.pl \
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/checkversion.pl scripts/checkstack.pl \
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/cleanfile scripts/checkversion.pl \
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/cleanpatch scripts/cleanfile \
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/documentation-file-ref-check scripts/cleanpatch \
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/export_report.pl scripts/documentation-file-ref-check \
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/extract-module-sig.pl scripts/export_report.pl \
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/extract-sys-certs.pl scripts/extract-module-sig.pl \
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/extract_xc3028.pl scripts/extract-sys-certs.pl \
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/get_abi.pl scripts/extract_xc3028.pl \
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/get_dvb_firmware scripts/get_abi.pl \
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/get_maintainer.pl scripts/get_dvb_firmware \
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/headerdep.pl scripts/get_maintainer.pl \
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/headers_check.pl scripts/headerdep.pl \
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/kernel-doc scripts/headers_check.pl \
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/leaking_addresses.pl scripts/kernel-doc \
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/markup_oops.pl scripts/leaking_addresses.pl \
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/profile2linkerlist.pl scripts/markup_oops.pl \
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/recordmcount.pl scripts/profile2linkerlist.pl \
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/split-man.pl scripts/recordmcount.pl \
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/stackdelta scripts/split-man.pl \
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/dtc/dt_to_config scripts/stackdelta \
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/kconfig/streamline_config.pl scripts/dtc/dt_to_config \
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' tools/testing/ktest/compare-ktest-sample.pl scripts/kconfig/streamline_config.pl \
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' tools/testing/selftests/kselftest/prefix.pl tools/testing/ktest/compare-ktest-sample.pl \
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' Documentation/sphinx/parse-headers.pl tools/testing/selftests/kselftest/prefix.pl \
Documentation/sphinx/parse-headers.pl
############################################################################ ############################################################################
@ -1781,7 +1753,9 @@ LC_ALL=C sed -ri "s/^EXTRAVERSION.*/EXTRAVERSION = -%{fullrpmrel}/" Makefile
make -C tools/perf -s V=1 DESTDIR=%{buildroot} WERROR=0 HAVE_CPLUS_DEMANGLE=1 prefix=%{_prefix} lib=%{_lib} install make -C tools/perf -s V=1 DESTDIR=%{buildroot} WERROR=0 HAVE_CPLUS_DEMANGLE=1 prefix=%{_prefix} lib=%{_lib} install
# Versionize shebang (#!/usr/bin/env python -> #!/usr/bin/python3) # Versionize shebang (#!/usr/bin/env python -> #!/usr/bin/python3)
sed -i -e '1 s,^.*$,#!%{__python3},' %{buildroot}%{_prefix}/libexec/perf-core/scripts/python/exported-sql-viewer.py sed -i '1 s,^#!/usr/bin/env python$,#!%{__python3},' \
%{buildroot}%{_prefix}/libexec/perf-core/scripts/python/exported-sql-viewer.py \
%{buildroot}%{_prefix}/libexec/perf-core/scripts/python/libxed.py
# Perf man pages (note: implicit rpm magic compresses them later) # Perf man pages (note: implicit rpm magic compresses them later)
make -C tools/perf -s V=1 DESTDIR=%{buildroot} WERROR=0 HAVE_CPLUS_DEMANGLE=1 prefix=%{_prefix} install-man make -C tools/perf -s V=1 DESTDIR=%{buildroot} WERROR=0 HAVE_CPLUS_DEMANGLE=1 prefix=%{_prefix} install-man

View file

@ -1,8 +1,7 @@
diff --git a/Documentation/admin-guide/sysctl/vm.rst b/Documentation/admin-guide/sysctl/vm.rst diff --git a/Documentation/admin-guide/sysctl/vm.rst b/Documentation/admin-guide/sysctl/vm.rst
index f455fa00c00f..a6146e0fc88a 100644
--- a/Documentation/admin-guide/sysctl/vm.rst --- a/Documentation/admin-guide/sysctl/vm.rst
+++ b/Documentation/admin-guide/sysctl/vm.rst +++ b/Documentation/admin-guide/sysctl/vm.rst
@@ -69,6 +69,8 @@ Currently, these files are in /proc/sys/vm: @@ -68,6 +68,8 @@
- stat_refresh - stat_refresh
- numa_stat - numa_stat
- swappiness - swappiness
@ -11,8 +10,8 @@ index f455fa00c00f..a6146e0fc88a 100644
- unprivileged_userfaultfd - unprivileged_userfaultfd
- user_reserve_kbytes - user_reserve_kbytes
- vfs_cache_pressure - vfs_cache_pressure
@@ -881,6 +883,31 @@ privileged users (with SYS_CAP_PTRACE capability). @@ -881,6 +883,31 @@
The default value is 1. The default value is 0.
+unevictable_activefile_kbytes_low +unevictable_activefile_kbytes_low
@ -47,7 +46,7 @@ diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index afad085960b8..8bb82cf5d74e 100644 index afad085960b8..8bb82cf5d74e 100644
--- a/kernel/sysctl.c --- a/kernel/sysctl.c
+++ b/kernel/sysctl.c +++ b/kernel/sysctl.c
@@ -111,6 +111,22 @@ @@ -113,6 +113,22 @@
static int sixty = 60; static int sixty = 60;
#endif #endif
@ -70,11 +69,10 @@ index afad085960b8..8bb82cf5d74e 100644
static int __maybe_unused neg_one = -1; static int __maybe_unused neg_one = -1;
static int __maybe_unused two = 2; static int __maybe_unused two = 2;
static int __maybe_unused four = 4; static int __maybe_unused four = 4;
@@ -3081,6 +3097,25 @@ static struct ctl_table vm_table[] = { @@ -3131,6 +3147,25 @@
.extra1 = SYSCTL_ZERO,
.extra2 = SYSCTL_ONE, .extra2 = SYSCTL_ONE,
}, },
+#endif #endif
+#if defined(CONFIG_UNEVICTABLE_ACTIVEFILE) +#if defined(CONFIG_UNEVICTABLE_ACTIVEFILE)
+ { + {
+ .procname = "unevictable_activefile_kbytes_low", + .procname = "unevictable_activefile_kbytes_low",
@ -93,14 +91,14 @@ index afad085960b8..8bb82cf5d74e 100644
+ .extra1 = &zero_ul, + .extra1 = &zero_ul,
+ .extra2 = &sysctl_unevictable_activefile_kbytes_low, + .extra2 = &sysctl_unevictable_activefile_kbytes_low,
+ }, + },
#endif +#endif
{ {
.procname = "user_reserve_kbytes", .procname = "user_reserve_kbytes",
.data = &sysctl_user_reserve_kbytes,
diff --git a/mm/Kconfig b/mm/Kconfig diff --git a/mm/Kconfig b/mm/Kconfig
index 390165ffbb0f..1e1fb8ad434a 100644
--- a/mm/Kconfig --- a/mm/Kconfig
+++ b/mm/Kconfig +++ b/mm/Kconfig
@@ -63,6 +63,41 @@ config SPARSEMEM_MANUAL @@ -47,6 +47,41 @@
endchoice endchoice
@ -139,14 +137,14 @@ index 390165ffbb0f..1e1fb8ad434a 100644
+ depends on UNEVICTABLE_ACTIVEFILE + depends on UNEVICTABLE_ACTIVEFILE
+ default "262144" + default "262144"
+ +
config DISCONTIGMEM config SPARSEMEM
def_bool y def_bool y
depends on (!SELECT_MEMORY_MODEL && ARCH_DISCONTIGMEM_ENABLE) || DISCONTIGMEM_MANUAL depends on (!SELECT_MEMORY_MODEL && ARCH_SPARSEMEM_ENABLE) || SPARSEMEM_MANUAL
diff --git a/mm/vmscan.c b/mm/vmscan.c diff --git a/mm/vmscan.c b/mm/vmscan.c
index 7b4e31eac2cf..93760769d676 100644 index 7b4e31eac2cf..93760769d676 100644
--- a/mm/vmscan.c --- a/mm/vmscan.c
+++ b/mm/vmscan.c +++ b/mm/vmscan.c
@@ -166,6 +166,11 @@ struct scan_control { @@ -171,6 +171,11 @@
#define prefetchw_prev_lru_page(_page, _base, _field) do { } while (0) #define prefetchw_prev_lru_page(_page, _base, _field) do { } while (0)
#endif #endif
@ -158,7 +156,7 @@ index 7b4e31eac2cf..93760769d676 100644
/* /*
* From 0 .. 200. Higher means more swappy. * From 0 .. 200. Higher means more swappy.
*/ */
@@ -2225,6 +2230,10 @@ enum scan_balance { @@ -2562,6 +2567,10 @@
SCAN_FILE, SCAN_FILE,
}; };
@ -169,7 +167,7 @@ index 7b4e31eac2cf..93760769d676 100644
/* /*
* Determine how aggressively the anon and file LRU lists should be * Determine how aggressively the anon and file LRU lists should be
* scanned. The relative value of each set of LRU lists is determined * scanned. The relative value of each set of LRU lists is determined
@@ -2418,6 +2427,19 @@ static void get_scan_count(struct lruvec *lruvec, struct scan_control *sc, @@ -2764,6 +2773,19 @@
BUG(); BUG();
} }