RT patch (disabled) with some fixes by ChrisK

http://forum.armbian.com/index.php/topic/1885-rt-patches-for-sun8i-kernel/
This commit is contained in:
Igor Pecovnik 2016-08-23 14:12:46 +02:00
parent e305fe4dbc
commit b1c387cec5
6 changed files with 24695 additions and 0 deletions

View file

@ -0,0 +1,11 @@
diff -uprNHd -x '*.orig' -x '*.rej' sun8i/drivers/base/firmware_class.c sun8i-rt/drivers/base/firmware_class.c
--- sun8i/drivers/base/firmware_class.c 2016-08-22 14:14:41.000000000 +0200
+++ sun8i-rt/drivers/base/firmware_class.c 2016-08-22 18:58:39.756320362 +0200
@@ -27,6 +27,7 @@
#include <linux/pm.h>
#include <linux/suspend.h>
#include <linux/syscore_ops.h>
+#include <linux/genhd.h>
#include <generated/utsrelease.h>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,10 @@
--- sun8i/drivers/crypto/sunxi/Kconfig 2016-08-22 14:14:14.000000000 +0200
+++ sun8i-rt/drivers/crypto/sunxi/Kconfig 2016-08-22 23:21:56.412501973 +0200
@@ -1,6 +1,6 @@
config CRYPTO_SUNXI
tristate "SUNXI SS controller"
- depends on ARCH_SUNXI
+ depends on ARCH_SUNXI && HIGHMEM
help
To compile this driver as a module, choose M here: the module
will be called caam.

View file

