diff options
author | Alexandre Bounine <alexandre.bounine@idt.com> | 2013-07-03 18:08:50 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-03 19:08:04 -0400 |
commit | 2ec3ba69faf301fb599e3651515e808e8efa533e (patch) | |
tree | 953f10726fd0cd61fec02082233c6097287d7257 | |
parent | 36f0efbbe8e21c153dfc2f94c91f89ab06fd64c5 (diff) |
rapidio: convert switch drivers to modules
Rework RapidIO switch drivers to add an option to build them as loadable
kernel modules.
This patch removes RapidIO-specific vmlinux section and converts switch
drivers to be compatible with LDM driver registration method. To simplify
registration of device-specific callback routines this patch introduces
rio_switch_ops data structure. The sw_sysfs() callback is removed from
the list of device-specific operations because under the new structure its
functions can be handled by switch driver's probe() and remove() routines.
If a specific switch device driver is not loaded the RapidIO subsystem
core will use default standard-based operations to configure a switch.
Because the current implementation of RapidIO enumeration/discovery method
relies on availability of device-specific operations for error management,
switch device drivers must be loaded before the RapidIO
enumeration/discovery starts.
This patch also moves several common routines from enumeration/discovery
module into the RapidIO core code to make switch-specific operations
accessible to all components of RapidIO subsystem.
Signed-off-by: Alexandre Bounine <alexandre.bounine@idt.com>
Cc: Matt Porter <mporter@kernel.crashing.org>
Cc: Li Yang <leoli@freescale.com>
Cc: Kumar Gala <galak@kernel.crashing.org>
Cc: Andre van Herk <andre.van.herk@Prodrive.nl>
Cc: Micha Nelissen <micha.nelissen@Prodrive.nl>
Cc: Stef van Os <stef.van.os@Prodrive.nl>
Cc: Jean Delvare <jdelvare@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | drivers/rapidio/Kconfig | 5 | ||||
-rw-r--r-- | drivers/rapidio/rio-scan.c | 171 | ||||
-rw-r--r-- | drivers/rapidio/rio-sysfs.c | 4 | ||||
-rw-r--r-- | drivers/rapidio/rio.c | 286 | ||||
-rw-r--r-- | drivers/rapidio/rio.h | 41 | ||||
-rw-r--r-- | drivers/rapidio/switches/Kconfig | 12 | ||||
-rw-r--r-- | drivers/rapidio/switches/idt_gen2.c | 98 | ||||
-rw-r--r-- | drivers/rapidio/switches/idtcps.c | 86 | ||||
-rw-r--r-- | drivers/rapidio/switches/tsi568.c | 71 | ||||
-rw-r--r-- | drivers/rapidio/switches/tsi57x.c | 81 | ||||
-rw-r--r-- | include/asm-generic/vmlinux.lds.h | 7 | ||||
-rw-r--r-- | include/linux/rio.h | 51 |
12 files changed, 568 insertions, 345 deletions
diff --git a/drivers/rapidio/Kconfig b/drivers/rapidio/Kconfig index 5ab056494bbe..3e3be57e9a1a 100644 --- a/drivers/rapidio/Kconfig +++ b/drivers/rapidio/Kconfig | |||
@@ -67,4 +67,9 @@ config RAPIDIO_ENUM_BASIC | |||
67 | 67 | ||
68 | endchoice | 68 | endchoice |
69 | 69 | ||
70 | menu "RapidIO Switch drivers" | ||
71 | depends on RAPIDIO | ||
72 | |||
70 | source "drivers/rapidio/switches/Kconfig" | 73 | source "drivers/rapidio/switches/Kconfig" |
74 | |||
75 | endmenu | ||
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c index 4b9b15ee8596..913950212605 100644 --- a/drivers/rapidio/rio-scan.c +++ b/drivers/rapidio/rio-scan.c | |||
@@ -406,6 +406,7 @@ static struct rio_dev *rio_setup_device(struct rio_net *net, | |||
406 | rio_mport_write_config_32(port, destid, hopcount, | 406 | rio_mport_write_config_32(port, destid, hopcount, |
407 | RIO_COMPONENT_TAG_CSR, next_comptag); | 407 | RIO_COMPONENT_TAG_CSR, next_comptag); |
408 | rdev->comp_tag = next_comptag++; | 408 | rdev->comp_tag = next_comptag++; |
409 | rdev->do_enum = true; | ||
409 | } else { | 410 | } else { |
410 | rio_mport_read_config_32(port, destid, hopcount, | 411 | rio_mport_read_config_32(port, destid, hopcount, |
411 | RIO_COMPONENT_TAG_CSR, | 412 | RIO_COMPONENT_TAG_CSR, |
@@ -434,6 +435,7 @@ static struct rio_dev *rio_setup_device(struct rio_net *net, | |||
434 | rswitch = rdev->rswitch; | 435 | rswitch = rdev->rswitch; |
435 | rswitch->switchid = rdev->comp_tag & RIO_CTAG_UDEVID; | 436 | rswitch->switchid = rdev->comp_tag & RIO_CTAG_UDEVID; |
436 | rswitch->port_ok = 0; | 437 | rswitch->port_ok = 0; |
438 | spin_lock_init(&rswitch->lock); | ||
437 | rswitch->route_table = kzalloc(sizeof(u8)* | 439 | rswitch->route_table = kzalloc(sizeof(u8)* |
438 | RIO_MAX_ROUTE_ENTRIES(port->sys_size), | 440 | RIO_MAX_ROUTE_ENTRIES(port->sys_size), |
439 | GFP_KERNEL); | 441 | GFP_KERNEL); |
@@ -445,11 +447,9 @@ static struct rio_dev *rio_setup_device(struct rio_net *net, | |||
445 | rswitch->route_table[rdid] = RIO_INVALID_ROUTE; | 447 | rswitch->route_table[rdid] = RIO_INVALID_ROUTE; |
446 | dev_set_name(&rdev->dev, "%02x:s:%04x", rdev->net->id, | 448 | dev_set_name(&rdev->dev, "%02x:s:%04x", rdev->net->id, |
447 | rswitch->switchid); | 449 | rswitch->switchid); |
448 | rio_switch_init(rdev, do_enum); | ||
449 | 450 | ||
450 | if (do_enum && rswitch->clr_table) | 451 | if (do_enum) |
451 | rswitch->clr_table(port, destid, hopcount, | 452 | rio_route_clr_table(rdev, RIO_GLOBAL_TABLE, 0); |
452 | RIO_GLOBAL_TABLE); | ||
453 | 453 | ||
454 | list_add_tail(&rswitch->node, &net->switches); | 454 | list_add_tail(&rswitch->node, &net->switches); |
455 | 455 | ||
@@ -533,156 +533,6 @@ rio_sport_is_active(struct rio_mport *port, u16 destid, u8 hopcount, int sport) | |||
533 | } | 533 | } |
534 | 534 | ||
535 | /** | 535 | /** |
536 | * rio_lock_device - Acquires host device lock for specified device | ||
537 | * @port: Master port to send transaction | ||
538 | * @destid: Destination ID for device/switch | ||
539 | * @hopcount: Hopcount to reach switch | ||
540 | * @wait_ms: Max wait time in msec (0 = no timeout) | ||
541 | * | ||
542 | * Attepts to acquire host device lock for specified device | ||
543 | * Returns 0 if device lock acquired or EINVAL if timeout expires. | ||
544 | */ | ||
545 | static int | ||
546 | rio_lock_device(struct rio_mport *port, u16 destid, u8 hopcount, int wait_ms) | ||
547 | { | ||
548 | u32 result; | ||
549 | int tcnt = 0; | ||
550 | |||
551 | /* Attempt to acquire device lock */ | ||
552 | rio_mport_write_config_32(port, destid, hopcount, | ||
553 | RIO_HOST_DID_LOCK_CSR, port->host_deviceid); | ||
554 | rio_mport_read_config_32(port, destid, hopcount, | ||
555 | RIO_HOST_DID_LOCK_CSR, &result); | ||
556 | |||
557 | while (result != port->host_deviceid) { | ||
558 | if (wait_ms != 0 && tcnt == wait_ms) { | ||
559 | pr_debug("RIO: timeout when locking device %x:%x\n", | ||
560 | destid, hopcount); | ||
561 | return -EINVAL; | ||
562 | } | ||
563 | |||
564 | /* Delay a bit */ | ||
565 | mdelay(1); | ||
566 | tcnt++; | ||
567 | /* Try to acquire device lock again */ | ||
568 | rio_mport_write_config_32(port, destid, | ||
569 | hopcount, | ||
570 | RIO_HOST_DID_LOCK_CSR, | ||
571 | port->host_deviceid); | ||
572 | rio_mport_read_config_32(port, destid, | ||
573 | hopcount, | ||
574 | RIO_HOST_DID_LOCK_CSR, &result); | ||
575 | } | ||
576 | |||
577 | return 0; | ||
578 | } | ||
579 | |||
580 | /** | ||
581 | * rio_unlock_device - Releases host device lock for specified device | ||
582 | * @port: Master port to send transaction | ||
583 | * @destid: Destination ID for device/switch | ||
584 | * @hopcount: Hopcount to reach switch | ||
585 | * | ||
586 | * Returns 0 if device lock released or EINVAL if fails. | ||
587 | */ | ||
588 | static int | ||
589 | rio_unlock_device(struct rio_mport *port, u16 destid, u8 hopcount) | ||
590 | { | ||
591 | u32 result; | ||
592 | |||
593 | /* Release device lock */ | ||
594 | rio_mport_write_config_32(port, destid, | ||
595 | hopcount, | ||
596 | RIO_HOST_DID_LOCK_CSR, | ||
597 | port->host_deviceid); | ||
598 | rio_mport_read_config_32(port, destid, hopcount, | ||
599 | RIO_HOST_DID_LOCK_CSR, &result); | ||
600 | if ((result & 0xffff) != 0xffff) { | ||
601 | pr_debug("RIO: badness when releasing device lock %x:%x\n", | ||
602 | destid, hopcount); | ||
603 | return -EINVAL; | ||
604 | } | ||
605 | |||
606 | return 0; | ||
607 | } | ||
608 | |||
609 | /** | ||
610 | * rio_route_add_entry- Add a route entry to a switch routing table | ||
611 | * @rdev: RIO device | ||
612 | * @table: Routing table ID | ||
613 | * @route_destid: Destination ID to be routed | ||
614 | * @route_port: Port number to be routed | ||
615 | * @lock: lock switch device flag | ||
616 | * | ||
617 | * Calls the switch specific add_entry() method to add a route entry | ||
618 | * on a switch. The route table can be specified using the @table | ||
619 | * argument if a switch has per port routing tables or the normal | ||
620 | * use is to specific all tables (or the global table) by passing | ||
621 | * %RIO_GLOBAL_TABLE in @table. Returns %0 on success or %-EINVAL | ||
622 | * on failure. | ||
623 | */ | ||
624 | static int | ||
625 | rio_route_add_entry(struct rio_dev *rdev, | ||
626 | u16 table, u16 route_destid, u8 route_port, int lock) | ||
627 | { | ||
628 | int rc; | ||
629 | |||
630 | if (lock) { | ||
631 | rc = rio_lock_device(rdev->net->hport, rdev->destid, | ||
632 | rdev->hopcount, 1000); | ||
633 | if (rc) | ||
634 | return rc; | ||
635 | } | ||
636 | |||
637 | rc = rdev->rswitch->add_entry(rdev->net->hport, rdev->destid, | ||
638 | rdev->hopcount, table, | ||
639 | route_destid, route_port); | ||
640 | if (lock) | ||
641 | rio_unlock_device(rdev->net->hport, rdev->destid, | ||
642 | rdev->hopcount); | ||
643 | |||
644 | return rc; | ||
645 | } | ||
646 | |||
647 | /** | ||
648 | * rio_route_get_entry- Read a route entry in a switch routing table | ||
649 | * @rdev: RIO device | ||
650 | * @table: Routing table ID | ||
651 | * @route_destid: Destination ID to be routed | ||
652 | * @route_port: Pointer to read port number into | ||
653 | * @lock: lock switch device flag | ||
654 | * | ||
655 | * Calls the switch specific get_entry() method to read a route entry | ||
656 | * in a switch. The route table can be specified using the @table | ||
657 | * argument if a switch has per port routing tables or the normal | ||
658 | * use is to specific all tables (or the global table) by passing | ||
659 | * %RIO_GLOBAL_TABLE in @table. Returns %0 on success or %-EINVAL | ||
660 | * on failure. | ||
661 | */ | ||
662 | static int | ||
663 | rio_route_get_entry(struct rio_dev *rdev, u16 table, | ||
664 | u16 route_destid, u8 *route_port, int lock) | ||
665 | { | ||
666 | int rc; | ||
667 | |||
668 | if (lock) { | ||
669 | rc = rio_lock_device(rdev->net->hport, rdev->destid, | ||
670 | rdev->hopcount, 1000); | ||
671 | if (rc) | ||
672 | return rc; | ||
673 | } | ||
674 | |||
675 | rc = rdev->rswitch->get_entry(rdev->net->hport, rdev->destid, | ||
676 | rdev->hopcount, table, | ||
677 | route_destid, route_port); | ||
678 | if (lock) | ||
679 | rio_unlock_device(rdev->net->hport, rdev->destid, | ||
680 | rdev->hopcount); | ||
681 | |||
682 | return rc; | ||
683 | } | ||
684 | |||
685 | /** | ||
686 | * rio_get_host_deviceid_lock- Reads the Host Device ID Lock CSR on a device | 536 | * rio_get_host_deviceid_lock- Reads the Host Device ID Lock CSR on a device |
687 | * @port: Master port to send transaction | 537 | * @port: Master port to send transaction |
688 | * @hopcount: Number of hops to the device | 538 | * @hopcount: Number of hops to the device |
@@ -1094,12 +944,9 @@ static void rio_update_route_tables(struct rio_net *net) | |||
1094 | 944 | ||
1095 | sport = RIO_GET_PORT_NUM(swrdev->swpinfo); | 945 | sport = RIO_GET_PORT_NUM(swrdev->swpinfo); |
1096 | 946 | ||
1097 | if (rswitch->add_entry) { | 947 | rio_route_add_entry(swrdev, RIO_GLOBAL_TABLE, |
1098 | rio_route_add_entry(swrdev, | 948 | destid, sport, 0); |
1099 | RIO_GLOBAL_TABLE, destid, | 949 | rswitch->route_table[destid] = sport; |
1100 | sport, 0); | ||
1101 | rswitch->route_table[destid] = sport; | ||
1102 | } | ||
1103 | } | 950 | } |
1104 | } | 951 | } |
1105 | } | 952 | } |
@@ -1115,8 +962,8 @@ static void rio_update_route_tables(struct rio_net *net) | |||
1115 | static void rio_init_em(struct rio_dev *rdev) | 962 | static void rio_init_em(struct rio_dev *rdev) |
1116 | { | 963 | { |
1117 | if (rio_is_switch(rdev) && (rdev->em_efptr) && | 964 | if (rio_is_switch(rdev) && (rdev->em_efptr) && |
1118 | (rdev->rswitch->em_init)) { | 965 | rdev->rswitch->ops && rdev->rswitch->ops->em_init) { |
1119 | rdev->rswitch->em_init(rdev); | 966 | rdev->rswitch->ops->em_init(rdev); |
1120 | } | 967 | } |
1121 | } | 968 | } |
1122 | 969 | ||
diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c index 66d4acd5e18f..864e52f193e1 100644 --- a/drivers/rapidio/rio-sysfs.c +++ b/drivers/rapidio/rio-sysfs.c | |||
@@ -257,8 +257,6 @@ int rio_create_sysfs_dev_files(struct rio_dev *rdev) | |||
257 | err |= device_create_file(&rdev->dev, &dev_attr_routes); | 257 | err |= device_create_file(&rdev->dev, &dev_attr_routes); |
258 | err |= device_create_file(&rdev->dev, &dev_attr_lnext); | 258 | err |= device_create_file(&rdev->dev, &dev_attr_lnext); |
259 | err |= device_create_file(&rdev->dev, &dev_attr_hopcount); | 259 | err |= device_create_file(&rdev->dev, &dev_attr_hopcount); |
260 | if (!err && rdev->rswitch->sw_sysfs) | ||
261 | err = rdev->rswitch->sw_sysfs(rdev, RIO_SW_SYSFS_CREATE); | ||
262 | } | 260 | } |
263 | 261 | ||
264 | if (err) | 262 | if (err) |
@@ -281,8 +279,6 @@ void rio_remove_sysfs_dev_files(struct rio_dev *rdev) | |||
281 | device_remove_file(&rdev->dev, &dev_attr_routes); | 279 | device_remove_file(&rdev->dev, &dev_attr_routes); |
282 | device_remove_file(&rdev->dev, &dev_attr_lnext); | 280 | device_remove_file(&rdev->dev, &dev_attr_lnext); |
283 | device_remove_file(&rdev->dev, &dev_attr_hopcount); | 281 | device_remove_file(&rdev->dev, &dev_attr_hopcount); |
284 | if (rdev->rswitch->sw_sysfs) | ||
285 | rdev->rswitch->sw_sysfs(rdev, RIO_SW_SYSFS_REMOVE); | ||
286 | } | 282 | } |
287 | } | 283 | } |
288 | 284 | ||
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c index cb1c08996fbb..b17d5218005e 100644 --- a/drivers/rapidio/rio.c +++ b/drivers/rapidio/rio.c | |||
@@ -7,7 +7,6 @@ | |||
7 | * | 7 | * |
8 | * Copyright 2009 Integrated Device Technology, Inc. | 8 | * Copyright 2009 Integrated Device Technology, Inc. |
9 | * Alex Bounine <alexandre.bounine@idt.com> | 9 | * Alex Bounine <alexandre.bounine@idt.com> |
10 | * - Added Port-Write/Error Management initialization and handling | ||
11 | * | 10 | * |
12 | * This program is free software; you can redistribute it and/or modify it | 11 | * This program is free software; you can redistribute it and/or modify it |
13 | * under the terms of the GNU General Public License as published by the | 12 | * under the terms of the GNU General Public License as published by the |
@@ -580,44 +579,6 @@ int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock) | |||
580 | EXPORT_SYMBOL_GPL(rio_set_port_lockout); | 579 | EXPORT_SYMBOL_GPL(rio_set_port_lockout); |
581 | 580 | ||
582 | /** | 581 | /** |
583 | * rio_switch_init - Sets switch operations for a particular vendor switch | ||
584 | * @rdev: RIO device | ||
585 | * @do_enum: Enumeration/Discovery mode flag | ||
586 | * | ||
587 | * Searches the RIO switch ops table for known switch types. If the vid | ||
588 | * and did match a switch table entry, then call switch initialization | ||
589 | * routine to setup switch-specific routines. | ||
590 | */ | ||
591 | void rio_switch_init(struct rio_dev *rdev, int do_enum) | ||
592 | { | ||
593 | struct rio_switch_ops *cur = __start_rio_switch_ops; | ||
594 | struct rio_switch_ops *end = __end_rio_switch_ops; | ||
595 | |||
596 | while (cur < end) { | ||
597 | if ((cur->vid == rdev->vid) && (cur->did == rdev->did)) { | ||
598 | pr_debug("RIO: calling init routine for %s\n", | ||
599 | rio_name(rdev)); | ||
600 | cur->init_hook(rdev, do_enum); | ||
601 | break; | ||
602 | } | ||
603 | cur++; | ||
604 | } | ||
605 | |||
606 | if ((cur >= end) && (rdev->pef & RIO_PEF_STD_RT)) { | ||
607 | pr_debug("RIO: adding STD routing ops for %s\n", | ||
608 | rio_name(rdev)); | ||
609 | rdev->rswitch->add_entry = rio_std_route_add_entry; | ||
610 | rdev->rswitch->get_entry = rio_std_route_get_entry; | ||
611 | rdev->rswitch->clr_table = rio_std_route_clr_table; | ||
612 | } | ||
613 | |||
614 | if (!rdev->rswitch->add_entry || !rdev->rswitch->get_entry) | ||
615 | printk(KERN_ERR "RIO: missing routing ops for %s\n", | ||
616 | rio_name(rdev)); | ||
617 | } | ||
618 | EXPORT_SYMBOL_GPL(rio_switch_init); | ||
619 | |||
620 | /** | ||
621 | * rio_enable_rx_tx_port - enable input receiver and output transmitter of | 582 | * rio_enable_rx_tx_port - enable input receiver and output transmitter of |
622 | * given port | 583 | * given port |
623 | * @port: Master port associated with the RIO network | 584 | * @port: Master port associated with the RIO network |
@@ -970,8 +931,8 @@ int rio_inb_pwrite_handler(union rio_pw_msg *pw_msg) | |||
970 | /* | 931 | /* |
971 | * Process the port-write notification from switch | 932 | * Process the port-write notification from switch |
972 | */ | 933 | */ |
973 | if (rdev->rswitch->em_handle) | 934 | if (rdev->rswitch->ops && rdev->rswitch->ops->em_handle) |
974 | rdev->rswitch->em_handle(rdev, portnum); | 935 | rdev->rswitch->ops->em_handle(rdev, portnum); |
975 | 936 | ||
976 | rio_read_config_32(rdev, | 937 | rio_read_config_32(rdev, |
977 | rdev->phys_efptr + RIO_PORT_N_ERR_STS_CSR(portnum), | 938 | rdev->phys_efptr + RIO_PORT_N_ERR_STS_CSR(portnum), |
@@ -1207,8 +1168,9 @@ struct rio_dev *rio_get_device(u16 vid, u16 did, struct rio_dev *from) | |||
1207 | * @route_destid: destID entry in the RT | 1168 | * @route_destid: destID entry in the RT |
1208 | * @route_port: destination port for specified destID | 1169 | * @route_port: destination port for specified destID |
1209 | */ | 1170 | */ |
1210 | int rio_std_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount, | 1171 | static int |
1211 | u16 table, u16 route_destid, u8 route_port) | 1172 | rio_std_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount, |
1173 | u16 table, u16 route_destid, u8 route_port) | ||
1212 | { | 1174 | { |
1213 | if (table == RIO_GLOBAL_TABLE) { | 1175 | if (table == RIO_GLOBAL_TABLE) { |
1214 | rio_mport_write_config_32(mport, destid, hopcount, | 1176 | rio_mport_write_config_32(mport, destid, hopcount, |
@@ -1234,8 +1196,9 @@ int rio_std_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount, | |||
1234 | * @route_destid: destID entry in the RT | 1196 | * @route_destid: destID entry in the RT |
1235 | * @route_port: returned destination port for specified destID | 1197 | * @route_port: returned destination port for specified destID |
1236 | */ | 1198 | */ |
1237 | int rio_std_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount, | 1199 | static int |
1238 | u16 table, u16 route_destid, u8 *route_port) | 1200 | rio_std_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount, |
1201 | u16 table, u16 route_destid, u8 *route_port) | ||
1239 | { | 1202 | { |
1240 | u32 result; | 1203 | u32 result; |
1241 | 1204 | ||
@@ -1259,8 +1222,9 @@ int rio_std_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount, | |||
1259 | * @hopcount: Number of switch hops to the device | 1222 | * @hopcount: Number of switch hops to the device |
1260 | * @table: routing table ID (global or port-specific) | 1223 | * @table: routing table ID (global or port-specific) |
1261 | */ | 1224 | */ |
1262 | int rio_std_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount, | 1225 | static int |
1263 | u16 table) | 1226 | rio_std_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount, |
1227 | u16 table) | ||
1264 | { | 1228 | { |
1265 | u32 max_destid = 0xff; | 1229 | u32 max_destid = 0xff; |
1266 | u32 i, pef, id_inc = 1, ext_cfg = 0; | 1230 | u32 i, pef, id_inc = 1, ext_cfg = 0; |
@@ -1301,6 +1265,234 @@ int rio_std_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount, | |||
1301 | return 0; | 1265 | return 0; |
1302 | } | 1266 | } |
1303 | 1267 | ||
1268 | /** | ||
1269 | * rio_lock_device - Acquires host device lock for specified device | ||
1270 | * @port: Master port to send transaction | ||
1271 | * @destid: Destination ID for device/switch | ||
1272 | * @hopcount: Hopcount to reach switch | ||
1273 | * @wait_ms: Max wait time in msec (0 = no timeout) | ||
1274 | * | ||
1275 | * Attepts to acquire host device lock for specified device | ||
1276 | * Returns 0 if device lock acquired or EINVAL if timeout expires. | ||
1277 | */ | ||
1278 | int rio_lock_device(struct rio_mport *port, u16 destid, | ||
1279 | u8 hopcount, int wait_ms) | ||
1280 | { | ||
1281 | u32 result; | ||
1282 | int tcnt = 0; | ||
1283 | |||
1284 | /* Attempt to acquire device lock */ | ||
1285 | rio_mport_write_config_32(port, destid, hopcount, | ||
1286 | RIO_HOST_DID_LOCK_CSR, port->host_deviceid); | ||
1287 | rio_mport_read_config_32(port, destid, hopcount, | ||
1288 | RIO_HOST_DID_LOCK_CSR, &result); | ||
1289 | |||
1290 | while (result != port->host_deviceid) { | ||
1291 | if (wait_ms != 0 && tcnt == wait_ms) { | ||
1292 | pr_debug("RIO: timeout when locking device %x:%x\n", | ||
1293 | destid, hopcount); | ||
1294 | return -EINVAL; | ||
1295 | } | ||
1296 | |||
1297 | /* Delay a bit */ | ||
1298 | mdelay(1); | ||
1299 | tcnt++; | ||
1300 | /* Try to acquire device lock again */ | ||
1301 | rio_mport_write_config_32(port, destid, | ||
1302 | hopcount, | ||
1303 | RIO_HOST_DID_LOCK_CSR, | ||
1304 | port->host_deviceid); | ||
1305 | rio_mport_read_config_32(port, destid, | ||
1306 | hopcount, | ||
1307 | RIO_HOST_DID_LOCK_CSR, &result); | ||
1308 | } | ||
1309 | |||
1310 | return 0; | ||
1311 | } | ||
1312 | EXPORT_SYMBOL_GPL(rio_lock_device); | ||
1313 | |||
1314 | /** | ||
1315 | * rio_unlock_device - Releases host device lock for specified device | ||
1316 | * @port: Master port to send transaction | ||
1317 | * @destid: Destination ID for device/switch | ||
1318 | * @hopcount: Hopcount to reach switch | ||
1319 | * | ||
1320 | * Returns 0 if device lock released or EINVAL if fails. | ||
1321 | */ | ||
1322 | int rio_unlock_device(struct rio_mport *port, u16 destid, u8 hopcount) | ||
1323 | { | ||
1324 | u32 result; | ||
1325 | |||
1326 | /* Release device lock */ | ||
1327 | rio_mport_write_config_32(port, destid, | ||
1328 | hopcount, | ||
1329 | RIO_HOST_DID_LOCK_CSR, | ||
1330 | port->host_deviceid); | ||
1331 | rio_mport_read_config_32(port, destid, hopcount, | ||
1332 | RIO_HOST_DID_LOCK_CSR, &result); | ||
1333 | if ((result & 0xffff) != 0xffff) { | ||
1334 | pr_debug("RIO: badness when releasing device lock %x:%x\n", | ||
1335 | destid, hopcount); | ||
1336 | return -EINVAL; | ||
1337 | } | ||
1338 | |||
1339 | return 0; | ||
1340 | } | ||
1341 | EXPORT_SYMBOL_GPL(rio_unlock_device); | ||
1342 | |||
1343 | /** | ||
1344 | * rio_route_add_entry- Add a route entry to a switch routing table | ||
1345 | * @rdev: RIO device | ||
1346 | * @table: Routing table ID | ||
1347 | * @route_destid: Destination ID to be routed | ||
1348 | * @route_port: Port number to be routed | ||
1349 | * @lock: apply a hardware lock on switch device flag (1=lock, 0=no_lock) | ||
1350 | * | ||
1351 | * If available calls the switch specific add_entry() method to add a route | ||
1352 | * entry into a switch routing table. Otherwise uses standard RT update method | ||
1353 | * as defined by RapidIO specification. A specific routing table can be selected | ||
1354 | * using the @table argument if a switch has per port routing tables or | ||
1355 | * the standard (or global) table may be used by passing | ||
1356 | * %RIO_GLOBAL_TABLE in @table. | ||
1357 | * | ||
1358 | * Returns %0 on success or %-EINVAL on failure. | ||
1359 | */ | ||
1360 | int rio_route_add_entry(struct rio_dev *rdev, | ||
1361 | u16 table, u16 route_destid, u8 route_port, int lock) | ||
1362 | { | ||
1363 | int rc = -EINVAL; | ||
1364 | struct rio_switch_ops *ops = rdev->rswitch->ops; | ||
1365 | |||
1366 | if (lock) { | ||
1367 | rc = rio_lock_device(rdev->net->hport, rdev->destid, | ||
1368 | rdev->hopcount, 1000); | ||
1369 | if (rc) | ||
1370 | return rc; | ||
1371 | } | ||
1372 | |||
1373 | spin_lock(&rdev->rswitch->lock); | ||
1374 | |||
1375 | if (ops == NULL || ops->add_entry == NULL) { | ||
1376 | rc = rio_std_route_add_entry(rdev->net->hport, rdev->destid, | ||
1377 | rdev->hopcount, table, | ||
1378 | route_destid, route_port); | ||
1379 | } else if (try_module_get(ops->owner)) { | ||
1380 | rc = ops->add_entry(rdev->net->hport, rdev->destid, | ||
1381 | rdev->hopcount, table, route_destid, | ||
1382 | route_port); | ||
1383 | module_put(ops->owner); | ||
1384 | } | ||
1385 | |||
1386 | spin_unlock(&rdev->rswitch->lock); | ||
1387 | |||
1388 | if (lock) | ||
1389 | rio_unlock_device(rdev->net->hport, rdev->destid, | ||
1390 | rdev->hopcount); | ||
1391 | |||
1392 | return rc; | ||
1393 | } | ||
1394 | EXPORT_SYMBOL_GPL(rio_route_add_entry); | ||
1395 | |||
1396 | /** | ||
1397 | * rio_route_get_entry- Read an entry from a switch routing table | ||
1398 | * @rdev: RIO device | ||
1399 | * @table: Routing table ID | ||
1400 | * @route_destid: Destination ID to be routed | ||
1401 | * @route_port: Pointer to read port number into | ||
1402 | * @lock: apply a hardware lock on switch device flag (1=lock, 0=no_lock) | ||
1403 | * | ||
1404 | * If available calls the switch specific get_entry() method to fetch a route | ||
1405 | * entry from a switch routing table. Otherwise uses standard RT read method | ||
1406 | * as defined by RapidIO specification. A specific routing table can be selected | ||
1407 | * using the @table argument if a switch has per port routing tables or | ||
1408 | * the standard (or global) table may be used by passing | ||
1409 | * %RIO_GLOBAL_TABLE in @table. | ||
1410 | * | ||
1411 | * Returns %0 on success or %-EINVAL on failure. | ||
1412 | */ | ||
1413 | int rio_route_get_entry(struct rio_dev *rdev, u16 table, | ||
1414 | u16 route_destid, u8 *route_port, int lock) | ||
1415 | { | ||
1416 | int rc = -EINVAL; | ||
1417 | struct rio_switch_ops *ops = rdev->rswitch->ops; | ||
1418 | |||
1419 | if (lock) { | ||
1420 | rc = rio_lock_device(rdev->net->hport, rdev->destid, | ||
1421 | rdev->hopcount, 1000); | ||
1422 | if (rc) | ||
1423 | return rc; | ||
1424 | } | ||
1425 | |||
1426 | spin_lock(&rdev->rswitch->lock); | ||
1427 | |||
1428 | if (ops == NULL || ops->get_entry == NULL) { | ||
1429 | rc = rio_std_route_get_entry(rdev->net->hport, rdev->destid, | ||
1430 | rdev->hopcount, table, | ||
1431 | route_destid, route_port); | ||
1432 | } else if (try_module_get(ops->owner)) { | ||
1433 | rc = ops->get_entry(rdev->net->hport, rdev->destid, | ||
1434 | rdev->hopcount, table, route_destid, | ||
1435 | route_port); | ||
1436 | module_put(ops->owner); | ||
1437 | } | ||
1438 | |||
1439 | spin_unlock(&rdev->rswitch->lock); | ||
1440 | |||
1441 | if (lock) | ||
1442 | rio_unlock_device(rdev->net->hport, rdev->destid, | ||
1443 | rdev->hopcount); | ||
1444 | return rc; | ||
1445 | } | ||
1446 | EXPORT_SYMBOL_GPL(rio_route_get_entry); | ||
1447 | |||
1448 | /** | ||
1449 | * rio_route_clr_table - Clear a switch routing table | ||
1450 | * @rdev: RIO device | ||
1451 | * @table: Routing table ID | ||
1452 | * @lock: apply a hardware lock on switch device flag (1=lock, 0=no_lock) | ||
1453 | * | ||
1454 | * If available calls the switch specific clr_table() method to clear a switch | ||
1455 | * routing table. Otherwise uses standard RT write method as defined by RapidIO | ||
1456 | * specification. A specific routing table can be selected using the @table | ||
1457 | * argument if a switch has per port routing tables or the standard (or global) | ||
1458 | * table may be used by passing %RIO_GLOBAL_TABLE in @table. | ||
1459 | * | ||
1460 | * Returns %0 on success or %-EINVAL on failure. | ||
1461 | */ | ||
1462 | int rio_route_clr_table(struct rio_dev *rdev, u16 table, int lock) | ||
1463 | { | ||
1464 | int rc = -EINVAL; | ||
1465 | struct rio_switch_ops *ops = rdev->rswitch->ops; | ||
1466 | |||
1467 | if (lock) { | ||
1468 | rc = rio_lock_device(rdev->net->hport, rdev->destid, | ||
1469 | rdev->hopcount, 1000); | ||
1470 | if (rc) | ||
1471 | return rc; | ||
1472 | } | ||
1473 | |||
1474 | spin_lock(&rdev->rswitch->lock); | ||
1475 | |||
1476 | if (ops == NULL || ops->clr_table == NULL) { | ||
1477 | rc = rio_std_route_clr_table(rdev->net->hport, rdev->destid, | ||
1478 | rdev->hopcount, table); | ||
1479 | } else if (try_module_get(ops->owner)) { | ||
1480 | rc = ops->clr_table(rdev->net->hport, rdev->destid, | ||
1481 | rdev->hopcount, table); | ||
1482 | |||
1483 | module_put(ops->owner); | ||
1484 | } | ||
1485 | |||
1486 | spin_unlock(&rdev->rswitch->lock); | ||
1487 | |||
1488 | if (lock) | ||
1489 | rio_unlock_device(rdev->net->hport, rdev->destid, | ||
1490 | rdev->hopcount); | ||
1491 | |||
1492 | return rc; | ||
1493 | } | ||
1494 | EXPORT_SYMBOL_GPL(rio_route_clr_table); | ||
1495 | |||
1304 | #ifdef CONFIG_RAPIDIO_DMA_ENGINE | 1496 | #ifdef CONFIG_RAPIDIO_DMA_ENGINE |
1305 | 1497 | ||
1306 | static bool rio_chan_filter(struct dma_chan *chan, void *arg) | 1498 | static bool rio_chan_filter(struct dma_chan *chan, void *arg) |
diff --git a/drivers/rapidio/rio.h b/drivers/rapidio/rio.h index c14f864dea5c..d59587762c76 100644 --- a/drivers/rapidio/rio.h +++ b/drivers/rapidio/rio.h | |||
@@ -28,18 +28,17 @@ extern u32 rio_mport_get_efb(struct rio_mport *port, int local, u16 destid, | |||
28 | extern int rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid, | 28 | extern int rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid, |
29 | u8 hopcount); | 29 | u8 hopcount); |
30 | extern int rio_create_sysfs_dev_files(struct rio_dev *rdev); | 30 | extern int rio_create_sysfs_dev_files(struct rio_dev *rdev); |
31 | extern int rio_std_route_add_entry(struct rio_mport *mport, u16 destid, | 31 | extern int rio_lock_device(struct rio_mport *port, u16 destid, |
32 | u8 hopcount, u16 table, u16 route_destid, | 32 | u8 hopcount, int wait_ms); |
33 | u8 route_port); | 33 | extern int rio_unlock_device(struct rio_mport *port, u16 destid, u8 hopcount); |
34 | extern int rio_std_route_get_entry(struct rio_mport *mport, u16 destid, | 34 | extern int rio_route_add_entry(struct rio_dev *rdev, |
35 | u8 hopcount, u16 table, u16 route_destid, | 35 | u16 table, u16 route_destid, u8 route_port, int lock); |
36 | u8 *route_port); | 36 | extern int rio_route_get_entry(struct rio_dev *rdev, u16 table, |
37 | extern int rio_std_route_clr_table(struct rio_mport *mport, u16 destid, | 37 | u16 route_destid, u8 *route_port, int lock); |
38 | u8 hopcount, u16 table); | 38 | extern int rio_route_clr_table(struct rio_dev *rdev, u16 table, int lock); |
39 | extern int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock); | 39 | extern int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock); |
40 | extern struct rio_dev *rio_get_comptag(u32 comp_tag, struct rio_dev *from); | 40 | extern struct rio_dev *rio_get_comptag(u32 comp_tag, struct rio_dev *from); |
41 | extern int rio_add_device(struct rio_dev *rdev); | 41 | extern int rio_add_device(struct rio_dev *rdev); |
42 | extern void rio_switch_init(struct rio_dev *rdev, int do_enum); | ||
43 | extern int rio_enable_rx_tx_port(struct rio_mport *port, int local, u16 destid, | 42 | extern int rio_enable_rx_tx_port(struct rio_mport *port, int local, u16 destid, |
44 | u8 hopcount, u8 port_num); | 43 | u8 hopcount, u8 port_num); |
45 | extern int rio_register_scan(int mport_id, struct rio_scan *scan_ops); | 44 | extern int rio_register_scan(int mport_id, struct rio_scan *scan_ops); |
@@ -51,29 +50,5 @@ extern struct rio_mport *rio_find_mport(int mport_id); | |||
51 | extern struct device_attribute rio_dev_attrs[]; | 50 | extern struct device_attribute rio_dev_attrs[]; |
52 | extern struct bus_attribute rio_bus_attrs[]; | 51 | extern struct bus_attribute rio_bus_attrs[]; |
53 | 52 | ||
54 | extern struct rio_switch_ops __start_rio_switch_ops[]; | ||
55 | extern struct rio_switch_ops __end_rio_switch_ops[]; | ||
56 | |||
57 | /* Helpers internal to the RIO core code */ | ||
58 | #define DECLARE_RIO_SWITCH_SECTION(section, name, vid, did, init_hook) \ | ||
59 | static const struct rio_switch_ops __rio_switch_##name __used \ | ||
60 | __section(section) = { vid, did, init_hook }; | ||
61 | |||
62 | /** | ||
63 | * DECLARE_RIO_SWITCH_INIT - Registers switch initialization routine | ||
64 | * @vid: RIO vendor ID | ||
65 | * @did: RIO device ID | ||
66 | * @init_hook: Callback that performs switch-specific initialization | ||
67 | * | ||
68 | * Manipulating switch route tables and error management in RIO | ||
69 | * is switch specific. This registers a switch by vendor and device ID with | ||
70 | * initialization callback for setting up switch operations and (if required) | ||
71 | * hardware initialization. A &struct rio_switch_ops is initialized with | ||
72 | * pointer to the init routine and placed into a RIO-specific kernel section. | ||
73 | */ | ||
74 | #define DECLARE_RIO_SWITCH_INIT(vid, did, init_hook) \ | ||
75 | DECLARE_RIO_SWITCH_SECTION(.rio_switch_ops, vid##did, \ | ||
76 | vid, did, init_hook) | ||
77 | |||
78 | #define RIO_GET_DID(size, x) (size ? (x & 0xffff) : ((x & 0x00ff0000) >> 16)) | 53 | #define RIO_GET_DID(size, x) (size ? (x & 0xffff) : ((x & 0x00ff0000) >> 16)) |
79 | #define RIO_SET_DID(size, x) (size ? (x & 0xffff) : ((x & 0x000000ff) << 16)) | 54 | #define RIO_SET_DID(size, x) (size ? (x & 0xffff) : ((x & 0x000000ff) << 16)) |
diff --git a/drivers/rapidio/switches/Kconfig b/drivers/rapidio/switches/Kconfig index 62d4a065230f..345841562f95 100644 --- a/drivers/rapidio/switches/Kconfig +++ b/drivers/rapidio/switches/Kconfig | |||
@@ -2,27 +2,23 @@ | |||
2 | # RapidIO switches configuration | 2 | # RapidIO switches configuration |
3 | # | 3 | # |
4 | config RAPIDIO_TSI57X | 4 | config RAPIDIO_TSI57X |
5 | bool "IDT Tsi57x SRIO switches support" | 5 | tristate "IDT Tsi57x SRIO switches support" |
6 | depends on RAPIDIO | ||
7 | ---help--- | 6 | ---help--- |
8 | Includes support for IDT Tsi57x family of serial RapidIO switches. | 7 | Includes support for IDT Tsi57x family of serial RapidIO switches. |
9 | 8 | ||
10 | config RAPIDIO_CPS_XX | 9 | config RAPIDIO_CPS_XX |
11 | bool "IDT CPS-xx SRIO switches support" | 10 | tristate "IDT CPS-xx SRIO switches support" |
12 | depends on RAPIDIO | ||
13 | ---help--- | 11 | ---help--- |
14 | Includes support for IDT CPS-16/12/10/8 serial RapidIO switches. | 12 | Includes support for IDT CPS-16/12/10/8 serial RapidIO switches. |
15 | 13 | ||
16 | config RAPIDIO_TSI568 | 14 | config RAPIDIO_TSI568 |
17 | bool "Tsi568 SRIO switch support" | 15 | tristate "Tsi568 SRIO switch support" |
18 | depends on RAPIDIO | ||
19 | default n | 16 | default n |
20 | ---help--- | 17 | ---help--- |
21 | Includes support for IDT Tsi568 serial RapidIO switch. | 18 | Includes support for IDT Tsi568 serial RapidIO switch. |
22 | 19 | ||
23 | config RAPIDIO_CPS_GEN2 | 20 | config RAPIDIO_CPS_GEN2 |
24 | bool "IDT CPS Gen.2 SRIO switch support" | 21 | tristate "IDT CPS Gen.2 SRIO switch support" |
25 | depends on RAPIDIO | ||
26 | default n | 22 | default n |
27 | ---help--- | 23 | ---help--- |
28 | Includes support for ITD CPS Gen.2 serial RapidIO switches. | 24 | Includes support for ITD CPS Gen.2 serial RapidIO switches. |
diff --git a/drivers/rapidio/switches/idt_gen2.c b/drivers/rapidio/switches/idt_gen2.c index 809b7a3336ba..00a71ebb5cac 100644 --- a/drivers/rapidio/switches/idt_gen2.c +++ b/drivers/rapidio/switches/idt_gen2.c | |||
@@ -11,6 +11,7 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/stat.h> | 13 | #include <linux/stat.h> |
14 | #include <linux/module.h> | ||
14 | #include <linux/rio.h> | 15 | #include <linux/rio.h> |
15 | #include <linux/rio_drv.h> | 16 | #include <linux/rio_drv.h> |
16 | #include <linux/rio_ids.h> | 17 | #include <linux/rio_ids.h> |
@@ -387,12 +388,12 @@ idtg2_show_errlog(struct device *dev, struct device_attribute *attr, char *buf) | |||
387 | 388 | ||
388 | static DEVICE_ATTR(errlog, S_IRUGO, idtg2_show_errlog, NULL); | 389 | static DEVICE_ATTR(errlog, S_IRUGO, idtg2_show_errlog, NULL); |
389 | 390 | ||
390 | static int idtg2_sysfs(struct rio_dev *rdev, int create) | 391 | static int idtg2_sysfs(struct rio_dev *rdev, bool create) |
391 | { | 392 | { |
392 | struct device *dev = &rdev->dev; | 393 | struct device *dev = &rdev->dev; |
393 | int err = 0; | 394 | int err = 0; |
394 | 395 | ||
395 | if (create == RIO_SW_SYSFS_CREATE) { | 396 | if (create) { |
396 | /* Initialize sysfs entries */ | 397 | /* Initialize sysfs entries */ |
397 | err = device_create_file(dev, &dev_attr_errlog); | 398 | err = device_create_file(dev, &dev_attr_errlog); |
398 | if (err) | 399 | if (err) |
@@ -403,29 +404,90 @@ static int idtg2_sysfs(struct rio_dev *rdev, int create) | |||
403 | return err; | 404 | return err; |
404 | } | 405 | } |
405 | 406 | ||
406 | static int idtg2_switch_init(struct rio_dev *rdev, int do_enum) | 407 | static struct rio_switch_ops idtg2_switch_ops = { |
408 | .owner = THIS_MODULE, | ||
409 | .add_entry = idtg2_route_add_entry, | ||
410 | .get_entry = idtg2_route_get_entry, | ||
411 | .clr_table = idtg2_route_clr_table, | ||
412 | .set_domain = idtg2_set_domain, | ||
413 | .get_domain = idtg2_get_domain, | ||
414 | .em_init = idtg2_em_init, | ||
415 | .em_handle = idtg2_em_handler, | ||
416 | }; | ||
417 | |||
418 | static int idtg2_probe(struct rio_dev *rdev, const struct rio_device_id *id) | ||
407 | { | 419 | { |
408 | pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev)); | 420 | pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev)); |
409 | rdev->rswitch->add_entry = idtg2_route_add_entry; | 421 | |
410 | rdev->rswitch->get_entry = idtg2_route_get_entry; | 422 | spin_lock(&rdev->rswitch->lock); |
411 | rdev->rswitch->clr_table = idtg2_route_clr_table; | 423 | |
412 | rdev->rswitch->set_domain = idtg2_set_domain; | 424 | if (rdev->rswitch->ops) { |
413 | rdev->rswitch->get_domain = idtg2_get_domain; | 425 | spin_unlock(&rdev->rswitch->lock); |
414 | rdev->rswitch->em_init = idtg2_em_init; | 426 | return -EINVAL; |
415 | rdev->rswitch->em_handle = idtg2_em_handler; | 427 | } |
416 | rdev->rswitch->sw_sysfs = idtg2_sysfs; | 428 | |
417 | 429 | rdev->rswitch->ops = &idtg2_switch_ops; | |
418 | if (do_enum) { | 430 | |
431 | if (rdev->do_enum) { | ||
419 | /* Ensure that default routing is disabled on startup */ | 432 | /* Ensure that default routing is disabled on startup */ |
420 | rio_write_config_32(rdev, | 433 | rio_write_config_32(rdev, |
421 | RIO_STD_RTE_DEFAULT_PORT, IDT_NO_ROUTE); | 434 | RIO_STD_RTE_DEFAULT_PORT, IDT_NO_ROUTE); |
422 | } | 435 | } |
423 | 436 | ||
437 | /* Create device-specific sysfs attributes */ | ||
438 | idtg2_sysfs(rdev, true); | ||
439 | |||
440 | spin_unlock(&rdev->rswitch->lock); | ||
424 | return 0; | 441 | return 0; |
425 | } | 442 | } |
426 | 443 | ||
427 | DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS1848, idtg2_switch_init); | 444 | static void idtg2_remove(struct rio_dev *rdev) |
428 | DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS1616, idtg2_switch_init); | 445 | { |
429 | DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTVPS1616, idtg2_switch_init); | 446 | pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev)); |
430 | DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTSPS1616, idtg2_switch_init); | 447 | spin_lock(&rdev->rswitch->lock); |
431 | DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS1432, idtg2_switch_init); | 448 | if (rdev->rswitch->ops != &idtg2_switch_ops) { |
449 | spin_unlock(&rdev->rswitch->lock); | ||
450 | return; | ||
451 | } | ||
452 | rdev->rswitch->ops = NULL; | ||
453 | |||
454 | /* Remove device-specific sysfs attributes */ | ||
455 | idtg2_sysfs(rdev, false); | ||
456 | |||
457 | spin_unlock(&rdev->rswitch->lock); | ||
458 | } | ||
459 | |||
460 | static struct rio_device_id idtg2_id_table[] = { | ||
461 | {RIO_DEVICE(RIO_DID_IDTCPS1848, RIO_VID_IDT)}, | ||
462 | {RIO_DEVICE(RIO_DID_IDTCPS1616, RIO_VID_IDT)}, | ||
463 | {RIO_DEVICE(RIO_DID_IDTVPS1616, RIO_VID_IDT)}, | ||
464 | {RIO_DEVICE(RIO_DID_IDTSPS1616, RIO_VID_IDT)}, | ||
465 | {RIO_DEVICE(RIO_DID_IDTCPS1432, RIO_VID_IDT)}, | ||
466 | { 0, } /* terminate list */ | ||
467 | }; | ||
468 | |||
469 | static struct rio_driver idtg2_driver = { | ||
470 | .name = "idt_gen2", | ||
471 | .id_table = idtg2_id_table, | ||
472 | .probe = idtg2_probe, | ||
473 | .remove = idtg2_remove, | ||
474 | }; | ||
475 | |||
476 | static int __init idtg2_init(void) | ||
477 | { | ||
478 | return rio_register_driver(&idtg2_driver); | ||
479 | } | ||
480 | |||
481 | static void __exit idtg2_exit(void) | ||
482 | { | ||
483 | pr_debug("RIO: %s\n", __func__); | ||
484 | rio_unregister_driver(&idtg2_driver); | ||
485 | pr_debug("RIO: %s done\n", __func__); | ||
486 | } | ||
487 | |||
488 | device_initcall(idtg2_init); | ||
489 | module_exit(idtg2_exit); | ||
490 | |||
491 | MODULE_DESCRIPTION("IDT CPS Gen.2 Serial RapidIO switch family driver"); | ||
492 | MODULE_AUTHOR("Integrated Device Technology, Inc."); | ||
493 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rapidio/switches/idtcps.c b/drivers/rapidio/switches/idtcps.c index d06ee2d44b44..7fbb60d31796 100644 --- a/drivers/rapidio/switches/idtcps.c +++ b/drivers/rapidio/switches/idtcps.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/rio.h> | 13 | #include <linux/rio.h> |
14 | #include <linux/rio_drv.h> | 14 | #include <linux/rio_drv.h> |
15 | #include <linux/rio_ids.h> | 15 | #include <linux/rio_ids.h> |
16 | #include <linux/module.h> | ||
16 | #include "../rio.h" | 17 | #include "../rio.h" |
17 | 18 | ||
18 | #define CPS_DEFAULT_ROUTE 0xde | 19 | #define CPS_DEFAULT_ROUTE 0xde |
@@ -118,18 +119,31 @@ idtcps_get_domain(struct rio_mport *mport, u16 destid, u8 hopcount, | |||
118 | return 0; | 119 | return 0; |
119 | } | 120 | } |
120 | 121 | ||
121 | static int idtcps_switch_init(struct rio_dev *rdev, int do_enum) | 122 | static struct rio_switch_ops idtcps_switch_ops = { |
123 | .owner = THIS_MODULE, | ||
124 | .add_entry = idtcps_route_add_entry, | ||
125 | .get_entry = idtcps_route_get_entry, | ||
126 | .clr_table = idtcps_route_clr_table, | ||
127 | .set_domain = idtcps_set_domain, | ||
128 | .get_domain = idtcps_get_domain, | ||
129 | .em_init = NULL, | ||
130 | .em_handle = NULL, | ||
131 | }; | ||
132 | |||
133 | static int idtcps_probe(struct rio_dev *rdev, const struct rio_device_id *id) | ||
122 | { | 134 | { |
123 | pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev)); | 135 | pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev)); |
124 | rdev->rswitch->add_entry = idtcps_route_add_entry; | 136 | |
125 | rdev->rswitch->get_entry = idtcps_route_get_entry; | 137 | spin_lock(&rdev->rswitch->lock); |
126 | rdev->rswitch->clr_table = idtcps_route_clr_table; | 138 | |
127 | rdev->rswitch->set_domain = idtcps_set_domain; | 139 | if (rdev->rswitch->ops) { |
128 | rdev->rswitch->get_domain = idtcps_get_domain; | 140 | spin_unlock(&rdev->rswitch->lock); |
129 | rdev->rswitch->em_init = NULL; | 141 | return -EINVAL; |
130 | rdev->rswitch->em_handle = NULL; | 142 | } |
131 | 143 | ||
132 | if (do_enum) { | 144 | rdev->rswitch->ops = &idtcps_switch_ops; |
145 | |||
146 | if (rdev->do_enum) { | ||
133 | /* set TVAL = ~50us */ | 147 | /* set TVAL = ~50us */ |
134 | rio_write_config_32(rdev, | 148 | rio_write_config_32(rdev, |
135 | rdev->phys_efptr + RIO_PORT_LINKTO_CTL_CSR, 0x8e << 8); | 149 | rdev->phys_efptr + RIO_PORT_LINKTO_CTL_CSR, 0x8e << 8); |
@@ -138,12 +152,52 @@ static int idtcps_switch_init(struct rio_dev *rdev, int do_enum) | |||
138 | RIO_STD_RTE_DEFAULT_PORT, CPS_NO_ROUTE); | 152 | RIO_STD_RTE_DEFAULT_PORT, CPS_NO_ROUTE); |
139 | } | 153 | } |
140 | 154 | ||
155 | spin_unlock(&rdev->rswitch->lock); | ||
141 | return 0; | 156 | return 0; |
142 | } | 157 | } |
143 | 158 | ||
144 | DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS6Q, idtcps_switch_init); | 159 | static void idtcps_remove(struct rio_dev *rdev) |
145 | DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS8, idtcps_switch_init); | 160 | { |
146 | DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS10Q, idtcps_switch_init); | 161 | pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev)); |
147 | DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS12, idtcps_switch_init); | 162 | spin_lock(&rdev->rswitch->lock); |
148 | DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS16, idtcps_switch_init); | 163 | if (rdev->rswitch->ops != &idtcps_switch_ops) { |
149 | DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDT70K200, idtcps_switch_init); | 164 | spin_unlock(&rdev->rswitch->lock); |
165 | return; | ||
166 | } | ||
167 | rdev->rswitch->ops = NULL; | ||
168 | spin_unlock(&rdev->rswitch->lock); | ||
169 | } | ||
170 | |||
171 | static struct rio_device_id idtcps_id_table[] = { | ||
172 | {RIO_DEVICE(RIO_DID_IDTCPS6Q, RIO_VID_IDT)}, | ||
173 | {RIO_DEVICE(RIO_DID_IDTCPS8, RIO_VID_IDT)}, | ||
174 | {RIO_DEVICE(RIO_DID_IDTCPS10Q, RIO_VID_IDT)}, | ||
175 | {RIO_DEVICE(RIO_DID_IDTCPS12, RIO_VID_IDT)}, | ||
176 | {RIO_DEVICE(RIO_DID_IDTCPS16, RIO_VID_IDT)}, | ||
177 | {RIO_DEVICE(RIO_DID_IDT70K200, RIO_VID_IDT)}, | ||
178 | { 0, } /* terminate list */ | ||
179 | }; | ||
180 | |||
181 | static struct rio_driver idtcps_driver = { | ||
182 | .name = "idtcps", | ||
183 | .id_table = idtcps_id_table, | ||
184 | .probe = idtcps_probe, | ||
185 | .remove = idtcps_remove, | ||
186 | }; | ||
187 | |||
188 | static int __init idtcps_init(void) | ||
189 | { | ||
190 | return rio_register_driver(&idtcps_driver); | ||
191 | } | ||
192 | |||
193 | static void __exit idtcps_exit(void) | ||
194 | { | ||
195 | rio_unregister_driver(&idtcps_driver); | ||
196 | } | ||
197 | |||
198 | device_initcall(idtcps_init); | ||
199 | module_exit(idtcps_exit); | ||
200 | |||
201 | MODULE_DESCRIPTION("IDT CPS Gen.1 Serial RapidIO switch family driver"); | ||
202 | MODULE_AUTHOR("Integrated Device Technology, Inc."); | ||
203 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rapidio/switches/tsi568.c b/drivers/rapidio/switches/tsi568.c index 3994c00aa01f..8a43561b9d17 100644 --- a/drivers/rapidio/switches/tsi568.c +++ b/drivers/rapidio/switches/tsi568.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/rio_drv.h> | 19 | #include <linux/rio_drv.h> |
20 | #include <linux/rio_ids.h> | 20 | #include <linux/rio_ids.h> |
21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
22 | #include <linux/module.h> | ||
22 | #include "../rio.h" | 23 | #include "../rio.h" |
23 | 24 | ||
24 | /* Global (broadcast) route registers */ | 25 | /* Global (broadcast) route registers */ |
@@ -129,18 +130,70 @@ tsi568_em_init(struct rio_dev *rdev) | |||
129 | return 0; | 130 | return 0; |
130 | } | 131 | } |
131 | 132 | ||
132 | static int tsi568_switch_init(struct rio_dev *rdev, int do_enum) | 133 | static struct rio_switch_ops tsi568_switch_ops = { |
134 | .owner = THIS_MODULE, | ||
135 | .add_entry = tsi568_route_add_entry, | ||
136 | .get_entry = tsi568_route_get_entry, | ||
137 | .clr_table = tsi568_route_clr_table, | ||
138 | .set_domain = NULL, | ||
139 | .get_domain = NULL, | ||
140 | .em_init = tsi568_em_init, | ||
141 | .em_handle = NULL, | ||
142 | }; | ||
143 | |||
144 | static int tsi568_probe(struct rio_dev *rdev, const struct rio_device_id *id) | ||
133 | { | 145 | { |
134 | pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev)); | 146 | pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev)); |
135 | rdev->rswitch->add_entry = tsi568_route_add_entry; | ||
136 | rdev->rswitch->get_entry = tsi568_route_get_entry; | ||
137 | rdev->rswitch->clr_table = tsi568_route_clr_table; | ||
138 | rdev->rswitch->set_domain = NULL; | ||
139 | rdev->rswitch->get_domain = NULL; | ||
140 | rdev->rswitch->em_init = tsi568_em_init; | ||
141 | rdev->rswitch->em_handle = NULL; | ||
142 | 147 | ||
148 | spin_lock(&rdev->rswitch->lock); | ||
149 | |||
150 | if (rdev->rswitch->ops) { | ||
151 | spin_unlock(&rdev->rswitch->lock); | ||
152 | return -EINVAL; | ||
153 | } | ||
154 | |||
155 | rdev->rswitch->ops = &tsi568_switch_ops; | ||
156 | spin_unlock(&rdev->rswitch->lock); | ||
143 | return 0; | 157 | return 0; |
144 | } | 158 | } |
145 | 159 | ||
146 | DECLARE_RIO_SWITCH_INIT(RIO_VID_TUNDRA, RIO_DID_TSI568, tsi568_switch_init); | 160 | static void tsi568_remove(struct rio_dev *rdev) |
161 | { | ||
162 | pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev)); | ||
163 | spin_lock(&rdev->rswitch->lock); | ||
164 | if (rdev->rswitch->ops != &tsi568_switch_ops) { | ||
165 | spin_unlock(&rdev->rswitch->lock); | ||
166 | return; | ||
167 | } | ||
168 | rdev->rswitch->ops = NULL; | ||
169 | spin_unlock(&rdev->rswitch->lock); | ||
170 | } | ||
171 | |||
172 | static struct rio_device_id tsi568_id_table[] = { | ||
173 | {RIO_DEVICE(RIO_DID_TSI568, RIO_VID_TUNDRA)}, | ||
174 | { 0, } /* terminate list */ | ||
175 | }; | ||
176 | |||
177 | static struct rio_driver tsi568_driver = { | ||
178 | .name = "tsi568", | ||
179 | .id_table = tsi568_id_table, | ||
180 | .probe = tsi568_probe, | ||
181 | .remove = tsi568_remove, | ||
182 | }; | ||
183 | |||
184 | static int __init tsi568_init(void) | ||
185 | { | ||
186 | return rio_register_driver(&tsi568_driver); | ||
187 | } | ||
188 | |||
189 | static void __exit tsi568_exit(void) | ||
190 | { | ||
191 | rio_unregister_driver(&tsi568_driver); | ||
192 | } | ||
193 | |||
194 | device_initcall(tsi568_init); | ||
195 | module_exit(tsi568_exit); | ||
196 | |||
197 | MODULE_DESCRIPTION("IDT Tsi568 Serial RapidIO switch driver"); | ||
198 | MODULE_AUTHOR("Integrated Device Technology, Inc."); | ||
199 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rapidio/switches/tsi57x.c b/drivers/rapidio/switches/tsi57x.c index db8b8028988d..42c8b014fe15 100644 --- a/drivers/rapidio/switches/tsi57x.c +++ b/drivers/rapidio/switches/tsi57x.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/rio_drv.h> | 19 | #include <linux/rio_drv.h> |
20 | #include <linux/rio_ids.h> | 20 | #include <linux/rio_ids.h> |
21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
22 | #include <linux/module.h> | ||
22 | #include "../rio.h" | 23 | #include "../rio.h" |
23 | 24 | ||
24 | /* Global (broadcast) route registers */ | 25 | /* Global (broadcast) route registers */ |
@@ -292,27 +293,79 @@ exit_es: | |||
292 | return 0; | 293 | return 0; |
293 | } | 294 | } |
294 | 295 | ||
295 | static int tsi57x_switch_init(struct rio_dev *rdev, int do_enum) | 296 | static struct rio_switch_ops tsi57x_switch_ops = { |
297 | .owner = THIS_MODULE, | ||
298 | .add_entry = tsi57x_route_add_entry, | ||
299 | .get_entry = tsi57x_route_get_entry, | ||
300 | .clr_table = tsi57x_route_clr_table, | ||
301 | .set_domain = tsi57x_set_domain, | ||
302 | .get_domain = tsi57x_get_domain, | ||
303 | .em_init = tsi57x_em_init, | ||
304 | .em_handle = tsi57x_em_handler, | ||
305 | }; | ||
306 | |||
307 | static int tsi57x_probe(struct rio_dev *rdev, const struct rio_device_id *id) | ||
296 | { | 308 | { |
297 | pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev)); | 309 | pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev)); |
298 | rdev->rswitch->add_entry = tsi57x_route_add_entry; | 310 | |
299 | rdev->rswitch->get_entry = tsi57x_route_get_entry; | 311 | spin_lock(&rdev->rswitch->lock); |
300 | rdev->rswitch->clr_table = tsi57x_route_clr_table; | 312 | |
301 | rdev->rswitch->set_domain = tsi57x_set_domain; | 313 | if (rdev->rswitch->ops) { |
302 | rdev->rswitch->get_domain = tsi57x_get_domain; | 314 | spin_unlock(&rdev->rswitch->lock); |
303 | rdev->rswitch->em_init = tsi57x_em_init; | 315 | return -EINVAL; |
304 | rdev->rswitch->em_handle = tsi57x_em_handler; | 316 | } |
305 | 317 | rdev->rswitch->ops = &tsi57x_switch_ops; | |
306 | if (do_enum) { | 318 | |
319 | if (rdev->do_enum) { | ||
307 | /* Ensure that default routing is disabled on startup */ | 320 | /* Ensure that default routing is disabled on startup */ |
308 | rio_write_config_32(rdev, RIO_STD_RTE_DEFAULT_PORT, | 321 | rio_write_config_32(rdev, RIO_STD_RTE_DEFAULT_PORT, |
309 | RIO_INVALID_ROUTE); | 322 | RIO_INVALID_ROUTE); |
310 | } | 323 | } |
311 | 324 | ||
325 | spin_unlock(&rdev->rswitch->lock); | ||
312 | return 0; | 326 | return 0; |
313 | } | 327 | } |
314 | 328 | ||
315 | DECLARE_RIO_SWITCH_INIT(RIO_VID_TUNDRA, RIO_DID_TSI572, tsi57x_switch_init); | 329 | static void tsi57x_remove(struct rio_dev *rdev) |
316 | DECLARE_RIO_SWITCH_INIT(RIO_VID_TUNDRA, RIO_DID_TSI574, tsi57x_switch_init); | 330 | { |
317 | DECLARE_RIO_SWITCH_INIT(RIO_VID_TUNDRA, RIO_DID_TSI577, tsi57x_switch_init); | 331 | pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev)); |
318 | DECLARE_RIO_SWITCH_INIT(RIO_VID_TUNDRA, RIO_DID_TSI578, tsi57x_switch_init); | 332 | spin_lock(&rdev->rswitch->lock); |
333 | if (rdev->rswitch->ops != &tsi57x_switch_ops) { | ||
334 | spin_unlock(&rdev->rswitch->lock); | ||
335 | return; | ||
336 | } | ||
337 | rdev->rswitch->ops = NULL; | ||
338 | spin_unlock(&rdev->rswitch->lock); | ||
339 | } | ||
340 | |||
341 | static struct rio_device_id tsi57x_id_table[] = { | ||
342 | {RIO_DEVICE(RIO_DID_TSI572, RIO_VID_TUNDRA)}, | ||
343 | {RIO_DEVICE(RIO_DID_TSI574, RIO_VID_TUNDRA)}, | ||
344 | {RIO_DEVICE(RIO_DID_TSI577, RIO_VID_TUNDRA)}, | ||
345 | {RIO_DEVICE(RIO_DID_TSI578, RIO_VID_TUNDRA)}, | ||
346 | { 0, } /* terminate list */ | ||
347 | }; | ||
348 | |||
349 | static struct rio_driver tsi57x_driver = { | ||
350 | .name = "tsi57x", | ||
351 | .id_table = tsi57x_id_table, | ||
352 | .probe = tsi57x_probe, | ||
353 | .remove = tsi57x_remove, | ||
354 | }; | ||
355 | |||
356 | static int __init tsi57x_init(void) | ||
357 | { | ||
358 | return rio_register_driver(&tsi57x_driver); | ||
359 | } | ||
360 | |||
361 | static void __exit tsi57x_exit(void) | ||
362 | { | ||
363 | rio_unregister_driver(&tsi57x_driver); | ||
364 | } | ||
365 | |||
366 | device_initcall(tsi57x_init); | ||
367 | module_exit(tsi57x_exit); | ||
368 | |||
369 | MODULE_DESCRIPTION("IDT Tsi57x Serial RapidIO switch family driver"); | ||
370 | MODULE_AUTHOR("Integrated Device Technology, Inc."); | ||
371 | MODULE_LICENSE("GPL"); | ||
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 4f2737208c42..c74d88baea60 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h | |||
@@ -275,13 +275,6 @@ | |||
275 | VMLINUX_SYMBOL(__end_builtin_fw) = .; \ | 275 | VMLINUX_SYMBOL(__end_builtin_fw) = .; \ |
276 | } \ | 276 | } \ |
277 | \ | 277 | \ |
278 | /* RapidIO route ops */ \ | ||
279 | .rio_ops : AT(ADDR(.rio_ops) - LOAD_OFFSET) { \ | ||
280 | VMLINUX_SYMBOL(__start_rio_switch_ops) = .; \ | ||
281 | *(.rio_switch_ops) \ | ||
282 | VMLINUX_SYMBOL(__end_rio_switch_ops) = .; \ | ||
283 | } \ | ||
284 | \ | ||
285 | TRACEDATA \ | 278 | TRACEDATA \ |
286 | \ | 279 | \ |
287 | /* Kernel symbol table: Normal symbols */ \ | 280 | /* Kernel symbol table: Normal symbols */ \ |
diff --git a/include/linux/rio.h b/include/linux/rio.h index 18e099342e6f..fcd492e7aff4 100644 --- a/include/linux/rio.h +++ b/include/linux/rio.h | |||
@@ -94,6 +94,23 @@ union rio_pw_msg; | |||
94 | * @switchid: Switch ID that is unique across a network | 94 | * @switchid: Switch ID that is unique across a network |
95 | * @route_table: Copy of switch routing table | 95 | * @route_table: Copy of switch routing table |
96 | * @port_ok: Status of each port (one bit per port) - OK=1 or UNINIT=0 | 96 | * @port_ok: Status of each port (one bit per port) - OK=1 or UNINIT=0 |
97 | * @ops: pointer to switch-specific operations | ||
98 | * @lock: lock to serialize operations updates | ||
99 | * @nextdev: Array of per-port pointers to the next attached device | ||
100 | */ | ||
101 | struct rio_switch { | ||
102 | struct list_head node; | ||
103 | u16 switchid; | ||
104 | u8 *route_table; | ||
105 | u32 port_ok; | ||
106 | struct rio_switch_ops *ops; | ||
107 | spinlock_t lock; | ||
108 | struct rio_dev *nextdev[0]; | ||
109 | }; | ||
110 | |||
111 | /** | ||
112 | * struct rio_switch_ops - Per-switch operations | ||
113 | * @owner: The module owner of this structure | ||
97 | * @add_entry: Callback for switch-specific route add function | 114 | * @add_entry: Callback for switch-specific route add function |
98 | * @get_entry: Callback for switch-specific route get function | 115 | * @get_entry: Callback for switch-specific route get function |
99 | * @clr_table: Callback for switch-specific clear route table function | 116 | * @clr_table: Callback for switch-specific clear route table function |
@@ -101,14 +118,12 @@ union rio_pw_msg; | |||
101 | * @get_domain: Callback for switch-specific domain get function | 118 | * @get_domain: Callback for switch-specific domain get function |
102 | * @em_init: Callback for switch-specific error management init function | 119 | * @em_init: Callback for switch-specific error management init function |
103 | * @em_handle: Callback for switch-specific error management handler function | 120 | * @em_handle: Callback for switch-specific error management handler function |
104 | * @sw_sysfs: Callback that initializes switch-specific sysfs attributes | 121 | * |
105 | * @nextdev: Array of per-port pointers to the next attached device | 122 | * Defines the operations that are necessary to initialize/control |
123 | * a particular RIO switch device. | ||
106 | */ | 124 | */ |
107 | struct rio_switch { | 125 | struct rio_switch_ops { |
108 | struct list_head node; | 126 | struct module *owner; |
109 | u16 switchid; | ||
110 | u8 *route_table; | ||
111 | u32 port_ok; | ||
112 | int (*add_entry) (struct rio_mport *mport, u16 destid, u8 hopcount, | 127 | int (*add_entry) (struct rio_mport *mport, u16 destid, u8 hopcount, |
113 | u16 table, u16 route_destid, u8 route_port); | 128 | u16 table, u16 route_destid, u8 route_port); |
114 | int (*get_entry) (struct rio_mport *mport, u16 destid, u8 hopcount, | 129 | int (*get_entry) (struct rio_mport *mport, u16 destid, u8 hopcount, |
@@ -121,8 +136,6 @@ struct rio_switch { | |||
121 | u8 *sw_domain); | 136 | u8 *sw_domain); |
122 | int (*em_init) (struct rio_dev *dev); | 137 | int (*em_init) (struct rio_dev *dev); |
123 | int (*em_handle) (struct rio_dev *dev, u8 swport); | 138 | int (*em_handle) (struct rio_dev *dev, u8 swport); |
124 | int (*sw_sysfs) (struct rio_dev *dev, int create); | ||
125 | struct rio_dev *nextdev[0]; | ||
126 | }; | 139 | }; |
127 | 140 | ||
128 | /** | 141 | /** |
@@ -130,6 +143,7 @@ struct rio_switch { | |||
130 | * @global_list: Node in list of all RIO devices | 143 | * @global_list: Node in list of all RIO devices |
131 | * @net_list: Node in list of RIO devices in a network | 144 | * @net_list: Node in list of RIO devices in a network |
132 | * @net: Network this device is a part of | 145 | * @net: Network this device is a part of |
146 | * @do_enum: Enumeration flag | ||
133 | * @did: Device ID | 147 | * @did: Device ID |
134 | * @vid: Vendor ID | 148 | * @vid: Vendor ID |
135 | * @device_rev: Device revision | 149 | * @device_rev: Device revision |
@@ -158,6 +172,7 @@ struct rio_dev { | |||
158 | struct list_head global_list; /* node in list of all RIO devices */ | 172 | struct list_head global_list; /* node in list of all RIO devices */ |
159 | struct list_head net_list; /* node in per net list */ | 173 | struct list_head net_list; /* node in per net list */ |
160 | struct rio_net *net; /* RIO net this device resides in */ | 174 | struct rio_net *net; /* RIO net this device resides in */ |
175 | bool do_enum; | ||
161 | u16 did; | 176 | u16 did; |
162 | u16 vid; | 177 | u16 vid; |
163 | u32 device_rev; | 178 | u32 device_rev; |
@@ -297,10 +312,6 @@ struct rio_net { | |||
297 | struct rio_id_table destid_table; /* destID allocation table */ | 312 | struct rio_id_table destid_table; /* destID allocation table */ |
298 | }; | 313 | }; |
299 | 314 | ||
300 | /* Definitions used by switch sysfs initialization callback */ | ||
301 | #define RIO_SW_SYSFS_CREATE 1 /* Create switch attributes */ | ||
302 | #define RIO_SW_SYSFS_REMOVE 0 /* Remove switch attributes */ | ||
303 | |||
304 | /* Low-level architecture-dependent routines */ | 315 | /* Low-level architecture-dependent routines */ |
305 | 316 | ||
306 | /** | 317 | /** |
@@ -400,20 +411,6 @@ struct rio_device_id { | |||
400 | u16 asm_did, asm_vid; | 411 | u16 asm_did, asm_vid; |
401 | }; | 412 | }; |
402 | 413 | ||
403 | /** | ||
404 | * struct rio_switch_ops - Per-switch operations | ||
405 | * @vid: RIO vendor ID | ||
406 | * @did: RIO device ID | ||
407 | * @init_hook: Callback that performs switch device initialization | ||
408 | * | ||
409 | * Defines the operations that are necessary to initialize/control | ||
410 | * a particular RIO switch device. | ||
411 | */ | ||
412 | struct rio_switch_ops { | ||
413 | u16 vid, did; | ||
414 | int (*init_hook) (struct rio_dev *rdev, int do_enum); | ||
415 | }; | ||
416 | |||
417 | union rio_pw_msg { | 414 | union rio_pw_msg { |
418 | struct { | 415 | struct { |
419 | u32 comptag; /* Component Tag CSR */ | 416 | u32 comptag; /* Component Tag CSR */ |