Commit e79e7c2d authored by Nikita Shubin's avatar Nikita Shubin Committed by Arnd Bergmann
Browse files

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: default avatarNikita Shubin <nikita.shubin@maquefel.me>
Tested-by: default avatarAlexander Sverdlin <alexander.sverdlin@gmail.com>
Reviewed-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Reviewed-by: default avatarMark Brown <broonie@kernel.org>
Acked-by: default avatarAlexander Sverdlin <alexander.sverdlin@gmail.com>
Acked-by: default avatarVinod Koul <vkoul@kernel.org>
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parent cb029177
Loading
Loading
Loading
Loading
+23 −43
Original line number Diff line number Diff line
@@ -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)
{
	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)
static int ep93xx_spi_setup_dma(struct device *dev, 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,