// SPDX-License-Identifier: GPL-2.0-only
// Copyright (c) 2018-2021 Intel Corporation

#include <linux/bitfield.h>
#include <linux/peci.h>
#include <linux/peci-cpu.h>
#include <linux/slab.h>

#include "internal.h"

/*
 * PECI device can be removed using sysfs, but the removal can also happen as
 * a result of controller being removed.
 * Mutex is used to protect PECI device from being double-deleted.
 */
static DEFINE_MUTEX(peci_device_del_lock);

#define REVISION_NUM_MASK GENMASK(15, 8)
static int peci_get_revision(struct peci_device *device, u8 *revision)
{
	struct peci_request *req;
	u64 dib;

	req = peci_xfer_get_dib(device);
	if (IS_ERR(req))
		return PTR_ERR(req);

	/*
	 * PECI device may be in a state where it is unable to return a proper
	 * DIB, in which case it returns 0 as DIB value.
	 * Let's treat this as an error to avoid carrying on with the detection
	 * using invalid revision.
	 */
	dib = peci_request_dib_read(req);
	if (dib == 0) {
		peci_request_free(req);
		return -EIO;
	}

	*revision = FIELD_GET(REVISION_NUM_MASK, dib);

	peci_request_free(req);

	return 0;
}

static int peci_get_cpu_id(struct peci_device *device, u32 *cpu_id)
{
	struct peci_request *req;
	int ret;

	req = peci_xfer_pkg_cfg_readl(device, PECI_PCS_PKG_ID, PECI_PKG_ID_CPU_ID);
	if (IS_ERR(req))
		return PTR_ERR(req);

	ret = peci_request_status(req);
	if (ret)
		goto out_req_free;

	*cpu_id = peci_request_data_readl(req);
out_req_free:
	peci_request_free(req);

	return ret;
}

static unsigned int peci_x86_cpu_family(unsigned int sig)
{
	unsigned int x86;

	x86 = (sig >> 8) & 0xf;

	if (x86 == 0xf)
		x86 += (sig >> 20) & 0xff;

	return x86;
}

static unsigned int peci_x86_cpu_model(unsigned int sig)
{
	unsigned int fam, model;

	fam = peci_x86_cpu_family(sig);

	model = (sig >> 4) & 0xf;

	if (fam >= 0x6)
		model += ((sig >> 16) & 0xf) << 4;

	return model;
}

static int peci_device_info_init(struct peci_device *device)
{
	u8 revision;
	u32 cpu_id;
	int ret;

	ret = peci_get_cpu_id(device, &cpu_id);
	if (ret)
		return ret;

	device->info.family = peci_x86_cpu_family(cpu_id);
	device->info.model = peci_x86_cpu_model(cpu_id);

	ret = peci_get_revision(device, &revision);
	if (ret)
		return ret;
	device->info.peci_revision = revision;

	device->info.socket_id = device->addr - PECI_BASE_ADDR;

	return 0;
}

static int peci_detect(struct peci_controller *controller, u8 addr)
{
	/*
	 * PECI Ping is a command encoded by tx_len = 0, rx_len = 0.
	 * We expect correct Write FCS if the device at the target address
	 * is able to respond.
	 */
	struct peci_request req = { 0 };
	int ret;

	mutex_lock(&controller->bus_lock);
	ret = controller->ops->xfer(controller, addr, &req);
	mutex_unlock(&controller->bus_lock);

	return ret;
}

static bool peci_addr_valid(u8 addr)
{
	return addr >= PECI_BASE_ADDR && addr < PECI_BASE_ADDR + PECI_DEVICE_NUM_MAX;
}

static int peci_dev_exists(struct device *dev, void *data)
{
	struct peci_device *device = to_peci_device(dev);
	u8 *addr = data;

	if (device->addr == *addr)
		return -EBUSY;

	return 0;
}

int peci_device_create(struct peci_controller *controller, u8 addr)
{
	struct peci_device *device;
	int ret;

	if (!peci_addr_valid(addr))
		return -EINVAL;

	/* Check if we have already detected this device before. */
	ret = device_for_each_child(&controller->dev, &addr, peci_dev_exists);
	if (ret)
		return 0;

	ret = peci_detect(controller, addr);
	if (ret) {
		/*
		 * Device not present or host state doesn't allow successful
		 * detection at this time.
		 */
		if (ret == -EIO || ret == -ETIMEDOUT)
			return 0;

		return ret;
	}

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

	device_initialize(&device->dev);

	device->addr = addr;
	device->dev.parent = &controller->dev;
	device->dev.bus = &peci_bus_type;
	device->dev.type = &peci_device_type;

	ret = peci_device_info_init(device);
	if (ret)
		goto err_put;

	ret = dev_set_name(&device->dev, "%d-%02x", controller->id, device->addr);
	if (ret)
		goto err_put;

	ret = device_add(&device->dev);
	if (ret)
		goto err_put;

	return 0;

err_put:
	put_device(&device->dev);

	return ret;
}

void peci_device_destroy(struct peci_device *device)
{
	mutex_lock(&peci_device_del_lock);
	if (!device->deleted) {
		device_unregister(&device->dev);
		device->deleted = true;
	}
	mutex_unlock(&peci_device_del_lock);
}

int __peci_driver_register(struct peci_driver *driver, struct module *owner,
			   const char *mod_name)
{
	driver->driver.bus = &peci_bus_type;
	driver->driver.owner = owner;
	driver->driver.mod_name = mod_name;

	if (!driver->probe) {
		pr_err("peci: trying to register driver without probe callback\n");
		return -EINVAL;
	}

	if (!driver->id_table) {
		pr_err("peci: trying to register driver without device id table\n");
		return -EINVAL;
	}

	return driver_register(&driver->driver);
}
EXPORT_SYMBOL_NS_GPL(__peci_driver_register, PECI);

void peci_driver_unregister(struct peci_driver *driver)
{
	driver_unregister(&driver->driver);
}
EXPORT_SYMBOL_NS_GPL(peci_driver_unregister, PECI);

static void peci_device_release(struct device *dev)
{
	struct peci_device *device = to_peci_device(dev);

	kfree(device);
}

struct device_type peci_device_type = {
	.groups		= peci_device_groups,
	.release	= peci_device_release,
};
