diff options
| author | Zhang Wei <wei.zhang@freescale.com> | 2008-04-18 16:33:41 -0400 |
|---|---|---|
| committer | Paul Mackerras <paulus@samba.org> | 2008-04-29 05:40:28 -0400 |
| commit | cc2bb6968a2c842149d285d77cb35200d2d37b15 (patch) | |
| tree | 33349a2231af61b59bdf28312c385197f41a769f | |
| parent | ad1e9380b17addf112f89ce5a57d4d0bee129b7a (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/Makefile | 1 | ||||
| -rw-r--r-- | arch/powerpc/kernel/rio.c | 52 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/fsl_rio.c | 110 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/fsl_rio.h | 20 |
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 | |||
| 73 | obj-$(CONFIG_PCI) += pci_$(CONFIG_WORD_SIZE).o $(pci64-y) \ | 73 | obj-$(CONFIG_PCI) += pci_$(CONFIG_WORD_SIZE).o $(pci64-y) \ |
| 74 | pci-common.o | 74 | pci-common.o |
| 75 | obj-$(CONFIG_PCI_MSI) += msi.o | 75 | obj-$(CONFIG_PCI_MSI) += msi.o |
| 76 | obj-$(CONFIG_RAPIDIO) += rio.o | ||
| 77 | obj-$(CONFIG_KEXEC) += machine_kexec.o crash.o \ | 76 | obj-$(CONFIG_KEXEC) += machine_kexec.o crash.o \ |
| 78 | machine_kexec_$(CONFIG_WORD_SIZE).o | 77 | machine_kexec_$(CONFIG_WORD_SIZE).o |
| 79 | obj-$(CONFIG_AUDIT) += audit.o | 78 | obj-$(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 | */ | ||
| 26 | void __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 | */ | ||
| 39 | static 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 | |||
| 52 | subsys_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 | */ |
| 915 | void fsl_rio_setup(int law_start, int law_size) | 914 | int 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, ®s); | ||
| 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; |
| 976 | err: | 1029 | err: |
| 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 | */ | ||
| 1040 | static 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(); | ||
| 1053 | out: | ||
| 1054 | return rc; | ||
| 1055 | }; | ||
| 1056 | |||
| 1057 | static const struct of_device_id fsl_of_rio_rpn_ids[] = { | ||
| 1058 | { | ||
| 1059 | .compatible = "fsl,rapidio-delta", | ||
| 1060 | }, | ||
| 1061 | {}, | ||
| 1062 | }; | ||
| 1063 | |||
| 1064 | static 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 | |||
| 1070 | static __init int fsl_of_rio_rpn_init(void) | ||
| 1071 | { | ||
| 1072 | return of_register_platform_driver(&fsl_of_rio_rpn_driver); | ||
| 1073 | } | ||
| 1074 | |||
| 1075 | subsys_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 | |||
| 18 | extern void mpc85xx_rio_setup(int law_start, int law_size); | ||
| 19 | |||
| 20 | #endif /* __PPC_SYSLIB_PPC85XX_RIO_H */ | ||
