/*
 * The file intends to implement PE based on the information from
 * platforms. Basically, there have 3 types of PEs: PHB/Bus/Device.
 * All the PEs should be organized as hierarchy tree. The first level
 * of the tree will be associated to existing PHBs since the particular
 * PE is only meaningful in one PHB domain.
 *
 * Copyright Benjamin Herrenschmidt & Gavin Shan, IBM Corporation 2012.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 */

#include <linux/export.h>
#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/string.h>

#include <asm/pci-bridge.h>
#include <asm/ppc-pci.h>

static LIST_HEAD(eeh_phb_pe);

/**
 * eeh_pe_alloc - Allocate PE
 * @phb: PCI controller
 * @type: PE type
 *
 * Allocate PE instance dynamically.
 */
static struct eeh_pe *eeh_pe_alloc(struct pci_controller *phb, int type)
{
	struct eeh_pe *pe;

	/* Allocate PHB PE */
	pe = kzalloc(sizeof(struct eeh_pe), GFP_KERNEL);
	if (!pe) return NULL;

	/* Initialize PHB PE */
	pe->type = type;
	pe->phb = phb;
	INIT_LIST_HEAD(&pe->child_list);
	INIT_LIST_HEAD(&pe->child);
	INIT_LIST_HEAD(&pe->edevs);

	return pe;
}

/**
 * eeh_phb_pe_create - Create PHB PE
 * @phb: PCI controller
 *
 * The function should be called while the PHB is detected during
 * system boot or PCI hotplug in order to create PHB PE.
 */
int __devinit eeh_phb_pe_create(struct pci_controller *phb)
{
	struct eeh_pe *pe;

	/* Allocate PHB PE */
	pe = eeh_pe_alloc(phb, EEH_PE_PHB);
	if (!pe) {
		pr_err("%s: out of memory!\n", __func__);
		return -ENOMEM;
	}

	/* Put it into the list */
	eeh_lock();
	list_add_tail(&pe->child, &eeh_phb_pe);
	eeh_unlock();

	pr_debug("EEH: Add PE for PHB#%d\n", phb->global_number);

	return 0;
}

/**
 * eeh_phb_pe_get - Retrieve PHB PE based on the given PHB
 * @phb: PCI controller
 *
 * The overall PEs form hierarchy tree. The first layer of the
 * hierarchy tree is composed of PHB PEs. The function is used
 * to retrieve the corresponding PHB PE according to the given PHB.
 */
static struct eeh_pe *eeh_phb_pe_get(struct pci_controller *phb)
{
	struct eeh_pe *pe;

	list_for_each_entry(pe, &eeh_phb_pe, child) {
		/*
		 * Actually, we needn't check the type since
		 * the PE for PHB has been determined when that
		 * was created.
		 */
		if ((pe->type & EEH_PE_PHB) && pe->phb == phb)
			return pe;
	}

	return NULL;
}

/**
 * eeh_pe_next - Retrieve the next PE in the tree
 * @pe: current PE
 * @root: root PE
 *
 * The function is used to retrieve the next PE in the
 * hierarchy PE tree.
 */
static struct eeh_pe *eeh_pe_next(struct eeh_pe *pe,
				  struct eeh_pe *root)
{
	struct list_head *next = pe->child_list.next;

	if (next == &pe->child_list) {
		while (1) {
			if (pe == root)
				return NULL;
			next = pe->child.next;
			if (next != &pe->parent->child_list)
				break;
			pe = pe->parent;
		}
	}

	return list_entry(next, struct eeh_pe, child);
}

/**
 * eeh_pe_traverse - Traverse PEs in the specified PHB
 * @root: root PE
 * @fn: callback
 * @flag: extra parameter to callback
 *
 * The function is used to traverse the specified PE and its
 * child PEs. The traversing is to be terminated once the
 * callback returns something other than NULL, or no more PEs
 * to be traversed.
 */
static void *eeh_pe_traverse(struct eeh_pe *root,
			eeh_traverse_func fn, void *flag)
{
	struct eeh_pe *pe;
	void *ret;

	for (pe = root; pe; pe = eeh_pe_next(pe, root)) {
		ret = fn(pe, flag);
		if (ret) return ret;
	}

	return NULL;
}

/**
 * eeh_pe_dev_traverse - Traverse the devices from the PE
 * @root: EEH PE
 * @fn: function callback
 * @flag: extra parameter to callback
 *
 * The function is used to traverse the devices of the specified
 * PE and its child PEs.
 */
