/*
 * RSB (Reduced Serial Bus) driver.
 *
 * Author: Chen-Yu Tsai <wens@csie.org>
 *
 * This file is licensed under the terms of the GNU General Public License
 * version 2.  This program is licensed "as is" without any warranty of any
 * kind, whether express or implied.
 *
 * The RSB controller looks like an SMBus controller which only supports
 * byte and word data transfers. But, it differs from standard SMBus
 * protocol on several aspects:
 * - it uses addresses set at runtime to address slaves. Runtime addresses
 *   are sent to slaves using their 12bit hardware addresses. Up to 15
 *   runtime addresses are available.
 * - it adds a parity bit every 8bits of data and address for read and
 *   write accesses; this replaces the ack bit
 * - only one read access is required to read a byte (instead of a write
 *   followed by a read access in standard SMBus protocol)
 * - there's no Ack bit after each read access
 *
 * This means this bus cannot be used to interface with standard SMBus
 * devices. Devices known to support this interface include the AXP223,
 * AXP809, and AXP806 PMICs, and the AC100 audio codec, all from X-Powers.
 *
 * A description of the operation and wire protocol can be found in the
 * RSB section of Allwinner's A80 user manual, which can be found at
 *
 *     https://github.com/allwinner-zh/documents/tree/master/A80
 *
 * This document is officially released by Allwinner.
 *
 * This driver is based on i2c-sun6i-p2wi.c, the P2WI bus driver.
 *
 */

#include <linux/clk.h>
#include <linux/clk/clk-conf.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/slab.h>
#include <linux/sunxi-rsb.h>
#include <linux/types.h>

/* RSB registers */
#define RSB_CTRL	0x0	/* Global control */
#define RSB_CCR		0x4	/* Clock control */
#define RSB_INTE	0x8	/* Interrupt controls */
#define RSB_INTS	0xc	/* Interrupt status */
#define RSB_ADDR	0x10	/* Address to send with read/write command */
#define RSB_DATA	0x1c	/* Data to read/write */
#define RSB_LCR		0x24	/* Line control */
#define RSB_DMCR	0x28	/* Device mode (init) control */
#define RSB_CMD		0x2c	/* RSB Command */
#define RSB_DAR		0x30	/* Device address / runtime address */

/* CTRL fields */
#define RSB_CTRL_START_TRANS		BIT(7)
#define RSB_CTRL_ABORT_TRANS		BIT(6)
#define RSB_CTRL_GLOBAL_INT_ENB		BIT(1)
#define RSB_CTRL_SOFT_RST		BIT(0)

/* CLK CTRL fields */
#define RSB_CCR_SDA_OUT_DELAY(v)	(((v) & 0x7) << 8)
#define RSB_CCR_MAX_CLK_DIV		0xff
#define RSB_CCR_CLK_DIV(v)		((v) & RSB_CCR_MAX_CLK_DIV)

/* STATUS fields */
#define RSB_INTS_TRANS_ERR_ACK		BIT(16)
#define RSB_INTS_TRANS_ERR_DATA_BIT(v)	(((v) >> 8) & 0xf)
#define RSB_INTS_TRANS_ERR_DATA		GENMASK(11, 8)
#define RSB_INTS_LOAD_BSY		BIT(2)
#define RSB_INTS_TRANS_ERR		BIT(1)
#define RSB_INTS_TRANS_OVER		BIT(0)

/* LINE CTRL fields*/
#define RSB_LCR_SCL_STATE		BIT(5)
#define RSB_LCR_SDA_STATE		BIT(4)
#define RSB_LCR_SCL_CTL			BIT(3)
#define RSB_LCR_SCL_CTL_EN		BIT(2)
#define RSB_LCR_SDA_CTL			BIT(1)
#define RSB_LCR_SDA_CTL_EN		BIT(0)

/* DEVICE MODE CTRL field values */
#define RSB_DMCR_DEVICE_START		BIT(31)
#define RSB_DMCR_MODE_DATA		(0x7c << 16)
#define RSB_DMCR_MODE_REG		(0x3e << 8)
#define RSB_DMCR_DEV_ADDR		0x00

