// SPDX-License-Identifier: GPL-2.0-only
/*
 * Marvell Orion SPI controller driver
 *
 * Author: Shadi Ammouri <shadi@marvell.com>
 * Copyright (C) 2007-2008 Marvell Ltd.
 */

#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/spi/spi.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/clk.h>
#include <linux/sizes.h>
#include <asm/unaligned.h>

#define DRIVER_NAME			"orion_spi"

/* Runtime PM autosuspend timeout: PM is fairly light on this driver */
#define SPI_AUTOSUSPEND_TIMEOUT		200

/* Some SoCs using this driver support up to 8 chip selects.
 * It is up to the implementer to only use the chip selects
 * that are available.
 */
#define ORION_NUM_CHIPSELECTS		8

#define ORION_SPI_WAIT_RDY_MAX_LOOP	2000 /* in usec */

#define ORION_SPI_IF_CTRL_REG		0x00
#define ORION_SPI_IF_CONFIG_REG		0x04
#define ORION_SPI_IF_RXLSBF		BIT(14)
#define ORION_SPI_IF_TXLSBF		BIT(13)
#define ORION_SPI_DATA_OUT_REG		0x08
#define ORION_SPI_DATA_IN_REG		0x0c
#define ORION_SPI_INT_CAUSE_REG		0x10
#define ORION_SPI_TIMING_PARAMS_REG	0x18

/* Register for the "Direct Mode" */
#define SPI_DIRECT_WRITE_CONFIG_REG	0x20

#define ORION_SPI_TMISO_SAMPLE_MASK	(0x3 << 6)
#define ORION_SPI_TMISO_SAMPLE_1	(1 << 6)
#define ORION_SPI_TMISO_SAMPLE_2	(2 << 6)

#define ORION_SPI_MODE_CPOL		(1 << 11)
#define ORION_SPI_MODE_CPHA		(1 << 12)
#define ORION_SPI_IF_8_16_BIT_MODE	(1 << 5)
#define ORION_SPI_CLK_PRESCALE_MASK	0x1F
#define ARMADA_SPI_CLK_PRESCALE_MASK	0xDF
#define ORION_SPI_MODE_MASK		(ORION_SPI_MODE_CPOL | \
					 ORION_SPI_MODE_CPHA)
#define ORION_SPI_CS_MASK	0x1C
#define ORION_SPI_CS_SHIFT	2
#define ORION_SPI_CS(cs)	((cs << ORION_SPI_CS_SHIFT) & \
					ORION_SPI_CS_MASK)

enum orion_spi_type {
	ORION_SPI,
	ARMADA_SPI,
};

struct orion_spi_dev {
	enum orion_spi_type	typ;
	/*
	 * min_divisor and max_hz should be exclusive, the only we can
	 * have both is for managing the armada-370-spi case with old
	 * device tree
	 */
	unsigned long		max_hz;
	unsigned int		min_divisor;
	unsigned int		max_divisor;
	u32			prescale_mask;
	bool			is_errata_50mhz_ac;
};

struct orion_direct_acc {
	void __iomem		*vaddr;
	u32			size;
};

struct orion_child_options {
	struct orion_direct_acc direct_access;
};

struct orion_spi {
	struct spi_controller	*host;
	void __iomem		*base;
	struct clk              *clk;
	struct clk              *axi_clk;
	const struct orion_spi_dev *devdata;
	struct device		*dev;

	struct orion_child_options	child[ORION_NUM_CHIPSELECTS];
};

#ifdef CONFIG_PM
static int orion_spi_runtime_suspend(struct device *dev);
static int orion_spi_runtime_resume(struct device *dev);
#endif

static inline void __iomem *spi_reg(struct orion_spi *orion_spi, u32 reg)
{
	return orion_spi->base + reg;
}

static inline void
orion_spi_setbits(struct orion_spi *orion_spi, u32 reg, u32 mask)
{
	void __iomem *reg_addr = spi_reg(orion_spi, reg);
	u32 val;

	val = readl(reg_addr);
	val |= mask;
	writel(val, reg_addr);
}

