/*
 * Copyright (C) 2014 Freescale Semiconductor, Inc.
 */

/*
 * The code contained herein is licensed under the GNU General Public
 * License. You may obtain a copy of the GNU General Public License
 * Version 2 or later at the following locations:
 *
 * http://www.opensource.org/licenses/gpl-license.html
 * http://www.gnu.org/copyleft/gpl.html
 */

#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/imx_sema4.h>

static struct imx_sema4_mutex_device *imx6_sema4;

/*!
 * \brief mutex create function.
 *
 * This function allocates imx_sema4_mutex structure and returns a handle
 * to it. The mutex to be created is identified by SEMA4 device number and mutex
 * (gate) number. The handle is used to reference the created mutex in calls to
 * other imx_sema4_mutex API functions. This function is to be called only
 * once for each mutex.
 *
 * \param[in] dev_num     SEMA4 device (module) number.
 * \param[in] mutex_num   Mutex (gate) number.
 *
 * \return NULL (Failure.)
 * \return imx_sema4_mutex (Success.)
 */
struct imx_sema4_mutex *
imx_sema4_mutex_create(u32 dev_num, u32 mutex_num)
{
	struct imx_sema4_mutex *mutex_ptr = NULL;

	if (mutex_num >= SEMA4_NUM_GATES || dev_num >= SEMA4_NUM_DEVICES)
		goto out;

	if (imx6_sema4->cpine_val & (1 < mutex_num)) {
		pr_err("Error: requiring a allocated sema4.\n");
		pr_err("mutex_num %d cpine_val 0x%08x.\n",
				mutex_num, imx6_sema4->cpine_val);
	}
	mutex_ptr = kzalloc(sizeof(*mutex_ptr), GFP_KERNEL);
	if (!mutex_ptr)
		goto out;
	imx6_sema4->mutex_ptr[mutex_num] = mutex_ptr;
	imx6_sema4->alloced |= 1 < mutex_num;
	imx6_sema4->cpine_val |= idx_sema4[mutex_num];
	writew(imx6_sema4->cpine_val, imx6_sema4->ioaddr + SEMA4_CP0INE);

	mutex_ptr->valid = CORE_MUTEX_VALID;
	mutex_ptr->gate_num = mutex_num;
	init_waitqueue_head(&mutex_ptr->wait_q);

out:
	return mutex_ptr;
}
EXPORT_SYMBOL(imx_sema4_mutex_create);

/*!
 * \brief mutex destroy function.
 *
 * This function destroys a mutex.
 *
 * \param[in] mutex_ptr   Pointer to mutex structure.
 *
 * \return MQX_COMPONENT_DOES_NOT_EXIST (mutex component not installed.)
 * \return MQX_INVALID_PARAMETER (Wrong input parameter.)
 * \return COREMUTEX_OK (Success.)
 *
 */
int imx_sema4_mutex_destroy(struct imx_sema4_mutex *mutex_ptr)
{
	u32 mutex_num;

	if ((mutex_ptr == NULL) || (mutex_ptr->valid != CORE_MUTEX_VALID))
		return -EINVAL;

	mutex_num = mutex_ptr->gate_num;
	if ((imx6_sema4->cpine_val & idx_sema4[mutex_num]) == 0) {
		pr_err("Error: trying to destroy a un-allocated sema4.\n");
		pr_err("mutex_num %d cpine_val 0x%08x.\n",
				mutex_num, imx6_sema4->cpine_val);
	}
	imx6_sema4->mutex_ptr[mutex_num] = NULL;
	imx6_sema4->alloced &= ~(1 << mutex_num);
	imx6_sema4->cpine_val &= ~(idx_sema4[mutex_num]);
	writew(imx6_sema4->cpine_val, imx6_sema4->ioaddr + SEMA4_CP0INE);

	kfree(mutex_ptr);

	return 0;
}
EXPORT_SYMBOL(imx_sema4_mutex_destroy);

