/* Copyright 2013-2014 IBM Corp.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * 	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <skiboot.h>
#include <p7ioc.h>
#include <p7ioc-regs.h>
#include <cec.h>
#include <opal.h>
#include <io.h>
#include <vpd.h>
#include <interrupts.h>
#include <ccan/str/str.h>

/*
 * Determine the base address of LEM registers according to
 * the indicated error source.
 */
static void *p7ioc_LEM_base(struct p7ioc *ioc, uint32_t err_src)
{
	uint32_t index;
	void *base = NULL;

	switch (err_src) {
	case P7IOC_ERR_SRC_RGC:
		base = ioc->regs + P7IOC_RGC_LEM_BASE;
		break;
	case P7IOC_ERR_SRC_BI_UP:
		base = ioc->regs + P7IOC_BI_UP_LEM_BASE;
		break;
	case P7IOC_ERR_SRC_BI_DOWN:
		base = ioc->regs + P7IOC_BI_DOWN_LEM_BASE;
		break;
	case P7IOC_ERR_SRC_CI_P0:
	case P7IOC_ERR_SRC_CI_P1:
	case P7IOC_ERR_SRC_CI_P2:
	case P7IOC_ERR_SRC_CI_P3:
	case P7IOC_ERR_SRC_CI_P4:
	case P7IOC_ERR_SRC_CI_P5:
	case P7IOC_ERR_SRC_CI_P6:
	case P7IOC_ERR_SRC_CI_P7:
		index = err_src - P7IOC_ERR_SRC_CI_P0;
		base = ioc->regs + P7IOC_CI_PORTn_LEM_BASE(index);
		break;
	case P7IOC_ERR_SRC_PHB0:
	case P7IOC_ERR_SRC_PHB1:
	case P7IOC_ERR_SRC_PHB2:
	case P7IOC_ERR_SRC_PHB3:
	case P7IOC_ERR_SRC_PHB4:
	case P7IOC_ERR_SRC_PHB5:
		index = err_src - P7IOC_ERR_SRC_PHB0;
		base = ioc->regs + P7IOC_PHBn_LEM_BASE(index);
		break;
	case P7IOC_ERR_SRC_MISC:
		base = ioc->regs + P7IOC_MISC_LEM_BASE;
		break;
	case P7IOC_ERR_SRC_I2C:
		base = ioc->regs + P7IOC_I2C_LEM_BASE;
		break;
	default:
		prerror("%s: Unknown error source %d\n",
			__func__, err_src);
	}

	return base;
}

static void p7ioc_get_diag_common(struct p7ioc *ioc,
				  void *base,
				  struct OpalIoP7IOCErrorData *data)
{
	/* GEM */
	data->gemXfir    = in_be64(ioc->regs + P7IOC_GEM_XFIR);
	data->gemRfir    = in_be64(ioc->regs + P7IOC_GEM_RFIR);
	data->gemRirqfir = in_be64(ioc->regs + P7IOC_GEM_RIRQFIR);
	data->gemMask    = in_be64(ioc->regs + P7IOC_GEM_MASK);
	data->gemRwof    = in_be64(ioc->regs + P7IOC_GEM_RWOF);

	/* LEM */
	data->lemFir     = in_be64(base + P7IOC_LEM_FIR_OFFSET);
	data->lemErrMask = in_be64(base + P7IOC_LEM_ERR_MASK_OFFSET);
	data->lemAction0 = in_be64(base + P7IOC_LEM_ACTION_0_OFFSET);
	data->lemAction1 = in_be64(base + P7IOC_LEM_ACTION_1_OFFSET);
	data->lemWof     = in_be64(base + P7IOC_LEM_WOF_OFFSET);
}