/* CMD values */
#define RSB_CMD_RD8			0x8b
#define RSB_CMD_RD16			0x9c
#define RSB_CMD_RD32			0xa6
#define RSB_CMD_WR8			0x4e
#define RSB_CMD_WR16			0x59
#define RSB_CMD_WR32			0x63
#define RSB_CMD_STRA			0xe8

/* DAR fields */
#define RSB_DAR_RTA(v)			(((v) & 0xff) << 16)
#define RSB_DAR_DA(v)			((v) & 0xffff)

#define RSB_MAX_FREQ			20000000

#define RSB_CTRL_NAME			"sunxi-rsb"

struct sunxi_rsb_addr_map {
	u16 hwaddr;
	u8 rtaddr;
};

struct sunxi_rsb {
	struct device *dev;
	void __iomem *regs;
	struct clk *clk;
	struct reset_control *rstc;
	struct completion complete;
	struct mutex lock;
	unsigned int status;
	u32 clk_freq;
};

/* bus / slave device related functions */
static struct bus_type sunxi_rsb_bus;

static int sunxi_rsb_device_match(struct device *dev, struct device_driver *drv)
{
	return of_driver_match_device(dev, drv);
}

static int sunxi_rsb_device_probe(struct device *dev)
{
	const struct sunxi_rsb_driver *drv = to_sunxi_rsb_driver(dev->driver);
	struct sunxi_rsb_device *rdev = to_sunxi_rsb_device(dev);
	int ret;

	if (!drv->probe)
		return -ENODEV;

	if (!rdev->irq) {
		int irq = -ENOENT;

		if (dev->of_node)
			irq = of_irq_get(dev->of_node, 0);

		if (irq == -EPROBE_DEFER)
			return irq;
		if (irq < 0)
			irq = 0;

		rdev->irq = irq;
	}

	ret = of_clk_set_defaults(dev->of_node, false);
	if (ret < 0)
		return ret;

	return drv->probe(rdev);
}

static void sunxi_rsb_device_remove(struct device *dev)
{
	const struct sunxi_rsb_driver *drv = to_sunxi_rsb_driver(dev->driver);

	drv->remove(to_sunxi_rsb_device(dev));
}

static struct bus_type sunxi_rsb_bus = {
	.name		= RSB_CTRL_NAME,
	.match		= sunxi_rsb_device_match,
	.probe		= sunxi_rsb_device_probe,
	.remove		= sunxi_rsb_device_remove,
	.uevent		= of_device_uevent_modalias,
};

static void sunxi_rsb_dev_release(struct device *dev)
{
	struct sunxi_rsb_device *rdev = to_sunxi_rsb_device(dev);

	kfree(rdev);
}

/**
 * sunxi_rsb_device_create() - allocate and add an RSB device
 * @rsb:	RSB controller
 * @node:	RSB slave device node
 * @hwaddr:	RSB slave hardware address
 * @rtaddr:	RSB slave runtime address
 */
static struct sunxi_rsb_device *sunxi_rsb_device_create(struct sunxi_rsb *rsb,
		struct device_node *node, u16 hwaddr, u8 rtaddr)
{
	int err;
	struct sunxi_rsb_device *rdev;

	rdev = kzalloc(sizeof(*rdev), GFP_KERNEL);
	if (!rdev)
		return ERR_PTR(-ENOMEM);

	rdev->rsb = rsb;
	rdev->hwaddr = hwaddr;
	rdev->rtaddr = rtaddr;
	rdev->dev.bus = &sunxi_rsb_bus;
	rdev->dev.parent = rsb->dev;
	rdev->dev.of_node = node;
	rdev->dev.release = sunxi_rsb_dev_release;

	dev_set_name(&rdev->dev, "%s-%x", RSB_CTRL_NAME, hwaddr);

	err = device_register(&rdev->dev);
	if (err < 0) {
		dev_err(&rdev->dev, "Can't add %s, status %d\n",
			dev_name(&rdev->dev), err);
		goto err_device_add;
	}

	dev_dbg(&rdev->dev, "device %s registered\n", dev_name(&rdev->dev));

err_device_add:
	put_device(&rdev->dev);

	return ERR_PTR(err);
}

