Loading drivers/spi/spi-xilinx.c +66 −106 Original line number Diff line number Diff line Loading @@ -80,10 +80,9 @@ struct xilinx_spi { /* bitbang has to be first */ struct spi_bitbang bitbang; struct completion done; struct resource mem; /* phys mem */ void __iomem *regs; /* virt. address of the control registers */ u32 irq; int irq; u8 *rx_ptr; /* pointer in the Tx buffer */ const u8 *tx_ptr; /* pointer in the Rx buffer */ Loading Loading @@ -340,17 +339,34 @@ static const struct of_device_id xilinx_spi_of_match[] = { }; MODULE_DEVICE_TABLE(of, xilinx_spi_of_match); struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, u32 irq, s16 bus_num, int num_cs, int bits_per_word) static int xilinx_spi_probe(struct platform_device *pdev) { struct spi_master *master; struct xilinx_spi *xspi; int ret; struct xspi_platform_data *pdata; struct resource *res; int ret, num_cs = 0, bits_per_word = 8; struct spi_master *master; u32 tmp; u8 i; pdata = pdev->dev.platform_data; if (pdata) { num_cs = pdata->num_chipselect; bits_per_word = pdata->bits_per_word; } else { of_property_read_u32(pdev->dev.of_node, "xlnx,num-ss-bits", &num_cs); } master = spi_alloc_master(dev, sizeof(struct xilinx_spi)); if (!num_cs) { dev_err(&pdev->dev, "Missing slave select configuration data\n"); return -EINVAL; } master = spi_alloc_master(&pdev->dev, sizeof(struct xilinx_spi)); if (!master) return NULL; return -ENODEV; /* the spi->mode bits understood by this driver: */ master->mode_bits = SPI_CPOL | SPI_CPHA; Loading @@ -362,22 +378,16 @@ struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, xspi->bitbang.txrx_bufs = xilinx_spi_txrx_bufs; init_completion(&xspi->done); if (!request_mem_region(mem->start, resource_size(mem), XILINX_SPI_NAME)) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); xspi->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(xspi->regs)) { ret = PTR_ERR(xspi->regs); goto put_master; xspi->regs = ioremap(mem->start, resource_size(mem)); if (xspi->regs == NULL) { dev_warn(dev, "ioremap failure\n"); goto map_failed; } master->bus_num = bus_num; master->bus_num = pdev->dev.id; master->num_chipselect = num_cs; master->dev.of_node = dev->of_node; xspi->mem = *mem; xspi->irq = irq; master->dev.of_node = pdev->dev.of_node; /* * Detect endianess on the IP via loop bit in CR. Detection Loading Loading @@ -407,113 +417,63 @@ struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, } else if (xspi->bits_per_word == 32) { xspi->tx_fn = xspi_tx32; xspi->rx_fn = xspi_rx32; } else goto unmap_io; } else { ret = -EINVAL; goto put_master; } /* SPI controller initializations */ xspi_init_hw(xspi); xspi->irq = platform_get_irq(pdev, 0); if (xspi->irq < 0) { ret = xspi->irq; goto put_master; } /* Register for SPI Interrupt */ ret = request_irq(xspi->irq, xilinx_spi_irq, 0, XILINX_SPI_NAME, xspi); ret = devm_request_irq(&pdev->dev, xspi->irq, xilinx_spi_irq, 0, dev_name(&pdev->dev), xspi); if (ret) goto unmap_io; goto put_master; ret = spi_bitbang_start(&xspi->bitbang); if (ret) { dev_err(dev, "spi_bitbang_start FAILED\n"); goto free_irq; } dev_info(dev, "at 0x%08llX mapped to 0x%p, irq=%d\n", (unsigned long long)mem->start, xspi->regs, xspi->irq); return master; free_irq: free_irq(xspi->irq, xspi); unmap_io: iounmap(xspi->regs); map_failed: release_mem_region(mem->start, resource_size(mem)); put_master: spi_master_put(master); return NULL; } EXPORT_SYMBOL(xilinx_spi_init); void xilinx_spi_deinit(struct spi_master *master) { struct xilinx_spi *xspi; xspi = spi_master_get_devdata(master); spi_bitbang_stop(&xspi->bitbang); free_irq(xspi->irq, xspi); iounmap(xspi->regs); release_mem_region(xspi->mem.start, resource_size(&xspi->mem)); spi_master_put(xspi->bitbang.master); dev_err(&pdev->dev, "spi_bitbang_start FAILED\n"); goto put_master; } EXPORT_SYMBOL(xilinx_spi_deinit); static int xilinx_spi_probe(struct platform_device *dev) { struct xspi_platform_data *pdata; struct resource *r; int irq, num_cs = 0, bits_per_word = 8; struct spi_master *master; u8 i; dev_info(&pdev->dev, "at 0x%08llX mapped to 0x%p, irq=%d\n", (unsigned long long)res->start, xspi->regs, xspi->irq); pdata = dev->dev.platform_data; if (pdata) { num_cs = pdata->num_chipselect; bits_per_word = pdata->bits_per_word; for (i = 0; i < pdata->num_devices; i++) spi_new_device(master, pdata->devices + i); } #ifdef CONFIG_OF if (dev->dev.of_node) { const __be32 *prop; int len; platform_set_drvdata(pdev, master); return 0; /* number of slave select bits is required */ prop = of_get_property(dev->dev.of_node, "xlnx,num-ss-bits", &len); if (prop && len >= sizeof(*prop)) num_cs = __be32_to_cpup(prop); } #endif put_master: spi_master_put(master); if (!num_cs) { dev_err(&dev->dev, "Missing slave select configuration data\n"); return -EINVAL; return ret; } static int xilinx_spi_remove(struct platform_device *pdev) { struct spi_master *master = platform_get_drvdata(pdev); struct xilinx_spi *xspi = spi_master_get_devdata(master); void __iomem *regs_base = xspi->regs; r = platform_get_resource(dev, IORESOURCE_MEM, 0); if (!r) return -ENODEV; irq = platform_get_irq(dev, 0); if (irq < 0) return -ENXIO; master = xilinx_spi_init(&dev->dev, r, irq, dev->id, num_cs, bits_per_word); if (!master) return -ENODEV; if (pdata) { for (i = 0; i < pdata->num_devices; i++) spi_new_device(master, pdata->devices + i); } spi_bitbang_stop(&xspi->bitbang); platform_set_drvdata(dev, master); return 0; } /* Disable all the interrupts just in case */ xspi->write_fn(0, regs_base + XIPIF_V123B_IIER_OFFSET); /* Disable the global IPIF interrupt */ xspi->write_fn(0, regs_base + XIPIF_V123B_DGIER_OFFSET); static int xilinx_spi_remove(struct platform_device *dev) { xilinx_spi_deinit(platform_get_drvdata(dev)); spi_master_put(xspi->bitbang.master); return 0; } Loading Loading
drivers/spi/spi-xilinx.c +66 −106 Original line number Diff line number Diff line Loading @@ -80,10 +80,9 @@ struct xilinx_spi { /* bitbang has to be first */ struct spi_bitbang bitbang; struct completion done; struct resource mem; /* phys mem */ void __iomem *regs; /* virt. address of the control registers */ u32 irq; int irq; u8 *rx_ptr; /* pointer in the Tx buffer */ const u8 *tx_ptr; /* pointer in the Rx buffer */ Loading Loading @@ -340,17 +339,34 @@ static const struct of_device_id xilinx_spi_of_match[] = { }; MODULE_DEVICE_TABLE(of, xilinx_spi_of_match); struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, u32 irq, s16 bus_num, int num_cs, int bits_per_word) static int xilinx_spi_probe(struct platform_device *pdev) { struct spi_master *master; struct xilinx_spi *xspi; int ret; struct xspi_platform_data *pdata; struct resource *res; int ret, num_cs = 0, bits_per_word = 8; struct spi_master *master; u32 tmp; u8 i; pdata = pdev->dev.platform_data; if (pdata) { num_cs = pdata->num_chipselect; bits_per_word = pdata->bits_per_word; } else { of_property_read_u32(pdev->dev.of_node, "xlnx,num-ss-bits", &num_cs); } master = spi_alloc_master(dev, sizeof(struct xilinx_spi)); if (!num_cs) { dev_err(&pdev->dev, "Missing slave select configuration data\n"); return -EINVAL; } master = spi_alloc_master(&pdev->dev, sizeof(struct xilinx_spi)); if (!master) return NULL; return -ENODEV; /* the spi->mode bits understood by this driver: */ master->mode_bits = SPI_CPOL | SPI_CPHA; Loading @@ -362,22 +378,16 @@ struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, xspi->bitbang.txrx_bufs = xilinx_spi_txrx_bufs; init_completion(&xspi->done); if (!request_mem_region(mem->start, resource_size(mem), XILINX_SPI_NAME)) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); xspi->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(xspi->regs)) { ret = PTR_ERR(xspi->regs); goto put_master; xspi->regs = ioremap(mem->start, resource_size(mem)); if (xspi->regs == NULL) { dev_warn(dev, "ioremap failure\n"); goto map_failed; } master->bus_num = bus_num; master->bus_num = pdev->dev.id; master->num_chipselect = num_cs; master->dev.of_node = dev->of_node; xspi->mem = *mem; xspi->irq = irq; master->dev.of_node = pdev->dev.of_node; /* * Detect endianess on the IP via loop bit in CR. Detection Loading Loading @@ -407,113 +417,63 @@ struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, } else if (xspi->bits_per_word == 32) { xspi->tx_fn = xspi_tx32; xspi->rx_fn = xspi_rx32; } else goto unmap_io; } else { ret = -EINVAL; goto put_master; } /* SPI controller initializations */ xspi_init_hw(xspi); xspi->irq = platform_get_irq(pdev, 0); if (xspi->irq < 0) { ret = xspi->irq; goto put_master; } /* Register for SPI Interrupt */ ret = request_irq(xspi->irq, xilinx_spi_irq, 0, XILINX_SPI_NAME, xspi); ret = devm_request_irq(&pdev->dev, xspi->irq, xilinx_spi_irq, 0, dev_name(&pdev->dev), xspi); if (ret) goto unmap_io; goto put_master; ret = spi_bitbang_start(&xspi->bitbang); if (ret) { dev_err(dev, "spi_bitbang_start FAILED\n"); goto free_irq; } dev_info(dev, "at 0x%08llX mapped to 0x%p, irq=%d\n", (unsigned long long)mem->start, xspi->regs, xspi->irq); return master; free_irq: free_irq(xspi->irq, xspi); unmap_io: iounmap(xspi->regs); map_failed: release_mem_region(mem->start, resource_size(mem)); put_master: spi_master_put(master); return NULL; } EXPORT_SYMBOL(xilinx_spi_init); void xilinx_spi_deinit(struct spi_master *master) { struct xilinx_spi *xspi; xspi = spi_master_get_devdata(master); spi_bitbang_stop(&xspi->bitbang); free_irq(xspi->irq, xspi); iounmap(xspi->regs); release_mem_region(xspi->mem.start, resource_size(&xspi->mem)); spi_master_put(xspi->bitbang.master); dev_err(&pdev->dev, "spi_bitbang_start FAILED\n"); goto put_master; } EXPORT_SYMBOL(xilinx_spi_deinit); static int xilinx_spi_probe(struct platform_device *dev) { struct xspi_platform_data *pdata; struct resource *r; int irq, num_cs = 0, bits_per_word = 8; struct spi_master *master; u8 i; dev_info(&pdev->dev, "at 0x%08llX mapped to 0x%p, irq=%d\n", (unsigned long long)res->start, xspi->regs, xspi->irq); pdata = dev->dev.platform_data; if (pdata) { num_cs = pdata->num_chipselect; bits_per_word = pdata->bits_per_word; for (i = 0; i < pdata->num_devices; i++) spi_new_device(master, pdata->devices + i); } #ifdef CONFIG_OF if (dev->dev.of_node) { const __be32 *prop; int len; platform_set_drvdata(pdev, master); return 0; /* number of slave select bits is required */ prop = of_get_property(dev->dev.of_node, "xlnx,num-ss-bits", &len); if (prop && len >= sizeof(*prop)) num_cs = __be32_to_cpup(prop); } #endif put_master: spi_master_put(master); if (!num_cs) { dev_err(&dev->dev, "Missing slave select configuration data\n"); return -EINVAL; return ret; } static int xilinx_spi_remove(struct platform_device *pdev) { struct spi_master *master = platform_get_drvdata(pdev); struct xilinx_spi *xspi = spi_master_get_devdata(master); void __iomem *regs_base = xspi->regs; r = platform_get_resource(dev, IORESOURCE_MEM, 0); if (!r) return -ENODEV; irq = platform_get_irq(dev, 0); if (irq < 0) return -ENXIO; master = xilinx_spi_init(&dev->dev, r, irq, dev->id, num_cs, bits_per_word); if (!master) return -ENODEV; if (pdata) { for (i = 0; i < pdata->num_devices; i++) spi_new_device(master, pdata->devices + i); } spi_bitbang_stop(&xspi->bitbang); platform_set_drvdata(dev, master); return 0; } /* Disable all the interrupts just in case */ xspi->write_fn(0, regs_base + XIPIF_V123B_IIER_OFFSET); /* Disable the global IPIF interrupt */ xspi->write_fn(0, regs_base + XIPIF_V123B_DGIER_OFFSET); static int xilinx_spi_remove(struct platform_device *dev) { xilinx_spi_deinit(platform_get_drvdata(dev)); spi_master_put(xspi->bitbang.master); return 0; } Loading