static inline void
orion_spi_clrbits(struct orion_spi *orion_spi, u32 reg, u32 mask)
{
	void __iomem *reg_addr = spi_reg(orion_spi, reg);
	u32 val;

	val = readl(reg_addr);
	val &= ~mask;
	writel(val, reg_addr);
}

static int orion_spi_baudrate_set(struct spi_device *spi, unsigned int speed)
{
	u32 tclk_hz;
	u32 rate;
	u32 prescale;
	u32 reg;
	struct orion_spi *orion_spi;
	const struct orion_spi_dev *devdata;

	orion_spi = spi_controller_get_devdata(spi->controller);
	devdata = orion_spi->devdata;

	tclk_hz = clk_get_rate(orion_spi->clk);

	if (devdata->typ == ARMADA_SPI) {
		/*
		 * Given the core_clk (tclk_hz) and the target rate (speed) we
		 * determine the best values for SPR (in [0 .. 15]) and SPPR (in
		 * [0..7]) such that
		 *
		 * 	core_clk / (SPR * 2 ** SPPR)
		 *
		 * is as big as possible but not bigger than speed.
		 */

		/* best integer divider: */
		unsigned divider = DIV_ROUND_UP(tclk_hz, speed);
		unsigned spr, sppr;

		if (divider < 16) {
			/* This is the easy case, divider is less than 16 */
			spr = divider;
			sppr = 0;

		} else {
			unsigned two_pow_sppr;
			/*
			 * Find the highest bit set in divider. This and the
			 * three next bits define SPR (apart from rounding).
			 * SPPR is then the number of zero bits that must be
			 * appended:
			 */
			sppr = fls(divider) - 4;

			/*
			 * As SPR only has 4 bits, we have to round divider up
			 * to the next multiple of 2 ** sppr.
			 */
			two_pow_sppr = 1 << sppr;
			divider = (divider + two_pow_sppr - 1) & -two_pow_sppr;

			/*
			 * recalculate sppr as rounding up divider might have
			 * increased it enough to change the position of the
			 * highest set bit. In this case the bit that now
			 * doesn't make it into SPR is 0, so there is no need to
			 * round again.
			 */
			sppr = fls(divider) - 4;
			spr = divider >> sppr;

			/*
			 * Now do range checking. SPR is constructed to have a
			 * width of 4 bits, so this is fine for sure. So we
			 * still need to check for sppr to fit into 3 bits:
			 */
			if (sppr > 7)
				return -EINVAL;
		}

		prescale = ((sppr & 0x6) << 5) | ((sppr & 0x1) << 4) | spr;
	} else {
		/*
		 * the supported rates are: 4,6,8...30
		 * round up as we look for equal or less speed
		 */
		rate = DIV_ROUND_UP(tclk_hz, speed);
		rate = roundup(rate, 2);

		/* check if requested speed is too small */
		if (rate > 30)
			return -EINVAL;

		if (rate < 4)
			rate = 4;

		/* Convert the rate to SPI clock divisor value.	*/
		prescale = 0x10 + rate/2;
	}

	reg = readl(spi_reg(orion_spi, ORION_SPI_IF_CONFIG_REG));
	reg = ((reg & ~devdata->prescale_mask) | prescale);
	writel(reg, spi_reg(orion_spi, ORION_SPI_IF_CONFIG_REG));

	return 0;
}

static void
orion_spi_mode_set(struct spi_device *spi)
{
	u32 reg;
	struct orion_spi *orion_spi;

	orion_spi = spi_controller_get_devdata(spi->controller);

	reg = readl(spi_reg(orion_spi, ORION_SPI_IF_CONFIG_REG));
	reg &= ~ORION_SPI_MODE_MASK;
	if (spi->mode & SPI_CPOL)
		reg |= ORION_SPI_MODE_CPOL;
	if (spi->mode & SPI_CPHA)
		reg |= ORION_SPI_MODE_CPHA;
	if (spi->mode & SPI_LSB_FIRST)
		reg |= ORION_SPI_IF_RXLSBF | ORION_SPI_IF_TXLSBF;
	else
		reg &= ~(ORION_SPI_IF_RXLSBF | ORION_SPI_IF_TXLSBF);

	writel(reg, spi_reg(orion_spi, ORION_SPI_IF_CONFIG_REG));
}

