Skip to content

Commit

Permalink
[RAPIDIO] Add OF-tree support to RapidIO controller driver
Browse files Browse the repository at this point in the history
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: Zhang Wei <wei.zhang@freescale.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
  • Loading branch information
Zhang Wei authored and Paul Mackerras committed Apr 29, 2008
1 parent ad1e938 commit cc2bb69
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 81 deletions.
1 change: 0 additions & 1 deletion arch/powerpc/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ pci64-$(CONFIG_PPC64) += pci_dn.o isa-bridge.o
obj-$(CONFIG_PCI) += pci_$(CONFIG_WORD_SIZE).o $(pci64-y) \
pci-common.o
obj-$(CONFIG_PCI_MSI) += msi.o
obj-$(CONFIG_RAPIDIO) += rio.o
obj-$(CONFIG_KEXEC) += machine_kexec.o crash.o \
machine_kexec_$(CONFIG_WORD_SIZE).o
obj-$(CONFIG_AUDIT) += audit.o
Expand Down
52 changes: 0 additions & 52 deletions arch/powerpc/kernel/rio.c

This file was deleted.

110 changes: 102 additions & 8 deletions arch/powerpc/sysdev/fsl_rio.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <linux/interrupt.h>
#include <linux/rio.h>
#include <linux/rio_drv.h>
#include <linux/of_platform.h>

#include <asm/io.h>

Expand All @@ -28,7 +29,6 @@
#define IRQ_RIO_TX(m) (((struct rio_priv *)(m->priv))->txirq)
#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_MSG_REGS_OFFSET 0x11000
#define RIO_MAINT_WIN_SIZE 0x400000
Expand Down Expand Up @@ -905,19 +905,66 @@ __setup("riohdid=", fsl_rio_get_cmdline);

/**
* fsl_rio_setup - Setup MPC85xx RapidIO interface
* @law_start: Starting physical address of RapidIO LAW
* @law_size: Size of RapidIO LAW
* @fsl_rio_setup - Setup Freescale PowerPC RapidIO interface
*
* Initializes MPC85xx RapidIO hardware interface, configures
* master port with system-specific info, and registers the
* 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_mport *port;
struct rio_priv *priv = NULL;
int rc;
struct rio_priv *priv;
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->lcread = fsl_local_config_read;
Expand All @@ -942,6 +989,12 @@ void fsl_rio_setup(int law_start, int law_size)
port->iores.end = law_start + law_size;
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_mbox_res(&port->riores[RIO_INB_MBOX_RESOURCE], 0, 0);
rio_init_mbox_res(&port->riores[RIO_OUTB_MBOX_RESOURCE], 0, 0);
Expand All @@ -953,7 +1006,7 @@ void fsl_rio_setup(int law_start, int law_size)
port->priv = priv;
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
+ RIO_ATMU_REGS_OFFSET);
priv->maint_atmu_regs = priv->atmu_regs + 1;
Expand All @@ -972,10 +1025,51 @@ void fsl_rio_setup(int law_start, int law_size)
out_be32(&priv->dbell_atmu_regs->rowar, 0x8004200b);
fsl_rio_doorbell_init(port);

return;
return 0;
err:
if (priv)
iounmap(priv->regs_win);
kfree(ops);
kfree(priv);
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);
20 changes: 0 additions & 20 deletions arch/powerpc/sysdev/fsl_rio.h

This file was deleted.

0 comments on commit cc2bb69

Please sign in to comment.