/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/bitmap.h>
#include <linux/bitops.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <asm/hardware/gic.h>
#include <linux/spinlock.h>
#include <mach/msm_iomap.h>
#include <mach/gpio.h>

#include "mpm.h"

/******************************************************************************
 * Debug Definitions
 *****************************************************************************/

enum {
	MSM_MPM_DEBUG_NON_DETECTABLE_IRQ = BIT(0),
	MSM_MPM_DEBUG_PENDING_IRQ = BIT(1),
	MSM_MPM_DEBUG_WRITE = BIT(2),
	MSM_MPM_DEBUG_NON_DETECTABLE_IRQ_IDLE = BIT(3),
};

static int msm_mpm_debug_mask = 1;
module_param_named(
	debug_mask, msm_mpm_debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP
);

/******************************************************************************
 * Request and Status Definitions
 *****************************************************************************/

enum {
	MSM_MPM_REQUEST_REG_ENABLE,
	MSM_MPM_REQUEST_REG_DETECT_CTL,
	MSM_MPM_REQUEST_REG_POLARITY,
	MSM_MPM_REQUEST_REG_CLEAR,
};

enum {
	MSM_MPM_STATUS_REG_PENDING,
};

/******************************************************************************
 * IRQ Mapping Definitions
 *****************************************************************************/

#define MSM_MPM_NR_APPS_IRQS  (NR_MSM_IRQS + NR_GPIO_IRQS)

#define MSM_MPM_REG_WIDTH  DIV_ROUND_UP(MSM_MPM_NR_MPM_IRQS, 32)
#define MSM_MPM_IRQ_INDEX(irq)  (irq / 32)
#define MSM_MPM_IRQ_MASK(irq)  BIT(irq % 32)

static uint8_t msm_mpm_irqs_a2m[MSM_MPM_NR_APPS_IRQS];

static DEFINE_SPINLOCK(msm_mpm_lock);

/*
 * Note: the following two bitmaps only mark irqs that are _not_
 * mappable to MPM.
 */
static DECLARE_BITMAP(msm_mpm_enabled_apps_irqs, MSM_MPM_NR_APPS_IRQS);
static DECLARE_BITMAP(msm_mpm_wake_apps_irqs, MSM_MPM_NR_APPS_IRQS);

static DECLARE_BITMAP(msm_mpm_gpio_irqs_mask, MSM_MPM_NR_APPS_IRQS);

static uint32_t msm_mpm_enabled_irq[MSM_MPM_REG_WIDTH];
static uint32_t msm_mpm_wake_irq[MSM_MPM_REG_WIDTH];
static uint32_t msm_mpm_detect_ctl[MSM_MPM_REG_WIDTH];
static uint32_t msm_mpm_polarity[MSM_MPM_REG_WIDTH];


/******************************************************************************
 * Low Level Functions for Accessing MPM
 *****************************************************************************/

static inline uint32_t msm_mpm_read(
	unsigned int reg, unsigned int subreg_index)
{
	unsigned int offset = reg * MSM_MPM_REG_WIDTH + subreg_index;
	return __raw_readl(msm_mpm_dev_data.mpm_status_reg_base + offset * 4);
}

static inline void msm_mpm_write(
	unsigned int reg, unsigned int subreg_index, uint32_t value)
{
	unsigned int offset = reg * MSM_MPM_REG_WIDTH + subreg_index;
	__raw_writel(value, msm_mpm_dev_data.mpm_request_reg_base + offset * 4);

	if (MSM_MPM_DEBUG_WRITE & msm_mpm_debug_mask)
		pr_info("%s: reg %u.%u: 0x%08x\n",
			__func__, reg, subreg_index, value);
}

static inline void msm_mpm_send_interrupt(void)
{
	__raw_writel(msm_mpm_dev_data.mpm_apps_ipc_val,
			msm_mpm_dev_data.mpm_apps_ipc_reg);
	/* Ensure the write is complete before returning. */
	mb();
}

static irqreturn_t msm_mpm_irq(int irq, void *dev_id)
{
	return IRQ_HANDLED;
}

/******************************************************************************
 * MPM Access Functions
 *****************************************************************************/

