// SPDX-License-Identifier: GPL-2.0

/*
 * Copyright (C) 2020-2021 NVIDIA CORPORATION & AFFILIATES
 */

#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/device.h>
#include <linux/gpio/driver.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/resource.h>
#include <linux/seq_file.h>
#include <linux/spinlock.h>
#include <linux/types.h>

/*
 * There are 3 YU GPIO blocks:
 * gpio[0]: HOST_GPIO0->HOST_GPIO31
 * gpio[1]: HOST_GPIO32->HOST_GPIO63
 * gpio[2]: HOST_GPIO64->HOST_GPIO69
 */
#define MLXBF2_GPIO_MAX_PINS_PER_BLOCK 32

/*
 * arm_gpio_lock register:
 * bit[31]	lock status: active if set
 * bit[15:0]	set lock
 * The lock is enabled only if 0xd42f is written to this field
 */
#define YU_ARM_GPIO_LOCK_ADDR		0x2801088
#define YU_ARM_GPIO_LOCK_SIZE		0x8
#define YU_LOCK_ACTIVE_BIT(val)		(val >> 31)
#define YU_ARM_GPIO_LOCK_ACQUIRE	0xd42f
#define YU_ARM_GPIO_LOCK_RELEASE	0x0

/*
 * gpio[x] block registers and their offset
 */
#define YU_GPIO_DATAIN			0x04
#define YU_GPIO_MODE1			0x08
#define YU_GPIO_MODE0			0x0c
#define YU_GPIO_DATASET			0x14
#define YU_GPIO_DATACLEAR		0x18
#define YU_GPIO_CAUSE_RISE_EN		0x44
#define YU_GPIO_CAUSE_FALL_EN		0x48
#define YU_GPIO_MODE1_CLEAR		0x50
#define YU_GPIO_MODE0_SET		0x54
#define YU_GPIO_MODE0_CLEAR		0x58
#define YU_GPIO_CAUSE_OR_CAUSE_EVTEN0	0x80
#define YU_GPIO_CAUSE_OR_EVTEN0		0x94
#define YU_GPIO_CAUSE_OR_CLRCAUSE	0x98

struct mlxbf2_gpio_context_save_regs {
	u32 gpio_mode0;
	u32 gpio_mode1;
};

/* BlueField-2 gpio block context structure. */
struct mlxbf2_gpio_context {
	struct gpio_chip gc;

	/* YU GPIO blocks address */
	void __iomem *gpio_io;
	struct device *dev;

	struct mlxbf2_gpio_context_save_regs *csave_regs;
};

/* BlueField-2 gpio shared structure. */
struct mlxbf2_gpio_param {
	void __iomem *io;
	struct resource *res;
	struct mutex *lock;
};

static struct resource yu_arm_gpio_lock_res =
	DEFINE_RES_MEM_NAMED(YU_ARM_GPIO_LOCK_ADDR, YU_ARM_GPIO_LOCK_SIZE, "YU_ARM_GPIO_LOCK");

static DEFINE_MUTEX(yu_arm_gpio_lock_mutex);

static struct mlxbf2_gpio_param yu_arm_gpio_lock_param = {
	.res = &yu_arm_gpio_lock_res,
	.lock = &yu_arm_gpio_lock_mutex,
};

/* Request memory region and map yu_arm_gpio_lock resource */
static int mlxbf2_gpio_get_lock_res(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct resource *res;
	resource_size_t size;
	int ret = 0;

	mutex_lock(yu_arm_gpio_lock_param.lock);

	/* Check if the memory map already exists */
	if (yu_arm_gpio_lock_param.io)
		goto exit;

	res = yu_arm_gpio_lock_param.res;
	size = resource_size(res);

	if (!devm_request_mem_region(dev, res->start, size, res->name)) {
		ret = -EFAULT;
		goto exit;
	}

	yu_arm_gpio_lock_param.io = devm_ioremap(dev, res->start, size);
	if (!yu_arm_gpio_lock_param.io)
		ret = -ENOMEM;

exit:
	mutex_unlock(yu_arm_gpio_lock_param.lock);

	return ret;
}

/*
 * Acquire the YU arm_gpio_lock to be able to change the direction
 * mode. If the lock_active bit is already set, return an error.
 */