static int64_t p7ioc_get_diag_data(struct io_hub *hub,
				   void *diag_buffer,
				   uint64_t diag_buffer_len)
{
	struct p7ioc *ioc = iohub_to_p7ioc(hub);
	struct OpalIoP7IOCErrorData *data = diag_buffer;
	void *base;

	/* Make sure we have enough buffer */
	if (diag_buffer_len < sizeof(struct OpalIoP7IOCErrorData))
		return OPAL_PARAMETER;

	/* We need do nothing if there're no pending errors */
	if (!p7ioc_err_pending(ioc))
		return OPAL_CLOSED;

	/*
	 * We needn't collect diag-data for CI Port{2, ..., 7}
	 * and PHB{0, ..., 5} since their errors (except GXE)
	 * have been cached to the specific PHB.
	 */
	base = p7ioc_LEM_base(ioc, ioc->err.err_src);
	if (!base) {
		p7ioc_set_err_pending(ioc, false);
		return OPAL_INTERNAL_ERROR;
	}

	switch (ioc->err.err_src) {
	case P7IOC_ERR_SRC_RGC:
		data->type = OPAL_P7IOC_DIAG_TYPE_RGC;
		p7ioc_get_diag_common(ioc, base, data);

		data->rgc.rgcStatus	= in_be64(ioc->regs + 0x3E1C10);
		data->rgc.rgcLdcp	= in_be64(ioc->regs + 0x3E1C18);

		break;
	case P7IOC_ERR_SRC_BI_UP:
		data->type = OPAL_P7IOC_DIAG_TYPE_BI;
		data->bi.biDownbound = 0;
		p7ioc_get_diag_common(ioc, base, data);

		data->bi.biLdcp0	= in_be64(ioc->regs + 0x3C0100);
		data->bi.biLdcp1	= in_be64(ioc->regs + 0x3C0108);
		data->bi.biLdcp2	= in_be64(ioc->regs + 0x3C0110);
		data->bi.biFenceStatus	= in_be64(ioc->regs + 0x3C0130);

		break;
	case P7IOC_ERR_SRC_BI_DOWN:
		data->type = OPAL_P7IOC_DIAG_TYPE_BI;
		data->bi.biDownbound = 1;
		p7ioc_get_diag_common(ioc, base, data);

		data->bi.biLdcp0	= in_be64(ioc->regs + 0x3C0118);
		data->bi.biLdcp1	= in_be64(ioc->regs + 0x3C0120);
		data->bi.biLdcp2	= in_be64(ioc->regs + 0x3C0128);
		data->bi.biFenceStatus	= in_be64(ioc->regs + 0x3C0130);

		break;
	case P7IOC_ERR_SRC_CI_P0:
	case P7IOC_ERR_SRC_CI_P1:
		data->type = OPAL_P7IOC_DIAG_TYPE_CI;
		data->ci.ciPort = ioc->err.err_src - P7IOC_ERR_SRC_CI_P0;
		p7ioc_get_diag_common(ioc, base, data);

		data->ci.ciPortStatus	= in_be64(base + 0x008);
		data->ci.ciPortLdcp	= in_be64(base + 0x010);
		break;
	case P7IOC_ERR_SRC_MISC:
		data->type = OPAL_P7IOC_DIAG_TYPE_MISC;
		p7ioc_get_diag_common(ioc, base, data);
		break;
	case P7IOC_ERR_SRC_I2C:
		data->type = OPAL_P7IOC_DIAG_TYPE_I2C;
		p7ioc_get_diag_common(ioc, base, data);
		break;
	default:
		p7ioc_set_err_pending(ioc, false);
		return OPAL_CLOSED;
	}

	/* For errors of MAL class, we need mask it */
	if (ioc->err.err_class == P7IOC_ERR_CLASS_MAL)
		out_be64(base + P7IOC_LEM_ERR_MASK_OR_OFFSET,
			 PPC_BIT(63 - ioc->err.err_bit));
	p7ioc_set_err_pending(ioc, false);

	return OPAL_SUCCESS;
}

static const struct io_hub_ops p7ioc_hub_ops = {
	.get_diag_data	= p7ioc_get_diag_data,
	.reset		= p7ioc_reset,
};

static int64_t p7ioc_rgc_get_xive(struct irq_source *is, uint32_t isn,
				  uint16_t *server, uint8_t *prio)
{
	struct p7ioc *ioc = is->data;
	uint32_t irq = (isn & 0xf);
	uint32_t fbuid = P7_IRQ_FBUID(isn);
	uint64_t xive;

	if (fbuid != ioc->rgc_buid)
		return OPAL_PARAMETER;

	xive = ioc->xive_cache[irq];
	*server = GETFIELD(IODA_XIVT_SERVER, xive);
	*prio = GETFIELD(IODA_XIVT_PRIORITY, xive);

	return OPAL_SUCCESS;
 }

