[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