static void
orion_spi_50mhz_ac_timing_erratum(struct spi_device *spi, unsigned int speed)
{
	u32 reg;
	struct orion_spi *orion_spi;

	orion_spi = spi_controller_get_devdata(spi->controller);

	/*
	 * Erratum description: (Erratum NO. FE-9144572) The device
	 * SPI interface supports frequencies of up to 50 MHz.
	 * However, due to this erratum, when the device core clock is
	 * 250 MHz and the SPI interfaces is configured for 50MHz SPI
	 * clock and CPOL=CPHA=1 there might occur data corruption on
	 * reads from the SPI device.
	 * Erratum Workaround:
	 * Work in one of the following configurations:
	 * 1. Set CPOL=CPHA=0 in "SPI Interface Configuration
	 * Register".
	 * 2. Set TMISO_SAMPLE value to 0x2 in "SPI Timing Parameters 1
	 * Register" before setting the interface.
	 */
	reg = readl(spi_reg(orion_spi, ORION_SPI_TIMING_PARAMS_REG));
	reg &= ~ORION_SPI_TMISO_SAMPLE_MASK;

	if (clk_get_rate(orion_spi->clk) == 250000000 &&
			speed == 50000000 && spi->mode & SPI_CPOL &&
			spi->mode & SPI_CPHA)
		reg |= ORION_SPI_TMISO_SAMPLE_2;
	else
		reg |= ORION_SPI_TMISO_SAMPLE_1; /* This is the default value */

	writel(reg, spi_reg(orion_spi, ORION_SPI_TIMING_PARAMS_REG));
}

/*
 * called only when no transfer is active on the bus
 */
static int
orion_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
{
	struct orion_spi *orion_spi;
	unsigned int speed = spi->max_speed_hz;
	unsigned int bits_per_word = spi->bits_per_word;
	int	rc;

	orion_spi = spi_controller_get_devdata(spi->controller);

	if ((t != NULL) && t->speed_hz)
		speed = t->speed_hz;

	if ((t != NULL) && t->bits_per_word)
		bits_per_word = t->bits_per_word;

	orion_spi_mode_set(spi);

	if (orion_spi->devdata->is_errata_50mhz_ac)
		orion_spi_50mhz_ac_timing_erratum(spi, speed);

	rc = orion_spi_baudrate_set(spi, speed);
	if (rc)
		return rc;

	if (bits_per_word == 16)
		orion_spi_setbits(orion_spi, ORION_SPI_IF_CONFIG_REG,
				  ORION_SPI_IF_8_16_BIT_MODE);
	else
		orion_spi_clrbits(orion_spi, ORION_SPI_IF_CONFIG_REG,
				  ORION_SPI_IF_8_16_BIT_MODE);

	return 0;
}

static void orion_spi_set_cs(struct spi_device *spi, bool enable)
{
	struct orion_spi *orion_spi;
	void __iomem *ctrl_reg;
	u32 val;

	orion_spi = spi_controller_get_devdata(spi->controller);
	ctrl_reg = spi_reg(orion_spi, ORION_SPI_IF_CTRL_REG);

	val = readl(ctrl_reg);

	/* Clear existing chip-select and assertion state */
	val &= ~(ORION_SPI_CS_MASK | 0x1);

	/*
	 * If this line is using a GPIO to control chip select, this internal
	 * .set_cs() function will still be called, so we clear any previous
	 * chip select. The CS we activate will not have any elecrical effect,
	 * as it is handled by a GPIO, but that doesn't matter. What we need
	 * is to deassert the old chip select and assert some other chip select.
	 */
	val |= ORION_SPI_CS(spi_get_chipselect(spi, 0));

	/*
	 * Chip select logic is inverted from spi_set_cs(). For lines using a
	 * GPIO to do chip select SPI_CS_HIGH is enforced and inversion happens
	 * in the GPIO library, but we don't care about that, because in those
	 * cases we are dealing with an unused native CS anyways so the polarity
	 * doesn't matter.
	 */
	if (!enable)
		val |= 0x1;

	/*
	 * To avoid toggling unwanted chip selects update the register
	 * with a single write.
	 */
	writel(val, ctrl_reg);
}