static int mlxbf2_gpio_lock_acquire(struct mlxbf2_gpio_context *gs)
{
	u32 arm_gpio_lock_val;

	mutex_lock(yu_arm_gpio_lock_param.lock);
	raw_spin_lock(&gs->gc.bgpio_lock);

	arm_gpio_lock_val = readl(yu_arm_gpio_lock_param.io);

	/*
	 * When lock active bit[31] is set, ModeX is write enabled
	 */
	if (YU_LOCK_ACTIVE_BIT(arm_gpio_lock_val)) {
		raw_spin_unlock(&gs->gc.bgpio_lock);
		mutex_unlock(yu_arm_gpio_lock_param.lock);
		return -EINVAL;
	}

	writel(YU_ARM_GPIO_LOCK_ACQUIRE, yu_arm_gpio_lock_param.io);

	return 0;
}

/*
 * Release the YU arm_gpio_lock after changing the direction mode.
 */
static void mlxbf2_gpio_lock_release(struct mlxbf2_gpio_context *gs)
	__releases(&gs->gc.bgpio_lock)
	__releases(yu_arm_gpio_lock_param.lock)
{
	writel(YU_ARM_GPIO_LOCK_RELEASE, yu_arm_gpio_lock_param.io);
	raw_spin_unlock(&gs->gc.bgpio_lock);
	mutex_unlock(yu_arm_gpio_lock_param.lock);
}

/*
 * mode0 and mode1 are both locked by the gpio_lock field.
 *
 * Together, mode0 and mode1 define the gpio Mode dependeing also
 * on Reg_DataOut.
 *
 * {mode1,mode0}:{Reg_DataOut=0,Reg_DataOut=1}->{DataOut=0,DataOut=1}
 *
 * {0,0}:Reg_DataOut{0,1}->{Z,Z} Input PAD
 * {0,1}:Reg_DataOut{0,1}->{0,1} Full drive Output PAD
 * {1,0}:Reg_DataOut{0,1}->{0,Z} 0-set PAD to low, 1-float
 * {1,1}:Reg_DataOut{0,1}->{Z,1} 0-float, 1-set PAD to high
 */

/*
 * Set input direction:
 * {mode1,mode0} = {0,0}
 */
static int mlxbf2_gpio_direction_input(struct gpio_chip *chip,
				       unsigned int offset)
{
	struct mlxbf2_gpio_context *gs = gpiochip_get_data(chip);
	int ret;

	/*
	 * Although the arm_gpio_lock was set in the probe function, check again
	 * if it is still enabled to be able to write to the ModeX registers.
	 */
	ret = mlxbf2_gpio_lock_acquire(gs);
	if (ret < 0)
		return ret;

	writel(BIT(offset), gs->gpio_io + YU_GPIO_MODE0_CLEAR);
	writel(BIT(offset), gs->gpio_io + YU_GPIO_MODE1_CLEAR);

	mlxbf2_gpio_lock_release(gs);

	return ret;
}

/*
 * Set output direction:
 * {mode1,mode0} = {0,1}
 */
static int mlxbf2_gpio_direction_output(struct gpio_chip *chip,
					unsigned int offset,
					int value)
{
	struct mlxbf2_gpio_context *gs = gpiochip_get_data(chip);
	int ret = 0;

	/*
	 * Although the arm_gpio_lock was set in the probe function,
	 * check again it is still enabled to be able to write to the
	 * ModeX registers.
	 */
	ret = mlxbf2_gpio_lock_acquire(gs);
	if (ret < 0)
		return ret;

	writel(BIT(offset), gs->gpio_io + YU_GPIO_MODE1_CLEAR);
	writel(BIT(offset), gs->gpio_io + YU_GPIO_MODE0_SET);

	mlxbf2_gpio_lock_release(gs);

	return ret;
}