static void msm_mpm_set(bool wakeset)
{
	uint32_t *irqs;
	unsigned int reg;
	int i;

	irqs = wakeset ? msm_mpm_wake_irq : msm_mpm_enabled_irq;
	for (i = 0; i < MSM_MPM_REG_WIDTH; i++) {
		reg = MSM_MPM_REQUEST_REG_ENABLE;
		msm_mpm_write(reg, i, irqs[i]);

		reg = MSM_MPM_REQUEST_REG_DETECT_CTL;
		msm_mpm_write(reg, i, msm_mpm_detect_ctl[i]);

		reg = MSM_MPM_REQUEST_REG_POLARITY;
		msm_mpm_write(reg, i, msm_mpm_polarity[i]);

		reg = MSM_MPM_REQUEST_REG_CLEAR;
		msm_mpm_write(reg, i, 0xffffffff);
	}

	/* Ensure that the set operation is complete before sending the
	 * interrupt
	 */
	mb();
	msm_mpm_send_interrupt();
}

static void msm_mpm_clear(void)
{
	int i;

	for (i = 0; i < MSM_MPM_REG_WIDTH; i++) {
		msm_mpm_write(MSM_MPM_REQUEST_REG_ENABLE, i, 0);
		msm_mpm_write(MSM_MPM_REQUEST_REG_CLEAR, i, 0xffffffff);
	}

	/* Ensure the clear is complete before sending the interrupt */
	mb();
	msm_mpm_send_interrupt();
}

/******************************************************************************
 * Interrupt Mapping Functions
 *****************************************************************************/

static inline bool msm_mpm_is_valid_apps_irq(unsigned int irq)
{
	return irq < ARRAY_SIZE(msm_mpm_irqs_a2m);
}

static inline uint8_t msm_mpm_get_irq_a2m(unsigned int irq)
{
	return msm_mpm_irqs_a2m[irq];
}

static inline void msm_mpm_set_irq_a2m(unsigned int apps_irq,
	unsigned int mpm_irq)
{
	msm_mpm_irqs_a2m[apps_irq] = (uint8_t) mpm_irq;
}

static inline bool msm_mpm_is_valid_mpm_irq(unsigned int irq)
{
	return irq < msm_mpm_dev_data.irqs_m2a_size;
}

static inline uint16_t msm_mpm_get_irq_m2a(unsigned int irq)
{
	return msm_mpm_dev_data.irqs_m2a[irq];
}

static bool msm_mpm_bypass_apps_irq(unsigned int irq)
{
	int i;

	for (i = 0; i < msm_mpm_dev_data.bypassed_apps_irqs_size; i++)
		if (irq == msm_mpm_dev_data.bypassed_apps_irqs[i])
			return true;

	return false;
}

static int msm_mpm_enable_irq_exclusive(
	unsigned int irq, bool enable, bool wakeset)
{
	uint32_t mpm_irq;

	if (!msm_mpm_is_valid_apps_irq(irq))
		return -EINVAL;

	if (msm_mpm_bypass_apps_irq(irq))
		return 0;

	mpm_irq = msm_mpm_get_irq_a2m(irq);
	if (mpm_irq) {
		uint32_t *mpm_irq_masks = wakeset ?
				msm_mpm_wake_irq : msm_mpm_enabled_irq;
		uint32_t index = MSM_MPM_IRQ_INDEX(mpm_irq);
		uint32_t mask = MSM_MPM_IRQ_MASK(mpm_irq);

		if (enable)
			mpm_irq_masks[index] |= mask;
		else
			mpm_irq_masks[index] &= ~mask;
	} else {
		unsigned long *apps_irq_bitmap = wakeset ?
			msm_mpm_wake_apps_irqs : msm_mpm_enabled_apps_irqs;

		if (enable)
			__set_bit(irq, apps_irq_bitmap);
		else
			__clear_bit(irq, apps_irq_bitmap);
	}

	return 0;
}

static int msm_mpm_set_irq_type_exclusive(
	unsigned int irq, unsigned int flow_type)
{
	uint32_t mpm_irq;

	if (!msm_mpm_is_valid_apps_irq(irq))
		return -EINVAL;

	if (msm_mpm_bypass_apps_irq(irq))
		return 0;

	mpm_irq = msm_mpm_get_irq_a2m(irq);
	if (mpm_irq) {
		uint32_t index = MSM_MPM_IRQ_INDEX(mpm_irq);
		uint32_t mask = MSM_MPM_IRQ_MASK(mpm_irq);

		if (flow_type & IRQ_TYPE_EDGE_BOTH)
			msm_mpm_detect_ctl[index] |= mask;
		else
			msm_mpm_detect_ctl[index] &= ~mask;

		if (flow_type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_HIGH))
			msm_mpm_polarity[index] |= mask;
		else
			msm_mpm_polarity[index] &= ~mask;
	}

	return 0;
}

