// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright IBM Corp. 2020
 *
 * Author(s):
 *   Pierre Morel <pmorel@linux.ibm.com>
 *
 */

#define KMSG_COMPONENT "zpci"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt

#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/export.h>
#include <linux/delay.h>
#include <linux/seq_file.h>
#include <linux/jump_label.h>
#include <linux/pci.h>
#include <linux/printk.h>

#include <asm/pci_clp.h>
#include <asm/pci_dma.h>

#include "pci_bus.h"
#include "pci_iov.h"

static LIST_HEAD(zbus_list);
static DEFINE_SPINLOCK(zbus_list_lock);
static int zpci_nb_devices;

/* zpci_bus_scan
 * @zbus: the zbus holding the zdevices
 * @ops: the pci operations
 *
 * The domain number must be set before pci_scan_root_bus is called.
 * This function can be called once the domain is known, hence
 * when the function_0 is dicovered.
 */
static int zpci_bus_scan(struct zpci_bus *zbus, int domain, struct pci_ops *ops)
{
	struct pci_bus *bus;
	int rc;

	rc = zpci_alloc_domain(domain);
	if (rc < 0)
		return rc;
	zbus->domain_nr = rc;

	bus = pci_scan_root_bus(NULL, ZPCI_BUS_NR, ops, zbus, &zbus->resources);
	if (!bus) {
		zpci_free_domain(zbus->domain_nr);
		return -EFAULT;
	}

	zbus->bus = bus;
	pci_bus_add_devices(bus);
	return 0;
}

static void zpci_bus_release(struct kref *kref)
{
	struct zpci_bus *zbus = container_of(kref, struct zpci_bus, kref);

	if (zbus->bus) {
		pci_lock_rescan_remove();
		pci_stop_root_bus(zbus->bus);

		zpci_free_domain(zbus->domain_nr);
		pci_free_resource_list(&zbus->resources);

		pci_remove_root_bus(zbus->bus);
		pci_unlock_rescan_remove();
	}

	spin_lock(&zbus_list_lock);
	list_del(&zbus->bus_next);
	spin_unlock(&zbus_list_lock);
	kfree(zbus);
}

static void zpci_bus_put(struct zpci_bus *zbus)
{
	kref_put(&zbus->kref, zpci_bus_release);
}

static struct zpci_bus *zpci_bus_get(int pchid)
{
	struct zpci_bus *zbus;

	spin_lock(&zbus_list_lock);
	list_for_each_entry(zbus, &zbus_list, bus_next) {
		if (pchid == zbus->pchid) {
			kref_get(&zbus->kref);
			goto out_unlock;
		}
	}
	zbus = NULL;
out_unlock:
	spin_unlock(&zbus_list_lock);
	return zbus;
}

static struct zpci_bus *zpci_bus_alloc(int pchid)
{
	struct zpci_bus *zbus;

	zbus = kzalloc(sizeof(*zbus), GFP_KERNEL);
	if (!zbus)
		return NULL;

	zbus->pchid = pchid;
	INIT_LIST_HEAD(&zbus->bus_next);
	spin_lock(&zbus_list_lock);
	list_add_tail(&zbus->bus_next, &zbus_list);
	spin_unlock(&zbus_list_lock);

	kref_init(&zbus->kref);
	INIT_LIST_HEAD(&zbus->resources);

	zbus->bus_resource.start = 0;
	zbus->bus_resource.end = ZPCI_BUS_NR;
	zbus->bus_resource.flags = IORESOURCE_BUS;
	pci_add_resource(&zbus->resources, &zbus->bus_resource);

	return zbus;
}

void pcibios_bus_add_device(struct pci_dev *pdev)
{
	struct zpci_dev *zdev = to_zpci(pdev);

	/*
	 * With pdev->no_vf_scan the common PCI probing code does not
	 * perform PF/VF linking.
	 */
	if (zdev->vfn)
		zpci_iov_setup_virtfn(zdev->zbus, pdev, zdev->vfn);

}