/*!
 * \brief Lock the mutex, shouldn't be interruted by INT.
 *
 * This function attempts to lock a mutex. If the mutex is already locked
 * by another task the function return -EBUSY, and tell invoker wait until
 * it is possible to lock the mutex.
 *
 * \param[in] mutex_ptr   Pointer to mutex structure.
 *
 * \return MQX_INVALID_POINTER (Wrong pointer to the mutex structure provided.)
 * \return COREMUTEX_OK (mutex successfully locked.)
 *
 * \see imx_sema4_mutex_unlock
 */
int _imx_sema4_mutex_lock(struct imx_sema4_mutex *mutex_ptr)
{
	int ret = 0, i = 0;

	if ((mutex_ptr == NULL) || (mutex_ptr->valid != CORE_MUTEX_VALID))
		return -EINVAL;

	i = mutex_ptr->gate_num;
	mutex_ptr->gate_val = readb(imx6_sema4->ioaddr + i);
	mutex_ptr->gate_val &= SEMA4_GATE_MASK;
	/* Check to see if this core already own it */
	if (mutex_ptr->gate_val == SEMA4_A9_LOCK) {
		/* return -EBUSY, invoker should be in sleep, and re-lock ag */
		pr_err("%s -> %s %d already locked, wait! num %d val %d.\n",
				__FILE__, __func__, __LINE__,
				i, mutex_ptr->gate_val);
		ret = -EBUSY;
		goto out;
	} else {
		/* try to lock the mutex */
		mutex_ptr->gate_val = readb(imx6_sema4->ioaddr + i);
		mutex_ptr->gate_val &= (~SEMA4_GATE_MASK);
		mutex_ptr->gate_val |= SEMA4_A9_LOCK;
		writeb(mutex_ptr->gate_val, imx6_sema4->ioaddr + i);
		mutex_ptr->gate_val = readb(imx6_sema4->ioaddr + i);
		mutex_ptr->gate_val &= SEMA4_GATE_MASK;
		/* double check the mutex is locked, otherwise, return -EBUSY */
		if (mutex_ptr->gate_val != SEMA4_A9_LOCK) {
			pr_debug("wait-locked num %d val %d.\n",
					i, mutex_ptr->gate_val);
			ret = -EBUSY;
		}
	}
out:
	return ret;
}

/* !
 * \brief Try to lock the core mutex.
 *
 * This function attempts to lock a mutex. If the mutex is successfully locked
 * for the calling task, SEMA4_A9_LOCK is returned. If the mutex is already
 * locked by another task, the function does not block but rather returns
 * negative immediately.
 *
 * \param[in] mutex_ptr  Pointer to core_mutex structure.
 *
 * \return SEMA4_A9_LOCK (mutex successfully locked.)
 * \return negative (mutex not locked.)
 *
 */
int imx_sema4_mutex_trylock(struct imx_sema4_mutex *mutex_ptr)
{
	int ret = 0;

	ret = _imx_sema4_mutex_lock(mutex_ptr);
	if (ret == 0)
		return SEMA4_A9_LOCK;
	else
		return ret;
}
EXPORT_SYMBOL(imx_sema4_mutex_trylock);

/*!
 * \brief Invoke _imx_sema4_mutex_lock to lock the mutex.
 *
 * This function attempts to lock a mutex. If the mutex is already locked
 * by another task the function, sleep itself and schedule out.
 * Wait until it is possible to lock the mutex.
 *
 * Invoker should add its own wait queue into the wait queue header of the
 * required semaphore, set TASK_INTERRUPTIBLE and sleep on itself by
 * schedule() when the lock is failed. Re-try to lock the semaphore when
 * it is woke up by the sema4 isr.
 *
 * \param[in] mutex_ptr  Pointer to mutex structure.
 *
 * \return SEMA4_A9_LOCK (mutex successfully locked.)
 *
 * \see imx_sema4_mutex_unlock
 */
