Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cc2bb696 authored by Zhang Wei's avatar Zhang Wei Committed by Paul Mackerras
Browse files

[RAPIDIO] Add OF-tree support to RapidIO controller driver



This initializes the RapidIO controller driver using addresses and
interrupt numbers obtained from the firmware device tree, rather than
using hardcoded constants.

Signed-off-by: default avatarZhang Wei <wei.zhang@freescale.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent ad1e9380
Loading
Loading
Loading
Loading
+0 −1
Original line number Original line Diff line number Diff line
@@ -73,7 +73,6 @@ pci64-$(CONFIG_PPC64) += pci_dn.o isa-bridge.o
obj-$(CONFIG_PCI)		+= pci_$(CONFIG_WORD_SIZE).o $(pci64-y) \
obj-$(CONFIG_PCI)		+= pci_$(CONFIG_WORD_SIZE).o $(pci64-y) \
				   pci-common.o
				   pci-common.o
obj-$(CONFIG_PCI_MSI)		+= msi.o
obj-$(CONFIG_PCI_MSI)		+= msi.o
obj-$(CONFIG_RAPIDIO)		+= rio.o
obj-$(CONFIG_KEXEC)		+= machine_kexec.o crash.o \
obj-$(CONFIG_KEXEC)		+= machine_kexec.o crash.o \
				   machine_kexec_$(CONFIG_WORD_SIZE).o
				   machine_kexec_$(CONFIG_WORD_SIZE).o
obj-$(CONFIG_AUDIT)		+= audit.o
obj-$(CONFIG_AUDIT)		+= audit.o

arch/powerpc/kernel/rio.c

deleted100644 → 0
+0 −52
Original line number Original line Diff line number Diff line
/*
 * RapidIO PPC32 support
 *
 * Copyright 2005 MontaVista Software, Inc.
 * Matt Porter <mporter@kernel.crashing.org>
 *
 * 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.
 */

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/rio.h>

#include <asm/rio.h>

/**
 * platform_rio_init - Do platform specific RIO init
 *
 * Any platform specific initialization of RapdIO
 * hardware is done here as well as registration
 * of any active master ports in the system.
 */
void __attribute__ ((weak))
    platform_rio_init(void)
{
	printk(KERN_WARNING "RIO: No platform_rio_init() present\n");
}

/**
 * ppc_rio_init - Do PPC32 RIO init
 *
 * Calls platform-specific RIO init code and then calls
 * rio_init_mports() to initialize any master ports that
 * have been registered with the RIO subsystem.
 */
static int __init ppc_rio_init(void)
{
	printk(KERN_INFO "RIO: RapidIO init\n");

	/* Platform specific initialization */
	platform_rio_init();

	/* Enumerate all registered ports */
	rio_init_mports();

	return 0;
}

subsys_initcall(ppc_rio_init);
+102 −8
Original line number Original line Diff line number Diff line
@@ -20,6 +20,7 @@
#include <linux/interrupt.h>
#include <linux/interrupt.h>
#include <linux/rio.h>
#include <linux/rio.h>
#include <linux/rio_drv.h>
#include <linux/rio_drv.h>
#include <linux/of_platform.h>


#include <asm/io.h>
#include <asm/io.h>


@@ -28,7 +29,6 @@
#define IRQ_RIO_TX(m)		(((struct rio_priv *)(m->priv))->txirq)
#define IRQ_RIO_TX(m)		(((struct rio_priv *)(m->priv))->txirq)
#define IRQ_RIO_RX(m)		(((struct rio_priv *)(m->priv))->rxirq)
#define IRQ_RIO_RX(m)		(((struct rio_priv *)(m->priv))->rxirq)


#define RIO_REGS_BASE		(CCSRBAR + 0xc0000)
#define RIO_ATMU_REGS_OFFSET	0x10c00
#define RIO_ATMU_REGS_OFFSET	0x10c00
#define RIO_MSG_REGS_OFFSET	0x11000
#define RIO_MSG_REGS_OFFSET	0x11000
#define RIO_MAINT_WIN_SIZE	0x400000
#define RIO_MAINT_WIN_SIZE	0x400000
@@ -905,19 +905,66 @@ __setup("riohdid=", fsl_rio_get_cmdline);


/**
/**
 * fsl_rio_setup - Setup MPC85xx RapidIO interface
 * fsl_rio_setup - Setup MPC85xx RapidIO interface
 * @law_start: Starting physical address of RapidIO LAW
 * @fsl_rio_setup - Setup Freescale PowerPC RapidIO interface
 * @law_size: Size of RapidIO LAW
 *
 *
 * Initializes MPC85xx RapidIO hardware interface, configures
 * Initializes MPC85xx RapidIO hardware interface, configures
 * master port with system-specific info, and registers the
 * master port with system-specific info, and registers the
 * master port with the RapidIO subsystem.
 * master port with the RapidIO subsystem.
 */
 */
void fsl_rio_setup(int law_start, int law_size)
int fsl_rio_setup(struct of_device *dev)
{
{
	struct rio_ops *ops;
	struct rio_ops *ops;
	struct rio_mport *port;
	struct rio_mport *port;
	struct rio_priv *priv = NULL;
	struct rio_priv *priv;
	int rc;
	int rc = 0;
	const u32 *dt_range, *cell;
	struct resource regs;
	int rlen;
	u64 law_start, law_size;
	int paw, aw, sw;

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

	rc = of_address_to_resource(dev->node, 0, &regs);
	if (rc) {
		dev_err(&dev->dev, "Can't get %s property 'reg'\n",
				dev->node->full_name);
		return -EFAULT;
	}
	dev_info(&dev->dev, "Of-device full name %s\n", dev->node->full_name);
	dev_info(&dev->dev, "Regs start 0x%08x size 0x%08x\n",	regs.start,
						regs.end - regs.start + 1);

	dt_range = of_get_property(dev->node, "ranges", &rlen);
	if (!dt_range) {
		dev_err(&dev->dev, "Can't get %s property 'ranges'\n",
				dev->node->full_name);
		return -EFAULT;
	}

	/* Get node address wide */
	cell = of_get_property(dev->node, "#address-cells", NULL);
	if (cell)
		aw = *cell;
	else
		aw = of_n_addr_cells(dev->node);
	/* Get node size wide */
	cell = of_get_property(dev->node, "#size-cells", NULL);
	if (cell)
		sw = *cell;
	else
		sw = of_n_size_cells(dev->node);
	/* Get parent address wide wide */
	paw = of_n_addr_cells(dev->node);

	law_start = of_read_number(dt_range + aw, paw);
	law_size = of_read_number(dt_range + aw + paw, sw);

	dev_info(&dev->dev, "LAW start 0x%016llx, size 0x%016llx.\n",
			law_start, law_size);


	ops = kmalloc(sizeof(struct rio_ops), GFP_KERNEL);
	ops = kmalloc(sizeof(struct rio_ops), GFP_KERNEL);
	ops->lcread = fsl_local_config_read;
	ops->lcread = fsl_local_config_read;
@@ -942,6 +989,12 @@ void fsl_rio_setup(int law_start, int law_size)
	port->iores.end = law_start + law_size;
	port->iores.end = law_start + law_size;
	port->iores.flags = IORESOURCE_MEM;
	port->iores.flags = IORESOURCE_MEM;


	priv->bellirq = irq_of_parse_and_map(dev->node, 2);
	priv->txirq = irq_of_parse_and_map(dev->node, 3);
	priv->rxirq = irq_of_parse_and_map(dev->node, 4);
	dev_info(&dev->dev, "bellirq: %d, txirq: %d, rxirq %d\n", priv->bellirq,
				priv->txirq, priv->rxirq);

	rio_init_dbell_res(&port->riores[RIO_DOORBELL_RESOURCE], 0, 0xffff);
	rio_init_dbell_res(&port->riores[RIO_DOORBELL_RESOURCE], 0, 0xffff);
	rio_init_mbox_res(&port->riores[RIO_INB_MBOX_RESOURCE], 0, 0);
	rio_init_mbox_res(&port->riores[RIO_INB_MBOX_RESOURCE], 0, 0);
	rio_init_mbox_res(&port->riores[RIO_OUTB_MBOX_RESOURCE], 0, 0);
	rio_init_mbox_res(&port->riores[RIO_OUTB_MBOX_RESOURCE], 0, 0);
@@ -953,7 +1006,7 @@ void fsl_rio_setup(int law_start, int law_size)
	port->priv = priv;
	port->priv = priv;
	rio_register_mport(port);
	rio_register_mport(port);


	priv->regs_win = ioremap(RIO_REGS_BASE, 0x20000);
	priv->regs_win = ioremap(regs.start, regs.end - regs.start + 1);
	priv->atmu_regs = (struct rio_atmu_regs *)(priv->regs_win
	priv->atmu_regs = (struct rio_atmu_regs *)(priv->regs_win
					+ RIO_ATMU_REGS_OFFSET);
					+ RIO_ATMU_REGS_OFFSET);
	priv->maint_atmu_regs = priv->atmu_regs + 1;
	priv->maint_atmu_regs = priv->atmu_regs + 1;
@@ -972,10 +1025,51 @@ void fsl_rio_setup(int law_start, int law_size)
	out_be32(&priv->dbell_atmu_regs->rowar, 0x8004200b);
	out_be32(&priv->dbell_atmu_regs->rowar, 0x8004200b);
	fsl_rio_doorbell_init(port);
	fsl_rio_doorbell_init(port);


	return;
	return 0;
err:
err:
	if (priv)
	if (priv)
		iounmap(priv->regs_win);
		iounmap(priv->regs_win);
	kfree(ops);
	kfree(priv);
	kfree(priv);
	kfree(port);
	kfree(port);
	return rc;
}
}

/* The probe function for RapidIO peer-to-peer network.
 */
static int __devinit fsl_of_rio_rpn_probe(struct of_device *dev,
				     const struct of_device_id *match)
{
	int rc;
	printk(KERN_INFO "Setting up RapidIO peer-to-peer network %s\n",
			dev->node->full_name);

	rc = fsl_rio_setup(dev);
	if (rc)
		goto out;

	/* Enumerate all registered ports */
	rc = rio_init_mports();
out:
	return rc;
};

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

static struct of_platform_driver fsl_of_rio_rpn_driver = {
	.name = "fsl-of-rio",
	.match_table = fsl_of_rio_rpn_ids,
	.probe = fsl_of_rio_rpn_probe,
};

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

subsys_initcall(fsl_of_rio_rpn_init);

arch/powerpc/sysdev/fsl_rio.h

deleted100644 → 0
+0 −20
Original line number Original line Diff line number Diff line
/*
 * MPC85xx RapidIO definitions
 *
 * Copyright 2005 MontaVista Software, Inc.
 * Matt Porter <mporter@kernel.crashing.org>
 *
 * 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.
 */

#ifndef __PPC_SYSLIB_PPC85XX_RIO_H
#define __PPC_SYSLIB_PPC85XX_RIO_H

#include <linux/init.h>

extern void mpc85xx_rio_setup(int law_start, int law_size);

#endif				/* __PPC_SYSLIB_PPC85XX_RIO_H */