All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jan Kiszka <jan.kiszka@domain.hid>
To: xenomai-core <xenomai@xenomai.org>
Subject: [Xenomai-core] [PATCH] reduce config complexity of intr.c
Date: Sat, 07 Jul 2007 01:49:29 +0200	[thread overview]
Message-ID: <468ED509.8060105@domain.hid> (raw)


[-- Attachment #1.1: Type: text/plain, Size: 704 bytes --]

Here comes an attempt to clean up some of the mess that piled up in
nucleus/intr.c over the time and specifically after our last hot-fixes.

First of all, I think we don't loose much when merging the two separate
switches for level- and edge-triggered shared IRQs into a single one.
That already beatifies some lines, kills conditional code, and removes
one configuration decision the user has to make.

Then I reordered some code to avoid warnings for the non-shared non-SMP
case AND to fix a probable compilation issue of the simulator (due to
unknown ____cacheline_aligned_in_smp).

At this chance, a few redundant conditional lines in rtcan_*_pci.c
drivers were removed as well.

Jan

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: xnintr-cleanups.patch --]
[-- Type: text/x-patch; name="xnintr-cleanups.patch", Size: 14173 bytes --]

---
 include/nucleus/intr.h                     |    4 
 ksrc/drivers/can/sja1000/rtcan_ixxat_pci.c |    4 
 ksrc/drivers/can/sja1000/rtcan_peak_pci.c  |    4 
 ksrc/nucleus/Config.in                     |    8 -
 ksrc/nucleus/Kconfig                       |   32 +---
 ksrc/nucleus/intr.c                        |  213 ++++++++++++++---------------
 6 files changed, 116 insertions(+), 149 deletions(-)