static void mlxbf2_gpio_irq_enable(struct irq_data *irqd)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
	struct mlxbf2_gpio_context *gs = gpiochip_get_data(gc);
	int offset = irqd_to_hwirq(irqd);
	unsigned long flags;
	u32 val;

	gpiochip_enable_irq(gc, irqd_to_hwirq(irqd));
	raw_spin_lock_irqsave(&gs->gc.bgpio_lock, flags);
	val = readl(gs->gpio_io + YU_GPIO_CAUSE_OR_CLRCAUSE);
	val |= BIT(offset);
	writel(val, gs->gpio_io + YU_GPIO_CAUSE_OR_CLRCAUSE);

	val = readl(gs->gpio_io + YU_GPIO_CAUSE_OR_EVTEN0);
	val |= BIT(offset);
	writel(val, gs->gpio_io + YU_GPIO_CAUSE_OR_EVTEN0);
	raw_spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags);
}

static void mlxbf2_gpio_irq_disable(struct irq_data *irqd)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
	struct mlxbf2_gpio_context *gs = gpiochip_get_data(gc);
	int offset = irqd_to_hwirq(irqd);
	unsigned long flags;
	u32 val;

	raw_spin_lock_irqsave(&gs->gc.bgpio_lock, flags);
	val = readl(gs->gpio_io + YU_GPIO_CAUSE_OR_EVTEN0);
	val &= ~BIT(offset);
	writel(val, gs->gpio_io + YU_GPIO_CAUSE_OR_EVTEN0);
	raw_spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags);
	gpiochip_disable_irq(gc, irqd_to_hwirq(irqd));
}

static irqreturn_t mlxbf2_gpio_irq_handler(int irq, void *ptr)
{
	struct mlxbf2_gpio_context *gs = ptr;
	struct gpio_chip *gc = &gs->gc;
	unsigned long pending;
	u32 level;

	pending = readl(gs->gpio_io + YU_GPIO_CAUSE_OR_CAUSE_EVTEN0);
	writel(pending, gs->gpio_io + YU_GPIO_CAUSE_OR_CLRCAUSE);

	for_each_set_bit(level, &pending, gc->ngpio)
		generic_handle_domain_irq_safe(gc->irq.domain, level);

	return IRQ_RETVAL(pending);
}

static int
mlxbf2_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
	struct mlxbf2_gpio_context *gs = gpiochip_get_data(gc);
	int offset = irqd_to_hwirq(irqd);
	unsigned long flags;
	bool fall = false;
	bool rise = false;
	u32 val;

	switch (type & IRQ_TYPE_SENSE_MASK) {
	case IRQ_TYPE_EDGE_BOTH:
		fall = true;
		rise = true;
		break;
	case IRQ_TYPE_EDGE_RISING:
		rise = true;
		break;
	case IRQ_TYPE_EDGE_FALLING:
		fall = true;
		break;
	default:
		return -EINVAL;
	}

	raw_spin_lock_irqsave(&gs->gc.bgpio_lock, flags);
	if (fall) {
		val = readl(gs->gpio_io + YU_GPIO_CAUSE_FALL_EN);
		val |= BIT(offset);
		writel(val, gs->gpio_io + YU_GPIO_CAUSE_FALL_EN);
	}

	if (rise) {
		val = readl(gs->gpio_io + YU_GPIO_CAUSE_RISE_EN);
		val |= BIT(offset);
		writel(val, gs->gpio_io + YU_GPIO_CAUSE_RISE_EN);
	}
	raw_spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags);

	return 0;
}

static void mlxbf2_gpio_irq_print_chip(struct irq_data *irqd,
				       struct seq_file *p)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
	struct mlxbf2_gpio_context *gs = gpiochip_get_data(gc);

	seq_puts(p, dev_name(gs->dev));
}

static const struct irq_chip mlxbf2_gpio_irq_chip = {
	.irq_set_type = mlxbf2_gpio_irq_set_type,
	.irq_enable = mlxbf2_gpio_irq_enable,
	.irq_disable = mlxbf2_gpio_irq_disable,
	.irq_print_chip = mlxbf2_gpio_irq_print_chip,
	.flags = IRQCHIP_IMMUTABLE,
	GPIOCHIP_IRQ_RESOURCE_HELPERS,
};