static int __msm_mpm_enable_irq(unsigned int irq, unsigned int enable)
{
	unsigned long flags;
	int rc;

	spin_lock_irqsave(&msm_mpm_lock, flags);
	rc = msm_mpm_enable_irq_exclusive(irq, (bool)enable, false);
	spin_unlock_irqrestore(&msm_mpm_lock, flags);

	return rc;
}

static void msm_mpm_enable_irq(struct irq_data *d)
{
	__msm_mpm_enable_irq(d->irq, 1);
}

static void msm_mpm_disable_irq(struct irq_data *d)
{
	__msm_mpm_enable_irq(d->irq, 0);
}

static int msm_mpm_set_irq_wake(struct irq_data *d, unsigned int on)
{
	unsigned long flags;
	int rc;

	spin_lock_irqsave(&msm_mpm_lock, flags);
	rc = msm_mpm_enable_irq_exclusive(d->irq, (bool)on, true);
	spin_unlock_irqrestore(&msm_mpm_lock, flags);

	return rc;
}

static int msm_mpm_set_irq_type(struct irq_data *d, unsigned int flow_type)
{
	unsigned long flags;
	int rc;

	spin_lock_irqsave(&msm_mpm_lock, flags);
	rc = msm_mpm_set_irq_type_exclusive(d->irq, flow_type);
	spin_unlock_irqrestore(&msm_mpm_lock, flags);

	return rc;
}

/******************************************************************************
 * Public functions
 *****************************************************************************/
int msm_mpm_enable_pin(enum msm_mpm_pin pin, unsigned int enable)
{
	uint32_t index = MSM_MPM_IRQ_INDEX(pin);
	uint32_t mask = MSM_MPM_IRQ_MASK(pin);
	unsigned long flags;

	spin_lock_irqsave(&msm_mpm_lock, flags);

	if (enable)
		msm_mpm_enabled_irq[index] |= mask;
	else
		msm_mpm_enabled_irq[index] &= ~mask;

	spin_unlock_irqrestore(&msm_mpm_lock, flags);
	return 0;
}

int msm_mpm_set_pin_wake(enum msm_mpm_pin pin, unsigned int on)
{
	uint32_t index = MSM_MPM_IRQ_INDEX(pin);
	uint32_t mask = MSM_MPM_IRQ_MASK(pin);
	unsigned long flags;

	spin_lock_irqsave(&msm_mpm_lock, flags);

	if (on)
		msm_mpm_wake_irq[index] |= mask;
	else
		msm_mpm_wake_irq[index] &= ~mask;

	spin_unlock_irqrestore(&msm_mpm_lock, flags);
	return 0;
}

int msm_mpm_set_pin_type(enum msm_mpm_pin pin, unsigned int flow_type)
{
	uint32_t index = MSM_MPM_IRQ_INDEX(pin);
	uint32_t mask = MSM_MPM_IRQ_MASK(pin);
	unsigned long flags;

	spin_lock_irqsave(&msm_mpm_lock, flags);

	if (flow_type & IRQ_TYPE_EDGE_BOTH)
		msm_mpm_detect_ctl[index] |= mask;
	else
		msm_mpm_detect_ctl[index] &= ~mask;

	if (flow_type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_HIGH))
		msm_mpm_polarity[index] |= mask;
	else
		msm_mpm_polarity[index] &= ~mask;

	spin_unlock_irqrestore(&msm_mpm_lock, flags);
	return 0;
}

bool msm_mpm_irqs_detectable(bool from_idle)
{
	unsigned long *apps_irq_bitmap;
	int debug_mask;

	if (from_idle) {
		apps_irq_bitmap = msm_mpm_enabled_apps_irqs;
		debug_mask = msm_mpm_debug_mask &
					MSM_MPM_DEBUG_NON_DETECTABLE_IRQ_IDLE;
	} else {
		apps_irq_bitmap = msm_mpm_wake_apps_irqs;
		debug_mask = msm_mpm_debug_mask &
					MSM_MPM_DEBUG_NON_DETECTABLE_IRQ;
	}

	if (debug_mask) {
		static char buf[DIV_ROUND_UP(MSM_MPM_NR_APPS_IRQS, 32)*9+1];

		bitmap_scnprintf(buf, sizeof(buf), apps_irq_bitmap,
				MSM_MPM_NR_APPS_IRQS);
		buf[sizeof(buf) - 1] = '\0';

		pr_info("%s: cannot monitor %s", __func__, buf);
	}

	return (bool)__bitmap_empty(apps_irq_bitmap, MSM_MPM_NR_APPS_IRQS);
}