/**
 * sunxi_rsb_device_unregister(): unregister an RSB device
 * @rdev:	rsb_device to be removed
 */
static void sunxi_rsb_device_unregister(struct sunxi_rsb_device *rdev)
{
	device_unregister(&rdev->dev);
}

static int sunxi_rsb_remove_devices(struct device *dev, void *data)
{
	struct sunxi_rsb_device *rdev = to_sunxi_rsb_device(dev);

	if (dev->bus == &sunxi_rsb_bus)
		sunxi_rsb_device_unregister(rdev);

	return 0;
}

/**
 * sunxi_rsb_driver_register() - Register device driver with RSB core
 * @rdrv:	device driver to be associated with slave-device.
 *
 * This API will register the client driver with the RSB framework.
 * It is typically called from the driver's module-init function.
 */
int sunxi_rsb_driver_register(struct sunxi_rsb_driver *rdrv)
{
	rdrv->driver.bus = &sunxi_rsb_bus;
	return driver_register(&rdrv->driver);
}
EXPORT_SYMBOL_GPL(sunxi_rsb_driver_register);

/* common code that starts a transfer */
static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb)
{
	if (readl(rsb->regs + RSB_CTRL) & RSB_CTRL_START_TRANS) {
		dev_dbg(rsb->dev, "RSB transfer still in progress\n");
		return -EBUSY;
	}

	reinit_completion(&rsb->complete);

	writel(RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | RSB_INTS_TRANS_OVER,
	       rsb->regs + RSB_INTE);
	writel(RSB_CTRL_START_TRANS | RSB_CTRL_GLOBAL_INT_ENB,
	       rsb->regs + RSB_CTRL);

	if (!wait_for_completion_io_timeout(&rsb->complete,
					    msecs_to_jiffies(100))) {
		dev_dbg(rsb->dev, "RSB timeout\n");

		/* abort the transfer */
		writel(RSB_CTRL_ABORT_TRANS, rsb->regs + RSB_CTRL);

		/* clear any interrupt flags */
		writel(readl(rsb->regs + RSB_INTS), rsb->regs + RSB_INTS);

		return -ETIMEDOUT;
	}

	if (rsb->status & RSB_INTS_LOAD_BSY) {
		dev_dbg(rsb->dev, "RSB busy\n");
		return -EBUSY;
	}

	if (rsb->status & RSB_INTS_TRANS_ERR) {
		if (rsb->status & RSB_INTS_TRANS_ERR_ACK) {
			dev_dbg(rsb->dev, "RSB slave nack\n");
			return -EINVAL;
		}

		if (rsb->status & RSB_INTS_TRANS_ERR_DATA) {
			dev_dbg(rsb->dev, "RSB transfer data error\n");
			return -EIO;
		}
	}

	return 0;
}

static int sunxi_rsb_read(struct sunxi_rsb *rsb, u8 rtaddr, u8 addr,
			  u32 *buf, size_t len)
{
	u32 cmd;
	int ret;

	if (!buf)
		return -EINVAL;

	switch (len) {
	case 1:
		cmd = RSB_CMD_RD8;
		break;
	case 2:
		cmd = RSB_CMD_RD16;
		break;
	case 4:
		cmd = RSB_CMD_RD32;
		break;
	default:
		dev_err(rsb->dev, "Invalid access width: %zd\n", len);
		return -EINVAL;
	}

	ret = pm_runtime_resume_and_get(rsb->dev);
	if (ret)
		return ret;

	mutex_lock(&rsb->lock);

	writel(addr, rsb->regs + RSB_ADDR);
	writel(RSB_DAR_RTA(rtaddr), rsb->regs + RSB_DAR);
	writel(cmd, rsb->regs + RSB_CMD);

	ret = _sunxi_rsb_run_xfer(rsb);
	if (ret)
		goto unlock;

	*buf = readl(rsb->regs + RSB_DATA) & GENMASK(len * 8 - 1, 0);

unlock:
	mutex_unlock(&rsb->lock);

	pm_runtime_mark_last_busy(rsb->dev);
	pm_runtime_put_autosuspend(rsb->dev);

	return ret;
}

