return 0;
}
+static void pxa2xx_spi_ssp_release(void *ssp)
+{
+ pxa_ssp_free(ssp);
+}
+
+static struct ssp_device *pxa2xx_spi_ssp_request(struct platform_device *pdev)
+{
+ struct ssp_device *ssp;
+ int status;
+
+ ssp = pxa_ssp_request(pdev->id, pdev->name);
+ if (!ssp)
+ return ssp;
+
+ status = devm_add_action_or_reset(&pdev->dev, pxa2xx_spi_ssp_release, ssp);
+ if (status)
+ return ERR_PTR(status);
+
+ return ssp;
+}
+
static struct pxa2xx_spi_controller *
pxa2xx_spi_init_pdata(struct platform_device *pdev)
{
type = (enum pxa_ssp_type)value;
} else {
- ssp = pxa_ssp_request(pdev->id, pdev->name);
- if (ssp) {
+ ssp = pxa2xx_spi_ssp_request(pdev);
+ if (IS_ERR(ssp))
+ return ERR_CAST(ssp);
+ if (ssp)
type = ssp->type;
- pxa_ssp_free(ssp);
- }
}
/* Validate the SSP type correctness */
}
dev_dbg(dev, "DMA burst size set to %u\n", platform_info->dma_burst_size);
- ssp = pxa_ssp_request(pdev->id, pdev->name);
+ ssp = pxa2xx_spi_ssp_request(pdev);
+ if (IS_ERR(ssp))
+ return PTR_ERR(ssp);
if (!ssp)
ssp = &platform_info->ssp;
controller = devm_spi_alloc_target(dev, sizeof(*drv_data));
else
controller = devm_spi_alloc_host(dev, sizeof(*drv_data));
+ if (!controller)
+ return dev_err_probe(dev, -ENOMEM, "cannot alloc spi_controller\n");
- if (!controller) {
- status = dev_err_probe(dev, -ENOMEM, "cannot alloc spi_controller\n");
- goto out_error_controller_alloc;
- }
drv_data = spi_controller_get_devdata(controller);
drv_data->controller = controller;
drv_data->controller_info = platform_info;
status = request_irq(ssp->irq, ssp_int, IRQF_SHARED, dev_name(dev),
drv_data);
- if (status < 0) {
- dev_err_probe(dev, status, "cannot get IRQ %d\n", ssp->irq);
- goto out_error_controller_alloc;
- }
+ if (status < 0)
+ return dev_err_probe(dev, status, "cannot get IRQ %d\n", ssp->irq);
/* Setup DMA if requested */
if (platform_info->enable_dma) {
pxa2xx_spi_dma_release(drv_data);
free_irq(ssp->irq, drv_data);
-out_error_controller_alloc:
- pxa_ssp_free(ssp);
return status;
}
/* Release IRQ */
free_irq(ssp->irq, drv_data);
-
- /* Release SSP */
- pxa_ssp_free(ssp);
}
static int pxa2xx_spi_suspend(struct device *dev)