bool msm_mpm_gpio_irqs_detectable(bool from_idle)
{
	unsigned long *apps_irq_bitmap = from_idle ?
			msm_mpm_enabled_apps_irqs : msm_mpm_wake_apps_irqs;

	return !__bitmap_intersects(msm_mpm_gpio_irqs_mask, apps_irq_bitmap,
			MSM_MPM_NR_APPS_IRQS);
}

void msm_mpm_enter_sleep(bool from_idle)
{
	msm_mpm_set(!from_idle);
}

void msm_mpm_exit_sleep(bool from_idle)
{
	unsigned long pending;
	int i;
	int k;

	for (i = 0; i < MSM_MPM_REG_WIDTH; i++) {
		pending = msm_mpm_read(MSM_MPM_STATUS_REG_PENDING, i);

		if (MSM_MPM_DEBUG_PENDING_IRQ & msm_mpm_debug_mask)
			pr_info("%s: pending.%d: 0x%08lx", __func__,
					i, pending);

		k = find_first_bit(&pending, 32);
		while (k < 32) {
			unsigned int mpm_irq = 32 * i + k;
			unsigned int apps_irq = msm_mpm_get_irq_m2a(mpm_irq);
			struct irq_desc *desc = apps_irq ?
				irq_to_desc(apps_irq) : NULL;

			if (desc && !irqd_is_level_type(&desc->irq_data)) {
				irq_set_pending(apps_irq);
				if (from_idle)
					check_irq_resend(desc, apps_irq);
			}

			k = find_next_bit(&pending, 32, k + 1);
		}
	}

	msm_mpm_clear();
}

static int __init msm_mpm_early_init(void)
{
	uint8_t mpm_irq;
	uint16_t apps_irq;

	for (mpm_irq = 0; msm_mpm_is_valid_mpm_irq(mpm_irq); mpm_irq++) {
		apps_irq = msm_mpm_get_irq_m2a(mpm_irq);
		if (apps_irq && msm_mpm_is_valid_apps_irq(apps_irq))
			msm_mpm_set_irq_a2m(apps_irq, mpm_irq);
	}

	return 0;
}
core_initcall(msm_mpm_early_init);

void msm_mpm_irq_extn_init(void)
{
	gic_arch_extn.irq_mask = msm_mpm_disable_irq;
	gic_arch_extn.irq_unmask = msm_mpm_enable_irq;
	gic_arch_extn.irq_disable = msm_mpm_disable_irq;
	gic_arch_extn.irq_set_type = msm_mpm_set_irq_type;
	gic_arch_extn.irq_set_wake = msm_mpm_set_irq_wake;

	msm_gpio_irq_extn.irq_mask = msm_mpm_disable_irq;
	msm_gpio_irq_extn.irq_unmask = msm_mpm_enable_irq;
	msm_gpio_irq_extn.irq_disable = msm_mpm_disable_irq;
	msm_gpio_irq_extn.irq_set_type = msm_mpm_set_irq_type;
	msm_gpio_irq_extn.irq_set_wake = msm_mpm_set_irq_wake;

	bitmap_set(msm_mpm_gpio_irqs_mask, NR_MSM_IRQS, NR_GPIO_IRQS);
}

static int __init msm_mpm_init(void)
{
	unsigned int irq = msm_mpm_dev_data.mpm_ipc_irq;
	int rc;

	rc = request_irq(irq, msm_mpm_irq,
			IRQF_TRIGGER_RISING, "mpm_drv", msm_mpm_irq);

	if (rc) {
		pr_err("%s: failed to request irq %u: %d\n",
			__func__, irq, rc);
		goto init_bail;
	}

	rc = irq_set_irq_wake(irq, 1);
	if (rc) {
		pr_err("%s: failed to set wakeup irq %u: %d\n",
			__func__, irq, rc);
		goto init_free_bail;
	}

	return 0;

init_free_bail:
	free_irq(irq, msm_mpm_irq);

init_bail:
	return rc;
}
device_initcall(msm_mpm_init);
