// 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.x86_vfm = IFM(peci_x86_cpu_family(cpu_id), 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_obj(*device);
	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);
}

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