void *eeh_pe_dev_traverse(struct eeh_pe *root,
		eeh_traverse_func fn, void *flag)
{
	struct eeh_pe *pe;
	struct eeh_dev *edev;
	void *ret;

	if (!root) {
		pr_warning("%s: Invalid PE %p\n", __func__, root);
		return NULL;
	}

	eeh_lock();

	/* Traverse root PE */
	for (pe = root; pe; pe = eeh_pe_next(pe, root)) {
		eeh_pe_for_each_dev(pe, edev) {
			ret = fn(edev, flag);
			if (ret) {
				eeh_unlock();
				return ret;
			}
		}
	}

	eeh_unlock();

	return NULL;
}

/**
 * __eeh_pe_get - Check the PE address
 * @data: EEH PE
 * @flag: EEH device
 *
 * For one particular PE, it can be identified by PE address
 * or tranditional BDF address. BDF address is composed of
 * Bus/Device/Function number. The extra data referred by flag
 * indicates which type of address should be used.
 */
static void *__eeh_pe_get(void *data, void *flag)
{
	struct eeh_pe *pe = (struct eeh_pe *)data;
	struct eeh_dev *edev = (struct eeh_dev *)flag;

	/* Unexpected PHB PE */
	if (pe->type & EEH_PE_PHB)
		return NULL;

	/* We prefer PE address */
	if (edev->pe_config_addr &&
	   (edev->pe_config_addr == pe->addr))
		return pe;

	/* Try BDF address */
	if (edev->pe_config_addr &&
	   (edev->config_addr == pe->config_addr))
		return pe;

	return NULL;
}

/**
 * eeh_pe_get - Search PE based on the given address
 * @edev: EEH device
 *
 * Search the corresponding PE based on the specified address which
 * is included in the eeh device. The function is used to check if
 * the associated PE has been created against the PE address. It's
 * notable that the PE address has 2 format: traditional PE address
 * which is composed of PCI bus/device/function number, or unified
 * PE address.
 */
static struct eeh_pe *eeh_pe_get(struct eeh_dev *edev)
{
	struct eeh_pe *root = eeh_phb_pe_get(edev->phb);
	struct eeh_pe *pe;

	pe = eeh_pe_traverse(root, __eeh_pe_get, edev);

	return pe;
}

/**
 * eeh_pe_get_parent - Retrieve the parent PE
 * @edev: EEH device
 *
 * The whole PEs existing in the system are organized as hierarchy
 * tree. The function is used to retrieve the parent PE according
 * to the parent EEH device.
 */
static struct eeh_pe *eeh_pe_get_parent(struct eeh_dev *edev)
{
	struct device_node *dn;
	struct eeh_dev *parent;

	/*
	 * It might have the case for the indirect parent
	 * EEH device already having associated PE, but
	 * the direct parent EEH device doesn't have yet.
	 */
	dn = edev->dn->parent;
	while (dn) {
		/* We're poking out of PCI territory */
		if (!PCI_DN(dn)) return NULL;

		parent = of_node_to_eeh_dev(dn);
		/* We're poking out of PCI territory */
		if (!parent) return NULL;

		if (parent->pe)
			return parent->pe;

		dn = dn->parent;
	}

	return NULL;
}

/**
 * eeh_add_to_parent_pe - Add EEH device to parent PE
 * @edev: EEH device
 *
 * Add EEH device to the parent PE. If the parent PE already
 * exists, the PE type will be changed to EEH_PE_BUS. Otherwise,
 * we have to create new PE to hold the EEH device and the new
 * PE will be linked to its parent PE as well.
 */
