Index: linux-3.12.33-rt47-i386/kernel/irq/Kconfig
===================================================================
@ linux-3.12.33-rt47-i386/kernel/irq/Kconfig:63 @ config IRQ_DOMAIN_DEBUG
 config IRQ_FORCED_THREADING
        bool
 
+config IRQ_THREAD_PRIOS_PARAM
+	bool "Support kernel parameter 'irqthreadprios'"
+	---help---
+
+          This Kernel Parameter controls the thread-priority-setting of
+          automatic generated irq-threads.
+          The format is:   pat:prio[,pat:prio]
+
+          pat is a glob expression which matches the irq-thread name respectively
+          the second part of the thread name after the '-' in the
+          middle of the name.
+          The glob-pattern may use this special characters:
+          *   match 0..n
+          ?   match 1
+          [12]    char-class 1 and 2
+          [1-3]   char-class 1 to 3
+          [!1-3]  inverted char-class 1 to 3
+          \*  an escaped *
+          \?  an escaped ?
+          \[  an escaped [
+          \]  an escaped ]
+          \:  an escaped :
+
+          e.g. irqthreadprios=ata_piix:50,uio*:60,*:20
+          set irq/19-ata_piix  -> 50
+
+          you can verify proper operation with:
+          > dmesg|grep irqthreadprios
+          > ps axH -o tid,rtprio,policy,comm --sort -rtprio
+
+
+config IRQ_THREAD_PRIOS_PARAM_SIZE
+	int "maximum size of the irqthreadprios parameter"
+	depends on IRQ_THREAD_PRIOS_PARAM
+        default 200
+	help
+
+          maximum size of the irqthreadprios parameter. Unfortunately an
+          automatic adaption does not work because of missing malloc functionality
+          at early configuration time. :-(
+
+config IRQ_THREAD_PRIOS_PARAM_MAX
+	int "maximum number of irqthreadprios entries"
+	depends on IRQ_THREAD_PRIOS_PARAM
+        default 20
+	help
+
+          maximum number of the irqthreadprios entries. Unfortunately an
+          automatic adaption does not work because of missing malloc functionality
+          at early configuration time. :-(
+
+
 config SPARSE_IRQ
 	bool "Support sparse irq numbering" if MAY_HAVE_SPARSE_IRQ
 	---help---
Index: linux-3.12.33-rt47-i386/kernel/irq/manage.c
===================================================================
--- linux-3.12.33-rt47-i386.orig/kernel/irq/manage.c
+++ linux-3.12.33-rt47-i386/kernel/irq/manage.c
@ linux-3.12.33-rt47-i386/kernel/irq/Kconfig:37 @ early_param("threadirqs", setup_forced_i
 # endif
 #endif
 
+
+
+#ifdef CONFIG_IRQ_THREAD_PRIOS_PARAM
+struct irqthreadprios_tab_t {
+	char *pat;
+	int prio;
+};
+
+static struct irqthreadprios_tab_t irqthreadprios_tab[CONFIG_IRQ_THREAD_PRIOS_PARAM_MAX];
+static int irqthreadprios_num = 0;
+
+
+static bool __match_charclass(const char *pat, char c, const char **npat)
+{
+	bool complement = false, ret = true;
+
+	if (*pat == '!') {
+		complement = true;
+		pat++;
+	}
+	if (*pat++ == c)	/* First character is special */
+		goto end;
+
+	while (*pat && *pat != ']') {	/* Matching */
+		if (*pat == '-' && *(pat + 1) != ']') {	/* Range */
+			if (*(pat - 1) <= c && c <= *(pat + 1))
+				goto end;
+			if (*(pat - 1) > *(pat + 1))
+				goto error;
+			pat += 2;
+		} else if (*pat++ == c)
+			goto end;
+	}
+	if (!*pat)
+		goto error;
+	ret = false;
+
+end:
+	while (*pat && *pat != ']')	/* Searching closing */
+		pat++;
+	if (!*pat)
+		goto error;
+	*npat = pat + 1;
+	return complement ? !ret : ret;
+
+error:
+	return false;
+}
+
+/* Glob/lazy pattern matching */
+static bool __match_glob(const char *str, const char *pat)
+{
+	while (*str && *pat && *pat != '*') {
+		switch (*pat) {
+		case '?':	/* Matches any single character */
+			str++;
+			pat++;
+			continue;
+		case '[':	/* Character classes/Ranges */
+			if (__match_charclass(pat + 1, *str, &pat)) {
+				str++;
+				continue;
+			}
+			return false;
+		case '\\':	/* Escaped char match as normal char */
+			pat++;
+			//fallthrough
+		default:
+			if (*str++ != *pat++)
+				return false;
+		}
+	}
+	/* Check wild card */
+	if (*pat == '*') {
+		while (*pat == '*')	//skip '*', even more than one
+			pat++;
+		if (!*pat)	/* Tail wild card matches all */
+			return true;
+		while (*str)
+			if (__match_glob(str++, pat))
+				return true;
+	}
+	return !*str && !*pat;
+}
+
+
+int find_irq_prio(const char *intname)
+{
+	//  return MAX_USER_RT_PRIO/2;
+	int i;
+	for (i = 0; i < irqthreadprios_num; i++) {
+		char *pat = irqthreadprios_tab[i].pat;
+		//if((strncmp(s,"*",2)==0)|| (strncmp(s,intname,100)==0))
+		if (__match_glob(intname, pat)) {
+			printk(KERN_INFO
+			       "irqthreadprios: %20s prio = %d (match: %s)\n",
+			       intname, irqthreadprios_tab[i].prio, pat);
+
+			return irqthreadprios_tab[i].prio;
+		}
+	}
+	printk(KERN_WARNING
+	       "irqthreadprios: %20s prio = %d (WARNING no match, default prio used)\n",
+	       intname, MAX_USER_RT_PRIO / 2);
+
+	return MAX_USER_RT_PRIO / 2;
+}
+EXPORT_SYMBOL(find_irq_prio);
+
+static int parse_irqthreadprios(char *in_str)
+{
+	static char strbuf[CONFIG_IRQ_THREAD_PRIOS_PARAM_SIZE];
+	char *str;
+
+	if (strlen(in_str) > sizeof(strbuf) - 1) {
+		printk(KERN_ERR "irqthreadprios: string too long: %d\n",
+		       strlen(in_str));
+		return 0;
+	}
+	//duplicate input string for later reference of partial key-strings
+	strlcpy(strbuf, in_str, sizeof(strbuf) - 1);
+
+	for (str = strbuf; str;) {
+		int prio;
+		char *priop;
+		char *k = strchr(str, ',');
+
+		if (k)
+			*k++ = 0;	//terminate arg skip ',' to next arg
+
+		//arg format: 'name:val'   e.g. 'uartlite:22'
+		priop = strchr(str, ':');
+		while(priop && priop[-1]=='\\') { //support escaped '\:'
+			priop = strchr(++priop, ':');
+		}
+		if (priop) {	//ignore bad formatted args
+			*priop++ = 0;	//terminate name, skip to val
+
+			if (irqthreadprios_num <
+			    (sizeof(irqthreadprios_tab) /
+			     sizeof(irqthreadprios_tab[0]))) {
+				kstrtoint(priop, 0, &prio);
+				irqthreadprios_tab[irqthreadprios_num].prio =
+				    clamp(prio, 0, MAX_USER_RT_PRIO);
+				irqthreadprios_tab[irqthreadprios_num].pat =
+				    str;
+				irqthreadprios_num++;
+			} else {
+				printk(KERN_ERR
+				       "irqthreadprios: tab overflow %d\n",
+				       irqthreadprios_num);
+			}
+		}
+
+		str = k;	//next arg
+	}
+
+	return 0;
+}
+
+//format uartlite:55,uio_scu3:56,*:20
+early_param("irqthreadprios", parse_irqthreadprios);
+
+#endif
+
+
 /**
  *	synchronize_irq - wait for pending IRQ handlers (on other CPUs)
  *	@irq: interrupt number to wait for
@ linux-3.12.33-rt47-i386/kernel/irq/Kconfig:1197 @ __setup_irq(unsigned int irq, struct irq
 	 */
 	if (new->thread_fn && !nested) {
 		struct task_struct *t;
-		static const struct sched_param param = {
+		struct sched_param param = {
 			.sched_priority = MAX_USER_RT_PRIO/2,
 		};
+#ifdef CONFIG_IRQ_THREAD_PRIOS_PARAM
+		param.sched_priority = find_irq_prio(new->name);
+#endif
+
 
 		t = kthread_create(irq_thread, new, "irq/%d-%s", irq,
 				   new->name);
Index: linux-3.12.33-rt47-i386/include/linux/irq.h
===================================================================
--- linux-3.12.33-rt47-i386.orig/include/linux/irq.h
+++ linux-3.12.33-rt47-i386/include/linux/irq.h
@ linux-3.12.33-rt47-i386/kernel/irq/Kconfig:397 @ static inline void irq_move_irq(struct i
 static inline void irq_move_masked_irq(struct irq_data *data) { }
 #endif
 
+#ifdef CONFIG_IRQ_THREAD_PRIOS_PARAM
+extern int find_irq_prio(const char *intname);
+#endif
+
 extern int no_irq_affinity;
 
 #ifdef CONFIG_HARDIRQS_SW_RESEND
Index: linux-3.12.33-rt47-i386/kernel/softirq.c
===================================================================
--- linux-3.12.33-rt47-i386.orig/kernel/softirq.c
+++ linux-3.12.33-rt47-i386/kernel/softirq.c
@ linux-3.12.33-rt47-i386/kernel/irq/Kconfig:699 @ static inline void _local_bh_enable_nort
 static inline void ksoftirqd_set_sched_params(unsigned int cpu)
 {
 	struct sched_param param = { .sched_priority = 1 };
-
+#ifdef CONFIG_IRQ_THREAD_PRIOS_PARAM
+	param.sched_priority = find_irq_prio(current->comm);
+#endif
 	sched_setscheduler(current, SCHED_FIFO, &param);
 	/* Take over all pending softirqs when starting */
 	local_irq_disable();