Skip to content

Commit

Permalink
spi: dw: use managed resources
Browse files Browse the repository at this point in the history
Migrate mmio code and core driver to managed resources to reduce boilerplate
error handling code. Also, handle clk_enable() failure while at it, and drop
unused dw_spi iolen field.

Signed-off-by: Baruch Siach <[email protected]>
Signed-off-by: Mark Brown <[email protected]>
  • Loading branch information
baruchsiach authored and broonie committed Dec 31, 2013
1 parent 0a47d3c commit 04f421e
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 97 deletions.
70 changes: 20 additions & 50 deletions drivers/spi/spi-dw-mmio.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,95 +30,65 @@ static int dw_spi_mmio_probe(struct platform_device *pdev)
{
struct dw_spi_mmio *dwsmmio;
struct dw_spi *dws;
struct resource *mem, *ioarea;
struct resource *mem;
int ret;

dwsmmio = kzalloc(sizeof(struct dw_spi_mmio), GFP_KERNEL);
if (!dwsmmio) {
ret = -ENOMEM;
goto err_end;
}
dwsmmio = devm_kzalloc(&pdev->dev, sizeof(struct dw_spi_mmio),
GFP_KERNEL);
if (!dwsmmio)
return -ENOMEM;

dws = &dwsmmio->dws;

/* Get basic io resource and map it */
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem) {
dev_err(&pdev->dev, "no mem resource?\n");
ret = -EINVAL;
goto err_kfree;
return -EINVAL;
}

ioarea = request_mem_region(mem->start, resource_size(mem),
pdev->name);
if (!ioarea) {
dev_err(&pdev->dev, "SPI region already claimed\n");
ret = -EBUSY;
goto err_kfree;
}

dws->regs = ioremap_nocache(mem->start, resource_size(mem));
if (!dws->regs) {
dev_err(&pdev->dev, "SPI region already mapped\n");
ret = -ENOMEM;
goto err_release_reg;
dws->regs = devm_ioremap_resource(&pdev->dev, mem);
if (IS_ERR(dws->regs)) {
dev_err(&pdev->dev, "SPI region map failed\n");
return PTR_ERR(dws->regs);
}

dws->irq = platform_get_irq(pdev, 0);
if (dws->irq < 0) {
dev_err(&pdev->dev, "no irq resource?\n");
ret = dws->irq; /* -ENXIO */
goto err_unmap;
return dws->irq; /* -ENXIO */
}

dwsmmio->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(dwsmmio->clk)) {
ret = PTR_ERR(dwsmmio->clk);
goto err_unmap;
}
clk_enable(dwsmmio->clk);
dwsmmio->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(dwsmmio->clk))
return PTR_ERR(dwsmmio->clk);
ret = clk_enable(dwsmmio->clk);
if (ret)
return ret;

dws->parent_dev = &pdev->dev;
dws->bus_num = 0;
dws->num_cs = 4;
dws->max_freq = clk_get_rate(dwsmmio->clk);

ret = dw_spi_add_host(dws);
ret = dw_spi_add_host(&pdev->dev, dws);
if (ret)
goto err_clk;
goto out;

platform_set_drvdata(pdev, dwsmmio);
return 0;

err_clk:
out:
clk_disable(dwsmmio->clk);
clk_put(dwsmmio->clk);
dwsmmio->clk = NULL;
err_unmap:
iounmap(dws->regs);
err_release_reg:
release_mem_region(mem->start, resource_size(mem));
err_kfree:
kfree(dwsmmio);
err_end:
return ret;
}

static int dw_spi_mmio_remove(struct platform_device *pdev)
{
struct dw_spi_mmio *dwsmmio = platform_get_drvdata(pdev);
struct resource *mem;

clk_disable(dwsmmio->clk);
clk_put(dwsmmio->clk);
dwsmmio->clk = NULL;

dw_spi_remove_host(&dwsmmio->dws);
iounmap(dwsmmio->dws.regs);
kfree(dwsmmio);

mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
release_mem_region(mem->start, resource_size(mem));
return 0;
}