/* BlueField-2 GPIO driver initialization routine. */
static int
mlxbf2_gpio_probe(struct platform_device *pdev)
{
	struct mlxbf2_gpio_context *gs;
	struct device *dev = &pdev->dev;
	struct gpio_irq_chip *girq;
	struct gpio_chip *gc;
	unsigned int npins;
	const char *name;
	int ret, irq;

	name = dev_name(dev);

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

	gs->dev = dev;

	/* YU GPIO block address */
	gs->gpio_io = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(gs->gpio_io))
		return PTR_ERR(gs->gpio_io);

	ret = mlxbf2_gpio_get_lock_res(pdev);
	if (ret) {
		dev_err(dev, "Failed to get yu_arm_gpio_lock resource\n");
		return ret;
	}

	if (device_property_read_u32(dev, "npins", &npins))
		npins = MLXBF2_GPIO_MAX_PINS_PER_BLOCK;

	gc = &gs->gc;

	ret = bgpio_init(gc, dev, 4,
			gs->gpio_io + YU_GPIO_DATAIN,
			gs->gpio_io + YU_GPIO_DATASET,
			gs->gpio_io + YU_GPIO_DATACLEAR,
			NULL,
			NULL,
			0);

	if (ret) {
		dev_err(dev, "bgpio_init failed\n");
		return ret;
	}

	gc->direction_input = mlxbf2_gpio_direction_input;
	gc->direction_output = mlxbf2_gpio_direction_output;
	gc->ngpio = npins;
	gc->owner = THIS_MODULE;

	irq = platform_get_irq(pdev, 0);
	if (irq >= 0) {
		girq = &gs->gc.irq;
		gpio_irq_chip_set_chip(girq, &mlxbf2_gpio_irq_chip);
		girq->handler = handle_simple_irq;
		girq->default_type = IRQ_TYPE_NONE;
		/* This will let us handle the parent IRQ in the driver */
		girq->num_parents = 0;
		girq->parents = NULL;
		girq->parent_handler = NULL;

		/*
		 * Directly request the irq here instead of passing
		 * a flow-handler because the irq is shared.
		 */
		ret = devm_request_irq(dev, irq, mlxbf2_gpio_irq_handler,
				       IRQF_SHARED, name, gs);
		if (ret) {
			dev_err(dev, "failed to request IRQ");
			return ret;
		}
	}

	platform_set_drvdata(pdev, gs);

	ret = devm_gpiochip_add_data(dev, &gs->gc, gs);
	if (ret) {
		dev_err(dev, "Failed adding memory mapped gpiochip\n");
		return ret;
	}

	return 0;
}

static int __maybe_unused mlxbf2_gpio_suspend(struct device *dev)
{
	struct mlxbf2_gpio_context *gs = dev_get_drvdata(dev);

	gs->csave_regs->gpio_mode0 = readl(gs->gpio_io +
		YU_GPIO_MODE0);
	gs->csave_regs->gpio_mode1 = readl(gs->gpio_io +
		YU_GPIO_MODE1);

	return 0;
}

static int __maybe_unused mlxbf2_gpio_resume(struct device *dev)
{
	struct mlxbf2_gpio_context *gs = dev_get_drvdata(dev);

	writel(gs->csave_regs->gpio_mode0, gs->gpio_io +
		YU_GPIO_MODE0);
	writel(gs->csave_regs->gpio_mode1, gs->gpio_io +
		YU_GPIO_MODE1);

	return 0;
}
static SIMPLE_DEV_PM_OPS(mlxbf2_pm_ops, mlxbf2_gpio_suspend, mlxbf2_gpio_resume);

static const struct acpi_device_id __maybe_unused mlxbf2_gpio_acpi_match[] = {
	{ "MLNXBF22", 0 },
	{},
};
MODULE_DEVICE_TABLE(acpi, mlxbf2_gpio_acpi_match);

static struct platform_driver mlxbf2_gpio_driver = {
	.driver = {
		.name = "mlxbf2_gpio",
		.acpi_match_table = mlxbf2_gpio_acpi_match,
		.pm = &mlxbf2_pm_ops,
	},
	.probe    = mlxbf2_gpio_probe,
};

module_platform_driver(mlxbf2_gpio_driver);

MODULE_DESCRIPTION("Mellanox BlueField-2 GPIO Driver");
MODULE_AUTHOR("Asmaa Mnebhi <asmaa@nvidia.com>");
MODULE_LICENSE("GPL v2");