static int sunxi_rsb_write(struct sunxi_rsb *rsb, u8 rtaddr, u8 addr,
			   const u32 *buf, size_t len)
{
	u32 cmd;
	int ret;

	if (!buf)
		return -EINVAL;

	switch (len) {
	case 1:
		cmd = RSB_CMD_WR8;
		break;
	case 2:
		cmd = RSB_CMD_WR16;
		break;
	case 4:
		cmd = RSB_CMD_WR32;
		break;
	default:
		dev_err(rsb->dev, "Invalid access width: %zd\n", len);
		return -EINVAL;
	}

	ret = pm_runtime_resume_and_get(rsb->dev);
	if (ret)
		return ret;

	mutex_lock(&rsb->lock);

	writel(addr, rsb->regs + RSB_ADDR);
	writel(RSB_DAR_RTA(rtaddr), rsb->regs + RSB_DAR);
	writel(*buf, rsb->regs + RSB_DATA);
	writel(cmd, rsb->regs + RSB_CMD);
	ret = _sunxi_rsb_run_xfer(rsb);

	mutex_unlock(&rsb->lock);

	pm_runtime_mark_last_busy(rsb->dev);
	pm_runtime_put_autosuspend(rsb->dev);

	return ret;
}

/* RSB regmap functions */
struct sunxi_rsb_ctx {
	struct sunxi_rsb_device *rdev;
	int size;
};

static int regmap_sunxi_rsb_reg_read(void *context, unsigned int reg,
				     unsigned int *val)
{
	struct sunxi_rsb_ctx *ctx = context;
	struct sunxi_rsb_device *rdev = ctx->rdev;

	if (reg > 0xff)
		return -EINVAL;

	return sunxi_rsb_read(rdev->rsb, rdev->rtaddr, reg, val, ctx->size);
}

static int regmap_sunxi_rsb_reg_write(void *context, unsigned int reg,
				      unsigned int val)
{
	struct sunxi_rsb_ctx *ctx = context;
	struct sunxi_rsb_device *rdev = ctx->rdev;

	return sunxi_rsb_write(rdev->rsb, rdev->rtaddr, reg, &val, ctx->size);
}

static void regmap_sunxi_rsb_free_ctx(void *context)
{
	struct sunxi_rsb_ctx *ctx = context;

	kfree(ctx);
}

static struct regmap_bus regmap_sunxi_rsb = {
	.reg_write = regmap_sunxi_rsb_reg_write,
	.reg_read = regmap_sunxi_rsb_reg_read,
	.free_context = regmap_sunxi_rsb_free_ctx,
	.reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
	.val_format_endian_default = REGMAP_ENDIAN_NATIVE,
};

static struct sunxi_rsb_ctx *regmap_sunxi_rsb_init_ctx(struct sunxi_rsb_device *rdev,
		const struct regmap_config *config)
{
	struct sunxi_rsb_ctx *ctx;

	switch (config->val_bits) {
	case 8:
	case 16:
	case 32:
		break;
	default:
		return ERR_PTR(-EINVAL);
	}

	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
	if (!ctx)
		return ERR_PTR(-ENOMEM);

	ctx->rdev = rdev;
	ctx->size = config->val_bits / 8;

	return ctx;
}

struct regmap *__devm_regmap_init_sunxi_rsb(struct sunxi_rsb_device *rdev,
					    const struct regmap_config *config,
					    struct lock_class_key *lock_key,
					    const char *lock_name)
{
	struct sunxi_rsb_ctx *ctx = regmap_sunxi_rsb_init_ctx(rdev, config);

	if (IS_ERR(ctx))
		return ERR_CAST(ctx);

	return __devm_regmap_init(&rdev->dev, &regmap_sunxi_rsb, ctx, config,
				  lock_key, lock_name);
}
EXPORT_SYMBOL_GPL(__devm_regmap_init_sunxi_rsb);

/* RSB controller driver functions */
static irqreturn_t sunxi_rsb_irq(int irq, void *dev_id)
{
	struct sunxi_rsb *rsb = dev_id;
	u32 status;

	status = readl(rsb->regs + RSB_INTS);
	rsb->status = status;

	/* Clear interrupts */
	status &= (RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR |
		   RSB_INTS_TRANS_OVER);
	writel(status, rsb->regs + RSB_INTS);

	complete(&rsb->complete);

	return IRQ_HANDLED;
}

