// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2017 Red Hat, Inc
 */

#define pr_fmt(fmt)		KBUILD_MODNAME ": " fmt

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/libps2.h>
#include <linux/i2c.h>
#include <linux/serio.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include "psmouse.h"

struct psmouse_smbus_dev {
	struct i2c_board_info board;
	struct psmouse *psmouse;
	struct i2c_client *client;
	struct list_head node;
	bool dead;
	bool need_deactivate;
};

static LIST_HEAD(psmouse_smbus_list);
static DEFINE_MUTEX(psmouse_smbus_mutex);

static struct workqueue_struct *psmouse_smbus_wq;

static void psmouse_smbus_check_adapter(struct i2c_adapter *adapter)
{
	struct psmouse_smbus_dev *smbdev;

	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_HOST_NOTIFY))
		return;

	guard(mutex)(&psmouse_smbus_mutex);

	list_for_each_entry(smbdev, &psmouse_smbus_list, node) {
		if (smbdev->dead)
			continue;

		if (smbdev->client)
			continue;

		/*
		 * Here would be a good place to check if device is actually
		 * present, but it seems that SMBus will not respond unless we
		 * fully reset PS/2 connection.  So cross our fingers, and try
		 * to switch over, hopefully our system will not have too many
		 * "host notify" I2C adapters.
		 */
		psmouse_dbg(smbdev->psmouse,
			    "SMBus candidate adapter appeared, triggering rescan\n");
		serio_rescan(smbdev->psmouse->ps2dev.serio);
	}
}

static void psmouse_smbus_detach_i2c_client(struct i2c_client *client)
{
	struct psmouse_smbus_dev *smbdev, *tmp;

	guard(mutex)(&psmouse_smbus_mutex);

	list_for_each_entry_safe(smbdev, tmp, &psmouse_smbus_list, node) {
		if (smbdev->client != client)
			continue;

		kfree(client->dev.platform_data);
		client->dev.platform_data = NULL;

		if (!smbdev->dead) {
			psmouse_dbg(smbdev->psmouse,
				    "Marking SMBus companion %s as gone\n",
				    dev_name(&smbdev->client->dev));
			smbdev->dead = true;
			device_link_remove(&smbdev->client->dev,
					   &smbdev->psmouse->ps2dev.serio->dev);
			serio_rescan(smbdev->psmouse->ps2dev.serio);
		} else {
			list_del(&smbdev->node);
			kfree(smbdev);
		}
	}
}

static int psmouse_smbus_notifier_call(struct notifier_block *nb,
				       unsigned long action, void *data)
{
	struct device *dev = data;

	switch (action) {
	case BUS_NOTIFY_ADD_DEVICE:
		if (dev->type == &i2c_adapter_type)
			psmouse_smbus_check_adapter(to_i2c_adapter(dev));
		break;

	case BUS_NOTIFY_REMOVED_DEVICE:
		if (dev->type == &i2c_client_type)
			psmouse_smbus_detach_i2c_client(to_i2c_client(dev));
		break;
	}

	return 0;
}

static struct notifier_block psmouse_smbus_notifier = {
	.notifier_call = psmouse_smbus_notifier_call,
};

static psmouse_ret_t psmouse_smbus_process_byte(struct psmouse *psmouse)
{
	return PSMOUSE_FULL_PACKET;
}

static int psmouse_smbus_reconnect(struct psmouse *psmouse)
{
	struct psmouse_smbus_dev *smbdev = psmouse->private;

	if (smbdev->need_deactivate)
		psmouse_deactivate(psmouse);

	return 0;
}

struct psmouse_smbus_removal_work {
	struct work_struct work;
	struct i2c_client *client;
};

static void psmouse_smbus_remove_i2c_device(struct work_struct *work)
{
	struct psmouse_smbus_removal_work *rwork =
		container_of(work, struct psmouse_smbus_removal_work, work);

	dev_dbg(&rwork->client->dev, "destroying SMBus companion device\n");
	i2c_unregister_device(rwork->client);

	kfree(rwork);
}

/*
 * This schedules removal of SMBus companion device. We have to do
 * it in a separate tread to avoid deadlocking on psmouse_mutex in
 * case the device has a trackstick (which is also driven by psmouse).
 *
 * Note that this may be racing with i2c adapter removal, but we
 * can't do anything about that: i2c automatically destroys clients
 * attached to an adapter that is being removed. This has to be
 * fixed in i2c core.
 */
static void psmouse_smbus_schedule_remove(struct i2c_client *client)
{
	struct psmouse_smbus_removal_work *rwork;

	rwork = kzalloc_obj(*rwork);
	if (rwork) {
		INIT_WORK(&rwork->work, psmouse_smbus_remove_i2c_device);
		rwork->client = client;

		queue_work(psmouse_smbus_wq, &rwork->work);
	}
}

