mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-10 07:10:27 +00:00
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
@ -250,6 +250,30 @@ unlock:
|
|||||||
raw_spin_unlock(&desc->lock);
|
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,
|
static int __devinit fsl_of_msi_probe(struct of_device *dev,
|
||||||
const struct of_device_id *match)
|
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);
|
msi = kzalloc(sizeof(struct fsl_msi), GFP_KERNEL);
|
||||||
if (!msi) {
|
if (!msi) {
|
||||||
dev_err(&dev->dev, "No memory for MSI structure\n");
|
dev_err(&dev->dev, "No memory for MSI structure\n");
|
||||||
err = -ENOMEM;
|
return -ENOMEM;
|
||||||
goto error_out;
|
|
||||||
}
|
}
|
||||||
|
dev->dev.platform_data = msi;
|
||||||
|
|
||||||
msi->irqhost = irq_alloc_host(dev->node, IRQ_HOST_MAP_LINEAR,
|
msi->irqhost = irq_alloc_host(dev->node, IRQ_HOST_MAP_LINEAR,
|
||||||
NR_MSI_IRQS, &fsl_msi_host_ops, 0);
|
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;
|
offset = *p / IRQS_PER_MSI_REG;
|
||||||
|
|
||||||
count /= sizeof(u32);
|
count /= sizeof(u32);
|
||||||
for (i = 0; i < count / 2; i++) {
|
for (i = 0; i < min(count / 2, NR_MSI_REG); i++) {
|
||||||
if (i > NR_MSI_REG)
|
|
||||||
break;
|
|
||||||
virt_msir = irq_of_parse_and_map(dev->node, i);
|
virt_msir = irq_of_parse_and_map(dev->node, i);
|
||||||
if (virt_msir != NO_IRQ) {
|
if (virt_msir != NO_IRQ) {
|
||||||
cascade_data = kzalloc(
|
cascade_data = kzalloc(
|
||||||
@ -342,6 +364,7 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev,
|
|||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
goto error_out;
|
goto error_out;
|
||||||
}
|
}
|
||||||
|
msi->msi_virqs[i] = virt_msir;
|
||||||
cascade_data->index = i + offset;
|
cascade_data->index = i + offset;
|
||||||
cascade_data->msi_data = msi;
|
cascade_data->msi_data = msi;
|
||||||
set_irq_data(virt_msir, (void *)cascade_data);
|
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;
|
return 0;
|
||||||
error_out:
|
error_out:
|
||||||
kfree(msi);
|
fsl_of_msi_remove(dev);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -393,6 +416,7 @@ static struct of_platform_driver fsl_of_msi_driver = {
|
|||||||
.name = "fsl-msi",
|
.name = "fsl-msi",
|
||||||
.match_table = fsl_of_msi_ids,
|
.match_table = fsl_of_msi_ids,
|
||||||
.probe = fsl_of_msi_probe,
|
.probe = fsl_of_msi_probe,
|
||||||
|
.remove = fsl_of_msi_remove,
|
||||||
};
|
};
|
||||||
|
|
||||||
static __init int fsl_of_msi_init(void)
|
static __init int fsl_of_msi_init(void)
|
||||||
|
@ -32,6 +32,7 @@ struct fsl_msi {
|
|||||||
u32 msi_addr_hi;
|
u32 msi_addr_hi;
|
||||||
void __iomem *msi_regs;
|
void __iomem *msi_regs;
|
||||||
u32 feature;
|
u32 feature;
|
||||||
|
int msi_virqs[NR_MSI_REG];
|
||||||
|
|
||||||
struct msi_bitmap bitmap;
|
struct msi_bitmap bitmap;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user