mirror of
https://github.com/torvalds/linux.git
synced 2026-05-31 10:33:41 +02:00
spi: ep93xx: add DT support for Cirrus EP93xx
- add OF ID match table - add device tree DMA request, so we can probe defer, in case DMA is not ready yet - drop DMA platform code Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me> Tested-by: Alexander Sverdlin <alexander.sverdlin@gmail.com> Reviewed-by: Linus Walleij <linus.walleij@linaro.org> Reviewed-by: Mark Brown <broonie@kernel.org> Acked-by: Alexander Sverdlin <alexander.sverdlin@gmail.com> Acked-by: Vinod Koul <vkoul@kernel.org> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
parent
cb0291776f
commit
e79e7c2df6
|
|
@ -18,18 +18,18 @@
|
|||
#include <linux/err.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/dma-direction.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/dmaengine.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/spi/spi.h>
|
||||
|
||||
#include <linux/platform_data/dma-ep93xx.h>
|
||||
#include <linux/platform_data/spi-ep93xx.h>
|
||||
|
||||
#define SSPCR0 0x0000
|
||||
#define SSPCR0_SPO BIT(6)
|
||||
#define SSPCR0_SPH BIT(7)
|
||||
|
|
@ -92,8 +92,6 @@ struct ep93xx_spi {
|
|||
size_t fifo_level;
|
||||
struct dma_chan *dma_rx;
|
||||
struct dma_chan *dma_tx;
|
||||
struct ep93xx_dma_data dma_rx_data;
|
||||
struct ep93xx_dma_data dma_tx_data;
|
||||
struct sg_table rx_sgt;
|
||||
struct sg_table tx_sgt;
|
||||
void *zeropage;
|
||||
|
|
@ -575,46 +573,23 @@ static int ep93xx_spi_unprepare_hardware(struct spi_controller *host)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool ep93xx_spi_dma_filter(struct dma_chan *chan, void *filter_param)
|
||||
static int ep93xx_spi_setup_dma(struct device *dev, struct ep93xx_spi *espi)
|
||||
{
|
||||
if (ep93xx_dma_chan_is_m2p(chan))
|
||||
return false;
|
||||
|
||||
chan->private = filter_param;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int ep93xx_spi_setup_dma(struct ep93xx_spi *espi)
|
||||
{
|
||||
dma_cap_mask_t mask;
|
||||
int ret;
|
||||
|
||||
espi->zeropage = (void *)get_zeroed_page(GFP_KERNEL);
|
||||
if (!espi->zeropage)
|
||||
return -ENOMEM;
|
||||
|
||||
dma_cap_zero(mask);
|
||||
dma_cap_set(DMA_SLAVE, mask);
|
||||
|
||||
espi->dma_rx_data.port = EP93XX_DMA_SSP;
|
||||
espi->dma_rx_data.direction = DMA_DEV_TO_MEM;
|
||||
espi->dma_rx_data.name = "ep93xx-spi-rx";
|
||||
|
||||
espi->dma_rx = dma_request_channel(mask, ep93xx_spi_dma_filter,
|
||||
&espi->dma_rx_data);
|
||||
if (!espi->dma_rx) {
|
||||
ret = -ENODEV;
|
||||
espi->dma_rx = dma_request_chan(dev, "rx");
|
||||
if (IS_ERR(espi->dma_rx)) {
|
||||
ret = dev_err_probe(dev, PTR_ERR(espi->dma_rx), "rx DMA setup failed");
|
||||
goto fail_free_page;
|
||||
}
|
||||
|
||||
espi->dma_tx_data.port = EP93XX_DMA_SSP;
|
||||
espi->dma_tx_data.direction = DMA_MEM_TO_DEV;
|
||||
espi->dma_tx_data.name = "ep93xx-spi-tx";
|
||||
|
||||
espi->dma_tx = dma_request_channel(mask, ep93xx_spi_dma_filter,
|
||||
&espi->dma_tx_data);
|
||||
if (!espi->dma_tx) {
|
||||
ret = -ENODEV;
|
||||
espi->dma_tx = dma_request_chan(dev, "tx");
|
||||
if (IS_ERR(espi->dma_tx)) {
|
||||
ret = dev_err_probe(dev, PTR_ERR(espi->dma_tx), "tx DMA setup failed");
|
||||
goto fail_release_rx;
|
||||
}
|
||||
|
||||
|
|
@ -647,18 +622,11 @@ static void ep93xx_spi_release_dma(struct ep93xx_spi *espi)
|
|||
static int ep93xx_spi_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct spi_controller *host;
|
||||
struct ep93xx_spi_info *info;
|
||||
struct ep93xx_spi *espi;
|
||||
struct resource *res;
|
||||
int irq;
|
||||
int error;
|
||||
|
||||
info = dev_get_platdata(&pdev->dev);
|
||||
if (!info) {
|
||||
dev_err(&pdev->dev, "missing platform data\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
|
|
@ -713,12 +681,17 @@ static int ep93xx_spi_probe(struct platform_device *pdev)
|
|||
goto fail_release_host;
|
||||
}
|
||||
|
||||
if (info->use_dma && ep93xx_spi_setup_dma(espi))
|
||||
error = ep93xx_spi_setup_dma(&pdev->dev, espi);
|
||||
if (error == -EPROBE_DEFER)
|
||||
goto fail_release_host;
|
||||
|
||||
if (error)
|
||||
dev_warn(&pdev->dev, "DMA setup failed. Falling back to PIO\n");
|
||||
|
||||
/* make sure that the hardware is disabled */
|
||||
writel(0, espi->mmio + SSPCR1);
|
||||
|
||||
device_set_node(&host->dev, dev_fwnode(&pdev->dev));
|
||||
error = devm_spi_register_controller(&pdev->dev, host);
|
||||
if (error) {
|
||||
dev_err(&pdev->dev, "failed to register SPI host\n");
|
||||
|
|
@ -746,9 +719,16 @@ static void ep93xx_spi_remove(struct platform_device *pdev)
|
|||
ep93xx_spi_release_dma(espi);
|
||||
}
|
||||
|
||||
static const struct of_device_id ep93xx_spi_of_ids[] = {
|
||||
{ .compatible = "cirrus,ep9301-spi" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ep93xx_spi_of_ids);
|
||||
|
||||
static struct platform_driver ep93xx_spi_driver = {
|
||||
.driver = {
|
||||
.name = "ep93xx-spi",
|
||||
.of_match_table = ep93xx_spi_of_ids,
|
||||
},
|
||||
.probe = ep93xx_spi_probe,
|
||||
.remove_new = ep93xx_spi_remove,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user