/*
 * Intel MIC Platform Software Stack (MPSS)
 *
 * Copyright(c) 2014 Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License, 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.
 *
 * Intel SCIF driver.
 */
#include "scif_main.h"
#include "../bus/scif_bus.h"
#include "scif_peer_bus.h"

static inline struct scif_peer_dev *
dev_to_scif_peer(struct device *dev)
{
	return container_of(dev, struct scif_peer_dev, dev);
}

struct bus_type scif_peer_bus = {
	.name  = "scif_peer_bus",
};

static void scif_peer_release_dev(struct device *d)
{
	struct scif_peer_dev *sdev = dev_to_scif_peer(d);
	struct scif_dev *scifdev = &scif_dev[sdev->dnode];

	scif_cleanup_scifdev(scifdev);
	kfree(sdev);
}

static int scif_peer_initialize_device(struct scif_dev *scifdev)
{
	struct scif_peer_dev *spdev;
	int ret;

	spdev = kzalloc(sizeof(*spdev), GFP_KERNEL);
	if (!spdev) {
		ret = -ENOMEM;
		goto err;
	}

	spdev->dev.parent = scifdev->sdev->dev.parent;
	spdev->dev.release = scif_peer_release_dev;
	spdev->dnode = scifdev->node;
	spdev->dev.bus = &scif_peer_bus;
	dev_set_name(&spdev->dev, "scif_peer-dev%u", spdev->dnode);

	device_initialize(&spdev->dev);
	get_device(&spdev->dev);
	rcu_assign_pointer(scifdev->spdev, spdev);

	mutex_lock(&scif_info.conflock);
	scif_info.total++;
	scif_info.maxid = max_t(u32, spdev->dnode, scif_info.maxid);
	mutex_unlock(&scif_info.conflock);
	return 0;
err:
	dev_err(&scifdev->sdev->dev,
		"dnode %d: initialize_device rc %d\n", scifdev->node, ret);
	return ret;
}

static int scif_peer_add_device(struct scif_dev *scifdev)
{
	struct scif_peer_dev *spdev = rcu_dereference(scifdev->spdev);
	char pool_name[16];
	int ret;

	ret = device_add(&spdev->dev);
	put_device(&spdev->dev);
	if (ret) {
		dev_err(&scifdev->sdev->dev,
			"dnode %d: peer device_add failed\n", scifdev->node);
		goto put_spdev;
	}

	scnprintf(pool_name, sizeof(pool_name), "scif-%d", spdev->dnode);
	scifdev->signal_pool = dmam_pool_create(pool_name, &scifdev->sdev->dev,
						sizeof(struct scif_status), 1,
						0);
	if (!scifdev->signal_pool) {
		dev_err(&scifdev->sdev->dev,
			"dnode %d: dmam_pool_create failed\n", scifdev->node);
		ret = -ENOMEM;
		goto del_spdev;
	}
	dev_dbg(&spdev->dev, "Added peer dnode %d\n", spdev->dnode);
	return 0;
del_spdev:
	device_del(&spdev->dev);
put_spdev:
	RCU_INIT_POINTER(scifdev->spdev, NULL);
	synchronize_rcu();
	put_device(&spdev->dev);

	mutex_lock(&scif_info.conflock);
	scif_info.total--;
	mutex_unlock(&scif_info.conflock);
	return ret;
}

void scif_add_peer_device(struct work_struct *work)
{
	struct scif_dev *scifdev = container_of(work, struct scif_dev,
						peer_add_work);

	scif_peer_add_device(scifdev);
}

/*
 * Peer device registration is split into a device_initialize and a device_add.
 * The reason for doing this is as follows: First, peer device registration
 * itself cannot be done in the message processing thread and must be delegated
 * to another workqueue, otherwise if SCIF client probe, called during peer
 * device registration, calls scif_connect(..), it will block the message
 * processing thread causing a deadlock. Next, device_initialize is done in the
 * "top-half" message processing thread and device_add in the "bottom-half"
 * workqueue. If this is not done, SCIF_CNCT_REQ message processing executing
 * concurrently with SCIF_INIT message processing is unable to get a reference
 * on the peer device, thereby failing the connect request.
 */
void scif_peer_register_device(struct scif_dev *scifdev)
{
	int ret;

	mutex_lock(&scifdev->lock);
	ret = scif_peer_initialize_device(scifdev);
	if (ret)
		goto exit;
	schedule_work(&scifdev->peer_add_work);
exit:
	mutex_unlock(&scifdev->lock);
}

int scif_peer_unregister_device(struct scif_dev *scifdev)
{
	struct scif_peer_dev *spdev;

	mutex_lock(&scifdev->lock);
	/* Flush work to ensure device register is complete */
	flush_work(&scifdev->peer_add_work);

	/*
	 * Continue holding scifdev->lock since theoretically unregister_device
	 * can be called simultaneously from multiple threads
	 */
	spdev = rcu_dereference(scifdev->spdev);
	if (!spdev) {
		mutex_unlock(&scifdev->lock);
		return -ENODEV;
	}

	RCU_INIT_POINTER(scifdev->spdev, NULL);
	synchronize_rcu();
	mutex_unlock(&scifdev->lock);

	dev_dbg(&spdev->dev, "Removing peer dnode %d\n", spdev->dnode);
	device_unregister(&spdev->dev);

	mutex_lock(&scif_info.conflock);
	scif_info.total--;
	mutex_unlock(&scif_info.conflock);
	return 0;
}

int scif_peer_bus_init(void)
{
	return bus_register(&scif_peer_bus);
}

void scif_peer_bus_exit(void)
{
	bus_unregister(&scif_peer_bus);
}