static inline int orion_spi_wait_till_ready(struct orion_spi *orion_spi)
{
	int i;

	for (i = 0; i < ORION_SPI_WAIT_RDY_MAX_LOOP; i++) {
		if (readl(spi_reg(orion_spi, ORION_SPI_INT_CAUSE_REG)))
			return 1;

		udelay(1);
	}

	return -1;
}

static inline int
orion_spi_write_read_8bit(struct spi_device *spi,
			  const u8 **tx_buf, u8 **rx_buf)
{
	void __iomem *tx_reg, *rx_reg, *int_reg;
	struct orion_spi *orion_spi;
	bool cs_single_byte;

	cs_single_byte = spi->mode & SPI_CS_WORD;

	orion_spi = spi_controller_get_devdata(spi->controller);

	if (cs_single_byte)
		orion_spi_set_cs(spi, 0);

	tx_reg = spi_reg(orion_spi, ORION_SPI_DATA_OUT_REG);
	rx_reg = spi_reg(orion_spi, ORION_SPI_DATA_IN_REG);
	int_reg = spi_reg(orion_spi, ORION_SPI_INT_CAUSE_REG);

	/* clear the interrupt cause register */
	writel(0x0, int_reg);

	if (tx_buf && *tx_buf)
		writel(*(*tx_buf)++, tx_reg);
	else
		writel(0, tx_reg);

	if (orion_spi_wait_till_ready(orion_spi) < 0) {
		if (cs_single_byte) {
			orion_spi_set_cs(spi, 1);
			/* Satisfy some SLIC devices requirements */
			udelay(4);
		}
		dev_err(&spi->dev, "TXS timed out\n");
		return -1;
	}

	if (rx_buf && *rx_buf)
		*(*rx_buf)++ = readl(rx_reg);

	if (cs_single_byte) {
		orion_spi_set_cs(spi, 1);
		/* Satisfy some SLIC devices requirements */
		udelay(4);
	}

	return 1;
}

static inline int
orion_spi_write_read_16bit(struct spi_device *spi,
			   const u16 **tx_buf, u16 **rx_buf)
{
	void __iomem *tx_reg, *rx_reg, *int_reg;
	struct orion_spi *orion_spi;

	if (spi->mode & SPI_CS_WORD) {
		dev_err(&spi->dev, "SPI_CS_WORD is only supported for 8 bit words\n");
		return -1;
	}

	orion_spi = spi_controller_get_devdata(spi->controller);
	tx_reg = spi_reg(orion_spi, ORION_SPI_DATA_OUT_REG);
	rx_reg = spi_reg(orion_spi, ORION_SPI_DATA_IN_REG);
	int_reg = spi_reg(orion_spi, ORION_SPI_INT_CAUSE_REG);

	/* clear the interrupt cause register */
	writel(0x0, int_reg);

	if (tx_buf && *tx_buf)
		writel(__cpu_to_le16(get_unaligned((*tx_buf)++)), tx_reg);
	else
		writel(0, tx_reg);

	if (orion_spi_wait_till_ready(orion_spi) < 0) {
		dev_err(&spi->dev, "TXS timed out\n");
		return -1;
	}

	if (rx_buf && *rx_buf)
		put_unaligned(__le16_to_cpu(readl(rx_reg)), (*rx_buf)++);

	return 1;
}

static unsigned int
orion_spi_write_read(struct spi_device *spi, struct spi_transfer *xfer)
{
	unsigned int count;
	int word_len;
	struct orion_spi *orion_spi;
	int cs = spi_get_chipselect(spi, 0);
	void __iomem *vaddr;

	word_len = spi->bits_per_word;
	count = xfer->len;

	orion_spi = spi_controller_get_devdata(spi->controller);

	/*
	 * Use SPI direct write mode if base address is available
	 * and SPI_CS_WORD flag is not set.
	 * Otherwise fall back to PIO mode for this transfer.
	 */
	vaddr = orion_spi->child[cs].direct_access.vaddr;

	if (vaddr && xfer->tx_buf && word_len == 8 && (spi->mode & SPI_CS_WORD) == 0) {
		unsigned int cnt = count / 4;
		unsigned int rem = count % 4;

		/*
		 * Send the TX-data to the SPI device via the direct
		 * mapped address window
		 */
		iowrite32_rep(vaddr, xfer->tx_buf, cnt);
		if (rem) {
			u32 *buf = (u32 *)xfer->tx_buf;

			iowrite8_rep(vaddr, &buf[cnt], rem);
		}

		return count;
	}

	if (word_len == 8) {
		const u8 *tx = xfer->tx_buf;
		u8 *rx = xfer->rx_buf;

		do {
			if (orion_spi_write_read_8bit(spi, &tx, &rx) < 0)
				goto out;
			count--;
			spi_delay_exec(&xfer->word_delay, xfer);
		} while (count);
	} else if (word_len == 16) {
		const u16 *tx = xfer->tx_buf;
		u16 *rx = xfer->rx_buf;

		do {
			if (orion_spi_write_read_16bit(spi, &tx, &rx) < 0)
				goto out;
			count -= 2;
			spi_delay_exec(&xfer->word_delay, xfer);
		} while (count);
	}

out:
	return xfer->len - count;
}

static int orion_spi_transfer_one(struct spi_controller *host,
					struct spi_device *spi,
					struct spi_transfer *t)
{
	int status = 0;

	status = orion_spi_setup_transfer(spi, t);
	if (status < 0)
		return status;

	if (t->len)
		orion_spi_write_read(spi, t);

	return status;
}

static int orion_spi_setup(struct spi_device *spi)
{
	int ret;
#ifdef CONFIG_PM
	struct orion_spi *orion_spi = spi_controller_get_devdata(spi->controller);
	struct device *dev = orion_spi->dev;

	orion_spi_runtime_resume(dev);
#endif

	ret = orion_spi_setup_transfer(spi, NULL);

#ifdef CONFIG_PM
	orion_spi_runtime_suspend(dev);
#endif

	return ret;
}

static int orion_spi_reset(struct orion_spi *orion_spi)
{
	/* Verify that the CS is deasserted */
	orion_spi_clrbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1);

	/* Don't deassert CS between the direct mapped SPI transfers */
	writel(0, spi_reg(orion_spi, SPI_DIRECT_WRITE_CONFIG_REG));

	return 0;
}

static const struct orion_spi_dev orion_spi_dev_data = {
	.typ = ORION_SPI,
	.min_divisor = 4,
	.max_divisor = 30,
	.prescale_mask = ORION_SPI_CLK_PRESCALE_MASK,
};

static const struct orion_spi_dev armada_370_spi_dev_data = {
	.typ = ARMADA_SPI,
	.min_divisor = 4,
	.max_divisor = 1920,
	.max_hz = 50000000,
	.prescale_mask = ARMADA_SPI_CLK_PRESCALE_MASK,
};

static const struct orion_spi_dev armada_xp_spi_dev_data = {
	.typ = ARMADA_SPI,
	.max_hz = 50000000,
	.max_divisor = 1920,
	.prescale_mask = ARMADA_SPI_CLK_PRESCALE_MASK,
};

static const struct orion_spi_dev armada_375_spi_dev_data = {
	.typ = ARMADA_SPI,
	.min_divisor = 15,
	.max_divisor = 1920,
	.prescale_mask = ARMADA_SPI_CLK_PRESCALE_MASK,
};

static const struct orion_spi_dev armada_380_spi_dev_data = {
	.typ = ARMADA_SPI,
	.max_hz = 50000000,
	.max_divisor = 1920,
	.prescale_mask = ARMADA_SPI_CLK_PRESCALE_MASK,
	.is_errata_50mhz_ac = true,
};

static const struct of_device_id orion_spi_of_match_table[] = {
	{
		.compatible = "marvell,orion-spi",
		.data = &orion_spi_dev_data,
	},
	{
		.compatible = "marvell,armada-370-spi",
		.data = &armada_370_spi_dev_data,
	},
	{
		.compatible = "marvell,armada-375-spi",
		.data = &armada_375_spi_dev_data,
	},
	{
		.compatible = "marvell,armada-380-spi",
		.data = &armada_380_spi_dev_data,
	},
	{
		.compatible = "marvell,armada-390-spi",
		.data = &armada_xp_spi_dev_data,
	},
	{
		.compatible = "marvell,armada-xp-spi",
		.data = &armada_xp_spi_dev_data,
	},

	{}
};
MODULE_DEVICE_TABLE(of, orion_spi_of_match_table);

static int orion_spi_probe(struct platform_device *pdev)
{
	const struct orion_spi_dev *devdata;
	struct spi_controller *host;
	struct orion_spi *spi;
	struct resource *r;
	unsigned long tclk_hz;
	int status = 0;
	struct device_node *np;

	host = spi_alloc_host(&pdev->dev, sizeof(*spi));
	if (host == NULL) {
		dev_dbg(&pdev->dev, "host allocation failed\n");
		return -ENOMEM;
	}

	if (pdev->id != -1)
		host->bus_num = pdev->id;
	if (pdev->dev.of_node) {
		u32 cell_index;

		if (!of_property_read_u32(pdev->dev.of_node, "cell-index",
					  &cell_index))
			host->bus_num = cell_index;
	}

	/* we support all 4 SPI modes and LSB first option */
	host->mode_bits = SPI_CPHA | SPI_CPOL | SPI_LSB_FIRST | SPI_CS_WORD;
	host->set_cs = orion_spi_set_cs;
	host->transfer_one = orion_spi_transfer_one;
	host->num_chipselect = ORION_NUM_CHIPSELECTS;
	host->setup = orion_spi_setup;
	host->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16);
	host->auto_runtime_pm = true;
	host->use_gpio_descriptors = true;
	host->flags = SPI_CONTROLLER_GPIO_SS;

	platform_set_drvdata(pdev, host);

	spi = spi_controller_get_devdata(host);
	spi->host = host;
	spi->dev = &pdev->dev;

	devdata = device_get_match_data(&pdev->dev);
	devdata = devdata ? devdata : &orion_spi_dev_data;
	spi->devdata = devdata;

	spi->clk = devm_clk_get_enabled(&pdev->dev, NULL);
	if (IS_ERR(spi->clk)) {
		status = PTR_ERR(spi->clk);
		goto out;
	}

	/* The following clock is only used by some SoCs */
	spi->axi_clk = devm_clk_get(&pdev->dev, "axi");
	if (PTR_ERR(spi->axi_clk) == -EPROBE_DEFER) {
		status = -EPROBE_DEFER;
		goto out;
	}
	if (!IS_ERR(spi->axi_clk))
		clk_prepare_enable(spi->axi_clk);

	tclk_hz = clk_get_rate(spi->clk);

	/*
	 * With old device tree, armada-370-spi could be used with
	 * Armada XP, however for this SoC the maximum frequency is
	 * 50MHz instead of tclk/4. On Armada 370, tclk cannot be
	 * higher than 200MHz. So, in order to be able to handle both
	 * SoCs, we can take the minimum of 50MHz and tclk/4.
	 */
	if (of_device_is_compatible(pdev->dev.of_node,
					"marvell,armada-370-spi"))
		host->max_speed_hz = min(devdata->max_hz,
				DIV_ROUND_UP(tclk_hz, devdata->min_divisor));
	else if (devdata->min_divisor)
		host->max_speed_hz =
			DIV_ROUND_UP(tclk_hz, devdata->min_divisor);
	else
		host->max_speed_hz = devdata->max_hz;
	host->min_speed_hz = DIV_ROUND_UP(tclk_hz, devdata->max_divisor);

	spi->base = devm_platform_get_and_ioremap_resource(pdev, 0, &r);
	if (IS_ERR(spi->base)) {
		status = PTR_ERR(spi->base);
		goto out_rel_axi_clk;
	}

	for_each_available_child_of_node(pdev->dev.of_node, np) {
		struct orion_direct_acc *dir_acc;
		u32 cs;

		/* Get chip-select number from the "reg" property */
		status = of_property_read_u32(np, "reg", &cs);
		if (status) {
			dev_err(&pdev->dev,
				"%pOF has no valid 'reg' property (%d)\n",
				np, status);
			continue;
		}

		/*
		 * Check if an address is configured for this SPI device. If
		 * not, the MBus mapping via the 'ranges' property in the 'soc'
		 * node is not configured and this device should not use the
		 * direct mode. In this case, just continue with the next
		 * device.
		 */
		status = of_address_to_resource(pdev->dev.of_node, cs + 1, r);
		if (status)
			continue;

		/*
		 * Only map one page for direct access. This is enough for the
		 * simple TX transfer which only writes to the first word.
		 * This needs to get extended for the direct SPI NOR / SPI NAND
		 * support, once this gets implemented.
		 */
		dir_acc = &spi->child[cs].direct_access;
		dir_acc->vaddr = devm_ioremap(&pdev->dev, r->start, PAGE_SIZE);
		if (!dir_acc->vaddr) {
			status = -ENOMEM;
			of_node_put(np);
			goto out_rel_axi_clk;
		}
		dir_acc->size = PAGE_SIZE;

		dev_info(&pdev->dev, "CS%d configured for direct access\n", cs);
	}

	pm_runtime_set_active(&pdev->dev);
	pm_runtime_use_autosuspend(&pdev->dev);
	pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT);
	pm_runtime_enable(&pdev->dev);

	status = orion_spi_reset(spi);
	if (status < 0)
		goto out_rel_pm;

	host->dev.of_node = pdev->dev.of_node;
	status = spi_register_controller(host);
	if (status < 0)
		goto out_rel_pm;

	return status;

out_rel_pm:
	pm_runtime_disable(&pdev->dev);
out_rel_axi_clk:
	clk_disable_unprepare(spi->axi_clk);
out:
	spi_controller_put(host);
	return status;
}


static void orion_spi_remove(struct platform_device *pdev)
{
	struct spi_controller *host = platform_get_drvdata(pdev);
	struct orion_spi *spi = spi_controller_get_devdata(host);

	pm_runtime_get_sync(&pdev->dev);
	clk_disable_unprepare(spi->axi_clk);

	spi_unregister_controller(host);
	pm_runtime_disable(&pdev->dev);
}

MODULE_ALIAS("platform:" DRIVER_NAME);

#ifdef CONFIG_PM
static int orion_spi_runtime_suspend(struct device *dev)
{
	struct spi_controller *host = dev_get_drvdata(dev);
	struct orion_spi *spi = spi_controller_get_devdata(host);

	clk_disable_unprepare(spi->axi_clk);
	clk_disable_unprepare(spi->clk);
	return 0;
}

static int orion_spi_runtime_resume(struct device *dev)
{
	struct spi_controller *host = dev_get_drvdata(dev);
	struct orion_spi *spi = spi_controller_get_devdata(host);

	if (!IS_ERR(spi->axi_clk))
		clk_prepare_enable(spi->axi_clk);
	return clk_prepare_enable(spi->clk);
}
#endif

static const struct dev_pm_ops orion_spi_pm_ops = {
	SET_RUNTIME_PM_OPS(orion_spi_runtime_suspend,
			   orion_spi_runtime_resume,
			   NULL)
};

static struct platform_driver orion_spi_driver = {
	.driver = {
		.name	= DRIVER_NAME,
		.pm	= &orion_spi_pm_ops,
		.of_match_table = of_match_ptr(orion_spi_of_match_table),
	},
	.probe		= orion_spi_probe,
	.remove_new	= orion_spi_remove,
};

module_platform_driver(orion_spi_driver);

MODULE_DESCRIPTION("Orion SPI driver");
MODULE_AUTHOR("Shadi Ammouri <shadi@marvell.com>");
MODULE_LICENSE("GPL");
