// SPDX-License-Identifier: GPL-2.0
/*
 * R-Car Generation 2 da9063(L)/da9210 regulator quirk
 *
 * Certain Gen2 development boards have an da9063 and one or more da9210
 * regulators. All of these regulators have their interrupt request lines
 * tied to the same interrupt pin (IRQ2) on the SoC.
 *
 * After cold boot or da9063-induced restart, both the da9063 and da9210 seem
 * to assert their interrupt request lines.  Hence as soon as one driver
 * requests this irq, it gets stuck in an interrupt storm, as it only manages
 * to deassert its own interrupt request line, and the other driver hasn't
 * installed an interrupt handler yet.
 *
 * To handle this, install a quirk that masks the interrupts in both the
 * da9063 and da9210.  This quirk has to run after the i2c master driver has
 * been initialized, but before the i2c slave drivers are initialized.
 *
 * Copyright (C) 2015 Glider bvba
 */

#include <linux/device.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/list.h>
#include <linux/notifier.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/mfd/da9063/registers.h>

#define IRQC_BASE		0xe61c0000
#define IRQC_MONITOR		0x104	/* IRQn Signal Level Monitor Register */

#define REGULATOR_IRQ_MASK	BIT(2)	/* IRQ2, active low */

/* start of DA9210 System Control and Event Registers */
#define DA9210_REG_MASK_A		0x54

struct regulator_quirk {
	struct list_head		list;
	const struct of_device_id	*id;
	struct device_node		*np;
	struct of_phandle_args		irq_args;
	struct i2c_msg			i2c_msg;
	bool				shared;	/* IRQ line is shared */
};

static LIST_HEAD(quirk_list);
static void __iomem *irqc;

/* first byte sets the memory pointer, following are consecutive reg values */
static u8 da9063_irq_clr[] = { DA9063_REG_IRQ_MASK_A, 0xff, 0xff, 0xff, 0xff };
static u8 da9210_irq_clr[] = { DA9210_REG_MASK_A, 0xff, 0xff };

static struct i2c_msg da9063_msg = {
	.len = ARRAY_SIZE(da9063_irq_clr),
	.buf = da9063_irq_clr,
};

static struct i2c_msg da9210_msg = {
	.len = ARRAY_SIZE(da9210_irq_clr),
	.buf = da9210_irq_clr,
};

static const struct of_device_id rcar_gen2_quirk_match[] = {
	{ .compatible = "dlg,da9063", .data = &da9063_msg },
	{ .compatible = "dlg,da9063l", .data = &da9063_msg },
	{ .compatible = "dlg,da9210", .data = &da9210_msg },
	{},
};

static int regulator_quirk_notify(struct notifier_block *nb,
				  unsigned long action, void *data)
{
	struct regulator_quirk *pos, *tmp;
	struct device *dev = data;
	struct i2c_client *client;
	static bool done;
	int ret;
	u32 mon;

	if (done)
		return 0;

	mon = ioread32(irqc + IRQC_MONITOR);
	dev_dbg(dev, "%s: %ld, IRQC_MONITOR = 0x%x\n", __func__, action, mon);
	if (mon & REGULATOR_IRQ_MASK)
		goto remove;

	if (action != BUS_NOTIFY_ADD_DEVICE || dev->type == &i2c_adapter_type)
		return 0;

	client = to_i2c_client(dev);
	dev_dbg(dev, "Detected %s\n", client->name);

	/*
	 * Send message to all PMICs that share an IRQ line to deassert it.
	 *
	 * WARNING: This works only if all the PMICs are on the same I2C bus.
	 */
	list_for_each_entry(pos, &quirk_list, list) {
		if (!pos->shared)
			continue;

		if (pos->np->parent != client->dev.parent->of_node)
			continue;

		dev_info(&client->dev, "clearing %s@0x%02x interrupts\n",
			 pos->id->compatible, pos->i2c_msg.addr);

		ret = i2c_transfer(client->adapter, &pos->i2c_msg, 1);
		if (ret != 1)
			dev_err(&client->dev, "i2c error %d\n", ret);
	}

	mon = ioread32(irqc + IRQC_MONITOR);
	if (mon & REGULATOR_IRQ_MASK)
		goto remove;

	return 0;

remove:
	dev_info(dev, "IRQ2 is not asserted, removing quirk\n");

	list_for_each_entry_safe(pos, tmp, &quirk_list, list) {
		list_del(&pos->list);
		kfree(pos);
	}

	done = true;
	iounmap(irqc);
	return 0;
}

static struct notifier_block regulator_quirk_nb = {
	.notifier_call = regulator_quirk_notify
};

static int __init rcar_gen2_regulator_quirk(void)
{
	struct regulator_quirk *quirk, *pos, *tmp;
	struct of_phandle_args *argsa, *argsb;
	const struct of_device_id *id;
	struct device_node *np;
	u32 mon, addr;
	int ret;

	if (!of_machine_is_compatible("renesas,koelsch") &&
	    !of_machine_is_compatible("renesas,lager") &&
	    !of_machine_is_compatible("renesas,porter") &&
	    !of_machine_is_compatible("renesas,stout") &&
	    !of_machine_is_compatible("renesas,gose"))
		return -ENODEV;

	for_each_matching_node_and_match(np, rcar_gen2_quirk_match, &id) {
		if (!of_device_is_available(np))
			break;

		ret = of_property_read_u32(np, "reg", &addr);
		if (ret)	/* Skip invalid entry and continue */
			continue;

		quirk = kzalloc(sizeof(*quirk), GFP_KERNEL);
		if (!quirk) {
			ret = -ENOMEM;
			goto err_mem;
		}

		argsa = &quirk->irq_args;
		memcpy(&quirk->i2c_msg, id->data, sizeof(quirk->i2c_msg));

		quirk->id = id;
		quirk->np = np;
		quirk->i2c_msg.addr = addr;

		ret = of_irq_parse_one(np, 0, argsa);
		if (ret) {	/* Skip invalid entry and continue */
			kfree(quirk);
			continue;
		}

		list_for_each_entry(pos, &quirk_list, list) {
			argsb = &pos->irq_args;

			if (argsa->args_count != argsb->args_count)
				continue;

			ret = memcmp(argsa->args, argsb->args,
				     argsa->args_count *
				     sizeof(argsa->args[0]));
			if (!ret) {
				pos->shared = true;
				quirk->shared = true;
			}
		}

		list_add_tail(&quirk->list, &quirk_list);
	}

	irqc = ioremap(IRQC_BASE, PAGE_SIZE);
	if (!irqc) {
		ret = -ENOMEM;
		goto err_mem;
	}

	mon = ioread32(irqc + IRQC_MONITOR);
	if (mon & REGULATOR_IRQ_MASK) {
		pr_debug("%s: IRQ2 is not asserted, not installing quirk\n",
			 __func__);
		ret = 0;
		goto err_free;
	}

	pr_info("IRQ2 is asserted, installing regulator quirk\n");

	bus_register_notifier(&i2c_bus_type, &regulator_quirk_nb);
	return 0;

err_free:
	iounmap(irqc);
err_mem:
	list_for_each_entry_safe(pos, tmp, &quirk_list, list) {
		list_del(&pos->list);
		kfree(pos);
	}

	return ret;
}

arch_initcall(rcar_gen2_regulator_quirk);