int imx_sema4_mutex_lock(struct imx_sema4_mutex *mutex_ptr)
{
	int ret = 0;
	unsigned long flags;

	spin_lock_irqsave(&imx6_sema4->lock, flags);
	ret = _imx_sema4_mutex_lock(mutex_ptr);
	spin_unlock_irqrestore(&imx6_sema4->lock, flags);
	while (-EBUSY == ret) {
		spin_lock_irqsave(&imx6_sema4->lock, flags);
		ret = _imx_sema4_mutex_lock(mutex_ptr);
		spin_unlock_irqrestore(&imx6_sema4->lock, flags);
		if (ret == 0)
			break;
	}

	return ret;
}
EXPORT_SYMBOL(imx_sema4_mutex_lock);

/*!
 * \brief Unlock the mutex.
 *
 * This function unlocks the specified mutex.
 *
 * \param[in] mutex_ptr   Pointer to mutex structure.
 *
 * \return -EINVAL (Wrong pointer to the mutex structure provided.)
 * \return -EINVAL (This mutex has not been locked by this core.)
 * \return 0 (mutex successfully unlocked.)
 *
 * \see imx_sema4_mutex_lock
 */
int imx_sema4_mutex_unlock(struct imx_sema4_mutex *mutex_ptr)
{
	int ret = 0, i = 0;

	if ((mutex_ptr == NULL) || (mutex_ptr->valid != CORE_MUTEX_VALID))
		return -EINVAL;

	i = mutex_ptr->gate_num;
	mutex_ptr->gate_val = readb(imx6_sema4->ioaddr + i);
	mutex_ptr->gate_val &= SEMA4_GATE_MASK;
	/* make sure it is locked by this core */
	if (mutex_ptr->gate_val != SEMA4_A9_LOCK) {
		pr_err("%d Trying to unlock an unlock mutex.\n", __LINE__);
		ret = -EINVAL;
		goto out;
	}
	/* unlock it */
	mutex_ptr->gate_val = readb(imx6_sema4->ioaddr + i);
	mutex_ptr->gate_val &= (~SEMA4_GATE_MASK);
	writeb(mutex_ptr->gate_val | SEMA4_UNLOCK, imx6_sema4->ioaddr + i);
	mutex_ptr->gate_val = readb(imx6_sema4->ioaddr + i);
	mutex_ptr->gate_val &= SEMA4_GATE_MASK;
	/* make sure it is locked by this core */
	if (mutex_ptr->gate_val == SEMA4_A9_LOCK)
		pr_err("%d ERROR, failed to unlock the mutex.\n", __LINE__);

out:
	return ret;
}
EXPORT_SYMBOL(imx_sema4_mutex_unlock);

/*
 * isr used by SEMA4, wake up the sleep tasks if there are the tasks waiting
 * for locking semaphore.
 * FIXME the bits order of the gatn, cpnie, cpnntf are not exact identified yet!
 */