static void psmouse_smbus_disconnect(struct psmouse *psmouse)
{
	struct psmouse_smbus_dev *smbdev = psmouse->private;

	guard(mutex)(&psmouse_smbus_mutex);

	if (smbdev->dead) {
		list_del(&smbdev->node);
		kfree(smbdev);
	} else {
		smbdev->dead = true;
		device_link_remove(&smbdev->client->dev,
				   &psmouse->ps2dev.serio->dev);
		psmouse_dbg(smbdev->psmouse,
			    "posting removal request for SMBus companion %s\n",
			    dev_name(&smbdev->client->dev));
		psmouse_smbus_schedule_remove(smbdev->client);
	}

	psmouse->private = NULL;
}

static int psmouse_smbus_create_companion(struct device *dev, void *data)
{
	struct psmouse_smbus_dev *smbdev = data;
	unsigned short addr_list[] = { smbdev->board.addr, I2C_CLIENT_END };
	struct i2c_adapter *adapter;
	struct i2c_client *client;

	adapter = i2c_verify_adapter(dev);
	if (!adapter)
		return 0;

	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_HOST_NOTIFY))
		return 0;

	client = i2c_new_scanned_device(adapter, &smbdev->board,
					addr_list, NULL);
	if (IS_ERR(client))
		return 0;

	/* We have our(?) device, stop iterating i2c bus. */
	smbdev->client = client;
	return 1;
}

void psmouse_smbus_cleanup(struct psmouse *psmouse)
{
	struct psmouse_smbus_dev *smbdev, *tmp;

	guard(mutex)(&psmouse_smbus_mutex);

	list_for_each_entry_safe(smbdev, tmp, &psmouse_smbus_list, node) {
		if (psmouse == smbdev->psmouse) {
			list_del(&smbdev->node);
			kfree(smbdev);
		}
	}
}

int psmouse_smbus_init(struct psmouse *psmouse,
		       const struct i2c_board_info *board,
		       const void *pdata, size_t pdata_size,
		       bool need_deactivate,
		       bool leave_breadcrumbs)
{
	struct psmouse_smbus_dev *smbdev;
	int error;

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

	smbdev->psmouse = psmouse;
	smbdev->board = *board;
	smbdev->need_deactivate = need_deactivate;

	if (pdata) {
		smbdev->board.platform_data = kmemdup(pdata, pdata_size,
						      GFP_KERNEL);
		if (!smbdev->board.platform_data) {
			kfree(smbdev);
			return -ENOMEM;
		}
	}

	if (need_deactivate)
		psmouse_deactivate(psmouse);

	psmouse->private = smbdev;
	psmouse->protocol_handler = psmouse_smbus_process_byte;
	psmouse->reconnect = psmouse_smbus_reconnect;
	psmouse->fast_reconnect = psmouse_smbus_reconnect;
	psmouse->disconnect = psmouse_smbus_disconnect;
	psmouse->resync_time = 0;

	scoped_guard(mutex, &psmouse_smbus_mutex) {
		list_add_tail(&smbdev->node, &psmouse_smbus_list);
	}

	/* Bind to already existing adapters right away */
	error = i2c_for_each_dev(smbdev, psmouse_smbus_create_companion);

	if (smbdev->client) {
		/* We have our companion device */
		if (!device_link_add(&smbdev->client->dev,
				     &psmouse->ps2dev.serio->dev,
				     DL_FLAG_STATELESS))
			psmouse_warn(psmouse,
				     "failed to set up link with iSMBus companion %s\n",
				     dev_name(&smbdev->client->dev));
		return 0;
	}

	/*
	 * If we did not create i2c device we will not need platform
	 * data even if we are leaving breadcrumbs.
	 */
	kfree(smbdev->board.platform_data);
	smbdev->board.platform_data = NULL;

	if (error < 0 || !leave_breadcrumbs) {
		scoped_guard(mutex, &psmouse_smbus_mutex) {
			list_del(&smbdev->node);
		}

		kfree(smbdev);
	}

	return error < 0 ? error : -EAGAIN;
}

int __init psmouse_smbus_module_init(void)
{
	int error;

	psmouse_smbus_wq = alloc_workqueue("psmouse-smbus", WQ_UNBOUND, 0);
	if (!psmouse_smbus_wq)
		return -ENOMEM;

	error = bus_register_notifier(&i2c_bus_type, &psmouse_smbus_notifier);
	if (error) {
		pr_err("failed to register i2c bus notifier: %d\n", error);
		destroy_workqueue(psmouse_smbus_wq);
		return error;
	}

	return 0;
}

void psmouse_smbus_module_exit(void)
{
	bus_unregister_notifier(&i2c_bus_type, &psmouse_smbus_notifier);
	destroy_workqueue(psmouse_smbus_wq);
}