@ -0,0 +1,11 @@
--- sun8i/fs/timerfd.c 2016-08-22 22:52:24.564481603 +0200
+++ sun8i-rt/fs/timerfd.c 2016-08-22 20:15:39.076373470 +0200
@@ -385,7 +385,7 @@ SYSCALL_DEFINE4(timerfd_settime, int, uf
break;
}
spin_unlock_irq(&ctx->wqh.lock);
- hrtimer_wait_for_timer(&ctx->tmr);
+ hrtimer_wait_for_timer(&ctx->t.tmr);
}
/*

View file

@ -0,0 +1,200 @@
diff -uprNHd -x '*.orig' -x '*.rej' sun8i-test-old/arch/arm/common/gic.c sun8i-test/arch/arm/common/gic.c
--- sun8i/arch/arm/common/gic.c 2016-08-22 23:01:38.000000000 +0200
+++ sun8i-rt/arch/arm/common/gic.c 2016-08-22 23:06:46.736491515 +0200
@@ -36,6 +36,7 @@
#include <linux/of_irq.h>
#include <linux/irqdomain.h>
#include <linux/interrupt.h>
+#include <linux/irqpriority.h>
#include <linux/percpu.h>
#include <linux/slab.h>
#include <trace/events/arm-ipi.h>
@@ -92,6 +93,19 @@ struct irq_chip gic_arch_extn = {
.irq_set_wake = NULL,
};
+/*
+ * Map generic interrupt priority levels (irqpriority_t) to GIC_DIST_PRI
+ * register value. Value should be mapped using table index assignment:
+ * [priority level] = <vale for GIC_DIST_PRI> which allow us to be compatible
+ * in case of irqpriority_t (see include/linux/irqpriority.h) further
+ * modification.
+ */
+static unsigned int priority_map [IRQP_LEVELS_NR] = {
+ [IRQP_HIGH] = 0x00000000,
+ [IRQP_DEFAULT] = 0xa0a0a0a0,
+ [IRQP_LOW] = 0xe0e0e0e0,
+};
+
#ifndef MAX_GIC_NR
#define MAX_GIC_NR 1
#endif
@@ -424,12 +438,32 @@ static void gic_handle_cascade_irq(unsig
chained_irq_exit(chip, desc);
}
+int gic_set_priority(struct irq_data *data, irqpriority_t priority)
+{
+ unsigned int hw_irq = gic_irq(data);
+ u32 cur_priority;
+
+ if (hw_irq < 32)
+ {
+ printk("gic_set_priority: cant set irq %i to pri %i\r\n", hw_irq, priority_map[priority]);
+ return -EINVAL;
+ }
+
+ raw_spin_lock(&irq_controller_lock);
+ cur_priority = readl_relaxed(gic_dist_base(data) + GIC_DIST_PRI + (hw_irq / 4) * 4);
+ cur_priority = priority_map[priority];
+ writel_relaxed(cur_priority, gic_dist_base(data) + GIC_DIST_PRI + (hw_irq / 4) * 4);
+ raw_spin_unlock(&irq_controller_lock);
+ return 0;
+}
+
static struct irq_chip gic_chip = {
.name = "GIC",
.irq_mask = gic_mask_irq,
.irq_unmask = gic_unmask_irq,
.irq_eoi = gic_eoi_irq,
.irq_set_type = gic_set_type,
+ .irq_set_priority = gic_set_priority,
.irq_retrigger = gic_retrigger,
#ifdef CONFIG_SMP
.irq_set_affinity = gic_set_affinity,
diff -uprNHd -x '*.orig' -x '*.rej' sun8i-test-old/include/linux/interrupt.h sun8i-test/include/linux/interrupt.h
--- sun8i-test-old/include/linux/interrupt.h 2016-08-22 23:01:38.000000000 +0200
+++ sun8i-test/include/linux/interrupt.h 2016-08-22 23:05:52.300490889 +0200
@@ -75,6 +75,7 @@
#define IRQF_NO_THREAD 0x00010000
#define IRQF_EARLY_RESUME 0x00020000
#define IRQF_NO_SOFTIRQ_CALL 0x00040000
+#define IRQF_HIGH_PRIORITY 0x00080000
#define IRQF_TIMER (__IRQF_TIMER | IRQF_NO_SUSPEND | IRQF_NO_THREAD)
diff -uprNHd -x '*.orig' -x '*.rej' sun8i-test-old/include/linux/irq.h sun8i-test/include/linux/irq.h
--- sun8i-test-old/include/linux/irq.h 2016-08-22 23:01:38.000000000 +0200
+++ sun8i-test/include/linux/irq.h 2016-08-22 23:05:52.316490889 +0200
@@ -20,6 +20,7 @@
#include <linux/gfp.h>
#include <linux/irqreturn.h>
#include <linux/irqnr.h>
+#include <linux/irqpriority.h>
#include <linux/errno.h>
#include <linux/topology.h>
#include <linux/wait.h>
@@ -324,6 +325,7 @@ struct irq_chip {
int (*irq_retrigger)(struct irq_data *data);
int (*irq_set_type)(struct irq_data *data, unsigned int flow_type);
int (*irq_set_wake)(struct irq_data *data, unsigned int on);
+ int (*irq_set_priority)(struct irq_data *data, irqpriority_t priority);
void (*irq_bus_lock)(struct irq_data *data);
void (*irq_bus_sync_unlock)(struct irq_data *data);
diff -uprNHd -x '*.orig' -x '*.rej' sun8i-test-old/include/linux/irqpriority.h sun8i-test/include/linux/irqpriority.h
--- sun8i-test-old/include/linux/irqpriority.h 1970-01-01 01:00:00.000000000 +0100
+++ sun8i-test/include/linux/irqpriority.h 2016-08-22 23:05:52.316490889 +0200
@@ -0,0 +1,24 @@
+#ifndef _LINUX_IRQPRIORITY_H
+#define _LINUX_IRQPRIORITY_H
+
+/**
+ * enum irqpriority
+ * @IRQP_HIGH address to low response latency interrupt e.g. error
+ * signaling
+ * @IRQP_DEFAULT default priority and set for all interrupt sources
+ * during interrupt controller initialization
+ * @IRQP_LOW interrupt which doesn't really care about response
+ * latency
+ * @... place for priority extension
+ */
+enum irqpriority {
+ IRQP_HIGH = 0,
+ IRQP_DEFAULT,
+ IRQP_LOW,
+
+ IRQP_LEVELS_NR
+};
+
+typedef enum irqpriority irqpriority_t;
+
+#endif /* _LINUX_IRQPRIORITY_H */
\ Kein Zeilenumbruch am Dateiende.
diff -uprNHd -x '*.orig' -x '*.rej' sun8i-test-old/kernel/irq/chip.c sun8i-test/kernel/irq/chip.c
--- sun8i-test-old/kernel/irq/chip.c 2016-08-22 23:01:38.000000000 +0200
+++ sun8i-test/kernel/irq/chip.c 2016-08-22 23:05:52.316490889 +0200
@@ -14,6 +14,7 @@
#include <linux/msi.h>
#include <linux/module.h>
#include <linux/interrupt.h>
+#include <linux/irqpriority.h>
#include <linux/kernel_stat.h>
#include <trace/events/irq.h>
@@ -254,6 +255,14 @@ void unmask_irq(struct irq_desc *desc)
}
}
+int irq_set_priority(struct irq_desc *desc, irqpriority_t priority)
+{
+ if (!desc->irq_data.chip->irq_set_priority)
+ return -EINVAL;
+
+ return desc->irq_data.chip->irq_set_priority(&desc->irq_data, priority);
+}
+
/*
* handle_nested_irq - Handle a nested irq from a irq thread
* @irq: the interrupt number
diff -uprNHd -x '*.orig' -x '*.rej' sun8i-test-old/kernel/irq/internals.h sun8i-test/kernel/irq/internals.h
--- sun8i-test-old/kernel/irq/internals.h 2016-08-22 23:01:38.000000000 +0200
+++ sun8i-test/kernel/irq/internals.h 2016-08-22 23:05:52.316490889 +0200
@@ -73,6 +73,7 @@ extern void irq_percpu_enable(struct irq
extern void irq_percpu_disable(struct irq_desc *desc, unsigned int cpu);
extern void mask_irq(struct irq_desc *desc);
extern void unmask_irq(struct irq_desc *desc);
+extern int irq_set_priority(struct irq_desc *desc, irqpriority_t priority);
#ifdef CONFIG_SPARSE_IRQ
extern void irq_lock_sparse(void);
diff -uprNHd -x '*.orig' -x '*.rej' sun8i-test-old/kernel/irq/manage.c sun8i-test/kernel/irq/manage.c
--- sun8i-test-old/kernel/irq/manage.c 2016-08-22 23:01:38.000000000 +0200
+++ sun8i-test/kernel/irq/manage.c 2016-08-22 23:05:52.316490889 +0200
@@ -12,6 +12,7 @@
#include <linux/module.h>
#include <linux/random.h>
#include <linux/interrupt.h>
+#include <linux/irqpriority.h>
#include <linux/slab.h>
#include <linux/sched.h>
@@ -1061,11 +1062,12 @@ __setup_irq(unsigned int irq, struct irq
* the same type (level, edge, polarity). So both flag
* fields must have IRQF_SHARED set and the bits which
* set the trigger type must match. Also all must
- * agree on ONESHOT.
+ * agree on ONESHOT and IRQF_HIGH_PRIORITY.
*/
if (!((old->flags & new->flags) & IRQF_SHARED) ||
((old->flags ^ new->flags) & IRQF_TRIGGER_MASK) ||
- ((old->flags ^ new->flags) & IRQF_ONESHOT)) {
++ ((old->flags ^ new->flags) & IRQF_ONESHOT) ||
++ ((old->flags ^ new->flags) & IRQF_HIGH_PRIORITY)) {
old_name = old->name;
goto mismatch;
}
@@ -1150,6 +1152,13 @@ __setup_irq(unsigned int irq, struct irq
if (new->flags & IRQF_ONESHOT)
desc->istate |= IRQS_ONESHOT;
+ if (new->flags & IRQF_HIGH_PRIORITY) {
+ printk("%s: setting high priority\r\n", new->name);
+ ret = irq_set_priority(desc, IRQP_HIGH);
+ if (ret)
+ goto out_mask;
+ }
+
if (irq_settings_can_autoenable(desc))
irq_startup(desc, true);
else

View file

@ -0,0 +1,12 @@
--- sun8i/kernel/irq/manage.c 2016-08-22 23:36:31.000000000 +0200
+++ sun8i-rt/kernel/irq/manage.c 2016-08-23 13:22:07.461081538 +0200
@@ -270,6 +270,9 @@ int irq_set_affinity_hint(unsigned int i
return -EINVAL;
desc->affinity_hint = m;
irq_put_desc_unlock(desc, flags);
+ /* set the initial affinity to prevent every interrupt being on CPU0 */
+ irq_set_affinity(irq, m);
+
return 0;
}
EXPORT_SYMBOL_GPL(irq_set_affinity_hint);