static int zpci_bus_add_device(struct zpci_bus *zbus, struct zpci_dev *zdev)
{
	struct pci_bus *bus;
	struct resource_entry *window, *n;
	struct resource *res;
	struct pci_dev *pdev;
	int rc;

	bus = zbus->bus;
	if (!bus)
		return -EINVAL;

	pdev = pci_get_slot(bus, zdev->devfn);
	if (pdev) {
		/* Device is already known. */
		pci_dev_put(pdev);
		return 0;
	}

	rc = zpci_init_slot(zdev);
	if (rc)
		return rc;
	zdev->has_hp_slot = 1;

	resource_list_for_each_entry_safe(window, n, &zbus->resources) {
		res = window->res;
		pci_bus_add_resource(bus, res, 0);
	}

	pdev = pci_scan_single_device(bus, zdev->devfn);
	if (pdev)
		pci_bus_add_device(pdev);

	return 0;
}

static void zpci_bus_add_devices(struct zpci_bus *zbus)
{
	int i;

	for (i = 1; i < ZPCI_FUNCTIONS_PER_BUS; i++)
		if (zbus->function[i])
			zpci_bus_add_device(zbus, zbus->function[i]);

	pci_lock_rescan_remove();
	pci_bus_add_devices(zbus->bus);
	pci_unlock_rescan_remove();
}

int zpci_bus_device_register(struct zpci_dev *zdev, struct pci_ops *ops)
{
	struct zpci_bus *zbus = NULL;
	int rc = -EBADF;

	if (zpci_nb_devices == ZPCI_NR_DEVICES) {
		pr_warn("Adding PCI function %08x failed because the configured limit of %d is reached\n",
			zdev->fid, ZPCI_NR_DEVICES);
		return -ENOSPC;
	}
	zpci_nb_devices++;

	if (zdev->devfn >= ZPCI_FUNCTIONS_PER_BUS)
		return -EINVAL;

	if (!s390_pci_no_rid && zdev->rid_available)
		zbus = zpci_bus_get(zdev->pchid);

	if (!zbus) {
		zbus = zpci_bus_alloc(zdev->pchid);
		if (!zbus)
			return -ENOMEM;
	}

	zdev->zbus = zbus;
	if (zbus->function[zdev->devfn]) {
		pr_err("devfn %04x is already assigned\n", zdev->devfn);
		goto error; /* rc already set */
	}
	zbus->function[zdev->devfn] = zdev;

	zpci_setup_bus_resources(zdev, &zbus->resources);

	if (zbus->bus) {
		if (!zbus->multifunction) {
			WARN_ONCE(1, "zbus is not multifunction\n");
			goto error_bus;
		}
		if (!zdev->rid_available) {
			WARN_ONCE(1, "rid_available not set for multifunction\n");
			goto error_bus;
		}
		rc = zpci_bus_add_device(zbus, zdev);
		if (rc)
			goto error_bus;
	} else if (zdev->devfn == 0) {
		if (zbus->multifunction && !zdev->rid_available) {
			WARN_ONCE(1, "rid_available not set on function 0 for multifunction\n");
			goto error_bus;
		}
		rc = zpci_bus_scan(zbus, (u16)zdev->uid, ops);
		if (rc)
			goto error_bus;
		zpci_bus_add_devices(zbus);
		rc = zpci_init_slot(zdev);
		if (rc)
			goto error_bus;
		zdev->has_hp_slot = 1;
		zbus->multifunction = zdev->rid_available;
		zbus->max_bus_speed = zdev->max_bus_speed;
	} else {
		zbus->multifunction = 1;
	}

	return 0;

error_bus:
	zpci_nb_devices--;
	zbus->function[zdev->devfn] = NULL;
error:
	pr_err("Adding PCI function %08x failed\n", zdev->fid);
	zpci_bus_put(zbus);
	return rc;
}

void zpci_bus_device_unregister(struct zpci_dev *zdev)
{
	struct zpci_bus *zbus = zdev->zbus;

	zpci_nb_devices--;
	zbus->function[zdev->devfn] = NULL;
	zpci_bus_put(zbus);
}
