summaryrefslogtreecommitdiff
path: root/drivers/rapidio/switches/idt_gen2.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-07-04 04:12:13 +0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-04 04:12:13 +0400
commit7f0ef0267e20d62d45d527911a993b1e998f4968 (patch)
treede51abc7da5903f59d83e23937f22420164c9477 /drivers/rapidio/switches/idt_gen2.c
parent862f0012549110d6f2586bf54b52ed4540cbff3a (diff)
parent9307c29524502c21f0e8a6d96d850b2f5bc0bd9a (diff)
downloadlinux-7f0ef0267e20d62d45d527911a993b1e998f4968.tar.xz
Merge branch 'akpm' (updates from Andrew Morton)
Merge first patch-bomb from Andrew Morton: - various misc bits - I'm been patchmonkeying ocfs2 for a while, as Joel and Mark have been distracted. There has been quite a bit of activity. - About half the MM queue - Some backlight bits - Various lib/ updates - checkpatch updates - zillions more little rtc patches - ptrace - signals - exec - procfs - rapidio - nbd - aoe - pps - memstick - tools/testing/selftests updates * emailed patches from Andrew Morton <akpm@linux-foundation.org>: (445 commits) tools/testing/selftests: don't assume the x bit is set on scripts selftests: add .gitignore for kcmp selftests: fix clean target in kcmp Makefile selftests: add .gitignore for vm selftests: add hugetlbfstest self-test: fix make clean selftests: exit 1 on failure kernel/resource.c: remove the unneeded assignment in function __find_resource aio: fix wrong comment in aio_complete() drivers/w1/slaves/w1_ds2408.c: add magic sequence to disable P0 test mode drivers/memstick/host/r592.c: convert to module_pci_driver drivers/memstick/host/jmb38x_ms: convert to module_pci_driver pps-gpio: add device-tree binding and support drivers/pps/clients/pps-gpio.c: convert to module_platform_driver drivers/pps/clients/pps-gpio.c: convert to devm_* helpers drivers/parport/share.c: use kzalloc Documentation/accounting/getdelays.c: avoid strncpy in accounting tool aoe: update internal version number to v83 aoe: update copyright date aoe: perform I/O completions in parallel ...
Diffstat (limited to 'drivers/rapidio/switches/idt_gen2.c')
-rw-r--r--drivers/rapidio/switches/idt_gen2.c98
1 files changed, 80 insertions, 18 deletions
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 @@
*/
#include <linux/stat.h>
+#include <linux/module.h>
#include <linux/rio.h>
#include <linux/rio_drv.h>
#include <linux/rio_ids.h>
@@ -387,12 +388,12 @@ idtg2_show_errlog(struct device *dev, struct device_attribute *attr, char *buf)
static DEVICE_ATTR(errlog, S_IRUGO, idtg2_show_errlog, NULL);
-static int idtg2_sysfs(struct rio_dev *rdev, int create)
+static int idtg2_sysfs(struct rio_dev *rdev, bool create)
{
struct device *dev = &rdev->dev;
int err = 0;
- if (create == RIO_SW_SYSFS_CREATE) {
+ if (create) {
/* Initialize sysfs entries */
err = device_create_file(dev, &dev_attr_errlog);
if (err)
@@ -403,29 +404,90 @@ static int idtg2_sysfs(struct rio_dev *rdev, int create)
return err;
}
-static int idtg2_switch_init(struct rio_dev *rdev, int do_enum)
+static struct rio_switch_ops idtg2_switch_ops = {
+ .owner = THIS_MODULE,
+ .add_entry = idtg2_route_add_entry,
+ .get_entry = idtg2_route_get_entry,
+ .clr_table = idtg2_route_clr_table,
+ .set_domain = idtg2_set_domain,
+ .get_domain = idtg2_get_domain,
+ .em_init = idtg2_em_init,
+ .em_handle = idtg2_em_handler,
+};
+
+static int idtg2_probe(struct rio_dev *rdev, const struct rio_device_id *id)
{
pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev));
- rdev->rswitch->add_entry = idtg2_route_add_entry;
- rdev->rswitch->get_entry = idtg2_route_get_entry;
- rdev->rswitch->clr_table = idtg2_route_clr_table;
- rdev->rswitch->set_domain = idtg2_set_domain;
- rdev->rswitch->get_domain = idtg2_get_domain;
- rdev->rswitch->em_init = idtg2_em_init;
- rdev->rswitch->em_handle = idtg2_em_handler;
- rdev->rswitch->sw_sysfs = idtg2_sysfs;
-
- if (do_enum) {
+
+ spin_lock(&rdev->rswitch->lock);
+
+ if (rdev->rswitch->ops) {
+ spin_unlock(&rdev->rswitch->lock);
+ return -EINVAL;
+ }
+
+ rdev->rswitch->ops = &idtg2_switch_ops;
+
+ if (rdev->do_enum) {
/* Ensure that default routing is disabled on startup */
rio_write_config_32(rdev,
RIO_STD_RTE_DEFAULT_PORT, IDT_NO_ROUTE);
}
+ /* Create device-specific sysfs attributes */
+ idtg2_sysfs(rdev, true);
+
+ spin_unlock(&rdev->rswitch->lock);
return 0;
}
-DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS1848, idtg2_switch_init);
-DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS1616, idtg2_switch_init);
-DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTVPS1616, idtg2_switch_init);
-DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTSPS1616, idtg2_switch_init);
-DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS1432, idtg2_switch_init);
+static void idtg2_remove(struct rio_dev *rdev)
+{
+ pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev));
+ spin_lock(&rdev->rswitch->lock);
+ if (rdev->rswitch->ops != &idtg2_switch_ops) {
+ spin_unlock(&rdev->rswitch->lock);
+ return;
+ }
+ rdev->rswitch->ops = NULL;
+
+ /* Remove device-specific sysfs attributes */
+ idtg2_sysfs(rdev, false);
+
+ spin_unlock(&rdev->rswitch->lock);
+}
+
+static struct rio_device_id idtg2_id_table[] = {
+ {RIO_DEVICE(RIO_DID_IDTCPS1848, RIO_VID_IDT)},
+ {RIO_DEVICE(RIO_DID_IDTCPS1616, RIO_VID_IDT)},
+ {RIO_DEVICE(RIO_DID_IDTVPS1616, RIO_VID_IDT)},
+ {RIO_DEVICE(RIO_DID_IDTSPS1616, RIO_VID_IDT)},
+ {RIO_DEVICE(RIO_DID_IDTCPS1432, RIO_VID_IDT)},
+ { 0, } /* terminate list */
+};
+
+static struct rio_driver idtg2_driver = {
+ .name = "idt_gen2",
+ .id_table = idtg2_id_table,
+ .probe = idtg2_probe,
+ .remove = idtg2_remove,
+};
+
+static int __init idtg2_init(void)
+{
+ return rio_register_driver(&idtg2_driver);
+}
+
+static void __exit idtg2_exit(void)
+{
+ pr_debug("RIO: %s\n", __func__);
+ rio_unregister_driver(&idtg2_driver);
+ pr_debug("RIO: %s done\n", __func__);
+}
+
+device_initcall(idtg2_init);
+module_exit(idtg2_exit);
+
+MODULE_DESCRIPTION("IDT CPS Gen.2 Serial RapidIO switch family driver");
+MODULE_AUTHOR("Integrated Device Technology, Inc.");
+MODULE_LICENSE("GPL");