/*
 * Recognize and maintain s390 storage class memory.
 *
 * Copyright IBM Corp. 2012
 * Author(s): Sebastian Ott <sebott@linux.vnet.ibm.com>
 */

#include <linux/device.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/err.h>
#include <asm/eadm.h>
#include "chsc.h"

static struct device *scm_root;
static struct eadm_ops *eadm_ops;
static DEFINE_MUTEX(eadm_ops_mutex);

#define to_scm_dev(n) container_of(n, struct scm_device, dev)
#define	to_scm_drv(d) container_of(d, struct scm_driver, drv)

static int scmdev_probe(struct device *dev)
{
	struct scm_device *scmdev = to_scm_dev(dev);
	struct scm_driver *scmdrv = to_scm_drv(dev->driver);

	return scmdrv->probe ? scmdrv->probe(scmdev) : -ENODEV;
}

static int scmdev_remove(struct device *dev)
{
	struct scm_device *scmdev = to_scm_dev(dev);
	struct scm_driver *scmdrv = to_scm_drv(dev->driver);

	return scmdrv->remove ? scmdrv->remove(scmdev) : -ENODEV;
}

static int scmdev_uevent(struct device *dev, struct kobj_uevent_env *env)
{
	return add_uevent_var(env, "MODALIAS=scm:scmdev");
}

static struct bus_type scm_bus_type = {
	.name  = "scm",
	.probe = scmdev_probe,
	.remove = scmdev_remove,
	.uevent = scmdev_uevent,
};

/**
 * scm_driver_register() - register a scm driver
 * @scmdrv: driver to be registered
 */
int scm_driver_register(struct scm_driver *scmdrv)
{
	struct device_driver *drv = &scmdrv->drv;

	drv->bus = &scm_bus_type;

	return driver_register(drv);
}
EXPORT_SYMBOL_GPL(scm_driver_register);

/**
 * scm_driver_unregister() - deregister a scm driver
 * @scmdrv: driver to be deregistered
 */
void scm_driver_unregister(struct scm_driver *scmdrv)
{
	driver_unregister(&scmdrv->drv);
}
EXPORT_SYMBOL_GPL(scm_driver_unregister);

int scm_get_ref(void)
{
	int ret = 0;

	mutex_lock(&eadm_ops_mutex);
	if (!eadm_ops || !try_module_get(eadm_ops->owner))
		ret = -ENOENT;
	mutex_unlock(&eadm_ops_mutex);

	return ret;
}
EXPORT_SYMBOL_GPL(scm_get_ref);

void scm_put_ref(void)
{
	mutex_lock(&eadm_ops_mutex);
	module_put(eadm_ops->owner);
	mutex_unlock(&eadm_ops_mutex);
}
EXPORT_SYMBOL_GPL(scm_put_ref);

void register_eadm_ops(struct eadm_ops *ops)
{
	mutex_lock(&eadm_ops_mutex);
	eadm_ops = ops;
	mutex_unlock(&eadm_ops_mutex);
}
EXPORT_SYMBOL_GPL(register_eadm_ops);

void unregister_eadm_ops(struct eadm_ops *ops)
{
	mutex_lock(&eadm_ops_mutex);
	eadm_ops = NULL;
	mutex_unlock(&eadm_ops_mutex);
}
EXPORT_SYMBOL_GPL(unregister_eadm_ops);

int scm_start_aob(struct aob *aob)
{
	return eadm_ops->eadm_start(aob);
}
EXPORT_SYMBOL_GPL(scm_start_aob);

void scm_irq_handler(struct aob *aob, int error)
{
	struct aob_rq_header *aobrq = (void *) aob->request.data;
	struct scm_device *scmdev = aobrq->scmdev;
	struct scm_driver *scmdrv = to_scm_drv(scmdev->dev.driver);

	scmdrv->handler(scmdev, aobrq->data, error);
}
EXPORT_SYMBOL_GPL(scm_irq_handler);

#define scm_attr(name)							\
static ssize_t show_##name(struct device *dev,				\
	       struct device_attribute *attr, char *buf)		\
{									\
	struct scm_device *scmdev = to_scm_dev(dev);			\
	int ret;							\
									\
	device_lock(dev);						\
	ret = sprintf(buf, "%u\n", scmdev->attrs.name);			\
	device_unlock(dev);						\
									\
	return ret;							\
}									\
static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL);

scm_attr(persistence);
scm_attr(oper_state);
scm_attr(data_state);
scm_attr(rank);
scm_attr(release);
scm_attr(res_id);

static struct attribute *scmdev_attrs[] = {
	&dev_attr_persistence.attr,
	&dev_attr_oper_state.attr,
	&dev_attr_data_state.attr,
	&dev_attr_rank.attr,
	&dev_attr_release.attr,
	&dev_attr_res_id.attr,
	NULL,
};

static struct attribute_group scmdev_attr_group = {
	.attrs = scmdev_attrs,
};

