/*
 * Copyright (c) 2015, Sony Mobile Communications Inc.
 * Copyright (c) 2012-2013, The Linux Foundation. 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/device.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/slab.h>
#include <linux/soc/qcom/smem_state.h>

static LIST_HEAD(smem_states);
static DEFINE_MUTEX(list_lock);

/**
 * struct qcom_smem_state - state context
 * @refcount:	refcount for the state
 * @orphan:	boolean indicator that this state has been unregistered
 * @list:	entry in smem_states list
 * @of_node:	of_node to use for matching the state in DT
 * @priv:	implementation private data
 * @ops:	ops for the state
 */
struct qcom_smem_state {
	struct kref refcount;
	bool orphan;

	struct list_head list;
	struct device_node *of_node;

	void *priv;

	struct qcom_smem_state_ops ops;
};

/**
 * qcom_smem_state_update_bits() - update the masked bits in state with value
 * @state:	state handle acquired by calling qcom_smem_state_get()
 * @mask:	bit mask for the change
 * @value:	new value for the masked bits
 *
 * Returns 0 on success, otherwise negative errno.
 */
int qcom_smem_state_update_bits(struct qcom_smem_state *state,
				u32 mask,
				u32 value)
{
	if (state->orphan)
		return -ENXIO;

	if (!state->ops.update_bits)
		return -ENOTSUPP;

	return state->ops.update_bits(state->priv, mask, value);
}
EXPORT_SYMBOL_GPL(qcom_smem_state_update_bits);

static struct qcom_smem_state *of_node_to_state(struct device_node *np)
{
	struct qcom_smem_state *state;

	mutex_lock(&list_lock);

	list_for_each_entry(state, &smem_states, list) {
		if (state->of_node == np) {
			kref_get(&state->refcount);
			goto unlock;
		}
	}
	state = ERR_PTR(-EPROBE_DEFER);

unlock:
	mutex_unlock(&list_lock);

	return state;
}

/**
 * qcom_smem_state_get() - acquire handle to a state
 * @dev:	client device pointer
 * @con_id:	name of the state to lookup
 * @bit:	flags from the state reference, indicating which bit's affected
 *
 * Returns handle to the state, or ERR_PTR(). qcom_smem_state_put() must be
 * called to release the returned state handle.
 */
struct qcom_smem_state *qcom_smem_state_get(struct device *dev,
					    const char *con_id,
					    unsigned *bit)
{
	struct qcom_smem_state *state;
	struct of_phandle_args args;
	int index = 0;
	int ret;

	if (con_id) {
		index = of_property_match_string(dev->of_node,
						 "qcom,state-names",
						 con_id);
		if (index < 0) {
			dev_err(dev, "missing qcom,state-names\n");
			return ERR_PTR(index);
		}
	}

	ret = of_parse_phandle_with_args(dev->of_node,
					 "qcom,state",
					 "#qcom,state-cells",
					 index,
					 &args);
	if (ret) {
		dev_err(dev, "failed to parse qcom,state property\n");
		return ERR_PTR(ret);
	}

	if (args.args_count != 1) {
		dev_err(dev, "invalid #qcom,state-cells\n");
		return ERR_PTR(-EINVAL);
	}

	state = of_node_to_state(args.np);
	if (IS_ERR(state))
		goto put;

	*bit = args.args[0];

put:
	of_node_put(args.np);
	return state;
}
EXPORT_SYMBOL_GPL(qcom_smem_state_get);

static void qcom_smem_state_release(struct kref *ref)
{
	struct qcom_smem_state *state = container_of(ref, struct qcom_smem_state, refcount);

	list_del(&state->list);
	kfree(state);
}

/**
 * qcom_smem_state_put() - release state handle
 * @state:	state handle to be released
 */
void qcom_smem_state_put(struct qcom_smem_state *state)
{
	mutex_lock(&list_lock);
	kref_put(&state->refcount, qcom_smem_state_release);
	mutex_unlock(&list_lock);
}
EXPORT_SYMBOL_GPL(qcom_smem_state_put);

/**
 * qcom_smem_state_register() - register a new state
 * @of_node:	of_node used for matching client lookups
 * @ops:	implementation ops
 * @priv:	implementation specific private data
 */
struct qcom_smem_state *qcom_smem_state_register(struct device_node *of_node,
						 const struct qcom_smem_state_ops *ops,
						 void *priv)
{
	struct qcom_smem_state *state;

	state = kzalloc(sizeof(*state), GFP_KERNEL);
	if (!state)
		return ERR_PTR(-ENOMEM);

	kref_init(&state->refcount);

	state->of_node = of_node;
	state->ops = *ops;
	state->priv = priv;

	mutex_lock(&list_lock);
	list_add(&state->list, &smem_states);
	mutex_unlock(&list_lock);

	return state;
}
EXPORT_SYMBOL_GPL(qcom_smem_state_register);

/**
 * qcom_smem_state_unregister() - unregister a registered state
 * @state:	state handle to be unregistered
 */
void qcom_smem_state_unregister(struct qcom_smem_state *state)
{
	state->orphan = true;
	qcom_smem_state_put(state);
}
EXPORT_SYMBOL_GPL(qcom_smem_state_unregister);