int eeh_add_to_parent_pe(struct eeh_dev *edev)
{
	struct eeh_pe *pe, *parent;

	eeh_lock();

	/*
	 * Search the PE has been existing or not according
	 * to the PE address. If that has been existing, the
	 * PE should be composed of PCI bus and its subordinate
	 * components.
	 */
	pe = eeh_pe_get(edev);
	if (pe && !(pe->type & EEH_PE_INVALID)) {
		if (!edev->pe_config_addr) {
			eeh_unlock();
			pr_err("%s: PE with addr 0x%x already exists\n",
				__func__, edev->config_addr);
			return -EEXIST;
		}

		/* Mark the PE as type of PCI bus */
		pe->type = EEH_PE_BUS;
		edev->pe = pe;

		/* Put the edev to PE */
		list_add_tail(&edev->list, &pe->edevs);
		eeh_unlock();
		pr_debug("EEH: Add %s to Bus PE#%x\n",
			edev->dn->full_name, pe->addr);

		return 0;
	} else if (pe && (pe->type & EEH_PE_INVALID)) {
		list_add_tail(&edev->list, &pe->edevs);
		edev->pe = pe;
		/*
		 * We're running to here because of PCI hotplug caused by
		 * EEH recovery. We need clear EEH_PE_INVALID until the top.
		 */
		parent = pe;
		while (parent) {
			if (!(parent->type & EEH_PE_INVALID))
				break;
			parent->type &= ~EEH_PE_INVALID;
			parent = parent->parent;
		}
		eeh_unlock();
		pr_debug("EEH: Add %s to Device PE#%x, Parent PE#%x\n",
			edev->dn->full_name, pe->addr, pe->parent->addr);

		return 0;
	}

	/* Create a new EEH PE */
	pe = eeh_pe_alloc(edev->phb, EEH_PE_DEVICE);
	if (!pe) {
		eeh_unlock();
		pr_err("%s: out of memory!\n", __func__);
		return -ENOMEM;
	}
	pe->addr	= edev->pe_config_addr;
	pe->config_addr	= edev->config_addr;

	/*
	 * Put the new EEH PE into hierarchy tree. If the parent
	 * can't be found, the newly created PE will be attached
	 * to PHB directly. Otherwise, we have to associate the
	 * PE with its parent.
	 */
	parent = eeh_pe_get_parent(edev);
	if (!parent) {
		parent = eeh_phb_pe_get(edev->phb);
		if (!parent) {
			eeh_unlock();
			pr_err("%s: No PHB PE is found (PHB Domain=%d)\n",
				__func__, edev->phb->global_number);
			edev->pe = NULL;
			kfree(pe);
			return -EEXIST;
		}
	}
	pe->parent = parent;

	/*
	 * Put the newly created PE into the child list and
	 * link the EEH device accordingly.
	 */
	list_add_tail(&pe->child, &parent->child_list);
	list_add_tail(&edev->list, &pe->edevs);
	edev->pe = pe;
	eeh_unlock();
	pr_debug("EEH: Add %s to Device PE#%x, Parent PE#%x\n",
		edev->dn->full_name, pe->addr, pe->parent->addr);

	return 0;
}

/**
 * eeh_rmv_from_parent_pe - Remove one EEH device from the associated PE
 * @edev: EEH device
 * @purge_pe: remove PE or not
 *
 * The PE hierarchy tree might be changed when doing PCI hotplug.
 * Also, the PCI devices or buses could be removed from the system
 * during EEH recovery. So we have to call the function remove the
 * corresponding PE accordingly if necessary.
 */
int eeh_rmv_from_parent_pe(struct eeh_dev *edev, int purge_pe)
{
	struct eeh_pe *pe, *parent, *child;
	int cnt;

	if (!edev->pe) {
		pr_warning("%s: No PE found for EEH device %s\n",
			__func__, edev->dn->full_name);
		return -EEXIST;
	}

	eeh_lock();

	/* Remove the EEH device */
	pe = edev->pe;
	edev->pe = NULL;
	list_del(&edev->list);

	/*
	 * Check if the parent PE includes any EEH devices.
	 * If not, we should delete that. Also, we should
	 * delete the parent PE if it doesn't have associated
	 * child PEs and EEH devices.
	 */
	while (1) {
		parent = pe->parent;
		if (pe->type & EEH_PE_PHB)
			break;

		if (purge_pe) {
			if (list_empty(&pe->edevs) &&
			    list_empty(&pe->child_list)) {
				list_del(&pe->child);
				kfree(pe);
			} else {
				break;
			}
		} else {
			if (list_empty(&pe->edevs)) {
				cnt = 0;
				list_for_each_entry(child, &pe->child_list, child) {
					if (!(child->type & EEH_PE_INVALID)) {
						cnt++;
						break;
					}
				}

				if (!cnt)
					pe->type |= EEH_PE_INVALID;
				else
					break;
			}
		}

		pe = parent;
	}

	eeh_unlock();

	return 0;
}

/**
 * __eeh_pe_state_mark - Mark the state for the PE
 * @data: EEH PE
 * @flag: state
 *
 * The function is used to mark the indicated state for the given
 * PE. Also, the associated PCI devices will be put into IO frozen
 * state as well.
 */
static void *__eeh_pe_state_mark(void *data, void *flag)
{
	struct eeh_pe *pe = (struct eeh_pe *)data;
	int state = *((int *)flag);
	struct eeh_dev *tmp;
	struct pci_dev *pdev;

	/*
	 * Mark the PE with the indicated state. Also,
	 * the associated PCI device will be put into
	 * I/O frozen state to avoid I/O accesses from
	 * the PCI device driver.
	 */
	pe->state |= state;
	eeh_pe_for_each_dev(pe, tmp) {
		pdev = eeh_dev_to_pci_dev(tmp);
		if (pdev)
			pdev->error_state = pci_channel_io_frozen;
	}

	return NULL;
}

/**
 * eeh_pe_state_mark - Mark specified state for PE and its associated device
 * @pe: EEH PE
 *
 * EEH error affects the current PE and its child PEs. The function
 * is used to mark appropriate state for the affected PEs and the
 * associated devices.
 */