static int64_t p7ioc_rgc_set_xive(struct irq_source *is, uint32_t isn,
				  uint16_t server, uint8_t prio)
{
	struct p7ioc *ioc = is->data;
	uint32_t irq = (isn & 0xf);
	uint32_t fbuid = P7_IRQ_FBUID(isn);
	uint64_t xive;
	uint64_t m_server, m_prio;

	if (fbuid != ioc->rgc_buid)
		return OPAL_PARAMETER;

	xive = SETFIELD(IODA_XIVT_SERVER, 0ull, server);
	xive = SETFIELD(IODA_XIVT_PRIORITY, xive, prio);
	ioc->xive_cache[irq] = xive;

	/* Now we mangle the server and priority */
	if (prio == 0xff) {
		m_server = 0;
		m_prio = 0xff;
	} else {
		m_server = server >> 3;
		m_prio = (prio >> 3) | ((server & 7) << 5);
	}

	/* Update the XIVE. Don't care HRT entry on P7IOC */
	out_be64(ioc->regs + 0x3e1820, (0x0002000000000000UL | irq));
	xive = in_be64(ioc->regs + 0x3e1830);
	xive = SETFIELD(IODA_XIVT_SERVER, xive, m_server);
	xive = SETFIELD(IODA_XIVT_PRIORITY, xive, m_prio);
	out_be64(ioc->regs + 0x3e1830, xive);

	return OPAL_SUCCESS;
}

/*
 * The function is used to figure out the error class and error
 * bit according to LEM WOF.
 *
 * The bits of WOF register have been classified according to
 * the error severity. Of course, we should process those errors
 * with higher priority. For example, there have 2 errors (GXE, INF)
 * pending, we should process GXE, and INF is meaningless in face
 * of GXE.
 */
