// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright 2019 NXP
 *
 * Implementation of the SCU IRQ functions using MU.
 *
 */

#include <dt-bindings/firmware/imx/rsrc.h>
#include <linux/firmware/imx/ipc.h>
#include <linux/firmware/imx/sci.h>
#include <linux/mailbox_client.h>
#include <linux/suspend.h>

#define IMX_SC_IRQ_FUNC_ENABLE	1
#define IMX_SC_IRQ_FUNC_STATUS	2
#define IMX_SC_IRQ_NUM_GROUP	4

static u32 mu_resource_id;

struct imx_sc_msg_irq_get_status {
	struct imx_sc_rpc_msg hdr;
	union {
		struct {
			u16 resource;
			u8 group;
			u8 reserved;
		} __packed req;
		struct {
			u32 status;
		} resp;
	} data;
};

struct imx_sc_msg_irq_enable {
	struct imx_sc_rpc_msg hdr;
	u32 mask;
	u16 resource;
	u8 group;
	u8 enable;
} __packed;

static struct imx_sc_ipc *imx_sc_irq_ipc_handle;
static struct work_struct imx_sc_irq_work;
static ATOMIC_NOTIFIER_HEAD(imx_scu_irq_notifier_chain);

int imx_scu_irq_register_notifier(struct notifier_block *nb)
{
	return atomic_notifier_chain_register(
		&imx_scu_irq_notifier_chain, nb);
}
EXPORT_SYMBOL(imx_scu_irq_register_notifier);

int imx_scu_irq_unregister_notifier(struct notifier_block *nb)
{
	return atomic_notifier_chain_unregister(
		&imx_scu_irq_notifier_chain, nb);
}
EXPORT_SYMBOL(imx_scu_irq_unregister_notifier);

static int imx_scu_irq_notifier_call_chain(unsigned long status, u8 *group)
{
	return atomic_notifier_call_chain(&imx_scu_irq_notifier_chain,
		status, (void *)group);
}

static void imx_scu_irq_work_handler(struct work_struct *work)
{
	struct imx_sc_msg_irq_get_status msg;
	struct imx_sc_rpc_msg *hdr = &msg.hdr;
	u32 irq_status;
	int ret;
	u8 i;

	for (i = 0; i < IMX_SC_IRQ_NUM_GROUP; i++) {
		hdr->ver = IMX_SC_RPC_VERSION;
		hdr->svc = IMX_SC_RPC_SVC_IRQ;
		hdr->func = IMX_SC_IRQ_FUNC_STATUS;
		hdr->size = 2;

		msg.data.req.resource = mu_resource_id;
		msg.data.req.group = i;

		ret = imx_scu_call_rpc(imx_sc_irq_ipc_handle, &msg, true);
		if (ret) {
			pr_err("get irq group %d status failed, ret %d\n",
			       i, ret);
			return;
		}

		irq_status = msg.data.resp.status;
		if (!irq_status)
			continue;

		pm_system_wakeup();
		imx_scu_irq_notifier_call_chain(irq_status, &i);
	}
}

int imx_scu_irq_group_enable(u8 group, u32 mask, u8 enable)
{
	struct imx_sc_msg_irq_enable msg;
	struct imx_sc_rpc_msg *hdr = &msg.hdr;
	int ret;

	if (!imx_sc_irq_ipc_handle)
		return -EPROBE_DEFER;

	hdr->ver = IMX_SC_RPC_VERSION;
	hdr->svc = IMX_SC_RPC_SVC_IRQ;
	hdr->func = IMX_SC_IRQ_FUNC_ENABLE;
	hdr->size = 3;

	msg.resource = mu_resource_id;
	msg.group = group;
	msg.mask = mask;
	msg.enable = enable;

	ret = imx_scu_call_rpc(imx_sc_irq_ipc_handle, &msg, true);
	if (ret)
		pr_err("enable irq failed, group %d, mask %d, ret %d\n",
			group, mask, ret);

	return ret;
}
EXPORT_SYMBOL(imx_scu_irq_group_enable);

static void imx_scu_irq_callback(struct mbox_client *c, void *msg)
{
	schedule_work(&imx_sc_irq_work);
}

int imx_scu_enable_general_irq_channel(struct device *dev)
{
	struct of_phandle_args spec;
	struct mbox_client *cl;
	struct mbox_chan *ch;
	int ret = 0, i = 0;

	ret = imx_scu_get_handle(&imx_sc_irq_ipc_handle);
	if (ret)
		return ret;

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

	cl->dev = dev;
	cl->rx_callback = imx_scu_irq_callback;

	/* SCU general IRQ uses general interrupt channel 3 */
	ch = mbox_request_channel_byname(cl, "gip3");
	if (IS_ERR(ch)) {
		ret = PTR_ERR(ch);
		dev_err(dev, "failed to request mbox chan gip3, ret %d\n", ret);
		devm_kfree(dev, cl);
		return ret;
	}

	INIT_WORK(&imx_sc_irq_work, imx_scu_irq_work_handler);

	if (!of_parse_phandle_with_args(dev->of_node, "mboxes",
				       "#mbox-cells", 0, &spec))
		i = of_alias_get_id(spec.np, "mu");

	/* use mu1 as general mu irq channel if failed */
	if (i < 0)
		i = 1;

	mu_resource_id = IMX_SC_R_MU_0A + i;

	return ret;
}
EXPORT_SYMBOL(imx_scu_enable_general_irq_channel);