static int sunxi_rsb_init_device_mode(struct sunxi_rsb *rsb)
{
	int ret = 0;
	u32 reg;

	/* send init sequence */
	writel(RSB_DMCR_DEVICE_START | RSB_DMCR_MODE_DATA |
	       RSB_DMCR_MODE_REG | RSB_DMCR_DEV_ADDR, rsb->regs + RSB_DMCR);

	readl_poll_timeout(rsb->regs + RSB_DMCR, reg,
			   !(reg & RSB_DMCR_DEVICE_START), 100, 250000);
	if (reg & RSB_DMCR_DEVICE_START)
		ret = -ETIMEDOUT;

	/* clear interrupt status bits */
	writel(readl(rsb->regs + RSB_INTS), rsb->regs + RSB_INTS);

	return ret;
}

/*
 * There are 15 valid runtime addresses, though Allwinner typically
 * skips the first, for unknown reasons, and uses the following three.
 *
 * 0x17, 0x2d, 0x3a, 0x4e, 0x59, 0x63, 0x74, 0x8b,
 * 0x9c, 0xa6, 0xb1, 0xc5, 0xd2, 0xe8, 0xff
 *
 * No designs with 2 RSB slave devices sharing identical hardware
 * addresses on the same bus have been seen in the wild. All designs
 * use 0x2d for the primary PMIC, 0x3a for the secondary PMIC if
 * there is one, and 0x45 for peripheral ICs.
 *
 * The hardware does not seem to support re-setting runtime addresses.
 * Attempts to do so result in the slave devices returning a NACK.
 * Hence we just hardcode the mapping here, like Allwinner does.
 */

static const struct sunxi_rsb_addr_map sunxi_rsb_addr_maps[] = {
	{ 0x3a3, 0x2d }, /* Primary PMIC: AXP223, AXP809, AXP81X, ... */
	{ 0x745, 0x3a }, /* Secondary PMIC: AXP806, ... */
	{ 0xe89, 0x4e }, /* Peripheral IC: AC100, ... */
};

static u8 sunxi_rsb_get_rtaddr(u16 hwaddr)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(sunxi_rsb_addr_maps); i++)
		if (hwaddr == sunxi_rsb_addr_maps[i].hwaddr)
			return sunxi_rsb_addr_maps[i].rtaddr;

	return 0; /* 0 is an invalid runtime address */
}

static int of_rsb_register_devices(struct sunxi_rsb *rsb)
{
	struct device *dev = rsb->dev;
	struct device_node *child, *np = dev->of_node;
	u32 hwaddr;
	u8 rtaddr;
	int ret;

	if (!np)
		return -EINVAL;

	/* Runtime addresses for all slaves should be set first */
	for_each_available_child_of_node(np, child) {
		dev_dbg(dev, "setting child %pOF runtime address\n",
			child);

		ret = of_property_read_u32(child, "reg", &hwaddr);
		if (ret) {
			dev_err(dev, "%pOF: invalid 'reg' property: %d\n",
				child, ret);
			continue;
		}

		rtaddr = sunxi_rsb_get_rtaddr(hwaddr);
		if (!rtaddr) {
			dev_err(dev, "%pOF: unknown hardware device address\n",
				child);
			continue;
		}

		/*
		 * Since no devices have been registered yet, we are the
		 * only ones using the bus, we can skip locking the bus.
		 */

		/* setup command parameters */
		writel(RSB_CMD_STRA, rsb->regs + RSB_CMD);
		writel(RSB_DAR_RTA(rtaddr) | RSB_DAR_DA(hwaddr),
		       rsb->regs + RSB_DAR);

		/* send command */
		ret = _sunxi_rsb_run_xfer(rsb);
		if (ret)
			dev_warn(dev, "%pOF: set runtime address failed: %d\n",
				 child, ret);
	}

	/* Then we start adding devices and probing them */
	for_each_available_child_of_node(np, child) {
		struct sunxi_rsb_device *rdev;

		dev_dbg(dev, "adding child %pOF\n", child);

		ret = of_property_read_u32(child, "reg", &hwaddr);
		if (ret)
			continue;

		rtaddr = sunxi_rsb_get_rtaddr(hwaddr);
		if (!rtaddr)
			continue;

		rdev = sunxi_rsb_device_create(rsb, child, hwaddr, rtaddr);
		if (IS_ERR(rdev))
			dev_err(dev, "failed to add child device %pOF: %ld\n",
				child, PTR_ERR(rdev));
	}

	return 0;
}

