[alsa-devel] Releasing IRQs in older kernels

Takashi Iwai tiwai at suse.de
Tue Apr 15 14:26:41 CEST 2008


At Mon, 14 Apr 2008 23:48:15 +0300,
Risto Suominen wrote:
> 
> I'd like to bring up a problem with using alsa-driver on older
> kernels. I already made a bug report regarding snd-powermac:
> https://bugtrack.alsa-project.org/alsa-bug/view.php?id=3883. It's
> possible that other drivers suffer from this, too.
> 
> If I've understood it right, 1.0.16 should be usable on 2.2 kernels
> and newer. Well, it woudn't compile on 2.6.15-26-powerpc (Ubuntu
> 6.06.1 Dapper) without some patching.
> 
> However, the real problem began, when I tried to unload the module. It
> seems that something has changed (when?) in the kernel's IRQ
> interface, and ALSA tries to make old code compatible with it by
> introducing snd_request/free_irq, to be used with older kernels. The
> idea is to distuingish between IRQs by the last parameter, usually
> chip's address. This leads to trouble when several IRQs come from the
> same chip, as is the case with snd-powermac.
> 
> My conclusion: the drivers suffering from this should be identified,
> and some alternative way of handling IRQs correctly on different
> kernel versions should be developed.

Does the patch below work?


Takashi

---

diff -r 9bd27001c3e6 acore/wrappers.c
--- a/acore/wrappers.c	Thu Mar 13 11:41:30 2008 +0100
+++ b/acore/wrappers.c	Tue Apr 15 12:12:54 2008 +0200
@@ -250,6 +250,7 @@ typedef int (*snd_irq_handler_t)(int, vo
 typedef int (*snd_irq_handler_t)(int, void *);
 struct irq_list {
 	snd_irq_handler_t handler;
+	int irq;
 	void *data;
 	struct list_head list;
 };
@@ -289,6 +290,7 @@ int snd_request_irq(unsigned int irq, sn
 	if (!list)
 		return -ENOMEM;
 	list->handler = handler;
+	list->irq = irq;
 	list->data = data;
 	err = request_irq(irq, irq_redirect, irq_flags, str, list);
 	if (err) {
@@ -309,7 +311,7 @@ void snd_free_irq(unsigned int irq, void
 	mutex_lock(&irq_list_mutex);
 	list_for_each(p, &irq_list_head) {
 		struct irq_list *list = list_entry(p, struct irq_list, list);
-		if (list->data == data) {
+		if (list->irq == irq && list->data == data) {
 			free_irq(irq, list);
 			list_del(p);
 			kfree(list);


More information about the Alsa-devel mailing list