Index: xenomai/include/nucleus/intr.h
===================================================================
--- xenomai.orig/include/nucleus/intr.h
+++ xenomai/include/nucleus/intr.h
@@ -45,9 +45,9 @@
 
 typedef struct xnintr {
 
-#if defined(CONFIG_XENO_OPT_SHIRQ_LEVEL) || defined(CONFIG_XENO_OPT_SHIRQ_EDGE)
+#ifdef CONFIG_XENO_OPT_SHIRQ
     struct xnintr *next; /* !< Next object in the IRQ-sharing chain. */
-#endif /* CONFIG_XENO_OPT_SHIRQ_LEVEL || CONFIG_XENO_OPT_SHIRQ_EDGE */
+#endif /* CONFIG_XENO_OPT_SHIRQ */
 
     unsigned unhandled;	/* !< Number of consequent unhandled interrupts */
 
Index: xenomai/ksrc/drivers/can/sja1000/rtcan_ixxat_pci.c
===================================================================
--- xenomai.orig/ksrc/drivers/can/sja1000/rtcan_ixxat_pci.c
+++ xenomai/ksrc/drivers/can/sja1000/rtcan_ixxat_pci.c
@@ -176,11 +176,7 @@ static int rtcan_ixxat_pci_add_chan(stru
     outb(intcsr, board->conf_addr + IXXAT_INTCSR_OFFSET);
 
     /* Register and setup interrupt handling */
-#ifdef CONFIG_XENO_OPT_SHIRQ_LEVEL
     chip->irq_flags = RTDM_IRQTYPE_SHARED;
-#else
-    chip->irq_flags = 0;
-#endif
     chip->irq_num = pdev->irq;
 
     RTCAN_DBG("%s: base_addr=0x%p conf_addr=%#x irq=%d ocr=%#x cdr=%#x\n",
Index: xenomai/ksrc/drivers/can/sja1000/rtcan_peak_pci.c
===================================================================
--- xenomai.orig/ksrc/drivers/can/sja1000/rtcan_peak_pci.c
+++ xenomai/ksrc/drivers/can/sja1000/rtcan_peak_pci.c
@@ -230,11 +230,7 @@ static int rtcan_peak_pci_add_chan(struc
     strncpy(dev->name, RTCAN_DEV_NAME, IFNAMSIZ);
 
     /* Register and setup interrupt handling */
-#ifdef CONFIG_XENO_OPT_SHIRQ_LEVEL
     chip->irq_flags = RTDM_IRQTYPE_SHARED;
-#else
-    chip->irq_flags = 0;
-#endif
     chip->irq_num = pdev->irq;
     pita_icr_high = readw(board->conf_addr + PITA_ICR + 2);
     if (channel == CHANNEL_SLAVE) {
Index: xenomai/ksrc/nucleus/Config.in
===================================================================
--- xenomai.orig/ksrc/nucleus/Config.in
+++ xenomai/ksrc/nucleus/Config.in
@@ -36,6 +36,8 @@ if [ "$CONFIG_XENO_OPT_NUCLEUS" != "n" ]
 		bool 'Watchdog support' CONFIG_XENO_OPT_WATCHDOG
 	fi
 
+	bool 'Shared interrupts' CONFIG_XENO_OPT_SHIRQ
+
 	bool 'Enable periodic timing' CONFIG_XENO_OPT_TIMING_PERIODIC
 	int 'Timer tuning latency (ns)' CONFIG_XENO_OPT_TIMING_TIMERLAT 0
 	int 'Scheduling latency (ns)' CONFIG_XENO_OPT_TIMING_SCHEDLAT 0
@@ -55,12 +57,6 @@ if [ "$CONFIG_XENO_OPT_NUCLEUS" != "n" ]
 	fi
 	endmenu
 
-	mainmenu_option next_comment
-	comment 'Shared interrupts'
-		bool 'Level-triggered interrupts' CONFIG_XENO_OPT_SHIRQ_LEVEL
-		bool 'Edge-triggered interrupts' CONFIG_XENO_OPT_SHIRQ_EDGE
-	endmenu
-
 	if [ "$CONFIG_LTT" != "n" ]; then
 		mainmenu_option next_comment
 		comment 'LTT tracepoints filtering'
Index: xenomai/ksrc/nucleus/Kconfig
===================================================================
--- xenomai.orig/ksrc/nucleus/Kconfig
+++ xenomai/ksrc/nucleus/Kconfig
@@ -208,6 +208,15 @@ config XENO_OPT_WATCHDOG
 	behalf of the timer tick handler, thus is only active after
 	the timer has been started.
 
+config XENO_OPT_SHIRQ
+	bool "Shared interrupts"
+	help
+
+	Enables support for both level- and edge-triggered shared
+	interrupts, so that multiple real-time interrupt handlers
+	are allowed to control dedicated hardware devices which are
+	configured to share the same interrupt line.
+
 menu "Timing"
 
 config XENO_OPT_TIMING_PERIODIC
@@ -319,29 +328,6 @@ config XENO_OPT_TIMER_WHEEL_STEP
 
 endmenu
 
-
-menu "Shared interrupts"
-
-config XENO_OPT_SHIRQ_LEVEL
-	bool "Level-triggered interrupts"
-	help
-
-	Enables support for shared level-triggered interrupts, so that
-	multiple real-time interrupt handlers are allowed to control
-	dedicated hardware devices which are configured to share
-	the same interrupt channel.
-
-config XENO_OPT_SHIRQ_EDGE
-	bool "Edge-triggered interrupts"
-	help
-
-	Enables support for shared edge-triggered interrupts, so that
-	multiple real-time interrupt handlers are allowed to control
-	dedicated hardware devices which are configured to share
-	the same interrupt channel.
-
-endmenu
-
 menu "LTT tracepoints filtering"
 
 	depends on LTT
Index: xenomai/ksrc/nucleus/intr.c
===================================================================
--- xenomai.orig/ksrc/nucleus/intr.c
+++ xenomai/ksrc/nucleus/intr.c
@@ -4,6 +4,7 @@
  *
  * Copyright (C) 2001,2002,2003 Philippe Gerum <rpm@xenomai.org>.
  * Copyright (C) 2005,2006 Dmitry Adamushko <dmitry.adamushko@domain.hid>.
+ * Copyright (C) 2007 Jan Kiszka <jan.kiszka@domain.hid>.
  *
  * Xenomai is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published
@@ -41,18 +42,6 @@
 
 DEFINE_PRIVATE_XNLOCK(intrlock);
 
-typedef struct xnintr_irq {
-
-	DECLARE_XNLOCK(lock);
-
-#if defined(CONFIG_XENO_OPT_SHIRQ_LEVEL) || defined(CONFIG_XENO_OPT_SHIRQ_EDGE)
-	xnintr_t *handlers;
-	int unhandled;
-#endif
-} ____cacheline_aligned_in_smp xnintr_irq_t;
-
-static xnintr_irq_t xnirqs[RTHAL_NR_IRQS];
-
 #ifdef CONFIG_XENO_OPT_STATS
 xnintr_t nkclock;	/* Only for statistics */
 int xnintr_count = 1;	/* Number of attached xnintr objects + nkclock */
@@ -94,71 +83,7 @@ static inline void xnintr_stat_counter_d
 static inline void xnintr_sync_stat_references(xnintr_t *intr) {}
 #endif /* CONFIG_XENO_OPT_STATS */
 
-/*
- * Low-level interrupt handler dispatching the ISRs -- Called with
- * interrupts off.
- */
-
-static void xnintr_irq_handler(unsigned irq, void *cookie)
-{
-	xnsched_t *sched = xnpod_current_sched();
-	xnintr_t *intr;
-	xnstat_runtime_t *prev;
-	xnticks_t start;
-	int s;
-
-	prev  = xnstat_runtime_get_current(sched);
-	start = xnstat_runtime_now();
-	xnltt_log_event(xeno_ev_ienter, irq);
-
-	++sched->inesting;
-
-	xnlock_get(&xnirqs[irq].lock);
-
-#ifdef CONFIG_SMP
-	/* In SMP case, we have to reload the cookie under the per-IRQ lock
-	   to avoid racing with xnintr_detach. */
-	intr = rthal_irq_cookie(&rthal_domain, irq);
-	if (unlikely(!intr)) {
-		s = 0;
-		goto unlock_and_exit;
-	}
-#else
-	/* cookie always valid, attach/detach happens with IRQs disabled */
-	intr = cookie;
-#endif
-	s = intr->isr(intr);
-
-	if (unlikely(s == XN_ISR_NONE)) {
-		if (++intr->unhandled == XNINTR_MAX_UNHANDLED) {
-			xnlogerr("%s: IRQ%d not handled. Disabling IRQ "
-				 "line.\n", __FUNCTION__, irq);
-			s |= XN_ISR_NOENABLE;
-		}
-	} else {
-		xnstat_counter_inc(&intr->stat[xnsched_cpu(sched)].hits);
-		xnstat_runtime_lazy_switch(sched,
-			&intr->stat[xnsched_cpu(sched)].account,
-			start);
-		intr->unhandled = 0;
-	}
-
-#ifdef CONFIG_SMP
- unlock_and_exit:
-#endif
-	xnlock_put(&xnirqs[irq].lock);
-
-	if (s & XN_ISR_PROPAGATE)
-		xnarch_chain_irq(irq);
-	else if (!(s & XN_ISR_NOENABLE))
-		xnarch_end_irq(irq);
-
-	if (--sched->inesting == 0 && xnsched_resched_p())
-		xnpod_schedule();
-
-	xnltt_log_event(xeno_ev_iexit, irq);
-	xnstat_runtime_switch(sched, prev);
-}
+static void xnintr_irq_handler(unsigned irq, void *cookie);
 
 /* Low-level clock irq handler. */
 
@@ -205,14 +130,23 @@ void xnintr_clock_handler(void)
 
 /* Optional support for shared interrupts. */
 
-#if defined(CONFIG_XENO_OPT_SHIRQ_LEVEL) || defined(CONFIG_XENO_OPT_SHIRQ_EDGE)
+#ifdef CONFIG_XENO_OPT_SHIRQ
+
+typedef struct xnintr_irq {
+
+	DECLARE_XNLOCK(lock);
+
+	xnintr_t *handlers;
+	int unhandled;
+
+} ____cacheline_aligned_in_smp xnintr_irq_t;
+
+static xnintr_irq_t xnirqs[RTHAL_NR_IRQS];
 
-#if defined(CONFIG_XENO_OPT_SHIRQ_LEVEL)
 /*
  * Low-level interrupt handler dispatching the user-defined ISRs for
  * shared interrupts -- Called with interrupts off.
  */
-
 static void xnintr_shirq_handler(unsigned irq, void *cookie)
 {
 	xnsched_t *sched = xnpod_current_sched();
@@ -272,14 +206,10 @@ static void xnintr_shirq_handler(unsigne
 	xnstat_runtime_switch(sched, prev);
 }
 
-#endif /* CONFIG_XENO_OPT_SHIRQ_LEVEL */
-
-#if defined(CONFIG_XENO_OPT_SHIRQ_EDGE)
 /*
  * Low-level interrupt handler dispatching the user-defined ISRs for
  * shared edge-triggered interrupts -- Called with interrupts off.
  */
-
 static void xnintr_edge_shirq_handler(unsigned irq, void *cookie)
 {
 	const int MAX_EDGEIRQ_COUNTER = 128;
@@ -356,8 +286,6 @@ static void xnintr_edge_shirq_handler(un
 	xnstat_runtime_switch(sched, prev);
 }
 
-#endif /* CONFIG_XENO_OPT_SHIRQ_EDGE */
-
 static inline int xnintr_irq_attach(xnintr_t *intr)
 {
 	xnintr_irq_t *shirq = &xnirqs[intr->irq];
@@ -389,17 +317,9 @@ static inline int xnintr_irq_attach(xnin
 
 		if (intr->flags & XN_ISR_SHARED) {
 			if (intr->flags & XN_ISR_EDGE)
-#if defined(CONFIG_XENO_OPT_SHIRQ_EDGE)
 				handler = &xnintr_edge_shirq_handler;
-#else /* !CONFIG_XENO_OPT_SHIRQ_EDGE */
-				return -ENOSYS;
-#endif /* CONFIG_XENO_OPT_SHIRQ_EDGE */
 			else
-#if defined(CONFIG_XENO_OPT_SHIRQ_LEVEL)
 				handler = &xnintr_shirq_handler;
-#else /* !CONFIG_XENO_OPT_SHIRQ_LEVEL */
-				return -ENOSYS;
-#endif /* CONFIG_XENO_OPT_SHIRQ_LEVEL */
 
 		}
 		shirq->unhandled = 0;
@@ -457,7 +377,17 @@ static inline int xnintr_irq_detach(xnin
 	return err;
 }
 
-#else /* !CONFIG_XENO_OPT_SHIRQ_LEVEL && !CONFIG_XENO_OPT_SHIRQ_EDGE */
+#else /* !CONFIG_XENO_OPT_SHIRQ */
+
+#ifdef CONFIG_SMP
+typedef struct xnintr_irq {
+
+	DECLARE_XNLOCK(lock);
+
+} ____cacheline_aligned_in_smp xnintr_irq_t;
+
+static xnintr_irq_t xnirqs[RTHAL_NR_IRQS];
+#endif /* CONFIG_SMP */
 
 static inline int xnintr_irq_attach(xnintr_t *intr)
 {
@@ -477,7 +407,72 @@ static inline int xnintr_irq_detach(xnin
 	return err;
 }
 
-#endif /* CONFIG_XENO_OPT_SHIRQ_LEVEL || CONFIG_XENO_OPT_SHIRQ_EDGE */
+#endif /* !CONFIG_XENO_OPT_SHIRQ */
+
+/*
+ * Low-level interrupt handler dispatching non-shared ISRs -- Called with
+ * interrupts off.
+ */
+static void xnintr_irq_handler(unsigned irq, void *cookie)
+{
+	xnsched_t *sched = xnpod_current_sched();
+	xnintr_t *intr;
+	xnstat_runtime_t *prev;
+	xnticks_t start;
+	int s;
+
+	prev  = xnstat_runtime_get_current(sched);
+	start = xnstat_runtime_now();
+	xnltt_log_event(xeno_ev_ienter, irq);
+
+	++sched->inesting;
+
+	xnlock_get(&xnirqs[irq].lock);
+
+#ifdef CONFIG_SMP
+	/* In SMP case, we have to reload the cookie under the per-IRQ lock
+	   to avoid racing with xnintr_detach. */
+	intr = rthal_irq_cookie(&rthal_domain, irq);
+	if (unlikely(!intr)) {
+		s = 0;
+		goto unlock_and_exit;
+	}
+#else
+	/* cookie always valid, attach/detach happens with IRQs disabled */
+	intr = cookie;
+#endif
+	s = intr->isr(intr);
+
+	if (unlikely(s == XN_ISR_NONE)) {
+		if (++intr->unhandled == XNINTR_MAX_UNHANDLED) {
+			xnlogerr("%s: IRQ%d not handled. Disabling IRQ "
+				 "line.\n", __FUNCTION__, irq);
+			s |= XN_ISR_NOENABLE;
+		}
+	} else {
+		xnstat_counter_inc(&intr->stat[xnsched_cpu(sched)].hits);
+		xnstat_runtime_lazy_switch(sched,
+			&intr->stat[xnsched_cpu(sched)].account,
+			start);
+		intr->unhandled = 0;
+	}
+
+#ifdef CONFIG_SMP
+ unlock_and_exit:
+#endif
+	xnlock_put(&xnirqs[irq].lock);
+
+	if (s & XN_ISR_PROPAGATE)
+		xnarch_chain_irq(irq);
+	else if (!(s & XN_ISR_NOENABLE))
+		xnarch_end_irq(irq);
+
+	if (--sched->inesting == 0 && xnsched_resched_p())
+		xnpod_schedule();
+
+	xnltt_log_event(xeno_ev_iexit, irq);
+	xnstat_runtime_switch(sched, prev);
+}
 
 int xnintr_mount(void)
 {
@@ -598,9 +593,9 @@ int xnintr_init(xnintr_t *intr,
 	intr->flags = flags;
 	intr->unhandled = 0;
 	memset(&intr->stat, 0, sizeof(intr->stat));
-#if defined(CONFIG_XENO_OPT_SHIRQ_LEVEL) || defined(CONFIG_XENO_OPT_SHIRQ_EDGE)
+#ifdef CONFIG_XENO_OPT_SHIRQ
 	intr->next = NULL;
-#endif /* CONFIG_XENO_OPT_SHIRQ_LEVEL || CONFIG_XENO_OPT_SHIRQ_EDGE */
+#endif
 
 	return 0;
 }
@@ -849,7 +844,7 @@ int xnintr_irq_proc(unsigned int irq, ch
 
 	xnlock_get_irqsave(&intrlock, s);
 
-#if defined(CONFIG_XENO_OPT_SHIRQ_LEVEL) || defined(CONFIG_XENO_OPT_SHIRQ_EDGE)
+#ifdef CONFIG_XENO_OPT_SHIRQ
 	intr = xnirqs[irq].handlers;
 	if (intr) {
 		strcpy(p, "        "); p += 8;
@@ -861,13 +856,13 @@ int xnintr_irq_proc(unsigned int irq, ch
 			intr = intr->next;
 		} while (intr);
 	}
-#else /* !CONFIG_XENO_OPT_SHIRQ_LEVEL && !CONFIG_XENO_OPT_SHIRQ_EDGE */
+#else /* !CONFIG_XENO_OPT_SHIRQ */
 	intr = rthal_irq_cookie(&rthal_domain, irq);
 	if (intr) {
 		strcpy(p, "         "); p += 9;
 		strcpy(p, intr->name); p += strlen(intr->name);
 	}
-#endif /* CONFIG_XENO_OPT_SHIRQ_LEVEL || CONFIG_XENO_OPT_SHIRQ_EDGE */
+#endif /* !CONFIG_XENO_OPT_SHIRQ */
 
 	xnlock_put_irqrestore(&intrlock, s);
 
@@ -897,21 +892,19 @@ int xnintr_query(int irq, int *cpu, xnin
 		goto unlock_and_exit;
 	}
 
-#if defined(CONFIG_XENO_OPT_SHIRQ_LEVEL) || defined(CONFIG_XENO_OPT_SHIRQ_EDGE)
-	if (*prev)
-		intr = (*prev)->next;
-	else if (irq == XNARCH_TIMER_IRQ)
+	if (irq == XNARCH_TIMER_IRQ)
 		intr = &nkclock;
+#ifdef CONFIG_XENO_OPT_SHIRQ
+	else if (*prev)
+		intr = (*prev)->next;
 	else
 		intr = xnirqs[irq].handlers;
-#else /* !CONFIG_XENO_OPT_SHIRQ_LEVEL && !CONFIG_XENO_OPT_SHIRQ_EDGE */
-	if (*prev)
+#else /* !CONFIG_XENO_OPT_SHIRQ */
+	else if (*prev)
 		intr = NULL;
-	else if (irq == XNARCH_TIMER_IRQ)
-		intr = &nkclock;
 	else
 		intr = rthal_irq_cookie(&rthal_domain, irq);
-#endif /* CONFIG_XENO_OPT_SHIRQ_LEVEL || CONFIG_XENO_OPT_SHIRQ_EDGE */
+#endif /* !CONFIG_XENO_OPT_SHIRQ */
 
 	if (!intr) {
 		err = -ENODEV;

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 249 bytes --]

             reply	other threads:[~2007-07-06 23:49 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-07-06 23:49 Jan Kiszka [this message]
2007-07-07  7:28 ` [Xenomai-core] [PATCH] reduce config complexity of intr.c Jan Kiszka
2007-07-08 10:11 ` Jan Kiszka

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=468ED509.8060105@domain.hid \
    --to=jan.kiszka@domain.hid \
    --cc=xenomai@xenomai.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.