static int sunxi_rsb_hw_init(struct sunxi_rsb *rsb)
{
	struct device *dev = rsb->dev;
	unsigned long p_clk_freq;
	u32 clk_delay, reg;
	int clk_div, ret;

	ret = clk_prepare_enable(rsb->clk);
	if (ret) {
		dev_err(dev, "failed to enable clk: %d\n", ret);
		return ret;
	}

	ret = reset_control_deassert(rsb->rstc);
	if (ret) {
		dev_err(dev, "failed to deassert reset line: %d\n", ret);
		goto err_clk_disable;
	}

	/* reset the controller */
	writel(RSB_CTRL_SOFT_RST, rsb->regs + RSB_CTRL);
	readl_poll_timeout(rsb->regs + RSB_CTRL, reg,
			   !(reg & RSB_CTRL_SOFT_RST), 1000, 100000);

	/*
	 * Clock frequency and delay calculation code is from
	 * Allwinner U-boot sources.
	 *
	 * From A83 user manual:
	 * bus clock frequency = parent clock frequency / (2 * (divider + 1))
	 */
	p_clk_freq = clk_get_rate(rsb->clk);
	clk_div = p_clk_freq / rsb->clk_freq / 2;
	if (!clk_div)
		clk_div = 1;
	else if (clk_div > RSB_CCR_MAX_CLK_DIV + 1)
		clk_div = RSB_CCR_MAX_CLK_DIV + 1;

	clk_delay = clk_div >> 1;
	if (!clk_delay)
		clk_delay = 1;

	dev_info(dev, "RSB running at %lu Hz\n", p_clk_freq / clk_div / 2);
	writel(RSB_CCR_SDA_OUT_DELAY(clk_delay) | RSB_CCR_CLK_DIV(clk_div - 1),
	       rsb->regs + RSB_CCR);

	return 0;

err_clk_disable:
	clk_disable_unprepare(rsb->clk);

	return ret;
}

static void sunxi_rsb_hw_exit(struct sunxi_rsb *rsb)
{
	/* Keep the clock and PM reference counts consistent. */
	if (pm_runtime_status_suspended(rsb->dev))
		pm_runtime_resume(rsb->dev);
	reset_control_assert(rsb->rstc);
	clk_disable_unprepare(rsb->clk);
}

static int __maybe_unused sunxi_rsb_runtime_suspend(struct device *dev)
{
	struct sunxi_rsb *rsb = dev_get_drvdata(dev);

	clk_disable_unprepare(rsb->clk);

	return 0;
}

static int __maybe_unused sunxi_rsb_runtime_resume(struct device *dev)
{
	struct sunxi_rsb *rsb = dev_get_drvdata(dev);

	return clk_prepare_enable(rsb->clk);
}

static int __maybe_unused sunxi_rsb_suspend(struct device *dev)
{
	struct sunxi_rsb *rsb = dev_get_drvdata(dev);

	sunxi_rsb_hw_exit(rsb);

	return 0;
}

static int __maybe_unused sunxi_rsb_resume(struct device *dev)
{
	struct sunxi_rsb *rsb = dev_get_drvdata(dev);

	return sunxi_rsb_hw_init(rsb);
}

