aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev/fsl_rio.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/sysdev/fsl_rio.c')
-rw-r--r--arch/powerpc/sysdev/fsl_rio.c110
1 files changed, 102 insertions, 8 deletions
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);