static const struct attribute_group *scmdev_attr_groups[] = {
	&scmdev_attr_group,
	NULL,
};

static void scmdev_release(struct device *dev)
{
	struct scm_device *scmdev = to_scm_dev(dev);

	kfree(scmdev);
}

static void scmdev_setup(struct scm_device *scmdev, struct sale *sale,
			 unsigned int size, unsigned int max_blk_count)
{
	dev_set_name(&scmdev->dev, "%016llx", (unsigned long long) sale->sa);
	scmdev->nr_max_block = max_blk_count;
	scmdev->address = sale->sa;
	scmdev->size = 1UL << size;
	scmdev->attrs.rank = sale->rank;
	scmdev->attrs.persistence = sale->p;
	scmdev->attrs.oper_state = sale->op_state;
	scmdev->attrs.data_state = sale->data_state;
	scmdev->attrs.rank = sale->rank;
	scmdev->attrs.release = sale->r;
	scmdev->attrs.res_id = sale->rid;
	scmdev->dev.parent = scm_root;
	scmdev->dev.bus = &scm_bus_type;
	scmdev->dev.release = scmdev_release;
	scmdev->dev.groups = scmdev_attr_groups;
}

/*
 * Check for state-changes, notify the driver and userspace.
 */
static void scmdev_update(struct scm_device *scmdev, struct sale *sale)
{
	struct scm_driver *scmdrv;
	bool changed;

	device_lock(&scmdev->dev);
	changed = scmdev->attrs.rank != sale->rank ||
		  scmdev->attrs.oper_state != sale->op_state;
	scmdev->attrs.rank = sale->rank;
	scmdev->attrs.oper_state = sale->op_state;
	if (!scmdev->dev.driver)
		goto out;
	scmdrv = to_scm_drv(scmdev->dev.driver);
	if (changed && scmdrv->notify)
		scmdrv->notify(scmdev, SCM_CHANGE);
out:
	device_unlock(&scmdev->dev);
	if (changed)
		kobject_uevent(&scmdev->dev.kobj, KOBJ_CHANGE);
}

static int check_address(struct device *dev, void *data)
{
	struct scm_device *scmdev = to_scm_dev(dev);
	struct sale *sale = data;

	return scmdev->address == sale->sa;
}

static struct scm_device *scmdev_find(struct sale *sale)
{
	struct device *dev;

	dev = bus_find_device(&scm_bus_type, NULL, sale, check_address);

	return dev ? to_scm_dev(dev) : NULL;
}

static int scm_add(struct chsc_scm_info *scm_info, size_t num)
{
	struct sale *sale, *scmal = scm_info->scmal;
	struct scm_device *scmdev;
	int ret;

	for (sale = scmal; sale < scmal + num; sale++) {
		scmdev = scmdev_find(sale);
		if (scmdev) {
			scmdev_update(scmdev, sale);
			/* Release reference from scm_find(). */
			put_device(&scmdev->dev);
			continue;
		}
		scmdev = kzalloc(sizeof(*scmdev), GFP_KERNEL);
		if (!scmdev)
			return -ENODEV;
		scmdev_setup(scmdev, sale, scm_info->is, scm_info->mbc);
		ret = device_register(&scmdev->dev);
		if (ret) {
			/* Release reference from device_initialize(). */
			put_device(&scmdev->dev);
			return ret;
		}
	}

	return 0;
}

int scm_update_information(void)
{
	struct chsc_scm_info *scm_info;
	u64 token = 0;
	size_t num;
	int ret;

	scm_info = (void *)__get_free_page(GFP_KERNEL | GFP_DMA);
	if (!scm_info)
		return -ENOMEM;

	do {
		ret = chsc_scm_info(scm_info, token);
		if (ret)
			break;

		num = (scm_info->response.length -
		       (offsetof(struct chsc_scm_info, scmal) -
			offsetof(struct chsc_scm_info, response))
		      ) / sizeof(struct sale);

		ret = scm_add(scm_info, num);
		if (ret)
			break;

		token = scm_info->restok;
	} while (token);

	free_page((unsigned long)scm_info);

	return ret;
}

static int scm_dev_avail(struct device *dev, void *unused)
{
	struct scm_driver *scmdrv = to_scm_drv(dev->driver);
	struct scm_device *scmdev = to_scm_dev(dev);

	if (dev->driver && scmdrv->notify)
		scmdrv->notify(scmdev, SCM_AVAIL);

	return 0;
}

int scm_process_availability_information(void)
{
	return bus_for_each_dev(&scm_bus_type, NULL, NULL, scm_dev_avail);
}

static int __init scm_init(void)
{
	int ret;

	ret = bus_register(&scm_bus_type);
	if (ret)
		return ret;

	scm_root = root_device_register("scm");
	if (IS_ERR(scm_root)) {
		bus_unregister(&scm_bus_type);
		return PTR_ERR(scm_root);
	}

	scm_update_information();
	return 0;
}
subsys_initcall_sync(scm_init);