static int sunxi_rsb_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	struct resource *r;
	struct sunxi_rsb *rsb;
	u32 clk_freq = 3000000;
	int irq, ret;

	of_property_read_u32(np, "clock-frequency", &clk_freq);
	if (clk_freq > RSB_MAX_FREQ) {
		dev_err(dev,
			"clock-frequency (%u Hz) is too high (max = 20MHz)\n",
			clk_freq);
		return -EINVAL;
	}

	rsb = devm_kzalloc(dev, sizeof(*rsb), GFP_KERNEL);
	if (!rsb)
		return -ENOMEM;

	rsb->dev = dev;
	rsb->clk_freq = clk_freq;
	platform_set_drvdata(pdev, rsb);
	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	rsb->regs = devm_ioremap_resource(dev, r);
	if (IS_ERR(rsb->regs))
		return PTR_ERR(rsb->regs);

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return irq;

	rsb->clk = devm_clk_get(dev, NULL);
	if (IS_ERR(rsb->clk)) {
		ret = PTR_ERR(rsb->clk);
		dev_err(dev, "failed to retrieve clk: %d\n", ret);
		return ret;
	}

	rsb->rstc = devm_reset_control_get(dev, NULL);
	if (IS_ERR(rsb->rstc)) {
		ret = PTR_ERR(rsb->rstc);
		dev_err(dev, "failed to retrieve reset controller: %d\n", ret);
		return ret;
	}

	init_completion(&rsb->complete);
	mutex_init(&rsb->lock);

	ret = devm_request_irq(dev, irq, sunxi_rsb_irq, 0, RSB_CTRL_NAME, rsb);
	if (ret) {
		dev_err(dev, "can't register interrupt handler irq %d: %d\n",
			irq, ret);
		return ret;
	}

	ret = sunxi_rsb_hw_init(rsb);
	if (ret)
		return ret;

	/* initialize all devices on the bus into RSB mode */
	ret = sunxi_rsb_init_device_mode(rsb);
	if (ret)
		dev_warn(dev, "Initialize device mode failed: %d\n", ret);

	pm_suspend_ignore_children(dev, true);
	pm_runtime_set_active(dev);
	pm_runtime_set_autosuspend_delay(dev, MSEC_PER_SEC);
	pm_runtime_use_autosuspend(dev);
	pm_runtime_enable(dev);

	of_rsb_register_devices(rsb);

	return 0;
}

static int sunxi_rsb_remove(struct platform_device *pdev)
{
	struct sunxi_rsb *rsb = platform_get_drvdata(pdev);

	device_for_each_child(rsb->dev, NULL, sunxi_rsb_remove_devices);
	pm_runtime_disable(&pdev->dev);
	sunxi_rsb_hw_exit(rsb);

	return 0;
}

static void sunxi_rsb_shutdown(struct platform_device *pdev)
{
	struct sunxi_rsb *rsb = platform_get_drvdata(pdev);

	pm_runtime_disable(&pdev->dev);
	sunxi_rsb_hw_exit(rsb);
}

static const struct dev_pm_ops sunxi_rsb_dev_pm_ops = {
	SET_RUNTIME_PM_OPS(sunxi_rsb_runtime_suspend,
			   sunxi_rsb_runtime_resume, NULL)
	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(sunxi_rsb_suspend, sunxi_rsb_resume)
};

static const struct of_device_id sunxi_rsb_of_match_table[] = {
	{ .compatible = "allwinner,sun8i-a23-rsb" },
	{}
};
MODULE_DEVICE_TABLE(of, sunxi_rsb_of_match_table);

static struct platform_driver sunxi_rsb_driver = {
	.probe = sunxi_rsb_probe,
	.remove	= sunxi_rsb_remove,
	.shutdown = sunxi_rsb_shutdown,
	.driver	= {
		.name = RSB_CTRL_NAME,
		.of_match_table = sunxi_rsb_of_match_table,
		.pm = &sunxi_rsb_dev_pm_ops,
	},
};

static int __init sunxi_rsb_init(void)
{
	int ret;

	ret = bus_register(&sunxi_rsb_bus);
	if (ret) {
		pr_err("failed to register sunxi sunxi_rsb bus: %d\n", ret);
		return ret;
	}

	return platform_driver_register(&sunxi_rsb_driver);
}
module_init(sunxi_rsb_init);

static void __exit sunxi_rsb_exit(void)
{
	platform_driver_unregister(&sunxi_rsb_driver);
	bus_unregister(&sunxi_rsb_bus);
}
module_exit(sunxi_rsb_exit);

MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
MODULE_DESCRIPTION("Allwinner sunXi Reduced Serial Bus controller driver");
MODULE_LICENSE("GPL v2");
