powerpc/fsl_msi: add removal path and probe failing path
Also cleanup the probe function. Signed-off-by: Li Yang <leoli@freescale.com> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
This commit is contained in:
parent
061ca4adfb
commit
480599933a
2 changed files with 31 additions and 6 deletions
|
@ -250,6 +250,30 @@ static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc)
|
|||
raw_spin_unlock(&desc->lock);
|
||||
}
|
||||
|
||||
static int fsl_of_msi_remove(struct of_device *ofdev)
|
||||
{
|
||||
struct fsl_msi *msi = ofdev->dev.platform_data;
|
||||
int virq, i;
|
||||
struct fsl_msi_cascade_data *cascade_data;
|
||||
|
||||
if (msi->list.prev != NULL)
|
||||
list_del(&msi->list);
|
||||
for (i = 0; i < NR_MSI_REG; i++) {
|
||||
virq = msi->msi_virqs[i];
|
||||
if (virq != NO_IRQ) {
|
||||
cascade_data = get_irq_data(virq);
|
||||
kfree(cascade_data);
|
||||
irq_dispose_mapping(virq);
|
||||
}
|
||||
}
|
||||
if (msi->bitmap.bitmap)
|
||||
msi_bitmap_free(&msi->bitmap);
|
||||
iounmap(msi->msi_regs);
|
||||
kfree(msi);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit fsl_of_msi_probe(struct of_device *dev,
|
||||
const struct of_device_id *match)
|
||||
{
|
||||
|
@ -269,9 +293,9 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev,
|
|||
msi = kzalloc(sizeof(struct fsl_msi), GFP_KERNEL);
|
||||
if (!msi) {
|
||||
dev_err(&dev->dev, "No memory for MSI structure\n");
|
||||
err = -ENOMEM;
|
||||
goto error_out;
|
||||
return -ENOMEM;
|
||||
}
|
||||
dev->dev.platform_data = msi;
|
||||
|
||||
msi->irqhost = irq_alloc_host(dev->node, IRQ_HOST_MAP_LINEAR,
|
||||
NR_MSI_IRQS, &fsl_msi_host_ops, 0);
|
||||
|
@ -328,9 +352,7 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev,
|
|||
offset = *p / IRQS_PER_MSI_REG;
|
||||
|
||||
count /= sizeof(u32);
|
||||
for (i = 0; i < count / 2; i++) {
|
||||
if (i > NR_MSI_REG)
|
||||
break;
|
||||
for (i = 0; i < min(count / 2, NR_MSI_REG); i++) {
|
||||
virt_msir = irq_of_parse_and_map(dev->node, i);
|
||||
if (virt_msir != NO_IRQ) {
|
||||
cascade_data = kzalloc(
|
||||
|
@ -342,6 +364,7 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev,
|
|||
err = -ENOMEM;
|
||||
goto error_out;
|
||||
}
|
||||
msi->msi_virqs[i] = virt_msir;
|
||||
cascade_data->index = i + offset;
|
||||
cascade_data->msi_data = msi;
|
||||
set_irq_data(virt_msir, (void *)cascade_data);
|
||||
|
@ -363,7 +386,7 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev,
|
|||
}
|
||||
return 0;
|
||||
error_out:
|
||||
kfree(msi);
|
||||
fsl_of_msi_remove(dev);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -393,6 +416,7 @@ static struct of_platform_driver fsl_of_msi_driver = {
|
|||
.name = "fsl-msi",
|
||||
.match_table = fsl_of_msi_ids,
|
||||
.probe = fsl_of_msi_probe,
|
||||
.remove = fsl_of_msi_remove,
|
||||
};
|
||||
|
||||
static __init int fsl_of_msi_init(void)
|
||||
|
|
|
@ -32,6 +32,7 @@ struct fsl_msi {
|
|||
u32 msi_addr_hi;
|
||||
void __iomem *msi_regs;
|
||||
u32 feature;
|
||||
int msi_virqs[NR_MSI_REG];
|
||||
|
||||
struct msi_bitmap bitmap;
|
||||
|
||||
|
|
Loading…
Reference in a new issue