void eeh_pe_state_mark(struct eeh_pe *pe, int state)
{
	eeh_lock();
	eeh_pe_traverse(pe, __eeh_pe_state_mark, &state);
	eeh_unlock();
}

/**
 * __eeh_pe_state_clear - Clear state for the PE
 * @data: EEH PE
 * @flag: state
 *
 * The function is used to clear the indicated state from the
 * given PE. Besides, we also clear the check count of the PE
 * as well.
 */
static void *__eeh_pe_state_clear(void *data, void *flag)
{
	struct eeh_pe *pe = (struct eeh_pe *)data;
	int state = *((int *)flag);

	pe->state &= ~state;
	pe->check_count = 0;

	return NULL;
}

/**
 * eeh_pe_state_clear - Clear state for the PE and its children
 * @pe: PE
 * @state: state to be cleared
 *
 * When the PE and its children has been recovered from error,
 * we need clear the error state for that. The function is used
 * for the purpose.
 */
void eeh_pe_state_clear(struct eeh_pe *pe, int state)
{
	eeh_lock();
	eeh_pe_traverse(pe, __eeh_pe_state_clear, &state);
	eeh_unlock();
}

/**
 * eeh_restore_one_device_bars - Restore the Base Address Registers for one device
 * @data: EEH device
 * @flag: Unused
 *
 * Loads the PCI configuration space base address registers,
 * the expansion ROM base address, the latency timer, and etc.
 * from the saved values in the device node.
 */
static void *eeh_restore_one_device_bars(void *data, void *flag)
{
	int i;
	u32 cmd;
	struct eeh_dev *edev = (struct eeh_dev *)data;
	struct device_node *dn = eeh_dev_to_of_node(edev);

	for (i = 4; i < 10; i++)
		eeh_ops->write_config(dn, i*4, 4, edev->config_space[i]);
	/* 12 == Expansion ROM Address */
	eeh_ops->write_config(dn, 12*4, 4, edev->config_space[12]);

#define BYTE_SWAP(OFF) (8*((OFF)/4)+3-(OFF))
#define SAVED_BYTE(OFF) (((u8 *)(edev->config_space))[BYTE_SWAP(OFF)])

	eeh_ops->write_config(dn, PCI_CACHE_LINE_SIZE, 1,
		SAVED_BYTE(PCI_CACHE_LINE_SIZE));
	eeh_ops->write_config(dn, PCI_LATENCY_TIMER, 1,
		SAVED_BYTE(PCI_LATENCY_TIMER));

	/* max latency, min grant, interrupt pin and line */
	eeh_ops->write_config(dn, 15*4, 4, edev->config_space[15]);

	/*
	 * Restore PERR & SERR bits, some devices require it,
	 * don't touch the other command bits
	 */
	eeh_ops->read_config(dn, PCI_COMMAND, 4, &cmd);
	if (edev->config_space[1] & PCI_COMMAND_PARITY)
		cmd |= PCI_COMMAND_PARITY;
	else
		cmd &= ~PCI_COMMAND_PARITY;
	if (edev->config_space[1] & PCI_COMMAND_SERR)
		cmd |= PCI_COMMAND_SERR;
	else
		cmd &= ~PCI_COMMAND_SERR;
	eeh_ops->write_config(dn, PCI_COMMAND, 4, cmd);

	return NULL;
}

/**
 * eeh_pe_restore_bars - Restore the PCI config space info
 * @pe: EEH PE
 *
 * This routine performs a recursive walk to the children
 * of this device as well.
 */
void eeh_pe_restore_bars(struct eeh_pe *pe)
{
	/*
	 * We needn't take the EEH lock since eeh_pe_dev_traverse()
	 * will take that.
	 */
	eeh_pe_dev_traverse(pe, eeh_restore_one_device_bars, NULL);
}

/**
 * eeh_pe_bus_get - Retrieve PCI bus according to the given PE
 * @pe: EEH PE
 *
 * Retrieve the PCI bus according to the given PE. Basically,
 * there're 3 types of PEs: PHB/Bus/Device. For PHB PE, the
 * primary PCI bus will be retrieved. The parent bus will be
 * returned for BUS PE. However, we don't have associated PCI
 * bus for DEVICE PE.
 */
struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe)
{
	struct pci_bus *bus = NULL;
	struct eeh_dev *edev;
	struct pci_dev *pdev;

	eeh_lock();

	if (pe->type & EEH_PE_PHB) {
		bus = pe->phb->bus;
	} else if (pe->type & EEH_PE_BUS) {
		edev = list_first_entry(&pe->edevs, struct eeh_dev, list);
		pdev = eeh_dev_to_pci_dev(edev);
		if (pdev)
			bus = pdev->bus;
	}

	eeh_unlock();

	return bus;
}
