/*
 * Copyright 2017 Thomas Gleixner <tglx@linutronix.de>
 *
 * This file is licensed under the GPL V2.
 */
#include <linux/irqdomain.h>
#include <linux/irq.h>
#include <linux/uaccess.h>

#include "internals.h"

static struct dentry *irq_dir;

struct irq_bit_descr {
	unsigned int	mask;
	char		*name;
};
#define BIT_MASK_DESCR(m)	{ .mask = m, .name = #m }

static void irq_debug_show_bits(struct seq_file *m, int ind, unsigned int state,
				const struct irq_bit_descr *sd, int size)
{
	int i;

	for (i = 0; i < size; i++, sd++) {
		if (state & sd->mask)
			seq_printf(m, "%*s%s\n", ind + 12, "", sd->name);
	}
}

#ifdef CONFIG_SMP
static void irq_debug_show_masks(struct seq_file *m, struct irq_desc *desc)
{
	struct irq_data *data = irq_desc_get_irq_data(desc);
	struct cpumask *msk;

	msk = irq_data_get_affinity_mask(data);
	seq_printf(m, "affinity: %*pbl\n", cpumask_pr_args(msk));
#ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK
	msk = irq_data_get_effective_affinity_mask(data);
	seq_printf(m, "effectiv: %*pbl\n", cpumask_pr_args(msk));
#endif
#ifdef CONFIG_GENERIC_PENDING_IRQ
	msk = desc->pending_mask;
	seq_printf(m, "pending:  %*pbl\n", cpumask_pr_args(msk));
#endif
}
#else
static void irq_debug_show_masks(struct seq_file *m, struct irq_desc *desc) { }
#endif

static const struct irq_bit_descr irqchip_flags[] = {
	BIT_MASK_DESCR(IRQCHIP_SET_TYPE_MASKED),
	BIT_MASK_DESCR(IRQCHIP_EOI_IF_HANDLED),
	BIT_MASK_DESCR(IRQCHIP_MASK_ON_SUSPEND),
	BIT_MASK_DESCR(IRQCHIP_ONOFFLINE_ENABLED),
	BIT_MASK_DESCR(IRQCHIP_SKIP_SET_WAKE),
	BIT_MASK_DESCR(IRQCHIP_ONESHOT_SAFE),
	BIT_MASK_DESCR(IRQCHIP_EOI_THREADED),
};

static void
irq_debug_show_chip(struct seq_file *m, struct irq_data *data, int ind)
{
	struct irq_chip *chip = data->chip;

	if (!chip) {
		seq_printf(m, "chip: None\n");
		return;
	}
	seq_printf(m, "%*schip:    %s\n", ind, "", chip->name);
	seq_printf(m, "%*sflags:   0x%lx\n", ind + 1, "", chip->flags);
	irq_debug_show_bits(m, ind, chip->flags, irqchip_flags,
			    ARRAY_SIZE(irqchip_flags));
}

static void
irq_debug_show_data(struct seq_file *m, struct irq_data *data, int ind)
{
	seq_printf(m, "%*sdomain:  %s\n", ind, "",
		   data->domain ? data->domain->name : "");
	seq_printf(m, "%*shwirq:   0x%lx\n", ind + 1, "", data->hwirq);
	irq_debug_show_chip(m, data, ind + 1);
	if (data->domain && data->domain->ops && data->domain->ops->debug_show)
		data->domain->ops->debug_show(m, NULL, data, ind + 1);
#ifdef	CONFIG_IRQ_DOMAIN_HIERARCHY
	if (!data->parent_data)
		return;
	seq_printf(m, "%*sparent:\n", ind + 1, "");
	irq_debug_show_data(m, data->parent_data, ind + 4);
#endif
}

static const struct irq_bit_descr irqdata_states[] = {
	BIT_MASK_DESCR(IRQ_TYPE_EDGE_RISING),
	BIT_MASK_DESCR(IRQ_TYPE_EDGE_FALLING),
	BIT_MASK_DESCR(IRQ_TYPE_LEVEL_HIGH),
	BIT_MASK_DESCR(IRQ_TYPE_LEVEL_LOW),
	BIT_MASK_DESCR(IRQD_LEVEL),

	BIT_MASK_DESCR(IRQD_ACTIVATED),
	BIT_MASK_DESCR(IRQD_IRQ_STARTED),
	BIT_MASK_DESCR(IRQD_IRQ_DISABLED),
	BIT_MASK_DESCR(IRQD_IRQ_MASKED),
	BIT_MASK_DESCR(IRQD_IRQ_INPROGRESS),

	BIT_MASK_DESCR(IRQD_PER_CPU),
	BIT_MASK_DESCR(IRQD_NO_BALANCING),

	BIT_MASK_DESCR(IRQD_SINGLE_TARGET),
	BIT_MASK_DESCR(IRQD_MOVE_PCNTXT),
	BIT_MASK_DESCR(IRQD_AFFINITY_SET),
	BIT_MASK_DESCR(IRQD_SETAFFINITY_PENDING),
	BIT_MASK_DESCR(IRQD_AFFINITY_MANAGED),
	BIT_MASK_DESCR(IRQD_MANAGED_SHUTDOWN),

	BIT_MASK_DESCR(IRQD_FORWARDED_TO_VCPU),

	BIT_MASK_DESCR(IRQD_WAKEUP_STATE),
	BIT_MASK_DESCR(IRQD_WAKEUP_ARMED),
};

