ALSA: serial-u16550: Allocate resources with device-managed APIs
This patch converts the resource management in serial u16550 driver with devres as a clean up. Each manual resource management is converted with the corresponding devres helper, and the card object release is managed now via card->private_free instead of a lowlevel snd_device. This should give no user-visible functional changes. Link: https://lore.kernel.org/r/20210715075941.23332-76-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
@@ -115,7 +115,6 @@ struct snd_uart16550 {
|
|||||||
int irq;
|
int irq;
|
||||||
|
|
||||||
unsigned long base;
|
unsigned long base;
|
||||||
struct resource *res_base;
|
|
||||||
|
|
||||||
unsigned int speed;
|
unsigned int speed;
|
||||||
unsigned int speed_base;
|
unsigned int speed_base;
|
||||||
@@ -323,8 +322,7 @@ static int snd_uart16550_detect(struct snd_uart16550 *uart)
|
|||||||
return -ENODEV; /* Not configured */
|
return -ENODEV; /* Not configured */
|
||||||
}
|
}
|
||||||
|
|
||||||
uart->res_base = request_region(io_base, 8, "Serial MIDI");
|
if (!devm_request_region(uart->card->dev, io_base, 8, "Serial MIDI")) {
|
||||||
if (uart->res_base == NULL) {
|
|
||||||
snd_printk(KERN_ERR "u16550: can't grab port 0x%lx\n", io_base);
|
snd_printk(KERN_ERR "u16550: can't grab port 0x%lx\n", io_base);
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
@@ -752,21 +750,6 @@ static const struct snd_rawmidi_ops snd_uart16550_input =
|
|||||||
.trigger = snd_uart16550_input_trigger,
|
.trigger = snd_uart16550_input_trigger,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int snd_uart16550_free(struct snd_uart16550 *uart)
|
|
||||||
{
|
|
||||||
if (uart->irq >= 0)
|
|
||||||
free_irq(uart->irq, uart);
|
|
||||||
release_and_free_resource(uart->res_base);
|
|
||||||
kfree(uart);
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int snd_uart16550_dev_free(struct snd_device *device)
|
|
||||||
{
|
|
||||||
struct snd_uart16550 *uart = device->device_data;
|
|
||||||
return snd_uart16550_free(uart);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int snd_uart16550_create(struct snd_card *card,
|
static int snd_uart16550_create(struct snd_card *card,
|
||||||
unsigned long iobase,
|
unsigned long iobase,
|
||||||
int irq,
|
int irq,
|
||||||
@@ -776,14 +759,11 @@ static int snd_uart16550_create(struct snd_card *card,
|
|||||||
int droponfull,
|
int droponfull,
|
||||||
struct snd_uart16550 **ruart)
|
struct snd_uart16550 **ruart)
|
||||||
{
|
{
|
||||||
static const struct snd_device_ops ops = {
|
|
||||||
.dev_free = snd_uart16550_dev_free,
|
|
||||||
};
|
|
||||||
struct snd_uart16550 *uart;
|
struct snd_uart16550 *uart;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
|
||||||
uart = kzalloc(sizeof(*uart), GFP_KERNEL);
|
uart = devm_kzalloc(card->dev, sizeof(*uart), GFP_KERNEL);
|
||||||
if (!uart)
|
if (!uart)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
uart->adaptor = adaptor;
|
uart->adaptor = adaptor;
|
||||||
@@ -796,12 +776,11 @@ static int snd_uart16550_create(struct snd_card *card,
|
|||||||
err = snd_uart16550_detect(uart);
|
err = snd_uart16550_detect(uart);
|
||||||
if (err <= 0) {
|
if (err <= 0) {
|
||||||
printk(KERN_ERR "no UART detected at 0x%lx\n", iobase);
|
printk(KERN_ERR "no UART detected at 0x%lx\n", iobase);
|
||||||
snd_uart16550_free(uart);
|
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (irq >= 0 && irq != SNDRV_AUTO_IRQ) {
|
if (irq >= 0 && irq != SNDRV_AUTO_IRQ) {
|
||||||
if (request_irq(irq, snd_uart16550_interrupt,
|
if (devm_request_irq(card->dev, irq, snd_uart16550_interrupt,
|
||||||
0, "Serial MIDI", uart)) {
|
0, "Serial MIDI", uart)) {
|
||||||
snd_printk(KERN_WARNING
|
snd_printk(KERN_WARNING
|
||||||
"irq %d busy. Using Polling.\n", irq);
|
"irq %d busy. Using Polling.\n", irq);
|
||||||
@@ -819,13 +798,6 @@ static int snd_uart16550_create(struct snd_card *card,
|
|||||||
timer_setup(&uart->buffer_timer, snd_uart16550_buffer_timer, 0);
|
timer_setup(&uart->buffer_timer, snd_uart16550_buffer_timer, 0);
|
||||||
uart->timer_running = 0;
|
uart->timer_running = 0;
|
||||||
|
|
||||||
/* Register device */
|
|
||||||
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, uart, &ops);
|
|
||||||
if (err < 0) {
|
|
||||||
snd_uart16550_free(uart);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (uart->adaptor) {
|
switch (uart->adaptor) {
|
||||||
case SNDRV_SERIAL_MS124W_SA:
|
case SNDRV_SERIAL_MS124W_SA:
|
||||||
case SNDRV_SERIAL_MS124W_MB:
|
case SNDRV_SERIAL_MS124W_MB:
|
||||||
@@ -927,7 +899,7 @@ static int snd_serial_probe(struct platform_device *devptr)
|
|||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = snd_card_new(&devptr->dev, index[dev], id[dev], THIS_MODULE,
|
err = snd_devm_card_new(&devptr->dev, index[dev], id[dev], THIS_MODULE,
|
||||||
0, &card);
|
0, &card);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
@@ -939,11 +911,11 @@ static int snd_serial_probe(struct platform_device *devptr)
|
|||||||
base[dev], adaptor[dev], droponfull[dev],
|
base[dev], adaptor[dev], droponfull[dev],
|
||||||
&uart);
|
&uart);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto _err;
|
return err;
|
||||||
|
|
||||||
err = snd_uart16550_rmidi(uart, 0, outs[dev], ins[dev], &uart->rmidi);
|
err = snd_uart16550_rmidi(uart, 0, outs[dev], ins[dev], &uart->rmidi);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto _err;
|
return err;
|
||||||
|
|
||||||
sprintf(card->longname, "%s [%s] at %#lx, irq %d",
|
sprintf(card->longname, "%s [%s] at %#lx, irq %d",
|
||||||
card->shortname,
|
card->shortname,
|
||||||
@@ -953,27 +925,16 @@ static int snd_serial_probe(struct platform_device *devptr)
|
|||||||
|
|
||||||
err = snd_card_register(card);
|
err = snd_card_register(card);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto _err;
|
return err;
|
||||||
|
|
||||||
platform_set_drvdata(devptr, card);
|
platform_set_drvdata(devptr, card);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
_err:
|
|
||||||
snd_card_free(card);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int snd_serial_remove(struct platform_device *devptr)
|
|
||||||
{
|
|
||||||
snd_card_free(platform_get_drvdata(devptr));
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SND_SERIAL_DRIVER "snd_serial_u16550"
|
#define SND_SERIAL_DRIVER "snd_serial_u16550"
|
||||||
|
|
||||||
static struct platform_driver snd_serial_driver = {
|
static struct platform_driver snd_serial_driver = {
|
||||||
.probe = snd_serial_probe,
|
.probe = snd_serial_probe,
|
||||||
.remove = snd_serial_remove,
|
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = SND_SERIAL_DRIVER,
|
.name = SND_SERIAL_DRIVER,
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user