Expand Down
40 changes: 10 additions & 30 deletions drivers/spi/spi-dw-pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,35 +43,24 @@ static int spi_pci_probe(struct pci_dev *pdev,
dev_info(&pdev->dev, "found PCI SPI controller(ID: %04x:%04x)\n",
pdev->vendor, pdev->device);

ret = pci_enable_device(pdev);
ret = pcim_enable_device(pdev);
if (ret)
return ret;

dwpci = kzalloc(sizeof(struct dw_spi_pci), GFP_KERNEL);
if (!dwpci) {
ret = -ENOMEM;
goto err_disable;
}
dwpci = devm_kzalloc(&pdev-dev, sizeof(struct dw_spi_pci), GFP_KERNEL);
if (!dwpci)
return -ENOMEM;

dwpci->pdev = pdev;
dws = &dwpci->dws;

/* Get basic io resource and map it */
dws->paddr = pci_resource_start(pdev, pci_bar);
dws->iolen = pci_resource_len(pdev, pci_bar);

ret = pci_request_region(pdev, pci_bar, dev_name(&pdev->dev));
ret = pcim_iomap_regions(pdev, 1, dev_name(&pdev->dev));
if (ret)
goto err_kfree;

dws->regs = ioremap_nocache((unsigned long)dws->paddr,
pci_resource_len(pdev, pci_bar));
if (!dws->regs) {
ret = -ENOMEM;
goto err_release_reg;
}
return ret;

dws->parent_dev = &pdev->dev;
dws->bus_num = 0;
dws->num_cs = 4;
dws->irq = pdev->irq;
Expand All @@ -83,26 +72,17 @@ static int spi_pci_probe(struct pci_dev *pdev,
if (pdev->device == 0x0800) {
ret = dw_spi_mid_init(dws);
if (ret)
goto err_unmap;
return ret;
}

ret = dw_spi_add_host(dws);
ret = dw_spi_add_host(&pdev->dev, dws);
if (ret)
goto err_unmap;
return ret;

/* PCI hook and SPI hook use the same drv data */
pci_set_drvdata(pdev, dwpci);
return 0;

err_unmap:
iounmap(dws->regs);
err_release_reg:
pci_release_region(pdev, pci_bar);
err_kfree:
kfree(dwpci);
err_disable:
pci_disable_device(pdev);
return ret;
return 0;
}

static void spi_pci_remove(struct pci_dev *pdev)
Expand Down
20 changes: 6 additions & 14 deletions drivers/spi/spi-dw.c
Original file line number Diff line number Diff line change
Expand Up @@ -775,18 +775,16 @@ static void spi_hw_init(struct dw_spi *dws)
}
}

int dw_spi_add_host(struct dw_spi *dws)
int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
{
struct spi_master *master;
int ret;

BUG_ON(dws == NULL);

master = spi_alloc_master(dws->parent_dev, 0);
if (!master) {
ret = -ENOMEM;
goto exit;
}
master = spi_alloc_master(dev, 0);
if (!master)
return -ENOMEM;

dws->master = master;
dws->type = SSI_MOTO_SPI;
Expand All @@ -796,7 +794,7 @@ int dw_spi_add_host(struct dw_spi *dws)
snprintf(dws->name, sizeof(dws->name), "dw_spi%d",
dws->bus_num);

ret = request_irq(dws->irq, dw_spi_irq, IRQF_SHARED,
ret = devm_request_irq(dev, dws->irq, dw_spi_irq, IRQF_SHARED,
dws->name, dws);
if (ret < 0) {
dev_err(&master->dev, "can not get IRQ\n");
Expand Down Expand Up @@ -835,7 +833,7 @@ int dw_spi_add_host(struct dw_spi *dws)
}

spi_master_set_devdata(master, dws);
ret = spi_register_master(master);
ret = devm_spi_register_master(dev, master);
if (ret) {
dev_err(&master->dev, "problem registering spi master\n");
goto err_queue_alloc;
Expand All @@ -850,10 +848,8 @@ int dw_spi_add_host(struct dw_spi *dws)
dws->dma_ops->dma_exit(dws);
err_diable_hw:
spi_enable_chip(dws, 0);
free_irq(dws->irq, dws);
err_free_master:
spi_master_put(master);
exit:
return ret;
}
EXPORT_SYMBOL_GPL(dw_spi_add_host);
Expand All @@ -877,10 +873,6 @@ void dw_spi_remove_host(struct dw_spi *dws)
spi_enable_chip(dws, 0);
/* Disable clk */
spi_set_clk(dws, 0);
free_irq(dws->irq, dws);

/* Disconnect from the SPI framework */
spi_unregister_master(dws->master);
}
EXPORT_SYMBOL_GPL(dw_spi_remove_host);

Expand Down
4 changes: 1 addition & 3 deletions drivers/spi/spi-dw.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,11 @@ struct dw_spi_dma_ops {
struct dw_spi {
struct spi_master *master;
struct spi_device *cur_dev;
struct device *parent_dev;
enum dw_ssi_type type;
char name[16];

void __iomem *regs;
unsigned long paddr;
u32 iolen;
int irq;
u32 fifo_len; /* depth of the FIFO buffer */
u32 max_freq; /* max bus freq supported */
Expand Down Expand Up @@ -230,7 +228,7 @@ struct dw_spi_chip {
void (*cs_control)(u32 command);
};

extern int dw_spi_add_host(struct dw_spi *dws);
extern int dw_spi_add_host(struct device *dev, struct dw_spi *dws);
extern void dw_spi_remove_host(struct dw_spi *dws);
extern int dw_spi_suspend_host(struct dw_spi *dws);
extern int dw_spi_resume_host(struct dw_spi *dws);
Expand Down

0 comments on commit 04f421e

Please sign in to comment.