static bool p7ioc_err_bit(struct p7ioc *ioc, uint64_t wof)
{
	uint64_t val, severity[P7IOC_ERR_CLASS_LAST];
        int32_t class, bit, err_bit = -1;

	/* Clear severity array */
	memset(severity, 0, sizeof(uint64_t) * P7IOC_ERR_CLASS_LAST);

	/*
	 * The severity array has fixed values. However, it depends
	 * on the damage settings for individual components. We're
	 * using fixed values based on the assumption that damage settings
	 * are fixed for now. If we change it some day, we also need
	 * change the severity array accordingly. Anyway, it's something
	 * to improve in future so that we can figure out the severity
	 * array from hardware registers.
	 */
	switch (ioc->err.err_src) {
	case P7IOC_ERR_SRC_EI:
		/* EI won't create interrupt yet */
		break;
	case P7IOC_ERR_SRC_RGC:
		severity[P7IOC_ERR_CLASS_GXE] = 0xF00086E0F4FCFFFFUL;
		severity[P7IOC_ERR_CLASS_RGA] = 0x0000010000000000UL;
		severity[P7IOC_ERR_CLASS_INF] = 0x0FFF781F0B030000UL;
		break;
	case P7IOC_ERR_SRC_BI_UP:
		severity[P7IOC_ERR_CLASS_GXE] = 0xF7FFFFFF7FFFFFFFUL;
		severity[P7IOC_ERR_CLASS_INF] = 0x0800000080000000UL;
		break;
	case P7IOC_ERR_SRC_BI_DOWN:
		severity[P7IOC_ERR_CLASS_GXE] = 0xDFFFF7F35F8000BFUL;
		severity[P7IOC_ERR_CLASS_INF] = 0x2000080CA07FFF40UL;
		break;
	case P7IOC_ERR_SRC_CI_P0:
		severity[P7IOC_ERR_CLASS_GXE] = 0xF5FF000000000000UL;
		severity[P7IOC_ERR_CLASS_INF] = 0x0200FFFFFFFFFFFFUL;
		severity[P7IOC_ERR_CLASS_MAL] = 0x0800000000000000UL;
		break;
	case P7IOC_ERR_SRC_CI_P1:
		severity[P7IOC_ERR_CLASS_GXE] = 0xFFFF000000000000UL;
		severity[P7IOC_ERR_CLASS_INF] = 0x0000FFFFFFFFFFFFUL;
		break;
	case P7IOC_ERR_SRC_CI_P2:
	case P7IOC_ERR_SRC_CI_P3:
	case P7IOC_ERR_SRC_CI_P4:
	case P7IOC_ERR_SRC_CI_P5:
	case P7IOC_ERR_SRC_CI_P6:
	case P7IOC_ERR_SRC_CI_P7:
		severity[P7IOC_ERR_CLASS_GXE] = 0x5B0B000000000000UL;
		severity[P7IOC_ERR_CLASS_PHB] = 0xA4F4000000000000UL;
		severity[P7IOC_ERR_CLASS_INF] = 0x0000FFFFFFFFFFFFUL;
		break;
	case P7IOC_ERR_SRC_MISC:
		severity[P7IOC_ERR_CLASS_GXE] = 0x0000000310000000UL;
		severity[P7IOC_ERR_CLASS_PLL] = 0x0000000001C00000UL;
		severity[P7IOC_ERR_CLASS_INF] = 0x555FFFF0EE3FFFFFUL;
		severity[P7IOC_ERR_CLASS_MAL] = 0xAAA0000C00000000UL;
		break;
	case P7IOC_ERR_SRC_I2C:
		severity[P7IOC_ERR_CLASS_GXE] = 0x1100000000000000UL;
		severity[P7IOC_ERR_CLASS_INF] = 0xEEFFFFFFFFFFFFFFUL;
		break;
	case P7IOC_ERR_SRC_PHB0:
	case P7IOC_ERR_SRC_PHB1:
	case P7IOC_ERR_SRC_PHB2:
	case P7IOC_ERR_SRC_PHB3:
	case P7IOC_ERR_SRC_PHB4:
	case P7IOC_ERR_SRC_PHB5:
		severity[P7IOC_ERR_CLASS_PHB] = 0xADB650CB808DD051UL;
		severity[P7IOC_ERR_CLASS_ER]  = 0x0000A0147F50092CUL;
		severity[P7IOC_ERR_CLASS_INF] = 0x52490F2000222682UL;
		break;
	}

        /*
         * The error class (ERR_CLASS) has been defined based on
         * their severity. The priority of those errors out of same
         * class should be defined based on the position of corresponding
         * bit in LEM (Local Error Macro) register.
         */
	for (class = P7IOC_ERR_CLASS_NONE + 1;
	     err_bit < 0 && class < P7IOC_ERR_CLASS_LAST;
	     class++) {
		val = wof & severity[class];
		if (!val) continue;

		for (bit = 0; bit < 64; bit++) {
			if (val & PPC_BIT(bit)) {
				err_bit = 63 - bit;
				break;
			}
		}
	}

	/* If we don't find the error bit, we needn't go on. */
	if (err_bit < 0)
		return false;

	ioc->err.err_class = class - 1;
	ioc->err.err_bit   = err_bit;
	return true;
}

/*
 * Check LEM to determine the detailed error information.
 * The function is expected to be called while OS calls
 * to OPAL API opal_pci_next_error(). Eventually, the errors
 * from CI Port{2, ..., 7} or PHB{0, ..., 5} would be cached
 * to the specific PHB, the left errors would be cached to
 * the IOC.
 */
