xref: /openbmc/linux/drivers/spi/spi-sprd-adi.c (revision 7e2903cb)
17e2903cbSBaolin Wang /*
27e2903cbSBaolin Wang  * Copyright (C) 2017 Spreadtrum Communications Inc.
37e2903cbSBaolin Wang  *
47e2903cbSBaolin Wang  * SPDX-License-Identifier: GPL-2.0
57e2903cbSBaolin Wang  */
67e2903cbSBaolin Wang 
77e2903cbSBaolin Wang #include <linux/hwspinlock.h>
87e2903cbSBaolin Wang #include <linux/init.h>
97e2903cbSBaolin Wang #include <linux/io.h>
107e2903cbSBaolin Wang #include <linux/kernel.h>
117e2903cbSBaolin Wang #include <linux/module.h>
127e2903cbSBaolin Wang #include <linux/of.h>
137e2903cbSBaolin Wang #include <linux/of_device.h>
147e2903cbSBaolin Wang #include <linux/platform_device.h>
157e2903cbSBaolin Wang #include <linux/spi/spi.h>
167e2903cbSBaolin Wang #include <linux/sizes.h>
177e2903cbSBaolin Wang 
187e2903cbSBaolin Wang /* Registers definitions for ADI controller */
197e2903cbSBaolin Wang #define REG_ADI_CTRL0			0x4
207e2903cbSBaolin Wang #define REG_ADI_CHN_PRIL		0x8
217e2903cbSBaolin Wang #define REG_ADI_CHN_PRIH		0xc
227e2903cbSBaolin Wang #define REG_ADI_INT_EN			0x10
237e2903cbSBaolin Wang #define REG_ADI_INT_RAW			0x14
247e2903cbSBaolin Wang #define REG_ADI_INT_MASK		0x18
257e2903cbSBaolin Wang #define REG_ADI_INT_CLR			0x1c
267e2903cbSBaolin Wang #define REG_ADI_GSSI_CFG0		0x20
277e2903cbSBaolin Wang #define REG_ADI_GSSI_CFG1		0x24
287e2903cbSBaolin Wang #define REG_ADI_RD_CMD			0x28
297e2903cbSBaolin Wang #define REG_ADI_RD_DATA			0x2c
307e2903cbSBaolin Wang #define REG_ADI_ARM_FIFO_STS		0x30
317e2903cbSBaolin Wang #define REG_ADI_STS			0x34
327e2903cbSBaolin Wang #define REG_ADI_EVT_FIFO_STS		0x38
337e2903cbSBaolin Wang #define REG_ADI_ARM_CMD_STS		0x3c
347e2903cbSBaolin Wang #define REG_ADI_CHN_EN			0x40
357e2903cbSBaolin Wang #define REG_ADI_CHN_ADDR(id)		(0x44 + (id - 2) * 4)
367e2903cbSBaolin Wang #define REG_ADI_CHN_EN1			0x20c
377e2903cbSBaolin Wang 
387e2903cbSBaolin Wang /* Bits definitions for register REG_ADI_GSSI_CFG0 */
397e2903cbSBaolin Wang #define BIT_CLK_ALL_ON			BIT(30)
407e2903cbSBaolin Wang 
417e2903cbSBaolin Wang /* Bits definitions for register REG_ADI_RD_DATA */
427e2903cbSBaolin Wang #define BIT_RD_CMD_BUSY			BIT(31)
437e2903cbSBaolin Wang #define RD_ADDR_SHIFT			16
447e2903cbSBaolin Wang #define RD_VALUE_MASK			GENMASK(15, 0)
457e2903cbSBaolin Wang #define RD_ADDR_MASK			GENMASK(30, 16)
467e2903cbSBaolin Wang 
477e2903cbSBaolin Wang /* Bits definitions for register REG_ADI_ARM_FIFO_STS */
487e2903cbSBaolin Wang #define BIT_FIFO_FULL			BIT(11)
497e2903cbSBaolin Wang #define BIT_FIFO_EMPTY			BIT(10)
507e2903cbSBaolin Wang 
517e2903cbSBaolin Wang /*
527e2903cbSBaolin Wang  * ADI slave devices include RTC, ADC, regulator, charger, thermal and so on.
537e2903cbSBaolin Wang  * The slave devices address offset is always 0x8000 and size is 4K.
547e2903cbSBaolin Wang  */
557e2903cbSBaolin Wang #define ADI_SLAVE_ADDR_SIZE		SZ_4K
567e2903cbSBaolin Wang #define ADI_SLAVE_OFFSET		0x8000
577e2903cbSBaolin Wang 
587e2903cbSBaolin Wang /* Timeout (ms) for the trylock of hardware spinlocks */
597e2903cbSBaolin Wang #define ADI_HWSPINLOCK_TIMEOUT		5000
607e2903cbSBaolin Wang /*
617e2903cbSBaolin Wang  * ADI controller has 50 channels including 2 software channels
627e2903cbSBaolin Wang  * and 48 hardware channels.
637e2903cbSBaolin Wang  */
647e2903cbSBaolin Wang #define ADI_HW_CHNS			50
657e2903cbSBaolin Wang 
667e2903cbSBaolin Wang #define ADI_FIFO_DRAIN_TIMEOUT		1000
677e2903cbSBaolin Wang #define ADI_READ_TIMEOUT		2000
687e2903cbSBaolin Wang #define REG_ADDR_LOW_MASK		GENMASK(11, 0)
697e2903cbSBaolin Wang 
707e2903cbSBaolin Wang struct sprd_adi {
717e2903cbSBaolin Wang 	struct spi_controller	*ctlr;
727e2903cbSBaolin Wang 	struct device		*dev;
737e2903cbSBaolin Wang 	void __iomem		*base;
747e2903cbSBaolin Wang 	struct hwspinlock	*hwlock;
757e2903cbSBaolin Wang 	unsigned long		slave_vbase;
767e2903cbSBaolin Wang 	unsigned long		slave_pbase;
777e2903cbSBaolin Wang };
787e2903cbSBaolin Wang 
797e2903cbSBaolin Wang static int sprd_adi_check_paddr(struct sprd_adi *sadi, u32 paddr)
807e2903cbSBaolin Wang {
817e2903cbSBaolin Wang 	if (paddr < sadi->slave_pbase || paddr >
827e2903cbSBaolin Wang 	    (sadi->slave_pbase + ADI_SLAVE_ADDR_SIZE)) {
837e2903cbSBaolin Wang 		dev_err(sadi->dev,
847e2903cbSBaolin Wang 			"slave physical address is incorrect, addr = 0x%x\n",
857e2903cbSBaolin Wang 			paddr);
867e2903cbSBaolin Wang 		return -EINVAL;
877e2903cbSBaolin Wang 	}
887e2903cbSBaolin Wang 
897e2903cbSBaolin Wang 	return 0;
907e2903cbSBaolin Wang }
917e2903cbSBaolin Wang 
927e2903cbSBaolin Wang static unsigned long sprd_adi_to_vaddr(struct sprd_adi *sadi, u32 paddr)
937e2903cbSBaolin Wang {
947e2903cbSBaolin Wang 	return (paddr - sadi->slave_pbase + sadi->slave_vbase);
957e2903cbSBaolin Wang }
967e2903cbSBaolin Wang 
977e2903cbSBaolin Wang static int sprd_adi_drain_fifo(struct sprd_adi *sadi)
987e2903cbSBaolin Wang {
997e2903cbSBaolin Wang 	u32 timeout = ADI_FIFO_DRAIN_TIMEOUT;
1007e2903cbSBaolin Wang 	u32 sts;
1017e2903cbSBaolin Wang 
1027e2903cbSBaolin Wang 	do {
1037e2903cbSBaolin Wang 		sts = readl_relaxed(sadi->base + REG_ADI_ARM_FIFO_STS);
1047e2903cbSBaolin Wang 		if (sts & BIT_FIFO_EMPTY)
1057e2903cbSBaolin Wang 			break;
1067e2903cbSBaolin Wang 
1077e2903cbSBaolin Wang 		cpu_relax();
1087e2903cbSBaolin Wang 	} while (--timeout);
1097e2903cbSBaolin Wang 
1107e2903cbSBaolin Wang 	if (timeout == 0) {
1117e2903cbSBaolin Wang 		dev_err(sadi->dev, "drain write fifo timeout\n");
1127e2903cbSBaolin Wang 		return -EBUSY;
1137e2903cbSBaolin Wang 	}
1147e2903cbSBaolin Wang 
1157e2903cbSBaolin Wang 	return 0;
1167e2903cbSBaolin Wang }
1177e2903cbSBaolin Wang 
1187e2903cbSBaolin Wang static int sprd_adi_fifo_is_full(struct sprd_adi *sadi)
1197e2903cbSBaolin Wang {
1207e2903cbSBaolin Wang 	return readl_relaxed(sadi->base + REG_ADI_ARM_FIFO_STS) & BIT_FIFO_FULL;
1217e2903cbSBaolin Wang }
1227e2903cbSBaolin Wang 
1237e2903cbSBaolin Wang static int sprd_adi_read(struct sprd_adi *sadi, u32 reg_paddr, u32 *read_val)
1247e2903cbSBaolin Wang {
1257e2903cbSBaolin Wang 	int read_timeout = ADI_READ_TIMEOUT;
1267e2903cbSBaolin Wang 	u32 val, rd_addr;
1277e2903cbSBaolin Wang 
1287e2903cbSBaolin Wang 	/*
1297e2903cbSBaolin Wang 	 * Set the physical register address need to read into RD_CMD register,
1307e2903cbSBaolin Wang 	 * then ADI controller will start to transfer automatically.
1317e2903cbSBaolin Wang 	 */
1327e2903cbSBaolin Wang 	writel_relaxed(reg_paddr, sadi->base + REG_ADI_RD_CMD);
1337e2903cbSBaolin Wang 
1347e2903cbSBaolin Wang 	/*
1357e2903cbSBaolin Wang 	 * Wait read operation complete, the BIT_RD_CMD_BUSY will be set
1367e2903cbSBaolin Wang 	 * simultaneously when writing read command to register, and the
1377e2903cbSBaolin Wang 	 * BIT_RD_CMD_BUSY will be cleared after the read operation is
1387e2903cbSBaolin Wang 	 * completed.
1397e2903cbSBaolin Wang 	 */
1407e2903cbSBaolin Wang 	do {
1417e2903cbSBaolin Wang 		val = readl_relaxed(sadi->base + REG_ADI_RD_DATA);
1427e2903cbSBaolin Wang 		if (!(val & BIT_RD_CMD_BUSY))
1437e2903cbSBaolin Wang 			break;
1447e2903cbSBaolin Wang 
1457e2903cbSBaolin Wang 		cpu_relax();
1467e2903cbSBaolin Wang 	} while (--read_timeout);
1477e2903cbSBaolin Wang 
1487e2903cbSBaolin Wang 	if (read_timeout == 0) {
1497e2903cbSBaolin Wang 		dev_err(sadi->dev, "ADI read timeout\n");
1507e2903cbSBaolin Wang 		return -EBUSY;
1517e2903cbSBaolin Wang 	}
1527e2903cbSBaolin Wang 
1537e2903cbSBaolin Wang 	/*
1547e2903cbSBaolin Wang 	 * The return value includes data and read register address, from bit 0
1557e2903cbSBaolin Wang 	 * to bit 15 are data, and from bit 16 to bit 30 are read register
1567e2903cbSBaolin Wang 	 * address. Then we can check the returned register address to validate
1577e2903cbSBaolin Wang 	 * data.
1587e2903cbSBaolin Wang 	 */
1597e2903cbSBaolin Wang 	rd_addr = (val & RD_ADDR_MASK ) >> RD_ADDR_SHIFT;
1607e2903cbSBaolin Wang 
1617e2903cbSBaolin Wang 	if (rd_addr != (reg_paddr & REG_ADDR_LOW_MASK)) {
1627e2903cbSBaolin Wang 		dev_err(sadi->dev, "read error, reg addr = 0x%x, val = 0x%x\n",
1637e2903cbSBaolin Wang 			reg_paddr, val);
1647e2903cbSBaolin Wang 		return -EIO;
1657e2903cbSBaolin Wang 	}
1667e2903cbSBaolin Wang 
1677e2903cbSBaolin Wang 	*read_val = val & RD_VALUE_MASK;
1687e2903cbSBaolin Wang 	return 0;
1697e2903cbSBaolin Wang }
1707e2903cbSBaolin Wang 
1717e2903cbSBaolin Wang static int sprd_adi_write(struct sprd_adi *sadi, unsigned long reg, u32 val)
1727e2903cbSBaolin Wang {
1737e2903cbSBaolin Wang 	u32 timeout = ADI_FIFO_DRAIN_TIMEOUT;
1747e2903cbSBaolin Wang 	int ret;
1757e2903cbSBaolin Wang 
1767e2903cbSBaolin Wang 	ret = sprd_adi_drain_fifo(sadi);
1777e2903cbSBaolin Wang 	if (ret < 0)
1787e2903cbSBaolin Wang 		return ret;
1797e2903cbSBaolin Wang 
1807e2903cbSBaolin Wang 	/*
1817e2903cbSBaolin Wang 	 * we should wait for write fifo is empty before writing data to PMIC
1827e2903cbSBaolin Wang 	 * registers.
1837e2903cbSBaolin Wang 	 */
1847e2903cbSBaolin Wang 	do {
1857e2903cbSBaolin Wang 		if (!sprd_adi_fifo_is_full(sadi)) {
1867e2903cbSBaolin Wang 			writel_relaxed(val, (void __iomem *)reg);
1877e2903cbSBaolin Wang 			break;
1887e2903cbSBaolin Wang 		}
1897e2903cbSBaolin Wang 
1907e2903cbSBaolin Wang 		cpu_relax();
1917e2903cbSBaolin Wang 	} while (--timeout);
1927e2903cbSBaolin Wang 
1937e2903cbSBaolin Wang 	if (timeout == 0) {
1947e2903cbSBaolin Wang 		dev_err(sadi->dev, "write fifo is full\n");
1957e2903cbSBaolin Wang 		return -EBUSY;
1967e2903cbSBaolin Wang 	}
1977e2903cbSBaolin Wang 
1987e2903cbSBaolin Wang 	return 0;
1997e2903cbSBaolin Wang }
2007e2903cbSBaolin Wang 
2017e2903cbSBaolin Wang static int sprd_adi_transfer_one(struct spi_controller *ctlr,
2027e2903cbSBaolin Wang 				 struct spi_device *spi_dev,
2037e2903cbSBaolin Wang 				 struct spi_transfer *t)
2047e2903cbSBaolin Wang {
2057e2903cbSBaolin Wang 	struct sprd_adi *sadi = spi_controller_get_devdata(ctlr);
2067e2903cbSBaolin Wang 	unsigned long flags, virt_reg;
2077e2903cbSBaolin Wang 	u32 phy_reg, val;
2087e2903cbSBaolin Wang 	int ret;
2097e2903cbSBaolin Wang 
2107e2903cbSBaolin Wang 	if (t->rx_buf) {
2117e2903cbSBaolin Wang 		phy_reg = *(u32 *)t->rx_buf + sadi->slave_pbase;
2127e2903cbSBaolin Wang 
2137e2903cbSBaolin Wang 		ret = sprd_adi_check_paddr(sadi, phy_reg);
2147e2903cbSBaolin Wang 		if (ret)
2157e2903cbSBaolin Wang 			return ret;
2167e2903cbSBaolin Wang 
2177e2903cbSBaolin Wang 		ret = hwspin_lock_timeout_irqsave(sadi->hwlock,
2187e2903cbSBaolin Wang 						  ADI_HWSPINLOCK_TIMEOUT,
2197e2903cbSBaolin Wang 						  &flags);
2207e2903cbSBaolin Wang 		if (ret) {
2217e2903cbSBaolin Wang 			dev_err(sadi->dev, "get the hw lock failed\n");
2227e2903cbSBaolin Wang 			return ret;
2237e2903cbSBaolin Wang 		}
2247e2903cbSBaolin Wang 
2257e2903cbSBaolin Wang 		ret = sprd_adi_read(sadi, phy_reg, &val);
2267e2903cbSBaolin Wang 		hwspin_unlock_irqrestore(sadi->hwlock, &flags);
2277e2903cbSBaolin Wang 		if (ret)
2287e2903cbSBaolin Wang 			return ret;
2297e2903cbSBaolin Wang 
2307e2903cbSBaolin Wang 		*(u32 *)t->rx_buf = val;
2317e2903cbSBaolin Wang 	} else if (t->tx_buf) {
2327e2903cbSBaolin Wang 		u32 *p = (u32 *)t->tx_buf;
2337e2903cbSBaolin Wang 
2347e2903cbSBaolin Wang 		/*
2357e2903cbSBaolin Wang 		 * Get the physical register address need to write and convert
2367e2903cbSBaolin Wang 		 * the physical address to virtual address. Since we need
2377e2903cbSBaolin Wang 		 * virtual register address to write.
2387e2903cbSBaolin Wang 		 */
2397e2903cbSBaolin Wang 		phy_reg = *p++ + sadi->slave_pbase;
2407e2903cbSBaolin Wang 		ret = sprd_adi_check_paddr(sadi, phy_reg);
2417e2903cbSBaolin Wang 		if (ret)
2427e2903cbSBaolin Wang 			return ret;
2437e2903cbSBaolin Wang 
2447e2903cbSBaolin Wang 		virt_reg = sprd_adi_to_vaddr(sadi, phy_reg);
2457e2903cbSBaolin Wang 		val = *p;
2467e2903cbSBaolin Wang 
2477e2903cbSBaolin Wang 		ret = hwspin_lock_timeout_irqsave(sadi->hwlock,
2487e2903cbSBaolin Wang 						  ADI_HWSPINLOCK_TIMEOUT,
2497e2903cbSBaolin Wang 						  &flags);
2507e2903cbSBaolin Wang 		if (ret) {
2517e2903cbSBaolin Wang 			dev_err(sadi->dev, "get the hw lock failed\n");
2527e2903cbSBaolin Wang 			return ret;
2537e2903cbSBaolin Wang 		}
2547e2903cbSBaolin Wang 
2557e2903cbSBaolin Wang 		ret = sprd_adi_write(sadi, virt_reg, val);
2567e2903cbSBaolin Wang 		hwspin_unlock_irqrestore(sadi->hwlock, &flags);
2577e2903cbSBaolin Wang 		if (ret)
2587e2903cbSBaolin Wang 			return ret;
2597e2903cbSBaolin Wang 	} else {
2607e2903cbSBaolin Wang 		dev_err(sadi->dev, "no buffer for transfer\n");
2617e2903cbSBaolin Wang 		return -EINVAL;
2627e2903cbSBaolin Wang 	}
2637e2903cbSBaolin Wang 
2647e2903cbSBaolin Wang 	return 0;
2657e2903cbSBaolin Wang }
2667e2903cbSBaolin Wang 
2677e2903cbSBaolin Wang static void sprd_adi_hw_init(struct sprd_adi *sadi)
2687e2903cbSBaolin Wang {
2697e2903cbSBaolin Wang 	struct device_node *np = sadi->dev->of_node;
2707e2903cbSBaolin Wang 	int i, size, chn_cnt;
2717e2903cbSBaolin Wang 	const __be32 *list;
2727e2903cbSBaolin Wang 	u32 tmp;
2737e2903cbSBaolin Wang 
2747e2903cbSBaolin Wang 	/* Address bits select default 12 bits */
2757e2903cbSBaolin Wang 	writel_relaxed(0, sadi->base + REG_ADI_CTRL0);
2767e2903cbSBaolin Wang 
2777e2903cbSBaolin Wang 	/* Set all channels as default priority */
2787e2903cbSBaolin Wang 	writel_relaxed(0, sadi->base + REG_ADI_CHN_PRIL);
2797e2903cbSBaolin Wang 	writel_relaxed(0, sadi->base + REG_ADI_CHN_PRIH);
2807e2903cbSBaolin Wang 
2817e2903cbSBaolin Wang 	/* Set clock auto gate mode */
2827e2903cbSBaolin Wang 	tmp = readl_relaxed(sadi->base + REG_ADI_GSSI_CFG0);
2837e2903cbSBaolin Wang 	tmp &= ~BIT_CLK_ALL_ON;
2847e2903cbSBaolin Wang 	writel_relaxed(tmp, sadi->base + REG_ADI_GSSI_CFG0);
2857e2903cbSBaolin Wang 
2867e2903cbSBaolin Wang 	/* Set hardware channels setting */
2877e2903cbSBaolin Wang 	list = of_get_property(np, "sprd,hw-channels", &size);
2887e2903cbSBaolin Wang 	if (!size || !list) {
2897e2903cbSBaolin Wang 		dev_info(sadi->dev, "no hw channels setting in node\n");
2907e2903cbSBaolin Wang 		return;
2917e2903cbSBaolin Wang 	}
2927e2903cbSBaolin Wang 
2937e2903cbSBaolin Wang 	chn_cnt = size / 8;
2947e2903cbSBaolin Wang 	for (i = 0; i < chn_cnt; i++) {
2957e2903cbSBaolin Wang 		u32 value;
2967e2903cbSBaolin Wang 		u32 chn_id = be32_to_cpu(*list++);
2977e2903cbSBaolin Wang 		u32 chn_config = be32_to_cpu(*list++);
2987e2903cbSBaolin Wang 
2997e2903cbSBaolin Wang 		/* Channel 0 and 1 are software channels */
3007e2903cbSBaolin Wang 		if (chn_id < 2)
3017e2903cbSBaolin Wang 			continue;
3027e2903cbSBaolin Wang 
3037e2903cbSBaolin Wang 		writel_relaxed(chn_config, sadi->base +
3047e2903cbSBaolin Wang 			       REG_ADI_CHN_ADDR(chn_id));
3057e2903cbSBaolin Wang 
3067e2903cbSBaolin Wang 		if (chn_id < 31) {
3077e2903cbSBaolin Wang 			value = readl_relaxed(sadi->base + REG_ADI_CHN_EN);
3087e2903cbSBaolin Wang 			value |= BIT(chn_id);
3097e2903cbSBaolin Wang 			writel_relaxed(value, sadi->base + REG_ADI_CHN_EN);
3107e2903cbSBaolin Wang 		} else if (chn_id < ADI_HW_CHNS) {
3117e2903cbSBaolin Wang 			value = readl_relaxed(sadi->base + REG_ADI_CHN_EN1);
3127e2903cbSBaolin Wang 			value |= BIT(chn_id - 32);
3137e2903cbSBaolin Wang 			writel_relaxed(value, sadi->base + REG_ADI_CHN_EN1);
3147e2903cbSBaolin Wang 		}
3157e2903cbSBaolin Wang 	}
3167e2903cbSBaolin Wang }
3177e2903cbSBaolin Wang 
3187e2903cbSBaolin Wang static int sprd_adi_probe(struct platform_device *pdev)
3197e2903cbSBaolin Wang {
3207e2903cbSBaolin Wang 	struct device_node *np = pdev->dev.of_node;
3217e2903cbSBaolin Wang 	struct spi_controller *ctlr;
3227e2903cbSBaolin Wang 	struct sprd_adi *sadi;
3237e2903cbSBaolin Wang 	struct resource *res;
3247e2903cbSBaolin Wang 	u32 num_chipselect;
3257e2903cbSBaolin Wang 	int ret;
3267e2903cbSBaolin Wang 
3277e2903cbSBaolin Wang 	if (!np) {
3287e2903cbSBaolin Wang 		dev_err(&pdev->dev, "can not find the adi bus node\n");
3297e2903cbSBaolin Wang 		return -ENODEV;
3307e2903cbSBaolin Wang 	}
3317e2903cbSBaolin Wang 
3327e2903cbSBaolin Wang 	pdev->id = of_alias_get_id(np, "spi");
3337e2903cbSBaolin Wang 	num_chipselect = of_get_child_count(np);
3347e2903cbSBaolin Wang 
3357e2903cbSBaolin Wang 	ctlr = spi_alloc_master(&pdev->dev, sizeof(struct sprd_adi));
3367e2903cbSBaolin Wang 	if (!ctlr)
3377e2903cbSBaolin Wang 		return -ENOMEM;
3387e2903cbSBaolin Wang 
3397e2903cbSBaolin Wang 	dev_set_drvdata(&pdev->dev, ctlr);
3407e2903cbSBaolin Wang 	sadi = spi_controller_get_devdata(ctlr);
3417e2903cbSBaolin Wang 
3427e2903cbSBaolin Wang 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
3437e2903cbSBaolin Wang 	sadi->base = devm_ioremap_resource(&pdev->dev, res);
3447e2903cbSBaolin Wang 	if (!sadi->base) {
3457e2903cbSBaolin Wang 		ret = -ENOMEM;
3467e2903cbSBaolin Wang 		goto put_ctlr;
3477e2903cbSBaolin Wang 	}
3487e2903cbSBaolin Wang 
3497e2903cbSBaolin Wang 	sadi->slave_vbase = (unsigned long)sadi->base + ADI_SLAVE_OFFSET;
3507e2903cbSBaolin Wang 	sadi->slave_pbase = res->start + ADI_SLAVE_OFFSET;
3517e2903cbSBaolin Wang 	sadi->ctlr = ctlr;
3527e2903cbSBaolin Wang 	sadi->dev = &pdev->dev;
3537e2903cbSBaolin Wang 	ret = of_hwspin_lock_get_id(np, 0);
3547e2903cbSBaolin Wang 	if (ret < 0) {
3557e2903cbSBaolin Wang 		dev_err(&pdev->dev, "can not get the hardware spinlock\n");
3567e2903cbSBaolin Wang 		goto put_ctlr;
3577e2903cbSBaolin Wang 	}
3587e2903cbSBaolin Wang 
3597e2903cbSBaolin Wang 	sadi->hwlock = hwspin_lock_request_specific(ret);
3607e2903cbSBaolin Wang 	if (!sadi->hwlock) {
3617e2903cbSBaolin Wang 		ret = -ENXIO;
3627e2903cbSBaolin Wang 		goto put_ctlr;
3637e2903cbSBaolin Wang 	}
3647e2903cbSBaolin Wang 
3657e2903cbSBaolin Wang 	sprd_adi_hw_init(sadi);
3667e2903cbSBaolin Wang 
3677e2903cbSBaolin Wang 	ctlr->dev.of_node = pdev->dev.of_node;
3687e2903cbSBaolin Wang 	ctlr->bus_num = pdev->id;
3697e2903cbSBaolin Wang 	ctlr->num_chipselect = num_chipselect;
3707e2903cbSBaolin Wang 	ctlr->flags = SPI_MASTER_HALF_DUPLEX;
3717e2903cbSBaolin Wang 	ctlr->bits_per_word_mask = 0;
3727e2903cbSBaolin Wang 	ctlr->transfer_one = sprd_adi_transfer_one;
3737e2903cbSBaolin Wang 
3747e2903cbSBaolin Wang 	ret = devm_spi_register_controller(&pdev->dev, ctlr);
3757e2903cbSBaolin Wang 	if (ret) {
3767e2903cbSBaolin Wang 		dev_err(&pdev->dev, "failed to register SPI controller\n");
3777e2903cbSBaolin Wang 		goto free_hwlock;
3787e2903cbSBaolin Wang 	}
3797e2903cbSBaolin Wang 
3807e2903cbSBaolin Wang 	return 0;
3817e2903cbSBaolin Wang 
3827e2903cbSBaolin Wang free_hwlock:
3837e2903cbSBaolin Wang 	hwspin_lock_free(sadi->hwlock);
3847e2903cbSBaolin Wang put_ctlr:
3857e2903cbSBaolin Wang 	spi_controller_put(ctlr);
3867e2903cbSBaolin Wang 	return ret;
3877e2903cbSBaolin Wang }
3887e2903cbSBaolin Wang 
3897e2903cbSBaolin Wang static int sprd_adi_remove(struct platform_device *pdev)
3907e2903cbSBaolin Wang {
3917e2903cbSBaolin Wang 	struct spi_controller *ctlr = dev_get_drvdata(&pdev->dev);
3927e2903cbSBaolin Wang 	struct sprd_adi *sadi = spi_controller_get_devdata(ctlr);
3937e2903cbSBaolin Wang 
3947e2903cbSBaolin Wang 	hwspin_lock_free(sadi->hwlock);
3957e2903cbSBaolin Wang 	return 0;
3967e2903cbSBaolin Wang }
3977e2903cbSBaolin Wang 
3987e2903cbSBaolin Wang static const struct of_device_id sprd_adi_of_match[] = {
3997e2903cbSBaolin Wang 	{
4007e2903cbSBaolin Wang 		.compatible = "sprd,sc9860-adi",
4017e2903cbSBaolin Wang 	},
4027e2903cbSBaolin Wang 	{ },
4037e2903cbSBaolin Wang };
4047e2903cbSBaolin Wang MODULE_DEVICE_TABLE(of, sprd_adi_of_match);
4057e2903cbSBaolin Wang 
4067e2903cbSBaolin Wang static struct platform_driver sprd_adi_driver = {
4077e2903cbSBaolin Wang 	.driver = {
4087e2903cbSBaolin Wang 		.name = "sprd-adi",
4097e2903cbSBaolin Wang 		.owner = THIS_MODULE,
4107e2903cbSBaolin Wang 		.of_match_table = sprd_adi_of_match,
4117e2903cbSBaolin Wang 	},
4127e2903cbSBaolin Wang 	.probe = sprd_adi_probe,
4137e2903cbSBaolin Wang 	.remove = sprd_adi_remove,
4147e2903cbSBaolin Wang };
4157e2903cbSBaolin Wang module_platform_driver(sprd_adi_driver);
4167e2903cbSBaolin Wang 
4177e2903cbSBaolin Wang MODULE_DESCRIPTION("Spreadtrum ADI Controller Driver");
4187e2903cbSBaolin Wang MODULE_AUTHOR("Baolin Wang <Baolin.Wang@spreadtrum.com>");
4197e2903cbSBaolin Wang MODULE_LICENSE("GPL v2");
420