mirror of
https://abf.rosa.ru/djam/kernel-6.1.git
synced 2025-02-23 15:22:54 +00:00
Kernel 5.10 -> 5.15
This commit is contained in:
parent
ac08a6c618
commit
3136620039
46 changed files with 25030 additions and 12176 deletions
4
.abf.yml
4
.abf.yml
|
@ -1,6 +1,6 @@
|
|||
sources:
|
||||
linux-5.10.tar.xz: be0b909f1fbb760cc2d5cf146e1da3b2af0cf899
|
||||
patch-5.10.105.xz: 417d3ebae4907d7308468e900430412c25a80aa6
|
||||
linux-5.15.tar.xz: ac61f2459040c09af1d5abd4ed100c3d316b443e
|
||||
patch-5.15.28.xz: 20337719e70d8bd465f2ffbccd84cd8c3b2b274b
|
||||
public_key_GOST_1.pem: b4fb6bf1cf73824944931a8f0c2cb7bf427e0774
|
||||
public_key_GOST_2.pem: cba209bd331f29031c5d945949b230a8d7a4dc12
|
||||
public_key_GOST_3.pem: e5a223dd7c556d4d0cac326f5ed9fc12dd769afb
|
||||
|
|
|
@ -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
|
@ -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);
|
|
@ -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
|
||||
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.
|
||||
|
||||
Signed-off-by: Mikhail Novosyolov <m.novosyolov@rosalinux.ru>
|
||||
---
|
||||
kernel/kallsyms.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
Update for 5.15.28
|
||||
|
||||
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
|
||||
index fe9de067771c..04b58bccbb0d 100644
|
||||
--- a/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);
|
||||
}
|
||||
+EXPORT_SYMBOL_GPL(kallsyms_lookup_name);
|
||||
|
||||
int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *,
|
||||
unsigned long),
|
||||
@@ -194,6 +195,7 @@ int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *,
|
||||
#ifdef CONFIG_LIVEPATCH
|
||||
/*
|
||||
@@ -226,6 +227,7 @@
|
||||
}
|
||||
return module_kallsyms_on_each_symbol(fn, data);
|
||||
return 0;
|
||||
}
|
||||
+EXPORT_SYMBOL_GPL(kallsyms_on_each_symbol);
|
||||
#endif /* CONFIG_LIVEPATCH */
|
||||
|
||||
static unsigned long get_symbol_pos(unsigned long addr,
|
||||
unsigned long *symbolsize,
|
||||
--
|
||||
2.30.0
|
||||
|
||||
|
|
1172
0001-altha.patch
Normal file
1172
0001-altha.patch
Normal file
File diff suppressed because it is too large
Load diff
|
@ -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
|
||||
|
||||
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.2 id-tc26-gost3410-12-512
|
||||
|
||||
Signed-off-by: Mikhail Novosyolov <m.novosyolov@rosalinux.ru>
|
||||
---
|
||||
crypto/asymmetric_keys/pkcs7_parser.c | 11 +++++++++++
|
||||
1 file changed, 11 insertions(+)
|
||||
Update for 5.15.28
|
||||
|
||||
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
|
||||
+++ 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:
|
||||
ctx->sinfo->sig->hash_algo = "sha224";
|
||||
break;
|
||||
|
@ -29,9 +22,9 @@ index 967329e0a07b..39c260a04167 100644
|
|||
default:
|
||||
printk("Unsupported digest algo: %u\n", ctx->last_oid);
|
||||
return -ENOPKG;
|
||||
@@ -269,6 +275,11 @@ int pkcs7_sig_note_pkey_algo(void *context, size_t hdrlen,
|
||||
ctx->sinfo->sig->pkey_algo = "rsa";
|
||||
ctx->sinfo->sig->encoding = "pkcs1";
|
||||
@@ -277,6 +283,11 @@
|
||||
ctx->sinfo->sig->pkey_algo = "ecdsa";
|
||||
ctx->sinfo->sig->encoding = "x962";
|
||||
break;
|
||||
+ case OID_gost2012PKey256:
|
||||
+ case OID_gost2012PKey512:
|
||||
|
|
|
@ -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
|
||||
|
||||
This is for disabling *config, mrproper, prepare, scripts on -devel rpms
|
||||
Needed, because otherwise the -devel won't build correctly.
|
||||
|
||||
Signed-off-by: Mikhail Novosyolov <m.novosyolov@rosalinux.ru>
|
||||
---
|
||||
Makefile | 22 +++++-----------------
|
||||
scripts/kconfig/Makefile | 17 -----------------
|
||||
2 files changed, 5 insertions(+), 34 deletions(-)
|
||||
Update for 5.15.28
|
||||
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 076d4e6b9ccc..75bf27049d60 100644
|
||||
--- a/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
|
||||
# in parallel
|
||||
PHONY += scripts
|
||||
|
@ -26,17 +18,17 @@ index 076d4e6b9ccc..75bf27049d60 100644
|
|||
|
||||
# Things we need to do before we recursively start building the kernel
|
||||
# or the modules are listed in "prepare".
|
||||
@@ -1206,7 +1205,7 @@ prepare0: archprepare
|
||||
@@ -1219,7 +1218,7 @@
|
||||
$(Q)$(MAKE) $(build)=.
|
||||
|
||||
# All the preparing..
|
||||
-prepare: prepare0 prepare-objtool prepare-resolve_btfids
|
||||
-prepare: prepare0
|
||||
+prepare:
|
||||
|
||||
# Support for using generic headers in asm-generic
|
||||
asm-generic := -f $(srctree)/scripts/Makefile.asm-generic obj
|
||||
@@ -1472,15 +1471,7 @@ CLEAN_FILES += include/ksym vmlinux.symvers \
|
||||
compile_commands.json
|
||||
PHONY += remove-stale-files
|
||||
remove-stale-files:
|
||||
@@ -1520,15 +1519,7 @@
|
||||
compile_commands.json .thinlto-cache
|
||||
|
||||
# Directories & files removed with 'make mrproper'
|
||||
-MRPROPER_FILES += include/config include/generated \
|
||||
|
@ -44,15 +36,15 @@ index 076d4e6b9ccc..75bf27049d60 100644
|
|||
- debian snap tar-install \
|
||||
- .config .config.old .version \
|
||||
- Module.symvers \
|
||||
- signing_key.pem signing_key.priv signing_key.x509 \
|
||||
- x509.genkey extra_certificates signing_key.x509.keyid \
|
||||
- signing_key.x509.signer vmlinux-gdb.py \
|
||||
- certs/signing_key.pem certs/signing_key.x509 \
|
||||
- certs/x509.genkey \
|
||||
- vmlinux-gdb.py \
|
||||
- *.spec
|
||||
+MRPROPER_FILES += ""
|
||||
|
||||
# Directories & files removed with 'make distclean'
|
||||
DISTCLEAN_FILES += tags TAGS cscope* GPATH GTAGS GRTAGS GSYMS
|
||||
@@ -1500,13 +1491,10 @@ clean: archclean vmlinuxclean
|
||||
# clean - Delete most, but leave enough to build external modules
|
||||
#
|
||||
@@ -1545,13 +1536,10 @@
|
||||
# mrproper - Delete all generated files, including .config
|
||||
#
|
||||
mrproper: rm-files := $(wildcard $(MRPROPER_FILES))
|
||||
|
@ -69,30 +61,9 @@ index 076d4e6b9ccc..75bf27049d60 100644
|
|||
|
||||
# distclean
|
||||
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
|
||||
index e46df0a2d4f9..edceb8d1d213 100644
|
||||
--- a/scripts/kconfig/Makefile
|
||||
+++ b/scripts/kconfig/Makefile
|
||||
@@ -20,19 +20,14 @@ endif
|
||||
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
|
||||
@@ -54,11 +54,9 @@
|
||||
cmp -s .tmp.config .config || \
|
||||
(mv -f .config .config.old.1; \
|
||||
mv -f .tmp.config .config; \
|
||||
|
@ -104,7 +75,7 @@ index e46df0a2d4f9..edceb8d1d213 100644
|
|||
fi
|
||||
$(Q)rm -f .tmp.config
|
||||
|
||||
@@ -68,24 +61,14 @@ simple-targets := oldconfig allnoconfig allyesconfig allmodconfig \
|
||||
@@ -74,24 +72,14 @@
|
||||
PHONY += $(simple-targets)
|
||||
|
||||
$(simple-targets): $(obj)/conf
|
||||
|
@ -129,6 +100,3 @@ index e46df0a2d4f9..edceb8d1d213 100644
|
|||
|
||||
configfiles=$(wildcard $(srctree)/kernel/configs/$@ $(srctree)/arch/$(SRCARCH)/configs/$@)
|
||||
|
||||
--
|
||||
2.25.1
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
23032
0601-baikalm.patch
Normal file
File diff suppressed because it is too large
Load diff
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
(cherry picked from commit 136cab54114b2b0b61cf503065d6d547f3d3d5a2)
|
||||
---
|
||||
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
|
||||
Update for 5.15.105
|
||||
|
||||
diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
|
||||
index 7a2304565a73..121f8e708d51 100644
|
||||
--- a/drivers/usb/dwc3/Kconfig
|
||||
+++ b/drivers/usb/dwc3/Kconfig
|
||||
@@ -139,4 +139,13 @@ config USB_DWC3_QCOM
|
||||
for peripheral mode support.
|
||||
@@ -158,4 +158,13 @@
|
||||
This driver handles both ZynqMP and Versal SoC operations.
|
||||
Say 'Y' or 'M' if you have one such device.
|
||||
|
||||
+config USB_DWC3_BAIKAL
|
||||
|
@ -30,13 +20,12 @@ index 7a2304565a73..121f8e708d51 100644
|
|||
+
|
||||
endif
|
||||
diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
|
||||
index ae86da0dc5bd..0dcaf92a43ec 100644
|
||||
--- a/drivers/usb/dwc3/Makefile
|
||||
+++ b/drivers/usb/dwc3/Makefile
|
||||
@@ -51,3 +51,4 @@ obj-$(CONFIG_USB_DWC3_MESON_G12A) += dwc3-meson-g12a.o
|
||||
obj-$(CONFIG_USB_DWC3_OF_SIMPLE) += dwc3-of-simple.o
|
||||
obj-$(CONFIG_USB_DWC3_ST) += dwc3-st.o
|
||||
@@ -53,3 +53,4 @@
|
||||
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
|
||||
diff --git a/drivers/usb/dwc3/dwc3-baikal.c b/drivers/usb/dwc3/dwc3-baikal.c
|
||||
new file mode 100644
|
||||
|
@ -170,6 +159,3 @@ index 000000000000..2426dc49bd79
|
|||
+MODULE_AUTHOR("Dmitry Dunaev <dmitry.dunaev@baikalelectronics.ru>");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
+MODULE_DESCRIPTION("DesignWare USB3 Baikal SoCs Glue Layer");
|
||||
--
|
||||
2.31.1
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
Improvements:
|
||||
|
@ -80,19 +77,10 @@ Improvements:
|
|||
[ 9.324041] Memory Limit: none
|
||||
|
||||
Note: detection of new firmware is not 100% reliable.
|
||||
---
|
||||
drivers/pci/controller/Kconfig | 12 +
|
||||
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
|
||||
|
||||
Update for 5.15.28
|
||||
|
||||
diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
|
||||
index 64e2f5e379aa..b8a5eb633259 100644
|
||||
--- a/drivers/pci/controller/Kconfig
|
||||
+++ b/drivers/pci/controller/Kconfig
|
||||
@@ -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
|
||||
--- a/drivers/pci/controller/dwc/Makefile
|
||||
+++ b/drivers/pci/controller/dwc/Makefile
|
||||
@@ -20,6 +20,7 @@ obj-$(CONFIG_PCI_MESON) += pci-meson.o
|
||||
obj-$(CONFIG_PCIE_TEGRA194) += pcie-tegra194.o
|
||||
@@ -24,6 +24,7 @@
|
||||
obj-$(CONFIG_PCIE_UNIPHIER) += pcie-uniphier.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
|
||||
|
||||
# The following drivers are for devices that use the generic ACPI
|
||||
# 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
|
||||
new file mode 100644
|
||||
index 000000000000..1eb5f0e780c4
|
||||
--- /dev/null
|
||||
+++ b/drivers/pci/controller/dwc/pcie-baikal.c
|
||||
@@ -0,0 +1,722 @@
|
||||
|
@ -856,7 +843,6 @@ index 000000000000..1eb5f0e780c4
|
|||
+MODULE_LICENSE("GPL v2");
|
||||
diff --git a/drivers/pci/controller/dwc/pcie-baikal.h b/drivers/pci/controller/dwc/pcie-baikal.h
|
||||
new file mode 100644
|
||||
index 000000000000..f59100cf0c6d
|
||||
--- /dev/null
|
||||
+++ b/drivers/pci/controller/dwc/pcie-baikal.h
|
||||
@@ -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 */
|
||||
diff --git a/include/linux/mfd/baikal/lcru-pcie.h b/include/linux/mfd/baikal/lcru-pcie.h
|
||||
new file mode 100644
|
||||
index 000000000000..40562d00ab85
|
||||
--- /dev/null
|
||||
+++ b/include/linux/mfd/baikal/lcru-pcie.h
|
||||
@@ -0,0 +1,140 @@
|
||||
|
@ -1223,6 +1208,3 @@ index 000000000000..40562d00ab85
|
|||
+}
|
||||
+
|
||||
+#endif /* _LINUX_MFD_SYSCON_BAIKAL_LCRU_H_ */
|
||||
--
|
||||
2.31.1
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
Appears to successfully probe the hardware, lspci -vv output
|
||||
looks good. No other testing has been done yet.
|
||||
---
|
||||
drivers/pci/controller/dwc/Makefile | 2 +-
|
||||
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
|
||||
|
||||
Update for 5.15.28
|
||||
|
||||
diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile
|
||||
index 85e6ad1954e5..dcd23d7d5430 100644
|
||||
--- a/drivers/pci/controller/dwc/Makefile
|
||||
+++ b/drivers/pci/controller/dwc/Makefile
|
||||
@@ -20,7 +20,7 @@ obj-$(CONFIG_PCI_MESON) += pci-meson.o
|
||||
obj-$(CONFIG_PCIE_TEGRA194) += pcie-tegra194.o
|
||||
@@ -24,7 +24,7 @@
|
||||
obj-$(CONFIG_PCIE_UNIPHIER) += pcie-uniphier.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 pcie-baikal-v44.o
|
||||
|
||||
|
@ -26,7 +19,6 @@ index 85e6ad1954e5..dcd23d7d5430 100644
|
|||
# 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
|
||||
new file mode 100644
|
||||
index 000000000000..5e5f0a9e59e2
|
||||
--- /dev/null
|
||||
+++ b/drivers/pci/controller/dwc/pcie-baikal-v44.c
|
||||
@@ -0,0 +1,826 @@
|
||||
|
@ -530,11 +522,11 @@ index 000000000000..5e5f0a9e59e2
|
|||
+ }
|
||||
+
|
||||
+ /* Deinitialise all iATU regions */
|
||||
+ for (idx = 0; idx < pp->num_viewport; ++idx) {
|
||||
+ dw_pcie_writel_dbi(pp, PCIE_IATU_VIEWPORT_REG,
|
||||
+ PCIE_IATU_REGION_OUTBOUND | idx);
|
||||
+ dw_pcie_writel_dbi(pp, PCIE_IATU_REGION_CTRL_2_REG, 0);
|
||||
+ }
|
||||
+// for (idx = 0; idx < pp->num_viewport; ++idx) {
|
||||
+// dw_pcie_writel_dbi(pp, PCIE_IATU_VIEWPORT_REG,
|
||||
+// PCIE_IATU_REGION_OUTBOUND | idx);
|
||||
+// dw_pcie_writel_dbi(pp, PCIE_IATU_REGION_CTRL_2_REG, 0);
|
||||
+// }
|
||||
+
|
||||
+ /*
|
||||
+ * 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_platform_driver(baikal_pcie_driver);
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
--
|
||||
2.31.1
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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
|
||||
SDK-M 4.3
|
||||
|
||||
|
@ -9,22 +6,17 @@ systems with firmware from SDK-M 4.3.
|
|||
|
||||
Note: the driver should be explicitly enabled with
|
||||
enable_broken_machines=y module parameter
|
||||
---
|
||||
drivers/gpu/drm/panfrost/panfrost_drv.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
Update for 5.15.28
|
||||
|
||||
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
|
||||
+++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
|
||||
@@ -681,6 +681,7 @@ static const struct of_device_id dt_match[] = {
|
||||
{ .compatible = "arm,mali-t860", .data = &default_data, },
|
||||
@@ -655,6 +655,7 @@
|
||||
{ .compatible = "arm,mali-t880", .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, },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, dt_match);
|
||||
--
|
||||
2.31.1
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
172
kernel.spec
172
kernel.spec
|
@ -28,8 +28,8 @@
|
|||
%global _build_pkgcheck_srpm %(echo "%{_build_pkgcheck_srpm}" | sed -e 's,/%{name}.rpmlintrc,/kernel.rpmlintrc,')
|
||||
|
||||
%define kernelversion 5
|
||||
%define patchlevel 10
|
||||
%define sublevel 105
|
||||
%define patchlevel 15
|
||||
%define sublevel 28
|
||||
|
||||
# Release number. Increase this before a rebuild.
|
||||
%define rpmrel 1
|
||||
|
@ -73,7 +73,7 @@
|
|||
%endif
|
||||
|
||||
# "Nickel" is a special brand for certified distros
|
||||
%if %{mdvver} == 201900 || %{mdvver} == 201905
|
||||
%if %{mdvver} == 201905
|
||||
%bcond_without nickel
|
||||
# Require kernel modules to be signed
|
||||
%bcond_without oblig_signed_modules
|
||||
|
@ -329,10 +329,7 @@ Patch111: 0001-Remove-RPM-illegal-chars-from-module-version.patch
|
|||
# https://www.altlinux.org/AltHa
|
||||
# http://git.altlinux.org/gears/k/kernel-image-un-def.git
|
||||
# TODO: known problem: https://bugzilla.altlinux.org/show_bug.cgi?id=38225
|
||||
Patch201: 0001-AltHa-LSM-module.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
|
||||
Patch201: 0001-altha.patch
|
||||
|
||||
# sent to upstream, https://patchwork.kernel.org/patch/11446123/
|
||||
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
|
||||
# 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
|
||||
Patch0601: 0601-Baikal-M-Kconfig-defconfig.patch
|
||||
Patch0602: 0602-Baikal-M-clock-driver.patch
|
||||
Patch0603: 0603-efi-rtc-avoid-calling-efi.get_time-on-Baikal-M-board.patch
|
||||
Patch0601: 0601-baikalm.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
|
||||
# https://bugzilla.altlinux.org/show_bug.cgi?id=40269
|
||||
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
|
||||
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
|
||||
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
|
||||
AutoReq: 0
|
||||
|
@ -418,6 +389,9 @@ BuildRequires: xz
|
|||
BuildRequires: zstd
|
||||
%endif
|
||||
%endif
|
||||
%ifarch aarch64
|
||||
BuildRequires: uboot-tools
|
||||
%endif
|
||||
BuildRequires: kmod-devel
|
||||
%ifarch x86_64 aarch64
|
||||
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
|
||||
|
||||
# Versionize python shebang (#!/usr/bin/env python -> #!/usr/bin/python3) in scripts
|
||||
sed -i -e '1 s,^.*$,#!%{__python3},' scripts/bloat-o-meter
|
||||
sed -i -e '1 s,^.*$,#!%{__python3},' scripts/bpf_helpers_doc.py
|
||||
sed -i -e '1 s,^.*$,#!%{__python3},' scripts/checkkconfigsymbols.py
|
||||
sed -i -e '1 s,^.*$,#!%{__python3},' scripts/diffconfig
|
||||
sed -i -e '1 s,^.*$,#!%{__python3},' scripts/jobserver-exec
|
||||
sed -i -e '1 s,^.*$,#!%{__python3},' scripts/show_delta
|
||||
sed -i -e '1 s,^.*$,#!%{__python3},' scripts/spdxcheck.py
|
||||
sed -i -e '1 s,^.*$,#!%{__python3},' scripts/clang-tools/gen_compile_commands.py
|
||||
sed -i -e '1 s,^.*$,#!%{__python3},' scripts/clang-tools/run-clang-tools.py
|
||||
sed -i -e '1 s,^.*$,#!%{__python3},' scripts/tracing/draw_functrace.py
|
||||
sed -i -e '1 s,^.*$,#!%{__python3},' tools/hv/vmbus_testing
|
||||
sed -i -e '1 s,^.*$,#!%{__python3},' tools/kvm/kvm_stat/kvm_stat
|
||||
sed -i -e '1 s,^.*$,#!%{__python3},' tools/perf/python/tracepoint.py
|
||||
sed -i -e '1 s,^.*$,#!%{__python3},' tools/perf/python/twatch.py
|
||||
#tools/perf/scripts/python/exported-sql-viewer.py
|
||||
sed -i -e '1 s,^.*$,#!%{__python3},' tools/power/pm-graph/bootgraph.py
|
||||
sed -i -e '1 s,^.*$,#!%{__python3},' tools/power/pm-graph/sleepgraph.py
|
||||
sed -i -e '1 s,^.*$,#!%{__python3},' tools/power/x86/intel_pstate_tracer/intel_pstate_tracer.py
|
||||
sed -i -e '1 s,^.*$,#!%{__python3},' tools/testing/kunit/kunit.py
|
||||
sed -i -e '1 s,^.*$,#!%{__python3},' tools/testing/kunit/kunit_tool_test.py
|
||||
sed -i -e '1 s,^.*$,#!%{__python3},' tools/testing/selftests/bpf/tcp_client.py
|
||||
sed -i -e '1 s,^.*$,#!%{__python3},' tools/testing/selftests/bpf/tcp_server.py
|
||||
sed -i -e '1 s,^.*$,#!%{__python3},' tools/testing/selftests/bpf/test_offload.py
|
||||
sed -i -e '1 s,^.*$,#!%{__python3},' tools/testing/selftests/drivers/net/mlxsw/sharedbuffer_configuration.py
|
||||
sed -i -e '1 s,^.*$,#!%{__python3},' tools/testing/selftests/exec/binfmt_script
|
||||
sed -i -e '1 s,^.*$,#!%{__python3},' tools/testing/selftests/net/devlink_port_split.py
|
||||
sed -i -e '1 s,^.*$,#!%{__python3},' tools/testing/selftests/tc-testing/tdc.py
|
||||
sed -i -e '1 s,^.*$,#!%{__python3},' tools/testing/selftests/tc-testing/tdc_batch.py
|
||||
sed -i -e '1 s,^.*$,#!%{__python3},' tools/testing/selftests/tc-testing/tdc_multibatch.py
|
||||
sed -i -e '1 s,^.*$,#!%{__python3},' Documentation/sphinx/kernel_include.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
|
||||
sed -i '1 s,^#!/usr/bin/env python$,#!%{__python3},' \
|
||||
scripts/bloat-o-meter \
|
||||
scripts/checkkconfigsymbols.py \
|
||||
scripts/diffconfig \
|
||||
scripts/jobserver-exec \
|
||||
scripts/show_delta \
|
||||
scripts/spdxcheck.py \
|
||||
scripts/clang-tools/gen_compile_commands.py \
|
||||
scripts/clang-tools/run-clang-tools.py \
|
||||
scripts/tracing/draw_functrace.py \
|
||||
tools/hv/vmbus_testing \
|
||||
tools/kvm/kvm_stat/kvm_stat \
|
||||
tools/perf/python/tracepoint.py \
|
||||
tools/perf/python/twatch.py \
|
||||
tools/power/pm-graph/bootgraph.py \
|
||||
tools/power/pm-graph/sleepgraph.py \
|
||||
tools/power/x86/intel_pstate_tracer/intel_pstate_tracer.py \
|
||||
tools/testing/kunit/kunit.py \
|
||||
tools/testing/kunit/kunit_tool_test.py \
|
||||
tools/testing/selftests/bpf/test_offload.py \
|
||||
tools/testing/selftests/drivers/net/mlxsw/sharedbuffer_configuration.py \
|
||||
tools/testing/selftests/exec/binfmt_script \
|
||||
tools/testing/selftests/net/devlink_port_split.py \
|
||||
tools/testing/selftests/tc-testing/tdc.py \
|
||||
tools/testing/selftests/tc-testing/tdc_batch.py \
|
||||
tools/testing/selftests/tc-testing/tdc_multibatch.py \
|
||||
Documentation/sphinx/kernel_include.py \
|
||||
Documentation/sphinx/maintainers_include.py \
|
||||
Documentation/sphinx/rstFlatTable.py \
|
||||
Documentation/target/tcm_mod_builder.py
|
||||
|
||||
# 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
|
||||
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/bootgraph.pl
|
||||
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/checkincludes.pl
|
||||
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/checkkconfigsymbols.py
|
||||
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/checkpatch.pl
|
||||
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/checkstack.pl
|
||||
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/checkversion.pl
|
||||
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/cleanfile
|
||||
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/cleanpatch
|
||||
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/documentation-file-ref-check
|
||||
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/export_report.pl
|
||||
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/extract-module-sig.pl
|
||||
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/extract-sys-certs.pl
|
||||
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/extract_xc3028.pl
|
||||
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/get_abi.pl
|
||||
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/get_dvb_firmware
|
||||
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/get_maintainer.pl
|
||||
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/headerdep.pl
|
||||
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/headers_check.pl
|
||||
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/kernel-doc
|
||||
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/leaking_addresses.pl
|
||||
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/markup_oops.pl
|
||||
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/profile2linkerlist.pl
|
||||
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/recordmcount.pl
|
||||
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/split-man.pl
|
||||
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/stackdelta
|
||||
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/dtc/dt_to_config
|
||||
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' scripts/kconfig/streamline_config.pl
|
||||
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' tools/testing/ktest/compare-ktest-sample.pl
|
||||
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' tools/testing/selftests/kselftest/prefix.pl
|
||||
sed -i -e '1 s,^.*$,#!%{_bindir}/perl,' Documentation/sphinx/parse-headers.pl
|
||||
sed -i '1 s,^#!.*env .*,#!%{_bindir}/perl,' \
|
||||
scripts/bootgraph.pl \
|
||||
scripts/checkincludes.pl \
|
||||
scripts/checkkconfigsymbols.py \
|
||||
scripts/checkpatch.pl \
|
||||
scripts/checkstack.pl \
|
||||
scripts/checkversion.pl \
|
||||
scripts/cleanfile \
|
||||
scripts/cleanpatch \
|
||||
scripts/documentation-file-ref-check \
|
||||
scripts/export_report.pl \
|
||||
scripts/extract-module-sig.pl \
|
||||
scripts/extract-sys-certs.pl \
|
||||
scripts/extract_xc3028.pl \
|
||||
scripts/get_abi.pl \
|
||||
scripts/get_dvb_firmware \
|
||||
scripts/get_maintainer.pl \
|
||||
scripts/headerdep.pl \
|
||||
scripts/headers_check.pl \
|
||||
scripts/kernel-doc \
|
||||
scripts/leaking_addresses.pl \
|
||||
scripts/markup_oops.pl \
|
||||
scripts/profile2linkerlist.pl \
|
||||
scripts/recordmcount.pl \
|
||||
scripts/split-man.pl \
|
||||
scripts/stackdelta \
|
||||
scripts/dtc/dt_to_config \
|
||||
scripts/kconfig/streamline_config.pl \
|
||||
tools/testing/ktest/compare-ktest-sample.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
|
||||
|
||||
# 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)
|
||||
make -C tools/perf -s V=1 DESTDIR=%{buildroot} WERROR=0 HAVE_CPLUS_DEMANGLE=1 prefix=%{_prefix} install-man
|
||||
|
|
30
le9pf.diff
30
le9pf.diff
|
@ -1,8 +1,7 @@
|
|||
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
|
||||
+++ 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
|
||||
- numa_stat
|
||||
- swappiness
|
||||
|
@ -11,8 +10,8 @@ index f455fa00c00f..a6146e0fc88a 100644
|
|||
- unprivileged_userfaultfd
|
||||
- user_reserve_kbytes
|
||||
- vfs_cache_pressure
|
||||
@@ -881,6 +883,31 @@ privileged users (with SYS_CAP_PTRACE capability).
|
||||
The default value is 1.
|
||||
@@ -881,6 +883,31 @@
|
||||
The default value is 0.
|
||||
|
||||
|
||||
+unevictable_activefile_kbytes_low
|
||||
|
@ -47,7 +46,7 @@ diff --git a/kernel/sysctl.c b/kernel/sysctl.c
|
|||
index afad085960b8..8bb82cf5d74e 100644
|
||||
--- a/kernel/sysctl.c
|
||||
+++ b/kernel/sysctl.c
|
||||
@@ -111,6 +111,22 @@
|
||||
@@ -113,6 +113,22 @@
|
||||
static int sixty = 60;
|
||||
#endif
|
||||
|
||||
|
@ -70,11 +69,10 @@ index afad085960b8..8bb82cf5d74e 100644
|
|||
static int __maybe_unused neg_one = -1;
|
||||
static int __maybe_unused two = 2;
|
||||
static int __maybe_unused four = 4;
|
||||
@@ -3081,6 +3097,25 @@ static struct ctl_table vm_table[] = {
|
||||
.extra1 = SYSCTL_ZERO,
|
||||
@@ -3131,6 +3147,25 @@
|
||||
.extra2 = SYSCTL_ONE,
|
||||
},
|
||||
+#endif
|
||||
#endif
|
||||
+#if defined(CONFIG_UNEVICTABLE_ACTIVEFILE)
|
||||
+ {
|
||||
+ .procname = "unevictable_activefile_kbytes_low",
|
||||
|
@ -93,14 +91,14 @@ index afad085960b8..8bb82cf5d74e 100644
|
|||
+ .extra1 = &zero_ul,
|
||||
+ .extra2 = &sysctl_unevictable_activefile_kbytes_low,
|
||||
+ },
|
||||
#endif
|
||||
+#endif
|
||||
{
|
||||
.procname = "user_reserve_kbytes",
|
||||
.data = &sysctl_user_reserve_kbytes,
|
||||
diff --git a/mm/Kconfig b/mm/Kconfig
|
||||
index 390165ffbb0f..1e1fb8ad434a 100644
|
||||
--- a/mm/Kconfig
|
||||
+++ b/mm/Kconfig
|
||||
@@ -63,6 +63,41 @@ config SPARSEMEM_MANUAL
|
||||
@@ -47,6 +47,41 @@
|
||||
|
||||
endchoice
|
||||
|
||||
|
@ -139,14 +137,14 @@ index 390165ffbb0f..1e1fb8ad434a 100644
|
|||
+ depends on UNEVICTABLE_ACTIVEFILE
|
||||
+ default "262144"
|
||||
+
|
||||
config DISCONTIGMEM
|
||||
config SPARSEMEM
|
||||
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
|
||||
index 7b4e31eac2cf..93760769d676 100644
|
||||
--- a/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)
|
||||
#endif
|
||||
|
||||
|
@ -158,7 +156,7 @@ index 7b4e31eac2cf..93760769d676 100644
|
|||
/*
|
||||
* From 0 .. 200. Higher means more swappy.
|
||||
*/
|
||||
@@ -2225,6 +2230,10 @@ enum scan_balance {
|
||||
@@ -2562,6 +2567,10 @@
|
||||
SCAN_FILE,
|
||||
};
|
||||
|
||||
|
@ -169,7 +167,7 @@ index 7b4e31eac2cf..93760769d676 100644
|
|||
/*
|
||||
* Determine how aggressively the anon and file LRU lists should be
|
||||
* 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();
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue