// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Freescale MPC85xx/MPC86xx RapidIO support
 *
 * Copyright 2009 Sysgo AG
 * Thomas Moll <thomas.moll@sysgo.com>
 * - fixed maintenance access routines, check for aligned access
 *
 * Copyright 2009 Integrated Device Technology, Inc.
 * Alex Bounine <alexandre.bounine@idt.com>
 * - Added Port-Write message handling
 * - Added Machine Check exception handling
 *
 * Copyright (C) 2007, 2008, 2010, 2011 Freescale Semiconductor, Inc.
 * Zhang Wei <wei.zhang@freescale.com>
 *
 * Copyright 2005 MontaVista Software, Inc.
 * Matt Porter <mporter@kernel.crashing.org>
 */

#include <linux/init.h>
#include <linux/extable.h>
#include <linux/types.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/device.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/delay.h>
#include <linux/slab.h>

#include <linux/io.h>
#include <linux/uaccess.h>
#include <asm/machdep.h>

#include "fsl_rio.h"

#undef DEBUG_PW	/* Port-Write debugging */

#define RIO_PORT1_EDCSR		0x0640
#define RIO_PORT2_EDCSR		0x0680
#define RIO_PORT1_IECSR		0x10130
#define RIO_PORT2_IECSR		0x101B0

#define RIO_GCCSR		0x13c
#define RIO_ESCSR		0x158
#define ESCSR_CLEAR		0x07120204
#define RIO_PORT2_ESCSR		0x178
#define RIO_CCSR		0x15c
#define RIO_LTLEDCSR_IER	0x80000000
#define RIO_LTLEDCSR_PRT	0x01000000
#define IECSR_CLEAR		0x80000000
#define RIO_ISR_AACR		0x10120
#define RIO_ISR_AACR_AA		0x1	/* Accept All ID */

#define RIWTAR_TRAD_VAL_SHIFT	12
#define RIWTAR_TRAD_MASK	0x00FFFFFF
#define RIWBAR_BADD_VAL_SHIFT	12
#define RIWBAR_BADD_MASK	0x003FFFFF
#define RIWAR_ENABLE		0x80000000
#define RIWAR_TGINT_LOCAL	0x00F00000
#define RIWAR_RDTYP_NO_SNOOP	0x00040000
#define RIWAR_RDTYP_SNOOP	0x00050000
#define RIWAR_WRTYP_NO_SNOOP	0x00004000
#define RIWAR_WRTYP_SNOOP	0x00005000
#define RIWAR_WRTYP_ALLOC	0x00006000
#define RIWAR_SIZE_MASK		0x0000003F

static DEFINE_SPINLOCK(fsl_rio_config_lock);

#define __fsl_read_rio_config(x, addr, err, op)		\
	__asm__ __volatile__(				\
		"1:	"op" %1,0(%2)\n"		\
		"	eieio\n"			\
		"2:\n"					\
		".section .fixup,\"ax\"\n"		\
		"3:	li %1,-1\n"			\
		"	li %0,%3\n"			\
		"	b 2b\n"				\
		".previous\n"				\
		EX_TABLE(1b, 3b)			\
		: "=r" (err), "=r" (x)			\
		: "b" (addr), "i" (-EFAULT), "0" (err))

void __iomem *rio_regs_win;
void __iomem *rmu_regs_win;
resource_size_t rio_law_start;

struct fsl_rio_dbell *dbell;
struct fsl_rio_pw *pw;

#ifdef CONFIG_E500
int fsl_rio_mcheck_exception(struct pt_regs *regs)
{
	const struct exception_table_entry *entry;
	unsigned long reason;

	if (!rio_regs_win)
		return 0;

	reason = in_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR));
	if (reason & (RIO_LTLEDCSR_IER | RIO_LTLEDCSR_PRT)) {
		/* Check if we are prepared to handle this fault */
		entry = search_exception_tables(regs->nip);
		if (entry) {
			pr_debug("RIO: %s - MC Exception handled\n",
				 __func__);
			out_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR),
				 0);
			regs_set_return_msr(regs, regs->msr | MSR_RI);
			regs_set_return_ip(regs, extable_fixup(entry));
			return 1;
		}
	}

	return 0;
}
EXPORT_SYMBOL_GPL(fsl_rio_mcheck_exception);
#endif

/**
 * fsl_local_config_read - Generate a MPC85xx local config space read
 * @mport: RapidIO master port info
 * @index: ID of RapdiIO interface
 * @offset: Offset into configuration space
 * @len: Length (in bytes) of the maintenance transaction
 * @data: Value to be read into
 *
 * Generates a MPC85xx local configuration space read. Returns %0 on
 * success or %-EINVAL on failure.
 */
static int fsl_local_config_read(struct rio_mport *mport,
				int index, u32 offset, int len, u32 *data)
{
	struct rio_priv *priv = mport->priv;
	pr_debug("fsl_local_config_read: index %d offset %8.8x\n", index,
		 offset);
	*data = in_be32(priv->regs_win + offset);

	return 0;
}

/**
 * fsl_local_config_write - Generate a MPC85xx local config space write
 * @mport: RapidIO master port info
 * @index: ID of RapdiIO interface
 * @offset: Offset into configuration space
 * @len: Length (in bytes) of the maintenance transaction
 * @data: Value to be written
 *
 * Generates a MPC85xx local configuration space write. Returns %0 on
 * success or %-EINVAL on failure.
 */
static int fsl_local_config_write(struct rio_mport *mport,
				int index, u32 offset, int len, u32 data)
{
	struct rio_priv *priv = mport->priv;
	pr_debug
		("fsl_local_config_write: index %d offset %8.8x data %8.8x\n",
		index, offset, data);
	out_be32(priv->regs_win + offset, data);

	return 0;
}

/**
 * fsl_rio_config_read - Generate a MPC85xx read maintenance transaction
 * @mport: RapidIO master port info
 * @index: ID of RapdiIO interface
 * @destid: Destination ID of transaction
 * @hopcount: Number of hops to target device
 * @offset: Offset into configuration space
 * @len: Length (in bytes) of the maintenance transaction
 * @val: Location to be read into
 *
 * Generates a MPC85xx read maintenance transaction. Returns %0 on
 * success or %-EINVAL on failure.
 */
static int
fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid,
			u8 hopcount, u32 offset, int len, u32 *val)
{
	struct rio_priv *priv = mport->priv;
	unsigned long flags;
	u8 *data;
	u32 rval, err = 0;

	pr_debug
		("fsl_rio_config_read:"
		" index %d destid %d hopcount %d offset %8.8x len %d\n",
		index, destid, hopcount, offset, len);

	/* 16MB maintenance window possible */
	/* allow only aligned access to maintenance registers */
	if (offset > (0x1000000 - len) || !IS_ALIGNED(offset, len))
		return -EINVAL;

	spin_lock_irqsave(&fsl_rio_config_lock, flags);

	out_be32(&priv->maint_atmu_regs->rowtar,
		 (destid << 22) | (hopcount << 12) | (offset >> 12));
	out_be32(&priv->maint_atmu_regs->rowtear, (destid >> 10));

	data = (u8 *) priv->maint_win + (offset & (RIO_MAINT_WIN_SIZE - 1));
	switch (len) {
	case 1:
		__fsl_read_rio_config(rval, data, err, "lbz");
		break;
	case 2:
		__fsl_read_rio_config(rval, data, err, "lhz");
		break;
	case 4:
		__fsl_read_rio_config(rval, data, err, "lwz");
		break;
	default:
		spin_unlock_irqrestore(&fsl_rio_config_lock, flags);
		return -EINVAL;
	}

	if (err) {
		pr_debug("RIO: cfg_read error %d for %x:%x:%x\n",
			 err, destid, hopcount, offset);
	}

	spin_unlock_irqrestore(&fsl_rio_config_lock, flags);
	*val = rval;

	return err;
}

/**
 * fsl_rio_config_write - Generate a MPC85xx write maintenance transaction
 * @mport: RapidIO master port info
 * @index: ID of RapdiIO interface
 * @destid: Destination ID of transaction
 * @hopcount: Number of hops to target device
 * @offset: Offset into configuration space
 * @len: Length (in bytes) of the maintenance transaction
 * @val: Value to be written
 *
 * Generates an MPC85xx write maintenance transaction. Returns %0 on
 * success or %-EINVAL on failure.
 */
static int
fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid,
			u8 hopcount, u32 offset, int len, u32 val)
{
	struct rio_priv *priv = mport->priv;
	unsigned long flags;
	u8 *data;
	int ret = 0;

	pr_debug
		("fsl_rio_config_write:"
		" index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n",
		index, destid, hopcount, offset, len, val);

	/* 16MB maintenance windows possible */
	/* allow only aligned access to maintenance registers */
	if (offset > (0x1000000 - len) || !IS_ALIGNED(offset, len))
		return -EINVAL;

	spin_lock_irqsave(&fsl_rio_config_lock, flags);

	out_be32(&priv->maint_atmu_regs->rowtar,
		 (destid << 22) | (hopcount << 12) | (offset >> 12));
	out_be32(&priv->maint_atmu_regs->rowtear, (destid >> 10));

	data = (u8 *) priv->maint_win + (offset & (RIO_MAINT_WIN_SIZE - 1));
	switch (len) {
	case 1:
		out_8((u8 *) data, val);
		break;
	case 2:
		out_be16((u16 *) data, val);
		break;
	case 4:
		out_be32((u32 *) data, val);
		break;
	default:
		ret = -EINVAL;
	}
	spin_unlock_irqrestore(&fsl_rio_config_lock, flags);

	return ret;
}

static void fsl_rio_inbound_mem_init(struct rio_priv *priv)
{
	int i;

	/* close inbound windows */
	for (i = 0; i < RIO_INB_ATMU_COUNT; i++)
		out_be32(&priv->inb_atmu_regs[i].riwar, 0);
}

int fsl_map_inb_mem(struct rio_mport *mport, dma_addr_t lstart,
	u64 rstart, u64 size, u32 flags)
{
	struct rio_priv *priv = mport->priv;
	u32 base_size;
	unsigned int base_size_log;
	u64 win_start, win_end;
	u32 riwar;
	int i;

	if ((size & (size - 1)) != 0 || size > 0x400000000ULL)
		return -EINVAL;

	base_size_log = ilog2(size);
	base_size = 1 << base_size_log;

	/* check if addresses are aligned with the window size */
	if (lstart & (base_size - 1))
		return -EINVAL;
	if (rstart & (base_size - 1))
		return -EINVAL;

	/* check for conflicting ranges */
	for (i = 0; i < RIO_INB_ATMU_COUNT; i++) {
		riwar = in_be32(&priv->inb_atmu_regs[i].riwar);
		if ((riwar & RIWAR_ENABLE) == 0)
			continue;
		win_start = ((u64)(in_be32(&priv->inb_atmu_regs[i].riwbar) & RIWBAR_BADD_MASK))
			<< RIWBAR_BADD_VAL_SHIFT;
		win_end = win_start + ((1 << ((riwar & RIWAR_SIZE_MASK) + 1)) - 1);
		if (rstart < win_end && (rstart + size) > win_start)
			return -EINVAL;
	}

	/* find unused atmu */
	for (i = 0; i < RIO_INB_ATMU_COUNT; i++) {
		riwar = in_be32(&priv->inb_atmu_regs[i].riwar);
		if ((riwar & RIWAR_ENABLE) == 0)
			break;
	}
	if (i >= RIO_INB_ATMU_COUNT)
		return -ENOMEM;

	out_be32(&priv->inb_atmu_regs[i].riwtar, lstart >> RIWTAR_TRAD_VAL_SHIFT);
	out_be32(&priv->inb_atmu_regs[i].riwbar, rstart >> RIWBAR_BADD_VAL_SHIFT);
	out_be32(&priv->inb_atmu_regs[i].riwar, RIWAR_ENABLE | RIWAR_TGINT_LOCAL |
		RIWAR_RDTYP_SNOOP | RIWAR_WRTYP_SNOOP | (base_size_log - 1));

	return 0;
}

void fsl_unmap_inb_mem(struct rio_mport *mport, dma_addr_t lstart)
{
	u32 win_start_shift, base_start_shift;
	struct rio_priv *priv = mport->priv;
	u32 riwar, riwtar;
	int i;

	/* skip default window */
	base_start_shift = lstart >> RIWTAR_TRAD_VAL_SHIFT;
	for (i = 0; i < RIO_INB_ATMU_COUNT; i++) {
		riwar = in_be32(&priv->inb_atmu_regs[i].riwar);
		if ((riwar & RIWAR_ENABLE) == 0)
			continue;

		riwtar = in_be32(&priv->inb_atmu_regs[i].riwtar);
		win_start_shift = riwtar & RIWTAR_TRAD_MASK;
		if (win_start_shift == base_start_shift) {
			out_be32(&priv->inb_atmu_regs[i].riwar, riwar & ~RIWAR_ENABLE);
			return;
		}
	}
}

void fsl_rio_port_error_handler(int offset)
{
	/*XXX: Error recovery is not implemented, we just clear errors */
	out_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR), 0);

	if (offset == 0) {
		out_be32((u32 *)(rio_regs_win + RIO_PORT1_EDCSR), 0);
		out_be32((u32 *)(rio_regs_win + RIO_PORT1_IECSR), IECSR_CLEAR);
		out_be32((u32 *)(rio_regs_win + RIO_ESCSR), ESCSR_CLEAR);
	} else {
		out_be32((u32 *)(rio_regs_win + RIO_PORT2_EDCSR), 0);
		out_be32((u32 *)(rio_regs_win + RIO_PORT2_IECSR), IECSR_CLEAR);
		out_be32((u32 *)(rio_regs_win + RIO_PORT2_ESCSR), ESCSR_CLEAR);
	}
}
static inline void fsl_rio_info(struct device *dev, u32 ccsr)
{
	const char *str;
	if (ccsr & 1) {
		/* Serial phy */
		switch (ccsr >> 30) {
		case 0:
			str = "1";
			break;
		case 1:
			str = "4";
			break;
		default:
			str = "Unknown";
			break;
		}
		dev_info(dev, "Hardware port width: %s\n", str);

		switch ((ccsr >> 27) & 7) {
		case 0:
			str = "Single-lane 0";
			break;
		case 1:
			str = "Single-lane 2";
			break;
		case 2:
			str = "Four-lane";
			break;
		default:
			str = "Unknown";
			break;
		}
		dev_info(dev, "Training connection status: %s\n", str);
	} else {
		/* Parallel phy */
		if (!(ccsr & 0x80000000))
			dev_info(dev, "Output port operating in 8-bit mode\n");
		if (!(ccsr & 0x08000000))
			dev_info(dev, "Input port operating in 8-bit mode\n");
	}
}

/**
 * fsl_rio_setup - Setup Freescale PowerPC RapidIO interface
 * @dev: platform_device pointer
 *
 * Initializes MPC85xx RapidIO hardware interface, configures
 * master port with system-specific info, and registers the
 * master port with the RapidIO subsystem.
 */
int fsl_rio_setup(struct platform_device *dev)
{
	struct rio_ops *ops;
	struct rio_mport *port;
	struct rio_priv *priv;
	int rc = 0;
	const u32 *dt_range, *cell, *port_index;
	u32 active_ports = 0;
	struct resource regs, rmu_regs;
	struct device_node *np, *rmu_node;
	int rlen;
	u32 ccsr;
	u64 range_start, range_size;
	int paw, aw, sw;
	u32 i;
	static int tmp;
	struct device_node *rmu_np[MAX_MSG_UNIT_NUM] = {NULL};

	if (!dev->dev.of_node) {
		dev_err(&dev->dev, "Device OF-Node is NULL");
		return -ENODEV;
	}

	rc = of_address_to_resource(dev->dev.of_node, 0, &regs);
	if (rc) {
		dev_err(&dev->dev, "Can't get %pOF property 'reg'\n",
				dev->dev.of_node);
		return -EFAULT;
	}
	dev_info(&dev->dev, "Of-device full name %pOF\n",
			dev->dev.of_node);
	dev_info(&dev->dev, "Regs: %pR\n", &regs);

	rio_regs_win = ioremap(regs.start, resource_size(&regs));
	if (!rio_regs_win) {
		dev_err(&dev->dev, "Unable to map rio register window\n");
		rc = -ENOMEM;
		goto err_rio_regs;
	}

	ops = kzalloc(sizeof(struct rio_ops), GFP_KERNEL);
	if (!ops) {
		rc = -ENOMEM;
		goto err_ops;
	}
	ops->lcread = fsl_local_config_read;
	ops->lcwrite = fsl_local_config_write;
	ops->cread = fsl_rio_config_read;
	ops->cwrite = fsl_rio_config_write;
	ops->dsend = fsl_rio_doorbell_send;
	ops->pwenable = fsl_rio_pw_enable;
	ops->open_outb_mbox = fsl_open_outb_mbox;
	ops->open_inb_mbox = fsl_open_inb_mbox;
	ops->close_outb_mbox = fsl_close_outb_mbox;
	ops->close_inb_mbox = fsl_close_inb_mbox;
	ops->add_outb_message = fsl_add_outb_message;
	ops->add_inb_buffer = fsl_add_inb_buffer;
	ops->get_inb_message = fsl_get_inb_message;
	ops->map_inb = fsl_map_inb_mem;
	ops->unmap_inb = fsl_unmap_inb_mem;

	rmu_node = of_parse_phandle(dev->dev.of_node, "fsl,srio-rmu-handle", 0);
	if (!rmu_node) {
		dev_err(&dev->dev, "No valid fsl,srio-rmu-handle property\n");
		rc = -ENOENT;
		goto err_rmu;
	}
	rc = of_address_to_resource(rmu_node, 0, &rmu_regs);
	if (rc) {
		dev_err(&dev->dev, "Can't get %pOF property 'reg'\n",
				rmu_node);
		goto err_rmu;
	}
	rmu_regs_win = ioremap(rmu_regs.start, resource_size(&rmu_regs));
	if (!rmu_regs_win) {
		dev_err(&dev->dev, "Unable to map rmu register window\n");
		rc = -ENOMEM;
		goto err_rmu;
	}
	for_each_compatible_node(np, NULL, "fsl,srio-msg-unit") {
		rmu_np[tmp] = np;
		tmp++;
	}

	/*set up doobell node*/
	np = of_find_compatible_node(NULL, NULL, "fsl,srio-dbell-unit");
	if (!np) {
		dev_err(&dev->dev, "No fsl,srio-dbell-unit node\n");
		rc = -ENODEV;
		goto err_dbell;
	}
	dbell = kzalloc(sizeof(struct fsl_rio_dbell), GFP_KERNEL);
	if (!(dbell)) {
		dev_err(&dev->dev, "Can't alloc memory for 'fsl_rio_dbell'\n");
		rc = -ENOMEM;
		goto err_dbell;
	}
	dbell->dev = &dev->dev;
	dbell->bellirq = irq_of_parse_and_map(np, 1);
	dev_info(&dev->dev, "bellirq: %d\n", dbell->bellirq);

	aw = of_n_addr_cells(np);
	dt_range = of_get_property(np, "reg", &rlen);
	if (!dt_range) {
		pr_err("%pOF: unable to find 'reg' property\n",
			np);
		rc = -ENOMEM;
		goto err_pw;
	}
	range_start = of_read_number(dt_range, aw);
	dbell->dbell_regs = (struct rio_dbell_regs *)(rmu_regs_win +
				(u32)range_start);

	/*set up port write node*/
	np = of_find_compatible_node(NULL, NULL, "fsl,srio-port-write-unit");
	if (!np) {
		dev_err(&dev->dev, "No fsl,srio-port-write-unit node\n");
		rc = -ENODEV;
		goto err_pw;
	}
	pw = kzalloc(sizeof(struct fsl_rio_pw), GFP_KERNEL);
	if (!(pw)) {
		dev_err(&dev->dev, "Can't alloc memory for 'fsl_rio_pw'\n");
		rc = -ENOMEM;
		goto err_pw;
	}
	pw->dev = &dev->dev;
	pw->pwirq = irq_of_parse_and_map(np, 0);
	dev_info(&dev->dev, "pwirq: %d\n", pw->pwirq);
	aw = of_n_addr_cells(np);
	dt_range = of_get_property(np, "reg", &rlen);
	if (!dt_range) {
		pr_err("%pOF: unable to find 'reg' property\n",
			np);
		rc = -ENOMEM;
		goto err;
	}
	range_start = of_read_number(dt_range, aw);
	pw->pw_regs = (struct rio_pw_regs *)(rmu_regs_win + (u32)range_start);

	/*set up ports node*/
	for_each_child_of_node(dev->dev.of_node, np) {
		port_index = of_get_property(np, "cell-index", NULL);
		if (!port_index) {
			dev_err(&dev->dev, "Can't get %pOF property 'cell-index'\n",
					np);
			continue;
		}

		dt_range = of_get_property(np, "ranges", &rlen);
		if (!dt_range) {
			dev_err(&dev->dev, "Can't get %pOF property 'ranges'\n",
					np);
			continue;
		}

		/* Get node address wide */
		cell = of_get_property(np, "#address-cells", NULL);
		if (cell)
			aw = *cell;
		else
			aw = of_n_addr_cells(np);
		/* Get node size wide */
		cell = of_get_property(np, "#size-cells", NULL);
		if (cell)
			sw = *cell;
		else
			sw = of_n_size_cells(np);
		/* Get parent address wide wide */
		paw = of_n_addr_cells(np);
		range_start = of_read_number(dt_range + aw, paw);
		range_size = of_read_number(dt_range + aw + paw, sw);

		dev_info(&dev->dev, "%pOF: LAW start 0x%016llx, size 0x%016llx.\n",
				np, range_start, range_size);

		port = kzalloc(sizeof(struct rio_mport), GFP_KERNEL);
		if (!port)
			continue;

		rc = rio_mport_initialize(port);
		if (rc) {
			kfree(port);
			continue;
		}

		i = *port_index - 1;
		port->index = (unsigned char)i;

		priv = kzalloc(sizeof(struct rio_priv), GFP_KERNEL);
		if (!priv) {
			dev_err(&dev->dev, "Can't alloc memory for 'priv'\n");
			kfree(port);
			continue;
		}

		INIT_LIST_HEAD(&port->dbells);
		port->iores.start = range_start;
		port->iores.end = port->iores.start + range_size - 1;
		port->iores.flags = IORESOURCE_MEM;
		port->iores.name = "rio_io_win";

		if (request_resource(&iomem_resource, &port->iores) < 0) {
			dev_err(&dev->dev, "RIO: Error requesting master port region"
				" 0x%016llx-0x%016llx\n",
				(u64)port->iores.start, (u64)port->iores.end);
				kfree(priv);
				kfree(port);
				continue;
		}
		sprintf(port->name, "RIO mport %d", i);

		priv->dev = &dev->dev;
		port->dev.parent = &dev->dev;
		port->ops = ops;
		port->priv = priv;
		port->phys_efptr = 0x100;
		port->phys_rmap = 1;
		priv->regs_win = rio_regs_win;

		ccsr = in_be32(priv->regs_win + RIO_CCSR + i*0x20);

		/* Checking the port training status */
		if (in_be32((priv->regs_win + RIO_ESCSR + i*0x20)) & 1) {
			dev_err(&dev->dev, "Port %d is not ready. "
			"Try to restart connection...\n", i);
			/* Disable ports */
			out_be32(priv->regs_win
				+ RIO_CCSR + i*0x20, 0);
			/* Set 1x lane */
			setbits32(priv->regs_win
				+ RIO_CCSR + i*0x20, 0x02000000);
			/* Enable ports */
			setbits32(priv->regs_win
				+ RIO_CCSR + i*0x20, 0x00600000);
			msleep(100);
			if (in_be32((priv->regs_win
					+ RIO_ESCSR + i*0x20)) & 1) {
				dev_err(&dev->dev,
					"Port %d restart failed.\n", i);
				release_resource(&port->iores);
				kfree(priv);
				kfree(port);
				continue;
			}
			dev_info(&dev->dev, "Port %d restart success!\n", i);
		}
		fsl_rio_info(&dev->dev, ccsr);

		port->sys_size = (in_be32((priv->regs_win + RIO_PEF_CAR))
					& RIO_PEF_CTLS) >> 4;
		dev_info(&dev->dev, "RapidIO Common Transport System size: %d\n",
				port->sys_size ? 65536 : 256);

		if (port->host_deviceid >= 0)
			out_be32(priv->regs_win + RIO_GCCSR, RIO_PORT_GEN_HOST |
				RIO_PORT_GEN_MASTER | RIO_PORT_GEN_DISCOVERED);
		else
			out_be32(priv->regs_win + RIO_GCCSR,
				RIO_PORT_GEN_MASTER);

		priv->atmu_regs = (struct rio_atmu_regs *)(priv->regs_win
			+ ((i == 0) ? RIO_ATMU_REGS_PORT1_OFFSET :
			RIO_ATMU_REGS_PORT2_OFFSET));

		priv->maint_atmu_regs = priv->atmu_regs + 1;
		priv->inb_atmu_regs = (struct rio_inb_atmu_regs __iomem *)
			(priv->regs_win +
			((i == 0) ? RIO_INB_ATMU_REGS_PORT1_OFFSET :
			RIO_INB_ATMU_REGS_PORT2_OFFSET));

		/* Set to receive packets with any dest ID */
		out_be32((priv->regs_win + RIO_ISR_AACR + i*0x80),
			 RIO_ISR_AACR_AA);

		/* Configure maintenance transaction window */
		out_be32(&priv->maint_atmu_regs->rowbar,
			port->iores.start >> 12);
		out_be32(&priv->maint_atmu_regs->rowar,
			 0x80077000 | (ilog2(RIO_MAINT_WIN_SIZE) - 1));

		priv->maint_win = ioremap(port->iores.start,
				RIO_MAINT_WIN_SIZE);

		rio_law_start = range_start;

		fsl_rio_setup_rmu(port, rmu_np[i]);
		fsl_rio_inbound_mem_init(priv);

		dbell->mport[i] = port;
		pw->mport[i] = port;

		if (rio_register_mport(port)) {
			release_resource(&port->iores);
			kfree(priv);
			kfree(port);
			continue;
		}
		active_ports++;
	}

	if (!active_ports) {
		rc = -ENOLINK;
		goto err;
	}

	fsl_rio_doorbell_init(dbell);
	fsl_rio_port_write_init(pw);

	return 0;
err:
	kfree(pw);
	pw = NULL;
err_pw:
	kfree(dbell);
	dbell = NULL;
err_dbell:
	iounmap(rmu_regs_win);
	rmu_regs_win = NULL;
err_rmu:
	kfree(ops);
err_ops:
	iounmap(rio_regs_win);
	rio_regs_win = NULL;
err_rio_regs:
	return rc;
}

/* The probe function for RapidIO peer-to-peer network.
 */
static int fsl_of_rio_rpn_probe(struct platform_device *dev)
{
	printk(KERN_INFO "Setting up RapidIO peer-to-peer network %pOF\n",
			dev->dev.of_node);

	return fsl_rio_setup(dev);
};

static const struct of_device_id fsl_of_rio_rpn_ids[] = {
	{
		.compatible = "fsl,srio",
	},
	{},
};

static struct platform_driver fsl_of_rio_rpn_driver = {
	.driver = {
		.name = "fsl-of-rio",
		.of_match_table = fsl_of_rio_rpn_ids,
	},
	.probe = fsl_of_rio_rpn_probe,
};

static __init int fsl_of_rio_rpn_init(void)
{
	return platform_driver_register(&fsl_of_rio_rpn_driver);
}

subsys_initcall(fsl_of_rio_rpn_init);
