aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rapidio/switches/tsi568.c
diff options
context:
space:
mode:
authorAlexandre Bounine <alexandre.bounine@idt.com>2010-05-26 14:43:57 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-27 09:12:50 -0700
commit07590ff03935a2efbc03bc7861f20c059576a479 (patch)
tree2da1ee2032e1425a138bc2864066a2e10533ce64 /drivers/rapidio/switches/tsi568.c
parentdrivers/char/applicom.c: use memdup_user (diff)
downloadlinux-dev-07590ff03935a2efbc03bc7861f20c059576a479.tar.xz
linux-dev-07590ff03935a2efbc03bc7861f20c059576a479.zip
rapidio: add IDT CPS/TSI switches
Extentions to RapidIO switch support: 1. modify switch route operation declarations to allow using single switch-specific file for family of switches that share the same route table operations. 2. add standard route table operations for switches that that support route table manipulation registers as defined in the Rev.1.3 of RapidIO specification. 3. add clear-route-table operation for switches 4. add CPSxx and TSIxxx families of RapidIO switches Signed-off-by: Alexandre Bounine <alexandre.bounine@idt.com> Tested-by: Thomas Moll <thomas.moll@sysgo.com> Cc: Matt Porter <mporter@kernel.crashing.org> Cc: Li Yang <leoli@freescale.com> Cc: Kumar Gala <galak@kernel.crashing.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/rapidio/switches/tsi568.c')
-rw-r--r--drivers/rapidio/switches/tsi568.c106
1 files changed, 106 insertions, 0 deletions
diff --git a/drivers/rapidio/switches/tsi568.c b/drivers/rapidio/switches/tsi568.c
new file mode 100644
index 000000000000..bce9112ff0d9
--- /dev/null
+++ b/drivers/rapidio/switches/tsi568.c
@@ -0,0 +1,106 @@
+/*
+ * RapidIO Tsi568 switch support
+ *
+ * Copyright 2009-2010 Integrated Device Technology, Inc.
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/rio.h>
+#include <linux/rio_drv.h>
+#include <linux/rio_ids.h>
+#include <linux/delay.h>
+#include "../rio.h"
+
+/* Global (broadcast) route registers */
+#define SPBC_ROUTE_CFG_DESTID 0x10070
+#define SPBC_ROUTE_CFG_PORT 0x10074
+
+/* Per port route registers */
+#define SPP_ROUTE_CFG_DESTID(n) (0x11070 + 0x100*n)
+#define SPP_ROUTE_CFG_PORT(n) (0x11074 + 0x100*n)
+
+static int
+tsi568_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
+ u16 table, u16 route_destid, u8 route_port)
+{
+ if (table == RIO_GLOBAL_TABLE) {
+ rio_mport_write_config_32(mport, destid, hopcount,
+ SPBC_ROUTE_CFG_DESTID, route_destid);
+ rio_mport_write_config_32(mport, destid, hopcount,
+ SPBC_ROUTE_CFG_PORT, route_port);
+ } else {
+ rio_mport_write_config_32(mport, destid, hopcount,
+ SPP_ROUTE_CFG_DESTID(table),
+ route_destid);
+ rio_mport_write_config_32(mport, destid, hopcount,
+ SPP_ROUTE_CFG_PORT(table), route_port);
+ }
+
+ udelay(10);
+
+ return 0;
+}
+
+static int
+tsi568_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
+ u16 table, u16 route_destid, u8 *route_port)
+{
+ int ret = 0;
+ u32 result;
+
+ if (table == RIO_GLOBAL_TABLE) {
+ rio_mport_write_config_32(mport, destid, hopcount,
+ SPBC_ROUTE_CFG_DESTID, route_destid);
+ rio_mport_read_config_32(mport, destid, hopcount,
+ SPBC_ROUTE_CFG_PORT, &result);
+ } else {
+ rio_mport_write_config_32(mport, destid, hopcount,
+ SPP_ROUTE_CFG_DESTID(table),
+ route_destid);
+ rio_mport_read_config_32(mport, destid, hopcount,
+ SPP_ROUTE_CFG_PORT(table), &result);
+ }
+
+ *route_port = result;
+ if (*route_port > 15)
+ ret = -1;
+
+ return ret;
+}
+
+static int
+tsi568_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount,
+ u16 table)
+{
+ u32 route_idx;
+ u32 lut_size;
+
+ lut_size = (mport->sys_size) ? 0x1ff : 0xff;
+
+ if (table == RIO_GLOBAL_TABLE) {
+ rio_mport_write_config_32(mport, destid, hopcount,
+ SPBC_ROUTE_CFG_DESTID, 0x80000000);
+ for (route_idx = 0; route_idx <= lut_size; route_idx++)
+ rio_mport_write_config_32(mport, destid, hopcount,
+ SPBC_ROUTE_CFG_PORT,
+ RIO_INVALID_ROUTE);
+ } else {
+ rio_mport_write_config_32(mport, destid, hopcount,
+ SPP_ROUTE_CFG_DESTID(table),
+ 0x80000000);
+ for (route_idx = 0; route_idx <= lut_size; route_idx++)
+ rio_mport_write_config_32(mport, destid, hopcount,
+ SPP_ROUTE_CFG_PORT(table),
+ RIO_INVALID_ROUTE);
+ }
+
+ return 0;
+}
+
+DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI568, tsi568_route_add_entry, tsi568_route_get_entry, tsi568_route_clr_table);