bool p7ioc_check_LEM(struct p7ioc *ioc,
		     uint16_t *pci_error_type,
		     uint16_t *severity)
{
	void *base;
	uint64_t fir, wof, mask;
	struct p7ioc_phb *p;
	int32_t index;
	bool ret;

	/* Make sure we have error pending on IOC */
	if (!p7ioc_err_pending(ioc))
		return false;

	/*
	 * The IOC probably has been put to fatal error
	 * state (GXE) because of failure on reading on
	 * GEM FIR.
	 */
	if (ioc->err.err_src == P7IOC_ERR_SRC_NONE &&
	    ioc->err.err_class != P7IOC_ERR_CLASS_NONE)
		goto err;

	/*
	 * Get the base address of LEM registers according
	 * to the error source. If we failed to get that,
	 * the error pending flag would be cleared.
	 */
	base = p7ioc_LEM_base(ioc, ioc->err.err_src);
	if (!base) {
		p7ioc_set_err_pending(ioc, false);
		return false;
	}

	/* IOC would be broken upon broken FIR */
	fir = in_be64(base + P7IOC_LEM_FIR_OFFSET);
	if (fir == 0xffffffffffffffffUL) {
		ioc->err.err_src   = P7IOC_ERR_SRC_NONE;
		ioc->err.err_class = P7IOC_ERR_CLASS_GXE;
		goto err;
	}

	/* Read on ERR_MASK and WOF. However, we needn't do for PHBn */
	wof = in_be64(base + P7IOC_LEM_WOF_OFFSET);
	if (ioc->err.err_src >= P7IOC_ERR_SRC_PHB0 &&
	    ioc->err.err_src <= P7IOC_ERR_SRC_PHB5) {
		mask = 0x0ull;
	} else {
		mask = in_be64(base + P7IOC_LEM_ERR_MASK_OFFSET);
		in_be64(base + P7IOC_LEM_ACTION_0_OFFSET);
		in_be64(base + P7IOC_LEM_ACTION_1_OFFSET);
	}

        /*
         * We need process those unmasked error first. If we're
         * failing to get the error bit, we needn't proceed.
         */
	if (wof & ~mask)
		wof &= ~mask;
	if (!wof) {
		p7ioc_set_err_pending(ioc, false);
		return false;
        }

	if (!p7ioc_err_bit(ioc, wof)) {
		p7ioc_set_err_pending(ioc, false);
		return false;
	}

err:
	/*
	 * We run into here because of valid error. Those errors
	 * from CI Port{2, ..., 7} and PHB{0, ..., 5} will be cached
	 * to the specific PHB. However, we will cache the global
	 * errors (e.g. GXE) to IOC directly. For the left errors,
	 * they will be cached to IOC.
	 */
	if (((ioc->err.err_src >= P7IOC_ERR_SRC_CI_P2  &&
	      ioc->err.err_src <= P7IOC_ERR_SRC_CI_P7) ||
	     (ioc->err.err_src >= P7IOC_ERR_SRC_PHB0   &&
	      ioc->err.err_src <= P7IOC_ERR_SRC_PHB5)) &&
	     ioc->err.err_class != P7IOC_ERR_CLASS_GXE) {
		index = (ioc->err.err_src >= P7IOC_ERR_SRC_PHB0 &&
			 ioc->err.err_src <= P7IOC_ERR_SRC_PHB5) ?
			(ioc->err.err_src - P7IOC_ERR_SRC_PHB0) :
			(ioc->err.err_src - P7IOC_ERR_SRC_CI_P2);
		p = &ioc->phbs[index];

		if (p7ioc_phb_enabled(ioc, index)) {
			p->err.err_src   = ioc->err.err_src;
			p->err.err_class = ioc->err.err_class;
			p->err.err_bit   = ioc->err.err_bit;
			p7ioc_phb_set_err_pending(p, true);
			p7ioc_set_err_pending(ioc, false);

			return false;
		}
	}

	/*
	 * Map the internal error class to that OS can recognize.
	 * Errors from PHB or the associated CI port would be
	 * GXE, PHB-fatal, ER, or INF. For the case, GXE will be
	 * cached to IOC and the left classes will be cached to
	 * the specific PHB.
	 */
	switch (ioc->err.err_class) {
	case P7IOC_ERR_CLASS_GXE:
	case P7IOC_ERR_CLASS_PLL:
	case P7IOC_ERR_CLASS_RGA:
		*pci_error_type = OPAL_EEH_IOC_ERROR;
		*severity = OPAL_EEH_SEV_IOC_DEAD;
		ret = true;
		break;
	case P7IOC_ERR_CLASS_INF:
	case P7IOC_ERR_CLASS_MAL:
		*pci_error_type = OPAL_EEH_IOC_ERROR;
		*severity = OPAL_EEH_SEV_INF;
		ret = false;
		break;
	default:
		p7ioc_set_err_pending(ioc, false);
		ret = false;
	}

	return ret;
}

/*
 * Check GEM to see if there has any problematic components.
 * The function is expected to be called in RGC interrupt
 * handler. Also, it's notable that failure on reading on
 * XFIR will cause GXE directly.
 */
