aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZhang Wei <wei.zhang@freescale.com>2008-04-18 16:33:41 -0400
committerPaul Mackerras <paulus@samba.org>2008-04-29 05:40:28 -0400
commitcc2bb6968a2c842149d285d77cb35200d2d37b15 (patch)
tree33349a2231af61b59bdf28312c385197f41a769f
parentad1e9380b17addf112f89ce5a57d4d0bee129b7a (diff)
[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: Zhang Wei <wei.zhang@freescale.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r--arch/powerpc/kernel/Makefile1
-rw-r--r--arch/powerpc/kernel/rio.c52
-rw-r--r--arch/powerpc/sysdev/fsl_rio.c110
-rw-r--r--arch/powerpc/sysdev/fsl_rio.h20
4 files changed, 102 insertions, 81 deletions
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 9177b21b1a95..d14cebf62bb0 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -73,7 +73,6 @@ pci64-$(CONFIG_PPC64) += pci_dn.o isa-bridge.o
73obj-$(CONFIG_PCI) += pci_$(CONFIG_WORD_SIZE).o $(pci64-y) \ 73obj-$(CONFIG_PCI) += pci_$(CONFIG_WORD_SIZE).o $(pci64-y) \
74 pci-common.o 74 pci-common.o
75obj-$(CONFIG_PCI_MSI) += msi.o 75obj-$(CONFIG_PCI_MSI) += msi.o
76obj-$(CONFIG_RAPIDIO) += rio.o
77obj-$(CONFIG_KEXEC) += machine_kexec.o crash.o \ 76obj-$(CONFIG_KEXEC) += machine_kexec.o crash.o \
78 machine_kexec_$(CONFIG_WORD_SIZE).o 77 machine_kexec_$(CONFIG_WORD_SIZE).o
79obj-$(CONFIG_AUDIT) += audit.o 78obj-$(CONFIG_AUDIT) += audit.o
diff --git a/arch/powerpc/kernel/rio.c b/arch/powerpc/kernel/rio.c
deleted file mode 100644
index 29487fedfc76..000000000000
--- a/arch/powerpc/kernel/rio.c
+++ /dev/null
@@ -1,52 +0,0 @@
1/*
2 * RapidIO PPC32 support
3 *
4 * Copyright 2005 MontaVista Software, Inc.
5 * Matt Porter <mporter@kernel.crashing.org>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/init.h>
14#include <linux/kernel.h>
15#include <linux/rio.h>
16
17#include <asm/rio.h>
18
19/**
20 * platform_rio_init - Do platform specific RIO init
21 *
22 * Any platform specific initialization of RapdIO
23 * hardware is done here as well as registration
24 * of any active master ports in the system.
25 */
26void __attribute__ ((weak))
27 platform_rio_init(void)
28{
29 printk(KERN_WARNING "RIO: No platform_rio_init() present\n");
30}
31
32/**
33 * ppc_rio_init - Do PPC32 RIO init
34 *
35 * Calls platform-specific RIO init code and then calls
36 * rio_init_mports() to initialize any master ports that
37 * have been registered with the RIO subsystem.
38 */
39static int __init ppc_rio_init(void)
40{
41 printk(KERN_INFO "RIO: RapidIO init\n");
42
43 /* Platform specific initialization */
44 platform_rio_init();
45
46 /* Enumerate all registered ports */
47 rio_init_mports();
48
49 return 0;
50}
51
52subsys_initcall(ppc_rio_init);
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index 80acc7940194..d2d14708e714 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -20,6 +20,7 @@
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21#include <linux/rio.h> 21#include <linux/rio.h>
22#include <linux/rio_drv.h> 22#include <linux/rio_drv.h>
23#include <linux/of_platform.h>
23 24
24#include <asm/io.h> 25#include <asm/io.h>
25 26
@@ -28,7 +29,6 @@
28#define IRQ_RIO_TX(m) (((struct rio_priv *)(m->priv))->txirq) 29#define IRQ_RIO_TX(m) (((struct rio_priv *)(m->priv))->txirq)
29#define IRQ_RIO_RX(m) (((struct rio_priv *)(m->priv))->rxirq) 30#define IRQ_RIO_RX(m) (((struct rio_priv *)(m->priv))->rxirq)
30 31
31#define RIO_REGS_BASE (CCSRBAR + 0xc0000)
32#define RIO_ATMU_REGS_OFFSET 0x10c00 32#define RIO_ATMU_REGS_OFFSET 0x10c00
33#define RIO_MSG_REGS_OFFSET 0x11000 33#define RIO_MSG_REGS_OFFSET 0x11000
34#define RIO_MAINT_WIN_SIZE 0x400000 34#define RIO_MAINT_WIN_SIZE 0x400000
@@ -905,19 +905,66 @@ __setup("riohdid=", fsl_rio_get_cmdline);
905 905
906/** 906/**
907 * fsl_rio_setup - Setup MPC85xx RapidIO interface 907 * fsl_rio_setup - Setup MPC85xx RapidIO interface
908 * @law_start: Starting physical address of RapidIO LAW 908 * @fsl_rio_setup - Setup Freescale PowerPC RapidIO interface
909 * @law_size: Size of RapidIO LAW
910 * 909 *
911 * Initializes MPC85xx RapidIO hardware interface, configures 910 * Initializes MPC85xx RapidIO hardware interface, configures
912 * master port with system-specific info, and registers the 911 * master port with system-specific info, and registers the
913 * master port with the RapidIO subsystem. 912 * master port with the RapidIO subsystem.
914 */ 913 */
915void fsl_rio_setup(int law_start, int law_size) 914int fsl_rio_setup(struct of_device *dev)
916{ 915{
917 struct rio_ops *ops; 916 struct rio_ops *ops;
918 struct rio_mport *port; 917 struct rio_mport *port;
919 struct rio_priv *priv = NULL; 918 struct rio_priv *priv;
920 int rc; 919 int rc = 0;
920 const u32 *dt_range, *cell;
921 struct resource regs;
922 int rlen;
923 u64 law_start, law_size;
924 int paw, aw, sw;
925
926 if (!dev->node) {
927 dev_err(&dev->dev, "Device OF-Node is NULL");
928 return -EFAULT;
929 }
930
931 rc = of_address_to_resource(dev->node, 0, &regs);
932 if (rc) {
933 dev_err(&dev->dev, "Can't get %s property 'reg'\n",
934 dev->node->full_name);
935 return -EFAULT;
936 }
937 dev_info(&dev->dev, "Of-device full name %s\n", dev->node->full_name);
938 dev_info(&dev->dev, "Regs start 0x%08x size 0x%08x\n", regs.start,
939 regs.end - regs.start + 1);
940
941 dt_range = of_get_property(dev->node, "ranges", &rlen);
942 if (!dt_range) {
943 dev_err(&dev->dev, "Can't get %s property 'ranges'\n",
944 dev->node->full_name);
945 return -EFAULT;
946 }
947
948 /* Get node address wide */
949 cell = of_get_property(dev->node, "#address-cells", NULL);
950 if (cell)
951 aw = *cell;
952 else
953 aw = of_n_addr_cells(dev->node);
954 /* Get node size wide */
955 cell = of_get_property(dev->node, "#size-cells", NULL);
956 if (cell)
957 sw = *cell;
958 else
959 sw = of_n_size_cells(dev->node);
960 /* Get parent address wide wide */
961 paw = of_n_addr_cells(dev->node);
962
963 law_start = of_read_number(dt_range + aw, paw);
964 law_size = of_read_number(dt_range + aw + paw, sw);
965
966 dev_info(&dev->dev, "LAW start 0x%016llx, size 0x%016llx.\n",
967 law_start, law_size);
921 968
922 ops = kmalloc(sizeof(struct rio_ops), GFP_KERNEL); 969 ops = kmalloc(sizeof(struct rio_ops), GFP_KERNEL);
923 ops->lcread = fsl_local_config_read; 970 ops->lcread = fsl_local_config_read;
@@ -942,6 +989,12 @@ void fsl_rio_setup(int law_start, int law_size)
942 port->iores.end = law_start + law_size; 989 port->iores.end = law_start + law_size;
943 port->iores.flags = IORESOURCE_MEM; 990 port->iores.flags = IORESOURCE_MEM;
944 991
992 priv->bellirq = irq_of_parse_and_map(dev->node, 2);
993 priv->txirq = irq_of_parse_and_map(dev->node, 3);
994 priv->rxirq = irq_of_parse_and_map(dev->node, 4);
995 dev_info(&dev->dev, "bellirq: %d, txirq: %d, rxirq %d\n", priv->bellirq,
996 priv->txirq, priv->rxirq);
997
945 rio_init_dbell_res(&port->riores[RIO_DOORBELL_RESOURCE], 0, 0xffff); 998 rio_init_dbell_res(&port->riores[RIO_DOORBELL_RESOURCE], 0, 0xffff);
946 rio_init_mbox_res(&port->riores[RIO_INB_MBOX_RESOURCE], 0, 0); 999 rio_init_mbox_res(&port->riores[RIO_INB_MBOX_RESOURCE], 0, 0);
947 rio_init_mbox_res(&port->riores[RIO_OUTB_MBOX_RESOURCE], 0, 0); 1000 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)
953 port->priv = priv; 1006 port->priv = priv;
954 rio_register_mport(port); 1007 rio_register_mport(port);
955 1008
956 priv->regs_win = ioremap(RIO_REGS_BASE, 0x20000); 1009 priv->regs_win = ioremap(regs.start, regs.end - regs.start + 1);
957 priv->atmu_regs = (struct rio_atmu_regs *)(priv->regs_win 1010 priv->atmu_regs = (struct rio_atmu_regs *)(priv->regs_win
958 + RIO_ATMU_REGS_OFFSET); 1011 + RIO_ATMU_REGS_OFFSET);
959 priv->maint_atmu_regs = priv->atmu_regs + 1; 1012 priv->maint_atmu_regs = priv->atmu_regs + 1;
@@ -972,10 +1025,51 @@ void fsl_rio_setup(int law_start, int law_size)
972 out_be32(&priv->dbell_atmu_regs->rowar, 0x8004200b); 1025 out_be32(&priv->dbell_atmu_regs->rowar, 0x8004200b);
973 fsl_rio_doorbell_init(port); 1026 fsl_rio_doorbell_init(port);
974 1027
975 return; 1028 return 0;
976err: 1029err:
977 if (priv) 1030 if (priv)
978 iounmap(priv->regs_win); 1031 iounmap(priv->regs_win);
1032 kfree(ops);
979 kfree(priv); 1033 kfree(priv);
980 kfree(port); 1034 kfree(port);
1035 return rc;
981} 1036}
1037
1038/* The probe function for RapidIO peer-to-peer network.
1039 */
1040static int __devinit fsl_of_rio_rpn_probe(struct of_device *dev,
1041 const struct of_device_id *match)
1042{
1043 int rc;
1044 printk(KERN_INFO "Setting up RapidIO peer-to-peer network %s\n",
1045 dev->node->full_name);
1046
1047 rc = fsl_rio_setup(dev);
1048 if (rc)
1049 goto out;
1050
1051 /* Enumerate all registered ports */
1052 rc = rio_init_mports();
1053out:
1054 return rc;
1055};
1056
1057static const struct of_device_id fsl_of_rio_rpn_ids[] = {
1058 {
1059 .compatible = "fsl,rapidio-delta",
1060 },
1061 {},
1062};
1063
1064static struct of_platform_driver fsl_of_rio_rpn_driver = {
1065 .name = "fsl-of-rio",
1066 .match_table = fsl_of_rio_rpn_ids,
1067 .probe = fsl_of_rio_rpn_probe,
1068};
1069
1070static __init int fsl_of_rio_rpn_init(void)
1071{
1072 return of_register_platform_driver(&fsl_of_rio_rpn_driver);
1073}
1074
1075subsys_initcall(fsl_of_rio_rpn_init);
diff --git a/arch/powerpc/sysdev/fsl_rio.h b/arch/powerpc/sysdev/fsl_rio.h
deleted file mode 100644
index 6d3ff30b1579..000000000000
--- a/arch/powerpc/sysdev/fsl_rio.h
+++ /dev/null
@@ -1,20 +0,0 @@
1/*
2 * MPC85xx RapidIO definitions
3 *
4 * Copyright 2005 MontaVista Software, Inc.
5 * Matt Porter <mporter@kernel.crashing.org>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#ifndef __PPC_SYSLIB_PPC85XX_RIO_H
14#define __PPC_SYSLIB_PPC85XX_RIO_H
15
16#include <linux/init.h>
17
18extern void mpc85xx_rio_setup(int law_start, int law_size);
19
20#endif /* __PPC_SYSLIB_PPC85XX_RIO_H */