static const struct irq_bit_descr irqdesc_states[] = {
	BIT_MASK_DESCR(_IRQ_NOPROBE),
	BIT_MASK_DESCR(_IRQ_NOREQUEST),
	BIT_MASK_DESCR(_IRQ_NOTHREAD),
	BIT_MASK_DESCR(_IRQ_NOAUTOEN),
	BIT_MASK_DESCR(_IRQ_NESTED_THREAD),
	BIT_MASK_DESCR(_IRQ_PER_CPU_DEVID),
	BIT_MASK_DESCR(_IRQ_IS_POLLED),
	BIT_MASK_DESCR(_IRQ_DISABLE_UNLAZY),
};

static const struct irq_bit_descr irqdesc_istates[] = {
	BIT_MASK_DESCR(IRQS_AUTODETECT),
	BIT_MASK_DESCR(IRQS_SPURIOUS_DISABLED),
	BIT_MASK_DESCR(IRQS_POLL_INPROGRESS),
	BIT_MASK_DESCR(IRQS_ONESHOT),
	BIT_MASK_DESCR(IRQS_REPLAY),
	BIT_MASK_DESCR(IRQS_WAITING),
	BIT_MASK_DESCR(IRQS_PENDING),
	BIT_MASK_DESCR(IRQS_SUSPENDED),
};


static int irq_debug_show(struct seq_file *m, void *p)
{
	struct irq_desc *desc = m->private;
	struct irq_data *data;

	raw_spin_lock_irq(&desc->lock);
	data = irq_desc_get_irq_data(desc);
	seq_printf(m, "handler:  %pf\n", desc->handle_irq);
	seq_printf(m, "device:   %s\n", desc->dev_name);
	seq_printf(m, "status:   0x%08x\n", desc->status_use_accessors);
	irq_debug_show_bits(m, 0, desc->status_use_accessors, irqdesc_states,
			    ARRAY_SIZE(irqdesc_states));
	seq_printf(m, "istate:   0x%08x\n", desc->istate);
	irq_debug_show_bits(m, 0, desc->istate, irqdesc_istates,
			    ARRAY_SIZE(irqdesc_istates));
	seq_printf(m, "ddepth:   %u\n", desc->depth);
	seq_printf(m, "wdepth:   %u\n", desc->wake_depth);
	seq_printf(m, "dstate:   0x%08x\n", irqd_get(data));
	irq_debug_show_bits(m, 0, irqd_get(data), irqdata_states,
			    ARRAY_SIZE(irqdata_states));
	seq_printf(m, "node:     %d\n", irq_data_get_node(data));
	irq_debug_show_masks(m, desc);
	irq_debug_show_data(m, data, 0);
	raw_spin_unlock_irq(&desc->lock);
	return 0;
}

static int irq_debug_open(struct inode *inode, struct file *file)
{
	return single_open(file, irq_debug_show, inode->i_private);
}

static ssize_t irq_debug_write(struct file *file, const char __user *user_buf,
			       size_t count, loff_t *ppos)
{
	struct irq_desc *desc = file_inode(file)->i_private;
	char buf[8] = { 0, };
	size_t size;

	size = min(sizeof(buf) - 1, count);
	if (copy_from_user(buf, user_buf, size))
		return -EFAULT;

	if (!strncmp(buf, "trigger", size)) {
		unsigned long flags;
		int err;

		/* Try the HW interface first */
		err = irq_set_irqchip_state(irq_desc_get_irq(desc),
					    IRQCHIP_STATE_PENDING, true);
		if (!err)
			return count;

		/*
		 * Otherwise, try to inject via the resend interface,
		 * which may or may not succeed.
		 */
		chip_bus_lock(desc);
		raw_spin_lock_irqsave(&desc->lock, flags);

		if (irq_settings_is_level(desc)) {
			/* Can't do level, sorry */
			err = -EINVAL;
		} else {
			desc->istate |= IRQS_PENDING;
			check_irq_resend(desc);
			err = 0;
		}

		raw_spin_unlock_irqrestore(&desc->lock, flags);
		chip_bus_sync_unlock(desc);

		return err ? err : count;
	}

	return count;
}

static const struct file_operations dfs_irq_ops = {
	.open		= irq_debug_open,
	.write		= irq_debug_write,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};

void irq_debugfs_copy_devname(int irq, struct device *dev)
{
	struct irq_desc *desc = irq_to_desc(irq);
	const char *name = dev_name(dev);

	if (name)
		desc->dev_name = kstrdup(name, GFP_KERNEL);
}

void irq_add_debugfs_entry(unsigned int irq, struct irq_desc *desc)
{
	char name [10];

	if (!irq_dir || !desc || desc->debugfs_file)
		return;

	sprintf(name, "%d", irq);
	desc->debugfs_file = debugfs_create_file(name, 0644, irq_dir, desc,
						 &dfs_irq_ops);
}

static int __init irq_debugfs_init(void)
{
	struct dentry *root_dir;
	int irq;

	root_dir = debugfs_create_dir("irq", NULL);
	if (!root_dir)
		return -ENOMEM;

	irq_domain_debugfs_init(root_dir);

	irq_dir = debugfs_create_dir("irqs", root_dir);

	irq_lock_sparse();
	for_each_active_irq(irq)
		irq_add_debugfs_entry(irq, irq_to_desc(irq));
	irq_unlock_sparse();

	return 0;
}
__initcall(irq_debugfs_init);