static irqreturn_t imx_sema4_isr(int irq, void *dev_id)
{
	int i;
	struct imx_sema4_mutex *mutex_ptr;
	unsigned int mask;
	struct imx_sema4_mutex_device *imx6_sema4 = dev_id;

	imx6_sema4->cpntf_val = readw(imx6_sema4->ioaddr + SEMA4_CP0NTF);
	for (i = 0; i < SEMA4_NUM_GATES; i++) {
		mask = idx_sema4[i];
		if ((imx6_sema4->cpntf_val) & mask) {
			mutex_ptr = imx6_sema4->mutex_ptr[i];
			/*
			 * An interrupt is pending on this mutex, the only way
			 * to clear it is to lock it (either by this core or
			 * another).
			 */
			mutex_ptr->gate_val = readb(imx6_sema4->ioaddr + i);
			mutex_ptr->gate_val &= (~SEMA4_GATE_MASK);
			mutex_ptr->gate_val |= SEMA4_A9_LOCK;
			writeb(mutex_ptr->gate_val, imx6_sema4->ioaddr + i);
			mutex_ptr->gate_val = readb(imx6_sema4->ioaddr + i);
			mutex_ptr->gate_val &= SEMA4_GATE_MASK;
			if (mutex_ptr->gate_val == SEMA4_A9_LOCK) {
				/*
				 * wake up the wait queue, whatever there
				 * are wait task or not.
				 * NOTE: check gate is locted or not in
				 * sema4_lock func by wait task.
				 */
				mutex_ptr->gate_val =
					readb(imx6_sema4->ioaddr + i);
				mutex_ptr->gate_val &= (~SEMA4_GATE_MASK);
				mutex_ptr->gate_val |= SEMA4_UNLOCK;

				writeb(mutex_ptr->gate_val,
						imx6_sema4->ioaddr + i);
				wake_up(&mutex_ptr->wait_q);
			} else {
				pr_debug("can't lock gate%d %s retry!\n", i,
						mutex_ptr->gate_val ?
						"locked by m4" : "");
			}
		}
	}

	return IRQ_HANDLED;
}

static const struct of_device_id imx_sema4_dt_ids[] = {
	{ .compatible = "fsl,imx6sx-sema4", },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, imx_sema4_dt_ids);

static int imx_sema4_probe(struct platform_device *pdev)
{
	struct resource *res;
	int ret;

	imx6_sema4 = devm_kzalloc(&pdev->dev, sizeof(*imx6_sema4), GFP_KERNEL);
	if (!imx6_sema4)
		return -ENOMEM;

	imx6_sema4->dev = &pdev->dev;
	imx6_sema4->cpine_val = 0;
	spin_lock_init(&imx6_sema4->lock);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (IS_ERR(res)) {
		dev_err(&pdev->dev, "unable to get imx sema4 resource 0\n");
		ret = -ENODEV;
		goto err;
	}

	imx6_sema4->ioaddr = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(imx6_sema4->ioaddr)) {
		ret = PTR_ERR(imx6_sema4->ioaddr);
		goto err;
	}

	imx6_sema4->irq = platform_get_irq(pdev, 0);
	if (!imx6_sema4->irq) {
		dev_err(&pdev->dev, "failed to get irq\n");
		ret = -ENODEV;
		goto err;
	}

	ret = devm_request_irq(&pdev->dev, imx6_sema4->irq, imx_sema4_isr,
				IRQF_SHARED, "imx6sx-sema4", imx6_sema4);
	if (ret) {
		dev_err(&pdev->dev, "failed to request imx sema4 irq\n");
		ret = -ENODEV;
		goto err;
	}

	platform_set_drvdata(pdev, imx6_sema4);

err:
	return ret;
}

static int imx_sema4_remove(struct platform_device *pdev)
{
	return 0;
}

static struct platform_driver imx_sema4_driver = {
	.driver = {
		   .owner = THIS_MODULE,
		   .name = "imx-sema4",
		   .of_match_table = imx_sema4_dt_ids,
		   },
	.probe = imx_sema4_probe,
	.remove = imx_sema4_remove,
};

static int __init imx_sema4_init(void)
{
	int ret;

	ret = platform_driver_register(&imx_sema4_driver);
	if (ret)
		pr_err("Unable to initialize sema4 driver\n");
	else
		pr_info("imx sema4 driver is registered.\n");

	return ret;
}

static void __exit imx_sema4_exit(void)
{
	pr_info("imx sema4 driver is unregistered.\n");
	platform_driver_unregister(&imx_sema4_driver);
}

module_exit(imx_sema4_exit);
module_init(imx_sema4_init);

MODULE_AUTHOR("Freescale Semiconductor, Inc.");
MODULE_DESCRIPTION("IMX SEMA4 driver");
MODULE_LICENSE("GPL");
