Commit ca18a0f8 authored by Dave Jones's avatar Dave Jones

[PATCH] MPU401 resource cleanups

parent b71bbdf9
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
* Alan Cox modularisation, use normal request_irq, use dev_id * Alan Cox modularisation, use normal request_irq, use dev_id
* Bartlomiej Zolnierkiewicz removed some __init to allow using many drivers * Bartlomiej Zolnierkiewicz removed some __init to allow using many drivers
* Chris Rankin Update the module-usage counter for the coprocessor * Chris Rankin Update the module-usage counter for the coprocessor
* Zwane Mwaikambo Changed attach/unload resource freeing
*/ */
#include <linux/module.h> #include <linux/module.h>
...@@ -79,7 +80,7 @@ struct mpu_config ...@@ -79,7 +80,7 @@ struct mpu_config
static void mpu401_close(int dev); static void mpu401_close(int dev);
static int mpu401_status(struct mpu_config *devc) static inline int mpu401_status(struct mpu_config *devc)
{ {
return inb(STATPORT(devc->base)); return inb(STATPORT(devc->base));
} }
...@@ -87,17 +88,17 @@ static int mpu401_status(struct mpu_config *devc) ...@@ -87,17 +88,17 @@ static int mpu401_status(struct mpu_config *devc)
#define input_avail(devc) (!(mpu401_status(devc)&INPUT_AVAIL)) #define input_avail(devc) (!(mpu401_status(devc)&INPUT_AVAIL))
#define output_ready(devc) (!(mpu401_status(devc)&OUTPUT_READY)) #define output_ready(devc) (!(mpu401_status(devc)&OUTPUT_READY))
static void write_command(struct mpu_config *devc, unsigned char cmd) static inline void write_command(struct mpu_config *devc, unsigned char cmd)
{ {
outb(cmd, COMDPORT(devc->base)); outb(cmd, COMDPORT(devc->base));
} }
static int read_data(struct mpu_config *devc) static inline int read_data(struct mpu_config *devc)
{ {
return inb(DATAPORT(devc->base)); return inb(DATAPORT(devc->base));
} }
static void write_data(struct mpu_config *devc, unsigned char byte) static inline void write_data(struct mpu_config *devc, unsigned char byte)
{ {
outb(byte, DATAPORT(devc->base)); outb(byte, DATAPORT(devc->base));
} }
...@@ -962,12 +963,12 @@ static void mpu401_chk_version(int n, struct mpu_config *devc) ...@@ -962,12 +963,12 @@ static void mpu401_chk_version(int n, struct mpu_config *devc)
spin_unlock_irqrestore(&devc->lock,flags); spin_unlock_irqrestore(&devc->lock,flags);
} }
void attach_mpu401(struct address_info *hw_config, struct module *owner) int attach_mpu401(struct address_info *hw_config, struct module *owner)
{ {
unsigned long flags; unsigned long flags;
char revision_char; char revision_char;
int m; int m, ret;
struct mpu_config *devc; struct mpu_config *devc;
hw_config->slots[1] = -1; hw_config->slots[1] = -1;
...@@ -975,7 +976,8 @@ void attach_mpu401(struct address_info *hw_config, struct module *owner) ...@@ -975,7 +976,8 @@ void attach_mpu401(struct address_info *hw_config, struct module *owner)
if (m == -1) if (m == -1)
{ {
printk(KERN_WARNING "MPU-401: Too many midi devices detected\n"); printk(KERN_WARNING "MPU-401: Too many midi devices detected\n");
return; ret = -ENOMEM;
goto out_err;
} }
devc = &dev_conf[m]; devc = &dev_conf[m];
devc->base = hw_config->io_base; devc->base = hw_config->io_base;
...@@ -1006,16 +1008,16 @@ void attach_mpu401(struct address_info *hw_config, struct module *owner) ...@@ -1006,16 +1008,16 @@ void attach_mpu401(struct address_info *hw_config, struct module *owner)
if (!reset_mpu401(devc)) if (!reset_mpu401(devc))
{ {
printk(KERN_WARNING "mpu401: Device didn't respond\n"); printk(KERN_WARNING "mpu401: Device didn't respond\n");
sound_unload_mididev(m); ret = -ENODEV;
return; goto out_mididev;
} }
if (!devc->shared_irq) if (!devc->shared_irq)
{ {
if (request_irq(devc->irq, mpuintr, 0, "mpu401", (void *)m) < 0) if (request_irq(devc->irq, mpuintr, 0, "mpu401", (void *)m) < 0)
{ {
printk(KERN_WARNING "mpu401: Failed to allocate IRQ%d\n", devc->irq); printk(KERN_WARNING "mpu401: Failed to allocate IRQ%d\n", devc->irq);
sound_unload_mididev(m); ret = -ENOMEM;
return; goto out_mididev;
} }
} }
spin_lock_irqsave(&devc->lock,flags); spin_lock_irqsave(&devc->lock,flags);
...@@ -1024,7 +1026,12 @@ void attach_mpu401(struct address_info *hw_config, struct module *owner) ...@@ -1024,7 +1026,12 @@ void attach_mpu401(struct address_info *hw_config, struct module *owner)
mpu401_chk_version(m, devc); mpu401_chk_version(m, devc);
spin_unlock_irqrestore(&devc->lock,flags); spin_unlock_irqrestore(&devc->lock,flags);
} }
request_region(hw_config->io_base, 2, "mpu401");
if (!request_region(hw_config->io_base, 2, "mpu401"))
{
ret = -ENOMEM;
goto out_irq;
}
if (devc->version != 0) if (devc->version != 0)
if (mpu_cmd(m, 0xC5, 0) >= 0) /* Set timebase OK */ if (mpu_cmd(m, 0xC5, 0) >= 0) /* Set timebase OK */
...@@ -1036,9 +1043,9 @@ void attach_mpu401(struct address_info *hw_config, struct module *owner) ...@@ -1036,9 +1043,9 @@ void attach_mpu401(struct address_info *hw_config, struct module *owner)
if (mpu401_synth_operations[m] == NULL) if (mpu401_synth_operations[m] == NULL)
{ {
sound_unload_mididev(m);
printk(KERN_ERR "mpu401: Can't allocate memory\n"); printk(KERN_ERR "mpu401: Can't allocate memory\n");
return; ret = -ENOMEM;
goto out_resource;
} }
if (!(devc->capabilities & MPU_CAP_INTLG)) /* No intelligent mode */ if (!(devc->capabilities & MPU_CAP_INTLG)) /* No intelligent mode */
{ {
...@@ -1117,6 +1124,17 @@ void attach_mpu401(struct address_info *hw_config, struct module *owner) ...@@ -1117,6 +1124,17 @@ void attach_mpu401(struct address_info *hw_config, struct module *owner)
hw_config->slots[1] = m; hw_config->slots[1] = m;
sequencer_init(); sequencer_init();
return 0;
out_resource:
release_region(hw_config->io_base, 2);
out_irq:
free_irq(devc->irq, (void *)m);
out_mididev:
sound_unload_mididev(m);
out_err:
return ret;
} }
static int reset_mpu401(struct mpu_config *devc) static int reset_mpu401(struct mpu_config *devc)
...@@ -1227,15 +1245,17 @@ void unload_mpu401(struct address_info *hw_config) ...@@ -1227,15 +1245,17 @@ void unload_mpu401(struct address_info *hw_config)
{ {
void *p; void *p;
int n=hw_config->slots[1]; int n=hw_config->slots[1];
release_region(hw_config->io_base, 2); if (n != -1) {
if (hw_config->always_detect == 0 && hw_config->irq > 0) release_region(hw_config->io_base, 2);
free_irq(hw_config->irq, (void *)n); if (hw_config->always_detect == 0 && hw_config->irq > 0)
p=mpu401_synth_operations[n]; free_irq(hw_config->irq, (void *)n);
sound_unload_mididev(n); p=mpu401_synth_operations[n];
sound_unload_timerdev(hw_config->slots[2]); sound_unload_mididev(n);
if(p) sound_unload_timerdev(hw_config->slots[2]);
kfree(p); if(p)
kfree(p);
}
} }
/***************************************************** /*****************************************************
...@@ -1752,6 +1772,7 @@ MODULE_PARM(io, "i"); ...@@ -1752,6 +1772,7 @@ MODULE_PARM(io, "i");
int __init init_mpu401(void) int __init init_mpu401(void)
{ {
int ret;
/* Can be loaded either for module use or to provide functions /* Can be loaded either for module use or to provide functions
to others */ to others */
if (io != -1 && irq != -1) { if (io != -1 && irq != -1) {
...@@ -1759,7 +1780,8 @@ int __init init_mpu401(void) ...@@ -1759,7 +1780,8 @@ int __init init_mpu401(void)
cfg.io_base = io; cfg.io_base = io;
if (probe_mpu401(&cfg) == 0) if (probe_mpu401(&cfg) == 0)
return -ENODEV; return -ENODEV;
attach_mpu401(&cfg, THIS_MODULE); if ((ret = attach_mpu401(&cfg, THIS_MODULE)))
return ret;
} }
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment