Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] RapidIO support: core base

Adds a RapidIO subsystem to the kernel. RIO is a switched fabric interconnect
used in higher-end embedded applications. The curious can look at the specs
over at http://www.rapidio.org

The core code implements enumeration/discovery, management of
devices/resources, and interfaces for RIO drivers.

There's a lot more to do to take advantages of all the hardware features.
However, this should provide a good base for folks with RIO hardware to start
contributing.

Signed-off-by: Matt Porter <mporter@kernel.crashing.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Matt Porter and committed by
Linus Torvalds
394b701c d217d545

+1393 -1
+1 -1
Documentation/DocBook/Makefile
··· 10 10 kernel-hacking.xml kernel-locking.xml deviceiobook.xml \ 11 11 procfs-guide.xml writing_usb_driver.xml \ 12 12 sis900.xml kernel-api.xml journal-api.xml lsm.xml usb.xml \ 13 - gadget.xml libata.xml mtdnand.xml librs.xml 13 + gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml 14 14 15 15 ### 16 16 # The build process is as follows (targets):
+160
Documentation/DocBook/rapidio.tmpl
··· 1 + <?xml version="1.0" encoding="UTF-8"?> 2 + <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" 3 + "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [ 4 + <!ENTITY rapidio SYSTEM "rapidio.xml"> 5 + ]> 6 + 7 + <book id="RapidIO-Guide"> 8 + <bookinfo> 9 + <title>RapidIO Subsystem Guide</title> 10 + 11 + <authorgroup> 12 + <author> 13 + <firstname>Matt</firstname> 14 + <surname>Porter</surname> 15 + <affiliation> 16 + <address> 17 + <email>mporter@kernel.crashing.org</email> 18 + <email>mporter@mvista.com</email> 19 + </address> 20 + </affiliation> 21 + </author> 22 + </authorgroup> 23 + 24 + <copyright> 25 + <year>2005</year> 26 + <holder>MontaVista Software, Inc.</holder> 27 + </copyright> 28 + 29 + <legalnotice> 30 + <para> 31 + This documentation is free software; you can redistribute 32 + it and/or modify it under the terms of the GNU General Public 33 + License version 2 as published by the Free Software Foundation. 34 + </para> 35 + 36 + <para> 37 + This program is distributed in the hope that it will be 38 + useful, but WITHOUT ANY WARRANTY; without even the implied 39 + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 40 + See the GNU General Public License for more details. 41 + </para> 42 + 43 + <para> 44 + You should have received a copy of the GNU General Public 45 + License along with this program; if not, write to the Free 46 + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 47 + MA 02111-1307 USA 48 + </para> 49 + 50 + <para> 51 + For more details see the file COPYING in the source 52 + distribution of Linux. 53 + </para> 54 + </legalnotice> 55 + </bookinfo> 56 + 57 + <toc></toc> 58 + 59 + <chapter id="intro"> 60 + <title>Introduction</title> 61 + <para> 62 + RapidIO is a high speed switched fabric interconnect with 63 + features aimed at the embedded market. RapidIO provides 64 + support for memory-mapped I/O as well as message-based 65 + transactions over the switched fabric network. RapidIO has 66 + a standardized discovery mechanism not unlike the PCI bus 67 + standard that allows simple detection of devices in a 68 + network. 69 + </para> 70 + <para> 71 + This documentation is provided for developers intending 72 + to support RapidIO on new architectures, write new drivers, 73 + or to understand the subsystem internals. 74 + </para> 75 + </chapter> 76 + 77 + <chapter id="bugs"> 78 + <title>Known Bugs and Limitations</title> 79 + 80 + <sect1> 81 + <title>Bugs</title> 82 + <para>None. ;)</para> 83 + </sect1> 84 + <sect1> 85 + <title>Limitations</title> 86 + <para> 87 + <orderedlist> 88 + <listitem><para>Access/management of RapidIO memory regions is not supported</para></listitem> 89 + <listitem><para>Multiple host enumeration is not supported</para></listitem> 90 + </orderedlist> 91 + </para> 92 + </sect1> 93 + </chapter> 94 + 95 + <chapter id="drivers"> 96 + <title>RapidIO driver interface</title> 97 + <para> 98 + Drivers are provided a set of calls in order 99 + to interface with the subsystem to gather info 100 + on devices, request/map memory region resources, 101 + and manage mailboxes/doorbells. 102 + </para> 103 + <sect1> 104 + <title>Functions</title> 105 + !Iinclude/linux/rio_drv.h 106 + !Edrivers/rapidio/rio-driver.c 107 + !Edrivers/rapidio/rio.c 108 + </sect1> 109 + </chapter> 110 + 111 + <chapter id="internals"> 112 + <title>Internals</title> 113 + 114 + <para> 115 + This chapter contains the autogenerated documentation of the RapidIO 116 + subsystem. 117 + </para> 118 + 119 + <sect1><title>Structures</title> 120 + !Iinclude/linux/rio.h 121 + </sect1> 122 + <sect1><title>Enumeration and Discovery</title> 123 + !Idrivers/rapidio/rio-scan.c 124 + </sect1> 125 + <sect1><title>Driver functionality</title> 126 + !Idrivers/rapidio/rio.c 127 + !Idrivers/rapidio/rio-access.c 128 + </sect1> 129 + <sect1><title>Device model support</title> 130 + !Idrivers/rapidio/rio-driver.c 131 + </sect1> 132 + <sect1><title>Sysfs support</title> 133 + !Idrivers/rapidio/rio-sysfs.c 134 + </sect1> 135 + <sect1><title>PPC32 support</title> 136 + !Iarch/ppc/kernel/rio.c 137 + !Earch/ppc/syslib/ppc85xx_rio.c 138 + !Iarch/ppc/syslib/ppc85xx_rio.c 139 + </sect1> 140 + </chapter> 141 + 142 + <chapter id="credits"> 143 + <title>Credits</title> 144 + <para> 145 + The following people have contributed to the RapidIO 146 + subsystem directly or indirectly: 147 + <orderedlist> 148 + <listitem><para>Matt Porter<email>mporter@kernel.crashing.org</email></para></listitem> 149 + <listitem><para>Randy Vinson<email>rvinson@mvista.com</email></para></listitem> 150 + <listitem><para>Dan Malek<email>dan@embeddedalley.com</email></para></listitem> 151 + </orderedlist> 152 + </para> 153 + <para> 154 + The following people have contributed to this document: 155 + <orderedlist> 156 + <listitem><para>Matt Porter<email>mporter@kernel.crashing.org</email></para></listitem> 157 + </orderedlist> 158 + </para> 159 + </chapter> 160 + </book>
+6
MAINTAINERS
··· 2071 2071 M: mpm@selenic.com 2072 2072 S: Maintained 2073 2073 2074 + RAPIDIO SUBSYSTEM 2075 + P: Matt Porter 2076 + M: mporter@kernel.crashing.org 2077 + L: linux-kernel@vger.kernel.org 2078 + S: Maintained 2079 + 2074 2080 REAL TIME CLOCK DRIVER 2075 2081 P: Paul Gortmaker 2076 2082 M: p_gortmaker@yahoo.com
+1
drivers/Makefile
··· 7 7 8 8 obj-$(CONFIG_PCI) += pci/ usb/ 9 9 obj-$(CONFIG_PARISC) += parisc/ 10 + obj-$(CONFIG_RAPIDIO) += rapidio/ 10 11 obj-y += video/ 11 12 obj-$(CONFIG_ACPI) += acpi/ 12 13 # PnP must come after ACPI since it will eventually need to check if acpi
+18
drivers/rapidio/Kconfig
··· 1 + # 2 + # RapidIO configuration 3 + # 4 + config RAPIDIO_8_BIT_TRANSPORT 5 + bool "8-bit transport addressing" 6 + depends on RAPIDIO 7 + ---help--- 8 + By default, the kernel assumes a 16-bit addressed RapidIO 9 + network. By selecting this option, the kernel will support 10 + an 8-bit addressed network. 11 + 12 + config RAPIDIO_DISC_TIMEOUT 13 + int "Discovery timeout duration (seconds)" 14 + depends on RAPIDIO 15 + default "30" 16 + ---help--- 17 + Amount of time a discovery node waits for a host to complete 18 + enumeration beforing giving up.
+6
drivers/rapidio/Makefile
··· 1 + # 2 + # Makefile for RapidIO interconnect services 3 + # 4 + obj-y += rio.o rio-access.o rio-driver.o rio-scan.o rio-sysfs.o 5 + 6 + obj-$(CONFIG_RAPIDIO) += switches/
+175
drivers/rapidio/rio-access.c
··· 1 + /* 2 + * RapidIO configuration space access 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/rio.h> 14 + #include <linux/module.h> 15 + 16 + /* 17 + * These interrupt-safe spinlocks protect all accesses to RIO 18 + * configuration space and doorbell access. 19 + */ 20 + static spinlock_t rio_config_lock = SPIN_LOCK_UNLOCKED; 21 + static spinlock_t rio_doorbell_lock = SPIN_LOCK_UNLOCKED; 22 + 23 + /* 24 + * Wrappers for all RIO configuration access functions. They just check 25 + * alignment, do locking and call the low-level functions pointed to 26 + * by rio_mport->ops. 27 + */ 28 + 29 + #define RIO_8_BAD 0 30 + #define RIO_16_BAD (offset & 1) 31 + #define RIO_32_BAD (offset & 3) 32 + 33 + /** 34 + * RIO_LOP_READ - Generate rio_local_read_config_* functions 35 + * @size: Size of configuration space read (8, 16, 32 bits) 36 + * @type: C type of value argument 37 + * @len: Length of configuration space read (1, 2, 4 bytes) 38 + * 39 + * Generates rio_local_read_config_* functions used to access 40 + * configuration space registers on the local device. 41 + */ 42 + #define RIO_LOP_READ(size,type,len) \ 43 + int __rio_local_read_config_##size \ 44 + (struct rio_mport *mport, u32 offset, type *value) \ 45 + { \ 46 + int res; \ 47 + unsigned long flags; \ 48 + u32 data = 0; \ 49 + if (RIO_##size##_BAD) return RIO_BAD_SIZE; \ 50 + spin_lock_irqsave(&rio_config_lock, flags); \ 51 + res = mport->ops->lcread(mport->id, offset, len, &data); \ 52 + *value = (type)data; \ 53 + spin_unlock_irqrestore(&rio_config_lock, flags); \ 54 + return res; \ 55 + } 56 + 57 + /** 58 + * RIO_LOP_WRITE - Generate rio_local_write_config_* functions 59 + * @size: Size of configuration space write (8, 16, 32 bits) 60 + * @type: C type of value argument 61 + * @len: Length of configuration space write (1, 2, 4 bytes) 62 + * 63 + * Generates rio_local_write_config_* functions used to access 64 + * configuration space registers on the local device. 65 + */ 66 + #define RIO_LOP_WRITE(size,type,len) \ 67 + int __rio_local_write_config_##size \ 68 + (struct rio_mport *mport, u32 offset, type value) \ 69 + { \ 70 + int res; \ 71 + unsigned long flags; \ 72 + if (RIO_##size##_BAD) return RIO_BAD_SIZE; \ 73 + spin_lock_irqsave(&rio_config_lock, flags); \ 74 + res = mport->ops->lcwrite(mport->id, offset, len, value); \ 75 + spin_unlock_irqrestore(&rio_config_lock, flags); \ 76 + return res; \ 77 + } 78 + 79 + RIO_LOP_READ(8, u8, 1) 80 + RIO_LOP_READ(16, u16, 2) 81 + RIO_LOP_READ(32, u32, 4) 82 + RIO_LOP_WRITE(8, u8, 1) 83 + RIO_LOP_WRITE(16, u16, 2) 84 + RIO_LOP_WRITE(32, u32, 4) 85 + 86 + EXPORT_SYMBOL_GPL(__rio_local_read_config_8); 87 + EXPORT_SYMBOL_GPL(__rio_local_read_config_16); 88 + EXPORT_SYMBOL_GPL(__rio_local_read_config_32); 89 + EXPORT_SYMBOL_GPL(__rio_local_write_config_8); 90 + EXPORT_SYMBOL_GPL(__rio_local_write_config_16); 91 + EXPORT_SYMBOL_GPL(__rio_local_write_config_32); 92 + 93 + /** 94 + * RIO_OP_READ - Generate rio_mport_read_config_* functions 95 + * @size: Size of configuration space read (8, 16, 32 bits) 96 + * @type: C type of value argument 97 + * @len: Length of configuration space read (1, 2, 4 bytes) 98 + * 99 + * Generates rio_mport_read_config_* functions used to access 100 + * configuration space registers on the local device. 101 + */ 102 + #define RIO_OP_READ(size,type,len) \ 103 + int rio_mport_read_config_##size \ 104 + (struct rio_mport *mport, u16 destid, u8 hopcount, u32 offset, type *value) \ 105 + { \ 106 + int res; \ 107 + unsigned long flags; \ 108 + u32 data = 0; \ 109 + if (RIO_##size##_BAD) return RIO_BAD_SIZE; \ 110 + spin_lock_irqsave(&rio_config_lock, flags); \ 111 + res = mport->ops->cread(mport->id, destid, hopcount, offset, len, &data); \ 112 + *value = (type)data; \ 113 + spin_unlock_irqrestore(&rio_config_lock, flags); \ 114 + return res; \ 115 + } 116 + 117 + /** 118 + * RIO_OP_WRITE - Generate rio_mport_write_config_* functions 119 + * @size: Size of configuration space write (8, 16, 32 bits) 120 + * @type: C type of value argument 121 + * @len: Length of configuration space write (1, 2, 4 bytes) 122 + * 123 + * Generates rio_mport_write_config_* functions used to access 124 + * configuration space registers on the local device. 125 + */ 126 + #define RIO_OP_WRITE(size,type,len) \ 127 + int rio_mport_write_config_##size \ 128 + (struct rio_mport *mport, u16 destid, u8 hopcount, u32 offset, type value) \ 129 + { \ 130 + int res; \ 131 + unsigned long flags; \ 132 + if (RIO_##size##_BAD) return RIO_BAD_SIZE; \ 133 + spin_lock_irqsave(&rio_config_lock, flags); \ 134 + res = mport->ops->cwrite(mport->id, destid, hopcount, offset, len, value); \ 135 + spin_unlock_irqrestore(&rio_config_lock, flags); \ 136 + return res; \ 137 + } 138 + 139 + RIO_OP_READ(8, u8, 1) 140 + RIO_OP_READ(16, u16, 2) 141 + RIO_OP_READ(32, u32, 4) 142 + RIO_OP_WRITE(8, u8, 1) 143 + RIO_OP_WRITE(16, u16, 2) 144 + RIO_OP_WRITE(32, u32, 4) 145 + 146 + EXPORT_SYMBOL_GPL(rio_mport_read_config_8); 147 + EXPORT_SYMBOL_GPL(rio_mport_read_config_16); 148 + EXPORT_SYMBOL_GPL(rio_mport_read_config_32); 149 + EXPORT_SYMBOL_GPL(rio_mport_write_config_8); 150 + EXPORT_SYMBOL_GPL(rio_mport_write_config_16); 151 + EXPORT_SYMBOL_GPL(rio_mport_write_config_32); 152 + 153 + /** 154 + * rio_mport_send_doorbell - Send a doorbell message 155 + * 156 + * @mport: RIO master port 157 + * @destid: RIO device destination ID 158 + * @data: Doorbell message data 159 + * 160 + * Send a doorbell message to a RIO device. The doorbell message 161 + * has a 16-bit info field provided by the data argument. 162 + */ 163 + int rio_mport_send_doorbell(struct rio_mport *mport, u16 destid, u16 data) 164 + { 165 + int res; 166 + unsigned long flags; 167 + 168 + spin_lock_irqsave(&rio_doorbell_lock, flags); 169 + res = mport->ops->dsend(mport->id, destid, data); 170 + spin_unlock_irqrestore(&rio_doorbell_lock, flags); 171 + 172 + return res; 173 + } 174 + 175 + EXPORT_SYMBOL_GPL(rio_mport_send_doorbell);
+229
drivers/rapidio/rio-driver.c
··· 1 + /* 2 + * RapidIO driver 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/module.h> 15 + #include <linux/rio.h> 16 + #include <linux/rio_ids.h> 17 + 18 + #include "rio.h" 19 + 20 + /** 21 + * rio_match_device - Tell if a RIO device has a matching RIO device id structure 22 + * @id: the RIO device id structure to match against 23 + * @rdev: the RIO device structure to match against 24 + * 25 + * Used from driver probe and bus matching to check whether a RIO device 26 + * matches a device id structure provided by a RIO driver. Returns the 27 + * matching &struct rio_device_id or %NULL if there is no match. 28 + */ 29 + static const struct rio_device_id *rio_match_device(const struct rio_device_id 30 + *id, 31 + const struct rio_dev *rdev) 32 + { 33 + while (id->vid || id->asm_vid) { 34 + if (((id->vid == RIO_ANY_ID) || (id->vid == rdev->vid)) && 35 + ((id->did == RIO_ANY_ID) || (id->did == rdev->did)) && 36 + ((id->asm_vid == RIO_ANY_ID) 37 + || (id->asm_vid == rdev->asm_vid)) 38 + && ((id->asm_did == RIO_ANY_ID) 39 + || (id->asm_did == rdev->asm_did))) 40 + return id; 41 + id++; 42 + } 43 + return NULL; 44 + } 45 + 46 + /** 47 + * rio_dev_get - Increments the reference count of the RIO device structure 48 + * 49 + * @rdev: RIO device being referenced 50 + * 51 + * Each live reference to a device should be refcounted. 52 + * 53 + * Drivers for RIO devices should normally record such references in 54 + * their probe() methods, when they bind to a device, and release 55 + * them by calling rio_dev_put(), in their disconnect() methods. 56 + */ 57 + struct rio_dev *rio_dev_get(struct rio_dev *rdev) 58 + { 59 + if (rdev) 60 + get_device(&rdev->dev); 61 + 62 + return rdev; 63 + } 64 + 65 + /** 66 + * rio_dev_put - Release a use of the RIO device structure 67 + * 68 + * @rdev: RIO device being disconnected 69 + * 70 + * Must be called when a user of a device is finished with it. 71 + * When the last user of the device calls this function, the 72 + * memory of the device is freed. 73 + */ 74 + void rio_dev_put(struct rio_dev *rdev) 75 + { 76 + if (rdev) 77 + put_device(&rdev->dev); 78 + } 79 + 80 + /** 81 + * rio_device_probe - Tell if a RIO device structure has a matching RIO 82 + * device id structure 83 + * @id: the RIO device id structure to match against 84 + * @dev: the RIO device structure to match against 85 + * 86 + * return 0 and set rio_dev->driver when drv claims rio_dev, else error 87 + */ 88 + static int rio_device_probe(struct device *dev) 89 + { 90 + struct rio_driver *rdrv = to_rio_driver(dev->driver); 91 + struct rio_dev *rdev = to_rio_dev(dev); 92 + int error = -ENODEV; 93 + const struct rio_device_id *id; 94 + 95 + if (!rdev->driver && rdrv->probe) { 96 + if (!rdrv->id_table) 97 + return error; 98 + id = rio_match_device(rdrv->id_table, rdev); 99 + rio_dev_get(rdev); 100 + if (id) 101 + error = rdrv->probe(rdev, id); 102 + if (error >= 0) { 103 + rdev->driver = rdrv; 104 + error = 0; 105 + rio_dev_put(rdev); 106 + } 107 + } 108 + return error; 109 + } 110 + 111 + /** 112 + * rio_device_remove - Remove a RIO device from the system 113 + * 114 + * @dev: the RIO device structure to match against 115 + * 116 + * Remove a RIO device from the system. If it has an associated 117 + * driver, then run the driver remove() method. Then update 118 + * the reference count. 119 + */ 120 + static int rio_device_remove(struct device *dev) 121 + { 122 + struct rio_dev *rdev = to_rio_dev(dev); 123 + struct rio_driver *rdrv = rdev->driver; 124 + 125 + if (rdrv) { 126 + if (rdrv->remove) 127 + rdrv->remove(rdev); 128 + rdev->driver = NULL; 129 + } 130 + 131 + rio_dev_put(rdev); 132 + 133 + return 0; 134 + } 135 + 136 + /** 137 + * rio_register_driver - register a new RIO driver 138 + * @rdrv: the RIO driver structure to register 139 + * 140 + * Adds a &struct rio_driver to the list of registered drivers 141 + * Returns a negative value on error, otherwise 0. If no error 142 + * occurred, the driver remains registered even if no device 143 + * was claimed during registration. 144 + */ 145 + int rio_register_driver(struct rio_driver *rdrv) 146 + { 147 + /* initialize common driver fields */ 148 + rdrv->driver.name = rdrv->name; 149 + rdrv->driver.bus = &rio_bus_type; 150 + rdrv->driver.probe = rio_device_probe; 151 + rdrv->driver.remove = rio_device_remove; 152 + 153 + /* register with core */ 154 + return driver_register(&rdrv->driver); 155 + } 156 + 157 + /** 158 + * rio_unregister_driver - unregister a RIO driver 159 + * @rdrv: the RIO driver structure to unregister 160 + * 161 + * Deletes the &struct rio_driver from the list of registered RIO 162 + * drivers, gives it a chance to clean up by calling its remove() 163 + * function for each device it was responsible for, and marks those 164 + * devices as driverless. 165 + */ 166 + void rio_unregister_driver(struct rio_driver *rdrv) 167 + { 168 + driver_unregister(&rdrv->driver); 169 + } 170 + 171 + /** 172 + * rio_match_bus - Tell if a RIO device structure has a matching RIO 173 + * driver device id structure 174 + * @dev: the standard device structure to match against 175 + * @drv: the standard driver structure containing the ids to match against 176 + * 177 + * Used by a driver to check whether a RIO device present in the 178 + * system is in its list of supported devices. Returns 1 if 179 + * there is a matching &struct rio_device_id or 0 if there is 180 + * no match. 181 + */ 182 + static int rio_match_bus(struct device *dev, struct device_driver *drv) 183 + { 184 + struct rio_dev *rdev = to_rio_dev(dev); 185 + struct rio_driver *rdrv = to_rio_driver(drv); 186 + const struct rio_device_id *id = rdrv->id_table; 187 + const struct rio_device_id *found_id; 188 + 189 + if (!id) 190 + goto out; 191 + 192 + found_id = rio_match_device(id, rdev); 193 + 194 + if (found_id) 195 + return 1; 196 + 197 + out:return 0; 198 + } 199 + 200 + static struct device rio_bus = { 201 + .bus_id = "rapidio", 202 + }; 203 + 204 + struct bus_type rio_bus_type = { 205 + .name = "rapidio", 206 + .match = rio_match_bus, 207 + .dev_attrs = rio_dev_attrs 208 + }; 209 + 210 + /** 211 + * rio_bus_init - Register the RapidIO bus with the device model 212 + * 213 + * Registers the RIO bus device and RIO bus type with the Linux 214 + * device model. 215 + */ 216 + static int __init rio_bus_init(void) 217 + { 218 + if (device_register(&rio_bus) < 0) 219 + printk("RIO: failed to register RIO bus device\n"); 220 + return bus_register(&rio_bus_type); 221 + } 222 + 223 + postcore_initcall(rio_bus_init); 224 + 225 + EXPORT_SYMBOL_GPL(rio_register_driver); 226 + EXPORT_SYMBOL_GPL(rio_unregister_driver); 227 + EXPORT_SYMBOL_GPL(rio_bus_type); 228 + EXPORT_SYMBOL_GPL(rio_dev_get); 229 + EXPORT_SYMBOL_GPL(rio_dev_put);
+230
drivers/rapidio/rio-sysfs.c
··· 1 + /* 2 + * RapidIO sysfs attributes and 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/config.h> 14 + #include <linux/kernel.h> 15 + #include <linux/rio.h> 16 + #include <linux/rio_drv.h> 17 + #include <linux/stat.h> 18 + 19 + #include "rio.h" 20 + 21 + /* Sysfs support */ 22 + #define rio_config_attr(field, format_string) \ 23 + static ssize_t \ 24 + field##_show(struct device *dev, char *buf) \ 25 + { \ 26 + struct rio_dev *rdev = to_rio_dev(dev); \ 27 + \ 28 + return sprintf(buf, format_string, rdev->field); \ 29 + } \ 30 + 31 + rio_config_attr(did, "0x%04x\n"); 32 + rio_config_attr(vid, "0x%04x\n"); 33 + rio_config_attr(device_rev, "0x%08x\n"); 34 + rio_config_attr(asm_did, "0x%04x\n"); 35 + rio_config_attr(asm_vid, "0x%04x\n"); 36 + rio_config_attr(asm_rev, "0x%04x\n"); 37 + 38 + static ssize_t routes_show(struct device *dev, char *buf) 39 + { 40 + struct rio_dev *rdev = to_rio_dev(dev); 41 + char *str = buf; 42 + int i; 43 + 44 + if (!rdev->rswitch) 45 + goto out; 46 + 47 + for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++) { 48 + if (rdev->rswitch->route_table[i] == RIO_INVALID_ROUTE) 49 + continue; 50 + str += 51 + sprintf(str, "%04x %02x\n", i, 52 + rdev->rswitch->route_table[i]); 53 + } 54 + 55 + out: 56 + return (str - buf); 57 + } 58 + 59 + struct device_attribute rio_dev_attrs[] = { 60 + __ATTR_RO(did), 61 + __ATTR_RO(vid), 62 + __ATTR_RO(device_rev), 63 + __ATTR_RO(asm_did), 64 + __ATTR_RO(asm_vid), 65 + __ATTR_RO(asm_rev), 66 + __ATTR_RO(routes), 67 + __ATTR_NULL, 68 + }; 69 + 70 + static ssize_t 71 + rio_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count) 72 + { 73 + struct rio_dev *dev = 74 + to_rio_dev(container_of(kobj, struct device, kobj)); 75 + unsigned int size = 0x100; 76 + loff_t init_off = off; 77 + u8 *data = (u8 *) buf; 78 + 79 + /* Several chips lock up trying to read undefined config space */ 80 + if (capable(CAP_SYS_ADMIN)) 81 + size = 0x200000; 82 + 83 + if (off > size) 84 + return 0; 85 + if (off + count > size) { 86 + size -= off; 87 + count = size; 88 + } else { 89 + size = count; 90 + } 91 + 92 + if ((off & 1) && size) { 93 + u8 val; 94 + rio_read_config_8(dev, off, &val); 95 + data[off - init_off] = val; 96 + off++; 97 + size--; 98 + } 99 + 100 + if ((off & 3) && size > 2) { 101 + u16 val; 102 + rio_read_config_16(dev, off, &val); 103 + data[off - init_off] = (val >> 8) & 0xff; 104 + data[off - init_off + 1] = val & 0xff; 105 + off += 2; 106 + size -= 2; 107 + } 108 + 109 + while (size > 3) { 110 + u32 val; 111 + rio_read_config_32(dev, off, &val); 112 + data[off - init_off] = (val >> 24) & 0xff; 113 + data[off - init_off + 1] = (val >> 16) & 0xff; 114 + data[off - init_off + 2] = (val >> 8) & 0xff; 115 + data[off - init_off + 3] = val & 0xff; 116 + off += 4; 117 + size -= 4; 118 + } 119 + 120 + if (size >= 2) { 121 + u16 val; 122 + rio_read_config_16(dev, off, &val); 123 + data[off - init_off] = (val >> 8) & 0xff; 124 + data[off - init_off + 1] = val & 0xff; 125 + off += 2; 126 + size -= 2; 127 + } 128 + 129 + if (size > 0) { 130 + u8 val; 131 + rio_read_config_8(dev, off, &val); 132 + data[off - init_off] = val; 133 + off++; 134 + --size; 135 + } 136 + 137 + return count; 138 + } 139 + 140 + static ssize_t 141 + rio_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count) 142 + { 143 + struct rio_dev *dev = 144 + to_rio_dev(container_of(kobj, struct device, kobj)); 145 + unsigned int size = count; 146 + loff_t init_off = off; 147 + u8 *data = (u8 *) buf; 148 + 149 + if (off > 0x200000) 150 + return 0; 151 + if (off + count > 0x200000) { 152 + size = 0x200000 - off; 153 + count = size; 154 + } 155 + 156 + if ((off & 1) && size) { 157 + rio_write_config_8(dev, off, data[off - init_off]); 158 + off++; 159 + size--; 160 + } 161 + 162 + if ((off & 3) && (size > 2)) { 163 + u16 val = data[off - init_off + 1]; 164 + val |= (u16) data[off - init_off] << 8; 165 + rio_write_config_16(dev, off, val); 166 + off += 2; 167 + size -= 2; 168 + } 169 + 170 + while (size > 3) { 171 + u32 val = data[off - init_off + 3]; 172 + val |= (u32) data[off - init_off + 2] << 8; 173 + val |= (u32) data[off - init_off + 1] << 16; 174 + val |= (u32) data[off - init_off] << 24; 175 + rio_write_config_32(dev, off, val); 176 + off += 4; 177 + size -= 4; 178 + } 179 + 180 + if (size >= 2) { 181 + u16 val = data[off - init_off + 1]; 182 + val |= (u16) data[off - init_off] << 8; 183 + rio_write_config_16(dev, off, val); 184 + off += 2; 185 + size -= 2; 186 + } 187 + 188 + if (size) { 189 + rio_write_config_8(dev, off, data[off - init_off]); 190 + off++; 191 + --size; 192 + } 193 + 194 + return count; 195 + } 196 + 197 + static struct bin_attribute rio_config_attr = { 198 + .attr = { 199 + .name = "config", 200 + .mode = S_IRUGO | S_IWUSR, 201 + .owner = THIS_MODULE, 202 + }, 203 + .size = 0x200000, 204 + .read = rio_read_config, 205 + .write = rio_write_config, 206 + }; 207 + 208 + /** 209 + * rio_create_sysfs_dev_files - create RIO specific sysfs files 210 + * @rdev: device whose entries should be created 211 + * 212 + * Create files when @rdev is added to sysfs. 213 + */ 214 + int rio_create_sysfs_dev_files(struct rio_dev *rdev) 215 + { 216 + sysfs_create_bin_file(&rdev->dev.kobj, &rio_config_attr); 217 + 218 + return 0; 219 + } 220 + 221 + /** 222 + * rio_remove_sysfs_dev_files - cleanup RIO specific sysfs files 223 + * @rdev: device whose entries we should free 224 + * 225 + * Cleanup when @rdev is removed from sysfs. 226 + */ 227 + void rio_remove_sysfs_dev_files(struct rio_dev *rdev) 228 + { 229 + sysfs_remove_bin_file(&rdev->dev.kobj, &rio_config_attr); 230 + }
+503
drivers/rapidio/rio.c
··· 1 + /* 2 + * RapidIO interconnect services 3 + * (RapidIO Interconnect Specification, http://www.rapidio.org) 4 + * 5 + * Copyright 2005 MontaVista Software, Inc. 6 + * Matt Porter <mporter@kernel.crashing.org> 7 + * 8 + * This program is free software; you can redistribute it and/or modify it 9 + * under the terms of the GNU General Public License as published by the 10 + * Free Software Foundation; either version 2 of the License, or (at your 11 + * option) any later version. 12 + */ 13 + 14 + #include <linux/config.h> 15 + #include <linux/types.h> 16 + #include <linux/kernel.h> 17 + 18 + #include <linux/delay.h> 19 + #include <linux/init.h> 20 + #include <linux/rio.h> 21 + #include <linux/rio_drv.h> 22 + #include <linux/rio_ids.h> 23 + #include <linux/rio_regs.h> 24 + #include <linux/module.h> 25 + #include <linux/spinlock.h> 26 + 27 + #include "rio.h" 28 + 29 + static LIST_HEAD(rio_mports); 30 + 31 + /** 32 + * rio_local_get_device_id - Get the base/extended device id for a port 33 + * @port: RIO master port from which to get the deviceid 34 + * 35 + * Reads the base/extended device id from the local device 36 + * implementing the master port. Returns the 8/16-bit device 37 + * id. 38 + */ 39 + u16 rio_local_get_device_id(struct rio_mport *port) 40 + { 41 + u32 result; 42 + 43 + rio_local_read_config_32(port, RIO_DID_CSR, &result); 44 + 45 + return (RIO_GET_DID(result)); 46 + } 47 + 48 + /** 49 + * rio_request_inb_mbox - request inbound mailbox service 50 + * @mport: RIO master port from which to allocate the mailbox resource 51 + * @mbox: Mailbox number to claim 52 + * @entries: Number of entries in inbound mailbox queue 53 + * @minb: Callback to execute when inbound message is received 54 + * 55 + * Requests ownership of an inbound mailbox resource and binds 56 + * a callback function to the resource. Returns %0 on success. 57 + */ 58 + int rio_request_inb_mbox(struct rio_mport *mport, 59 + int mbox, 60 + int entries, 61 + void (*minb) (struct rio_mport * mport, int mbox, 62 + int slot)) 63 + { 64 + int rc = 0; 65 + 66 + struct resource *res = kmalloc(sizeof(struct resource), GFP_KERNEL); 67 + 68 + if (res) { 69 + rio_init_mbox_res(res, mbox, mbox); 70 + 71 + /* Make sure this mailbox isn't in use */ 72 + if ((rc = 73 + request_resource(&mport->riores[RIO_INB_MBOX_RESOURCE], 74 + res)) < 0) { 75 + kfree(res); 76 + goto out; 77 + } 78 + 79 + mport->inb_msg[mbox].res = res; 80 + 81 + /* Hook the inbound message callback */ 82 + mport->inb_msg[mbox].mcback = minb; 83 + 84 + rc = rio_open_inb_mbox(mport, mbox, entries); 85 + } else 86 + rc = -ENOMEM; 87 + 88 + out: 89 + return rc; 90 + } 91 + 92 + /** 93 + * rio_release_inb_mbox - release inbound mailbox message service 94 + * @mport: RIO master port from which to release the mailbox resource 95 + * @mbox: Mailbox number to release 96 + * 97 + * Releases ownership of an inbound mailbox resource. Returns 0 98 + * if the request has been satisfied. 99 + */ 100 + int rio_release_inb_mbox(struct rio_mport *mport, int mbox) 101 + { 102 + rio_close_inb_mbox(mport, mbox); 103 + 104 + /* Release the mailbox resource */ 105 + return release_resource(mport->inb_msg[mbox].res); 106 + } 107 + 108 + /** 109 + * rio_request_outb_mbox - request outbound mailbox service 110 + * @mport: RIO master port from which to allocate the mailbox resource 111 + * @mbox: Mailbox number to claim 112 + * @entries: Number of entries in outbound mailbox queue 113 + * @moutb: Callback to execute when outbound message is sent 114 + * 115 + * Requests ownership of an outbound mailbox resource and binds 116 + * a callback function to the resource. Returns 0 on success. 117 + */ 118 + int rio_request_outb_mbox(struct rio_mport *mport, 119 + int mbox, 120 + int entries, 121 + void (*moutb) (struct rio_mport * mport, int mbox, 122 + int slot)) 123 + { 124 + int rc = 0; 125 + 126 + struct resource *res = kmalloc(sizeof(struct resource), GFP_KERNEL); 127 + 128 + if (res) { 129 + rio_init_mbox_res(res, mbox, mbox); 130 + 131 + /* Make sure this outbound mailbox isn't in use */ 132 + if ((rc = 133 + request_resource(&mport->riores[RIO_OUTB_MBOX_RESOURCE], 134 + res)) < 0) { 135 + kfree(res); 136 + goto out; 137 + } 138 + 139 + mport->outb_msg[mbox].res = res; 140 + 141 + /* Hook the inbound message callback */ 142 + mport->outb_msg[mbox].mcback = moutb; 143 + 144 + rc = rio_open_outb_mbox(mport, mbox, entries); 145 + } else 146 + rc = -ENOMEM; 147 + 148 + out: 149 + return rc; 150 + } 151 + 152 + /** 153 + * rio_release_outb_mbox - release outbound mailbox message service 154 + * @mport: RIO master port from which to release the mailbox resource 155 + * @mbox: Mailbox number to release 156 + * 157 + * Releases ownership of an inbound mailbox resource. Returns 0 158 + * if the request has been satisfied. 159 + */ 160 + int rio_release_outb_mbox(struct rio_mport *mport, int mbox) 161 + { 162 + rio_close_outb_mbox(mport, mbox); 163 + 164 + /* Release the mailbox resource */ 165 + return release_resource(mport->outb_msg[mbox].res); 166 + } 167 + 168 + /** 169 + * rio_setup_inb_dbell - bind inbound doorbell callback 170 + * @mport: RIO master port to bind the doorbell callback 171 + * @res: Doorbell message resource 172 + * @dinb: Callback to execute when doorbell is received 173 + * 174 + * Adds a doorbell resource/callback pair into a port's 175 + * doorbell event list. Returns 0 if the request has been 176 + * satisfied. 177 + */ 178 + static int 179 + rio_setup_inb_dbell(struct rio_mport *mport, struct resource *res, 180 + void (*dinb) (struct rio_mport * mport, u16 src, u16 dst, 181 + u16 info)) 182 + { 183 + int rc = 0; 184 + struct rio_dbell *dbell; 185 + 186 + if (!(dbell = kmalloc(sizeof(struct rio_dbell), GFP_KERNEL))) { 187 + rc = -ENOMEM; 188 + goto out; 189 + } 190 + 191 + dbell->res = res; 192 + dbell->dinb = dinb; 193 + 194 + list_add_tail(&dbell->node, &mport->dbells); 195 + 196 + out: 197 + return rc; 198 + } 199 + 200 + /** 201 + * rio_request_inb_dbell - request inbound doorbell message service 202 + * @mport: RIO master port from which to allocate the doorbell resource 203 + * @start: Doorbell info range start 204 + * @end: Doorbell info range end 205 + * @dinb: Callback to execute when doorbell is received 206 + * 207 + * Requests ownership of an inbound doorbell resource and binds 208 + * a callback function to the resource. Returns 0 if the request 209 + * has been satisfied. 210 + */ 211 + int rio_request_inb_dbell(struct rio_mport *mport, 212 + u16 start, 213 + u16 end, 214 + void (*dinb) (struct rio_mport * mport, u16 src, 215 + u16 dst, u16 info)) 216 + { 217 + int rc = 0; 218 + 219 + struct resource *res = kmalloc(sizeof(struct resource), GFP_KERNEL); 220 + 221 + if (res) { 222 + rio_init_dbell_res(res, start, end); 223 + 224 + /* Make sure these doorbells aren't in use */ 225 + if ((rc = 226 + request_resource(&mport->riores[RIO_DOORBELL_RESOURCE], 227 + res)) < 0) { 228 + kfree(res); 229 + goto out; 230 + } 231 + 232 + /* Hook the doorbell callback */ 233 + rc = rio_setup_inb_dbell(mport, res, dinb); 234 + } else 235 + rc = -ENOMEM; 236 + 237 + out: 238 + return rc; 239 + } 240 + 241 + /** 242 + * rio_release_inb_dbell - release inbound doorbell message service 243 + * @mport: RIO master port from which to release the doorbell resource 244 + * @start: Doorbell info range start 245 + * @end: Doorbell info range end 246 + * 247 + * Releases ownership of an inbound doorbell resource and removes 248 + * callback from the doorbell event list. Returns 0 if the request 249 + * has been satisfied. 250 + */ 251 + int rio_release_inb_dbell(struct rio_mport *mport, u16 start, u16 end) 252 + { 253 + int rc = 0, found = 0; 254 + struct rio_dbell *dbell; 255 + 256 + list_for_each_entry(dbell, &mport->dbells, node) { 257 + if ((dbell->res->start == start) && (dbell->res->end == end)) { 258 + found = 1; 259 + break; 260 + } 261 + } 262 + 263 + /* If we can't find an exact match, fail */ 264 + if (!found) { 265 + rc = -EINVAL; 266 + goto out; 267 + } 268 + 269 + /* Delete from list */ 270 + list_del(&dbell->node); 271 + 272 + /* Release the doorbell resource */ 273 + rc = release_resource(dbell->res); 274 + 275 + /* Free the doorbell event */ 276 + kfree(dbell); 277 + 278 + out: 279 + return rc; 280 + } 281 + 282 + /** 283 + * rio_request_outb_dbell - request outbound doorbell message range 284 + * @rdev: RIO device from which to allocate the doorbell resource 285 + * @start: Doorbell message range start 286 + * @end: Doorbell message range end 287 + * 288 + * Requests ownership of a doorbell message range. Returns a resource 289 + * if the request has been satisfied or %NULL on failure. 290 + */ 291 + struct resource *rio_request_outb_dbell(struct rio_dev *rdev, u16 start, 292 + u16 end) 293 + { 294 + struct resource *res = kmalloc(sizeof(struct resource), GFP_KERNEL); 295 + 296 + if (res) { 297 + rio_init_dbell_res(res, start, end); 298 + 299 + /* Make sure these doorbells aren't in use */ 300 + if (request_resource(&rdev->riores[RIO_DOORBELL_RESOURCE], res) 301 + < 0) { 302 + kfree(res); 303 + res = NULL; 304 + } 305 + } 306 + 307 + return res; 308 + } 309 + 310 + /** 311 + * rio_release_outb_dbell - release outbound doorbell message range 312 + * @rdev: RIO device from which to release the doorbell resource 313 + * @res: Doorbell resource to be freed 314 + * 315 + * Releases ownership of a doorbell message range. Returns 0 if the 316 + * request has been satisfied. 317 + */ 318 + int rio_release_outb_dbell(struct rio_dev *rdev, struct resource *res) 319 + { 320 + int rc = release_resource(res); 321 + 322 + kfree(res); 323 + 324 + return rc; 325 + } 326 + 327 + /** 328 + * rio_mport_get_feature - query for devices' extended features 329 + * @port: Master port to issue transaction 330 + * @local: Indicate a local master port or remote device access 331 + * @destid: Destination ID of the device 332 + * @hopcount: Number of switch hops to the device 333 + * @ftr: Extended feature code 334 + * 335 + * Tell if a device supports a given RapidIO capability. 336 + * Returns the offset of the requested extended feature 337 + * block within the device's RIO configuration space or 338 + * 0 in case the device does not support it. Possible 339 + * values for @ftr: 340 + * 341 + * %RIO_EFB_PAR_EP_ID LP/LVDS EP Devices 342 + * 343 + * %RIO_EFB_PAR_EP_REC_ID LP/LVDS EP Recovery Devices 344 + * 345 + * %RIO_EFB_PAR_EP_FREE_ID LP/LVDS EP Free Devices 346 + * 347 + * %RIO_EFB_SER_EP_ID LP/Serial EP Devices 348 + * 349 + * %RIO_EFB_SER_EP_REC_ID LP/Serial EP Recovery Devices 350 + * 351 + * %RIO_EFB_SER_EP_FREE_ID LP/Serial EP Free Devices 352 + */ 353 + u32 354 + rio_mport_get_feature(struct rio_mport * port, int local, u16 destid, 355 + u8 hopcount, int ftr) 356 + { 357 + u32 asm_info, ext_ftr_ptr, ftr_header; 358 + 359 + if (local) 360 + rio_local_read_config_32(port, RIO_ASM_INFO_CAR, &asm_info); 361 + else 362 + rio_mport_read_config_32(port, destid, hopcount, 363 + RIO_ASM_INFO_CAR, &asm_info); 364 + 365 + ext_ftr_ptr = asm_info & RIO_EXT_FTR_PTR_MASK; 366 + 367 + while (ext_ftr_ptr) { 368 + if (local) 369 + rio_local_read_config_32(port, ext_ftr_ptr, 370 + &ftr_header); 371 + else 372 + rio_mport_read_config_32(port, destid, hopcount, 373 + ext_ftr_ptr, &ftr_header); 374 + if (RIO_GET_BLOCK_ID(ftr_header) == ftr) 375 + return ext_ftr_ptr; 376 + if (!(ext_ftr_ptr = RIO_GET_BLOCK_PTR(ftr_header))) 377 + break; 378 + } 379 + 380 + return 0; 381 + } 382 + 383 + /** 384 + * rio_get_asm - Begin or continue searching for a RIO device by vid/did/asm_vid/asm_did 385 + * @vid: RIO vid to match or %RIO_ANY_ID to match all vids 386 + * @did: RIO did to match or %RIO_ANY_ID to match all dids 387 + * @asm_vid: RIO asm_vid to match or %RIO_ANY_ID to match all asm_vids 388 + * @asm_did: RIO asm_did to match or %RIO_ANY_ID to match all asm_dids 389 + * @from: Previous RIO device found in search, or %NULL for new search 390 + * 391 + * Iterates through the list of known RIO devices. If a RIO device is 392 + * found with a matching @vid, @did, @asm_vid, @asm_did, the reference 393 + * count to the device is incrememted and a pointer to its device 394 + * structure is returned. Otherwise, %NULL is returned. A new search 395 + * is initiated by passing %NULL to the @from argument. Otherwise, if 396 + * @from is not %NULL, searches continue from next device on the global 397 + * list. The reference count for @from is always decremented if it is 398 + * not %NULL. 399 + */ 400 + struct rio_dev *rio_get_asm(u16 vid, u16 did, 401 + u16 asm_vid, u16 asm_did, struct rio_dev *from) 402 + { 403 + struct list_head *n; 404 + struct rio_dev *rdev; 405 + 406 + WARN_ON(in_interrupt()); 407 + spin_lock(&rio_global_list_lock); 408 + n = from ? from->global_list.next : rio_devices.next; 409 + 410 + while (n && (n != &rio_devices)) { 411 + rdev = rio_dev_g(n); 412 + if ((vid == RIO_ANY_ID || rdev->vid == vid) && 413 + (did == RIO_ANY_ID || rdev->did == did) && 414 + (asm_vid == RIO_ANY_ID || rdev->asm_vid == asm_vid) && 415 + (asm_did == RIO_ANY_ID || rdev->asm_did == asm_did)) 416 + goto exit; 417 + n = n->next; 418 + } 419 + rdev = NULL; 420 + exit: 421 + rio_dev_put(from); 422 + rdev = rio_dev_get(rdev); 423 + spin_unlock(&rio_global_list_lock); 424 + return rdev; 425 + } 426 + 427 + /** 428 + * rio_get_device - Begin or continue searching for a RIO device by vid/did 429 + * @vid: RIO vid to match or %RIO_ANY_ID to match all vids 430 + * @did: RIO did to match or %RIO_ANY_ID to match all dids 431 + * @from: Previous RIO device found in search, or %NULL for new search 432 + * 433 + * Iterates through the list of known RIO devices. If a RIO device is 434 + * found with a matching @vid and @did, the reference count to the 435 + * device is incrememted and a pointer to its device structure is returned. 436 + * Otherwise, %NULL is returned. A new search is initiated by passing %NULL 437 + * to the @from argument. Otherwise, if @from is not %NULL, searches 438 + * continue from next device on the global list. The reference count for 439 + * @from is always decremented if it is not %NULL. 440 + */ 441 + struct rio_dev *rio_get_device(u16 vid, u16 did, struct rio_dev *from) 442 + { 443 + return rio_get_asm(vid, did, RIO_ANY_ID, RIO_ANY_ID, from); 444 + } 445 + 446 + static void rio_fixup_device(struct rio_dev *dev) 447 + { 448 + } 449 + 450 + static int __devinit rio_init(void) 451 + { 452 + struct rio_dev *dev = NULL; 453 + 454 + while ((dev = rio_get_device(RIO_ANY_ID, RIO_ANY_ID, dev)) != NULL) { 455 + rio_fixup_device(dev); 456 + } 457 + return 0; 458 + } 459 + 460 + device_initcall(rio_init); 461 + 462 + int rio_init_mports(void) 463 + { 464 + int rc = 0; 465 + struct rio_mport *port; 466 + 467 + list_for_each_entry(port, &rio_mports, node) { 468 + if (!request_mem_region(port->iores.start, 469 + port->iores.end - port->iores.start, 470 + port->name)) { 471 + printk(KERN_ERR 472 + "RIO: Error requesting master port region %8.8lx-%8.8lx\n", 473 + port->iores.start, port->iores.end - 1); 474 + rc = -ENOMEM; 475 + goto out; 476 + } 477 + 478 + if (port->host_deviceid >= 0) 479 + rio_enum_mport(port); 480 + else 481 + rio_disc_mport(port); 482 + } 483 + 484 + out: 485 + return rc; 486 + } 487 + 488 + void rio_register_mport(struct rio_mport *port) 489 + { 490 + list_add_tail(&port->node, &rio_mports); 491 + } 492 + 493 + EXPORT_SYMBOL_GPL(rio_local_get_device_id); 494 + EXPORT_SYMBOL_GPL(rio_get_device); 495 + EXPORT_SYMBOL_GPL(rio_get_asm); 496 + EXPORT_SYMBOL_GPL(rio_request_inb_dbell); 497 + EXPORT_SYMBOL_GPL(rio_release_inb_dbell); 498 + EXPORT_SYMBOL_GPL(rio_request_outb_dbell); 499 + EXPORT_SYMBOL_GPL(rio_release_outb_dbell); 500 + EXPORT_SYMBOL_GPL(rio_request_inb_mbox); 501 + EXPORT_SYMBOL_GPL(rio_release_inb_mbox); 502 + EXPORT_SYMBOL_GPL(rio_request_outb_mbox); 503 + EXPORT_SYMBOL_GPL(rio_release_outb_mbox);
+57
drivers/rapidio/rio.h
··· 1 + /* 2 + * RapidIO interconnect services 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/device.h> 14 + #include <linux/list.h> 15 + #include <linux/rio.h> 16 + 17 + /* Functions internal to the RIO core code */ 18 + 19 + extern u32 rio_mport_get_feature(struct rio_mport *mport, int local, u16 destid, 20 + u8 hopcount, int ftr); 21 + extern int rio_create_sysfs_dev_files(struct rio_dev *rdev); 22 + extern int rio_enum_mport(struct rio_mport *mport); 23 + extern int rio_disc_mport(struct rio_mport *mport); 24 + 25 + /* Structures internal to the RIO core code */ 26 + extern struct device_attribute rio_dev_attrs[]; 27 + extern spinlock_t rio_global_list_lock; 28 + 29 + /* Helpers internal to the RIO core code */ 30 + #define DECLARE_RIO_ROUTE_SECTION(section, vid, did, add_hook, get_hook) \ 31 + static struct rio_route_ops __rio_route_ops __attribute_used__ \ 32 + __attribute__((__section__(#section))) = { vid, did, add_hook, get_hook }; 33 + 34 + /** 35 + * DECLARE_RIO_ROUTE_OPS - Registers switch routing operations 36 + * @vid: RIO vendor ID 37 + * @did: RIO device ID 38 + * @add_hook: Callback that adds a route entry 39 + * @get_hook: Callback that gets a route entry 40 + * 41 + * Manipulating switch route tables in RIO is switch specific. This 42 + * registers a switch by vendor and device ID with two callbacks for 43 + * modifying and retrieving route entries in a switch. A &struct 44 + * rio_route_ops is initialized with the ops and placed into a 45 + * RIO-specific kernel section. 46 + */ 47 + #define DECLARE_RIO_ROUTE_OPS(vid, did, add_hook, get_hook) \ 48 + DECLARE_RIO_ROUTE_SECTION(.rio_route_ops, \ 49 + vid, did, add_hook, get_hook) 50 + 51 + #ifdef CONFIG_RAPIDIO_8_BIT_TRANSPORT 52 + #define RIO_GET_DID(x) ((x & 0x00ff0000) >> 16) 53 + #define RIO_SET_DID(x) ((x & 0x000000ff) << 16) 54 + #else 55 + #define RIO_GET_DID(x) (x & 0xffff) 56 + #define RIO_SET_DID(x) (x & 0xffff) 57 + #endif
+7
include/asm-generic/vmlinux.lds.h
··· 35 35 VMLINUX_SYMBOL(__end_pci_fixups_enable) = .; \ 36 36 } \ 37 37 \ 38 + /* RapidIO route ops */ \ 39 + .rio_route : AT(ADDR(.rio_route) - LOAD_OFFSET) { \ 40 + VMLINUX_SYMBOL(__start_rio_route_ops) = .; \ 41 + *(.rio_route_ops) \ 42 + VMLINUX_SYMBOL(__end_rio_route_ops) = .; \ 43 + } \ 44 + \ 38 45 /* Kernel symbol table: Normal symbols */ \ 39 46 __ksymtab : AT(ADDR(__ksymtab) - LOAD_OFFSET) { \ 40 47 VMLINUX_SYMBOL(__start___ksymtab) = .; \