static bool p7ioc_check_GEM(struct p7ioc *ioc)
{
	uint64_t xfir, rwof;

	/*
	 * Recov_5: Read GEM Xfir
	 * Recov_6: go to GXE recovery?
	 */
	xfir = in_be64(ioc->regs + P7IOC_GEM_XFIR);
	if (xfir == 0xffffffffffffffffUL) {
		ioc->err.err_src   = P7IOC_ERR_SRC_NONE;
		ioc->err.err_class = P7IOC_ERR_CLASS_GXE;
		p7ioc_set_err_pending(ioc, true);
		return true;
	}

	/*
	 * Recov_7: Read GEM Rfir
	 * Recov_8: Read GEM RIRQfir
	 * Recov_9: Read GEM RWOF
	 * Recov_10: Read Fence Shadow
	 * Recov_11: Read Fence Shadow WOF
	 */
        in_be64(ioc->regs + P7IOC_GEM_RFIR);
        in_be64(ioc->regs + P7IOC_GEM_RIRQFIR);
	rwof = in_be64(ioc->regs + P7IOC_GEM_RWOF);
	in_be64(ioc->regs + P7IOC_CHIP_FENCE_SHADOW);
	in_be64(ioc->regs + P7IOC_CHIP_FENCE_WOF);

	/*
	 * Check GEM RWOF to see which component has been
	 * put into problematic state.
	 */
	ioc->err.err_src = P7IOC_ERR_SRC_NONE;
	if	(rwof & PPC_BIT(1))  ioc->err.err_src = P7IOC_ERR_SRC_RGC;
	else if (rwof & PPC_BIT(2))  ioc->err.err_src = P7IOC_ERR_SRC_BI_UP;
	else if (rwof & PPC_BIT(3))  ioc->err.err_src = P7IOC_ERR_SRC_BI_DOWN;
	else if (rwof & PPC_BIT(4))  ioc->err.err_src = P7IOC_ERR_SRC_CI_P0;
	else if (rwof & PPC_BIT(5))  ioc->err.err_src = P7IOC_ERR_SRC_CI_P1;
	else if (rwof & PPC_BIT(6))  ioc->err.err_src = P7IOC_ERR_SRC_CI_P2;
	else if (rwof & PPC_BIT(7))  ioc->err.err_src = P7IOC_ERR_SRC_CI_P3;
	else if (rwof & PPC_BIT(8))  ioc->err.err_src = P7IOC_ERR_SRC_CI_P4;
	else if (rwof & PPC_BIT(9))  ioc->err.err_src = P7IOC_ERR_SRC_CI_P5;
	else if (rwof & PPC_BIT(10)) ioc->err.err_src = P7IOC_ERR_SRC_CI_P6;
	else if (rwof & PPC_BIT(11)) ioc->err.err_src = P7IOC_ERR_SRC_CI_P7;
	else if (rwof & PPC_BIT(16)) ioc->err.err_src = P7IOC_ERR_SRC_PHB0;
	else if (rwof & PPC_BIT(17)) ioc->err.err_src = P7IOC_ERR_SRC_PHB1;
	else if (rwof & PPC_BIT(18)) ioc->err.err_src = P7IOC_ERR_SRC_PHB2;
	else if (rwof & PPC_BIT(19)) ioc->err.err_src = P7IOC_ERR_SRC_PHB3;
	else if (rwof & PPC_BIT(20)) ioc->err.err_src = P7IOC_ERR_SRC_PHB4;
	else if (rwof & PPC_BIT(21)) ioc->err.err_src = P7IOC_ERR_SRC_PHB5;
	else if (rwof & PPC_BIT(24)) ioc->err.err_src = P7IOC_ERR_SRC_MISC;
	else if (rwof & PPC_BIT(25)) ioc->err.err_src = P7IOC_ERR_SRC_I2C;

	/*
	 * If we detect any problematic components, the OS is
	 * expected to poll that for more details through OPAL
	 * interface.
	 */
        if (ioc->err.err_src != P7IOC_ERR_SRC_NONE) {
		p7ioc_set_err_pending(ioc, true);
		return true;
	}

	return false;
}

static void p7ioc_rgc_interrupt(struct irq_source *is, uint32_t isn)
{
	struct p7ioc *ioc = is->data;

	printf("Got RGC interrupt 0x%04x\n", isn);

	/* We will notify OS while getting error from GEM */
	if (p7ioc_check_GEM(ioc))
		/* This is a bit hacky but works - we raise the event
		on a downstream phb as the OS needs to call
		opal_pci_next_error for all phbs to ensure all events
		are cleared anyway. */
		opal_pci_eeh_set_evt(ioc->phbs[0].phb.opal_id);
}

static uint64_t p7ioc_rgc_irq_attributes(struct irq_source *is __unused,
					 uint32_t isn __unused)
{
	return IRQ_ATTR_TARGET_OPAL | IRQ_ATTR_TARGET_RARE;
}

static const struct irq_source_ops p7ioc_rgc_irq_ops = {
	.get_xive = p7ioc_rgc_get_xive,
	.set_xive = p7ioc_rgc_set_xive,
	.attributes = p7ioc_rgc_irq_attributes,
	.interrupt = p7ioc_rgc_interrupt,
};

static void p7ioc_create_hub(struct dt_node *np)
{
	struct p7ioc *ioc;
	unsigned int i, id;
	u64 bar1, bar2;
	u32 pdt;
	char *path;

	/* Use the BUID extension as ID and add it to device-tree */
	id = dt_prop_get_u32(np, "ibm,buid-ext");
	path = dt_get_path(np);
	printf("P7IOC: Found at %s ID 0x%x\n", path, id);
	free(path);

	/* Load VPD LID */
	vpd_preload(np);
	vpd_iohub_load(np);

	ioc = zalloc(sizeof(struct p7ioc));
	if (!ioc)
		return;
	ioc->hub.hub_id = id;
	ioc->hub.ops = &p7ioc_hub_ops;
	ioc->dt_node = np;

	bar1 = dt_prop_get_u64(np, "ibm,gx-bar-1");
	bar2 = dt_prop_get_u64(np, "ibm,gx-bar-2");

	ioc->regs = (void *)bar1;

	ioc->mmio1_win_start = bar1;
	ioc->mmio1_win_size = MWIN1_SIZE;
	ioc->mmio2_win_start = bar2;
	ioc->mmio2_win_size = MWIN2_SIZE;

	ioc->buid_base = id << 9;
	ioc->rgc_buid = ioc->buid_base + RGC_BUID_OFFSET;

	/* Add some DT properties */
	dt_add_property_cells(np, "ibm,opal-hubid", 0, id);

	/* XXX Fixme: how many RGC interrupts ? */
	dt_add_property_cells(np, "interrupt-parent", get_ics_phandle());
	dt_add_property_cells(np, "interrupts", ioc->rgc_buid << 4, 1);
	dt_add_property_cells(np, "interrupt-base", ioc->rgc_buid << 4);

	/* XXX What about ibm,opal-mmio-real ? */

	/* Clear the RGC XIVE cache */
	for (i = 0; i < 16; i++)
		ioc->xive_cache[i] = SETFIELD(IODA_XIVT_PRIORITY, 0ull, 0xff);

	/*
	 * Register RGC interrupts
	 *
	 * For now I assume only 0 is... to verify with Greg or HW guys,
	 * we support all 16
	 */
	register_irq_source(&p7ioc_rgc_irq_ops, ioc, ioc->rgc_buid << 4, 1);

	/* Check for presence detect from HDAT, we use only BR1 on P7IOC */
	pdt = dt_prop_get_u32_def(np, "ibm,br1-presence-detect", 0xffffffff);
	if (pdt != 0xffffffff)
		printf("P7IOC: Presence detect from HDAT : 0x%02x\n", pdt);
	else {
	}
	ioc->phb_pdt = pdt & 0xff;

	/* Setup PHB structures (no HW access yet) */
	for (i = 0; i < P7IOC_NUM_PHBS; i++) {
		if (p7ioc_phb_enabled(ioc, i))
			p7ioc_phb_setup(ioc, i);
		else
			ioc->phbs[i].state = P7IOC_PHB_STATE_OFF;
	}

	/* Now, we do the bulk of the inits */
	p7ioc_inits(ioc);

	printf("P7IOC: Initialization complete\n");

	cec_register(&ioc->hub);
}

void probe_p7ioc(void)
{
	struct dt_node *np;

	dt_for_each_compatible(dt_root, np, "ibm,p7ioc")
		p7ioc_create_hub(np);
}



