// 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 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;

	mutex_lock(&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);
	}

	mutex_unlock(&psmouse_smbus_mutex);
}

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

	mutex_lock(&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);
		}
	}

	mutex_unlock(&psmouse_smbus_mutex);
}

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(sizeof(*rwork), GFP_KERNEL);
	if (rwork) {
		INIT_WORK(&rwork->work, psmouse_smbus_remove_i2c_device);
		rwork->client = client;

		schedule_work(&rwork->work);
	}
}

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

	mutex_lock(&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);
	}

	mutex_unlock(&psmouse_smbus_mutex);

	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;

	mutex_lock(&psmouse_smbus_mutex);

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

	mutex_unlock(&psmouse_smbus_mutex);
}

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;

	mutex_lock(&psmouse_smbus_mutex);
	list_add_tail(&smbdev->node, &psmouse_smbus_list);
	mutex_unlock(&psmouse_smbus_mutex);

	/* 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) {
		mutex_lock(&psmouse_smbus_mutex);
		list_del(&smbdev->node);
		mutex_unlock(&psmouse_smbus_mutex);

		kfree(smbdev);
	}

	return error < 0 ? error : -EAGAIN;
}

int __init psmouse_smbus_module_init(void)
{
	int error;

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

	return 0;
}

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